Move all buffers to DeviceAddress.
This commit is contained in:
parent
19e3222460
commit
7c07346e92
|
|
@ -30,6 +30,7 @@ struct Buffer
|
|||
vk::Buffer m_Buffer = nullptr;
|
||||
VmaAllocation m_Allocation = nullptr;
|
||||
u8 *m_Mapped = nullptr; ///< If the buffer is host visible, it should be (and stay) mapped.
|
||||
uptr m_DeviceAddr = 0;
|
||||
usize m_Size = 0;
|
||||
Flags m_Flags = {};
|
||||
|
||||
|
|
@ -54,7 +55,7 @@ struct Buffer
|
|||
|
||||
/// If Buffer Device Address is enabled,
|
||||
/// Get a pointer.
|
||||
uptr GetDeviceAddress(Device const *device) const;
|
||||
[[nodiscard]] uptr GetDeviceAddress() const;
|
||||
|
||||
// Constructors
|
||||
|
||||
|
|
|
|||
|
|
@ -16,13 +16,14 @@
|
|||
#include "aster/core/buffer.h"
|
||||
#include "aster/core/image_view.h"
|
||||
#include "aster/core/sampler.h"
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
namespace systems
|
||||
{
|
||||
class RenderingDevice;
|
||||
|
||||
class CommitManager
|
||||
namespace _internal
|
||||
{
|
||||
template <typename T>
|
||||
struct HandleMapper
|
||||
|
|
@ -196,7 +197,10 @@ class CommitManager
|
|||
}
|
||||
}
|
||||
};
|
||||
} // namespace _internal
|
||||
|
||||
class CommitManager
|
||||
{
|
||||
union WriteInfo {
|
||||
vk::DescriptorBufferInfo uBufferInfo;
|
||||
vk::DescriptorImageInfo uImageInfo;
|
||||
|
|
@ -221,8 +225,10 @@ class CommitManager
|
|||
PIN_MEMORY(CommitManager);
|
||||
|
||||
// Commit Buffer
|
||||
private:
|
||||
ResId<Buffer> CommitBuffer(Ref<Buffer> const &buffer);
|
||||
|
||||
public:
|
||||
// Commit Storage Images
|
||||
ResId<StorageImageView>
|
||||
CommitStorageImage(concepts::ViewRefTo<StorageImage> auto const &image)
|
||||
|
|
@ -302,9 +308,9 @@ class CommitManager
|
|||
constexpr static u8 IMAGE_BINDING_INDEX = 0x1;
|
||||
constexpr static u8 STORAGE_IMAGE_BINDING_INDEX = 0x2;
|
||||
|
||||
HandleMapper<Buffer> m_Buffers;
|
||||
HandleMapper<TextureView> m_Images;
|
||||
HandleMapper<StorageImageView> m_StorageImages;
|
||||
_internal::HandleMapper<Buffer> m_Buffers;
|
||||
_internal::HandleMapper<TextureView> m_Images;
|
||||
_internal::HandleMapper<StorageImageView> m_StorageImages;
|
||||
|
||||
Ref<Sampler> m_DefaultSampler;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ Buffer::Buffer(Device const *device, usize const size, vk::BufferUsageFlags cons
|
|||
|
||||
vk::BufferCreateInfo bufferCreateInfo = {
|
||||
.size = size,
|
||||
.usage = bufferUsage,
|
||||
.usage = bufferUsage | vk::BufferUsageFlagBits::eShaderDeviceAddress,
|
||||
.sharingMode = vk::SharingMode::eExclusive,
|
||||
};
|
||||
VmaAllocationCreateInfo const allocationCreateInfo = {
|
||||
|
|
@ -56,6 +56,9 @@ Buffer::Buffer(Device const *device, usize const size, vk::BufferUsageFlags cons
|
|||
if (bufferUsage & vk::BufferUsageFlagBits::eStorageBuffer)
|
||||
m_Flags |= FlagBits::eStorage;
|
||||
|
||||
vk::BufferDeviceAddressInfo const addressInfo = {.buffer = m_Buffer};
|
||||
m_DeviceAddr = m_Device->m_Device.getBufferAddress(&addressInfo);
|
||||
|
||||
device->SetName(m_Buffer, name);
|
||||
}
|
||||
|
||||
|
|
@ -64,6 +67,7 @@ Buffer::Buffer(Buffer &&other) noexcept
|
|||
, m_Buffer{Take(other.m_Buffer)}
|
||||
, m_Allocation{Take(other.m_Allocation)}
|
||||
, m_Mapped{Take(other.m_Mapped)}
|
||||
, m_DeviceAddr{Take(other.m_DeviceAddr)}
|
||||
, m_Size{Take(other.m_Size)}
|
||||
{
|
||||
}
|
||||
|
|
@ -78,6 +82,7 @@ Buffer::operator=(Buffer &&other) noexcept
|
|||
swap(m_Buffer, other.m_Buffer);
|
||||
swap(m_Allocation, other.m_Allocation);
|
||||
swap(m_Mapped, other.m_Mapped);
|
||||
swap(m_DeviceAddr, other.m_DeviceAddr);
|
||||
swap(m_Size, other.m_Size);
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -92,10 +97,9 @@ Buffer::~Buffer()
|
|||
}
|
||||
|
||||
uptr
|
||||
Buffer::GetDeviceAddress(Device const *device) const
|
||||
Buffer::GetDeviceAddress() const
|
||||
{
|
||||
vk::BufferDeviceAddressInfo const addressInfo = {.buffer = m_Buffer};
|
||||
return device->m_Device.getBufferAddress(&addressInfo);
|
||||
return m_DeviceAddr;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -5,11 +5,7 @@ cmake_minimum_required(VERSION 3.13)
|
|||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fsanitize=address")
|
||||
|
||||
add_executable(box "box.cpp" "stb_image.h")
|
||||
add_shader(box "shader/box.vert.glsl")
|
||||
add_shader(box "shader/box.frag.glsl")
|
||||
add_shader(box "shader/box.vs.hlsl")
|
||||
add_shader(box "shader/box.ps.hlsl")
|
||||
add_shader(box "shader/triangle.slang")
|
||||
add_shader(box "shader/box.slang")
|
||||
add_resource_dir(box "shader/")
|
||||
|
||||
target_link_libraries(box PRIVATE aster_core)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
constexpr auto VERTEX_SHADER_FILE = "shader/box.vs.hlsl.spv";
|
||||
constexpr auto FRAGMENT_SHADER_FILE = "shader/box.ps.hlsl.spv";
|
||||
constexpr auto SHADER_FILE = "triangle";
|
||||
constexpr auto SHADER_FILE = "box";
|
||||
|
||||
struct ImageFile
|
||||
{
|
||||
|
|
@ -328,11 +328,10 @@ main(int, char **)
|
|||
initDepthImages(extent);
|
||||
};
|
||||
|
||||
// TODO: Move to 64bit handles.
|
||||
struct PCB
|
||||
{
|
||||
systems::ResId<Buffer> m_VertexBuffer;
|
||||
systems::ResId<Buffer> m_Camera;
|
||||
uptr m_VertexBuffer;
|
||||
uptr m_Camera;
|
||||
systems::ResId<TextureView> m_Texture;
|
||||
};
|
||||
static_assert(sizeof(PCB) == 24);
|
||||
|
|
@ -340,8 +339,8 @@ main(int, char **)
|
|||
auto &commitManager = systems::CommitManager::Instance();
|
||||
|
||||
PCB pcb = {
|
||||
.m_VertexBuffer = commitManager.CommitBuffer(vbo),
|
||||
.m_Camera = commitManager.CommitBuffer(ubo),
|
||||
.m_VertexBuffer = vbo->GetDeviceAddress(),
|
||||
.m_Camera = ubo->GetDeviceAddress(),
|
||||
.m_Texture = commitManager.CommitTexture(crate),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
|
||||
|
||||
struct VertexData
|
||||
{
|
||||
float4 Position;
|
||||
float2 TexCoord0;
|
||||
float2 _pad0;
|
||||
};
|
||||
|
||||
struct CameraData
|
||||
{
|
||||
float4x4 Model;
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
};
|
||||
|
||||
struct Handle
|
||||
{
|
||||
uint value;
|
||||
|
||||
uint GetIndex()
|
||||
{
|
||||
return value & 0x0FFFFFFF;
|
||||
}
|
||||
};
|
||||
|
||||
[[vk::binding(0, 0)]] StructuredBuffer<VertexData> VertexDataBuffer[];
|
||||
[[vk::binding(0, 0)]] StructuredBuffer<CameraData> CameraDataBuffer[];
|
||||
|
||||
[[vk::binding(1, 0)]] Texture2D<float4> Textures[];
|
||||
[[vk::binding(1, 0)]] SamplerState Samplers[];
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
#version 450
|
||||
#pragma shader_stage(fragment)
|
||||
|
||||
layout (location = 0) in vec2 inUV;
|
||||
layout (location = 0) out vec4 outColor;
|
||||
|
||||
layout(binding = 1) uniform sampler2D tex;
|
||||
|
||||
void main() {
|
||||
outColor = vec4(texture(tex, inUV).rgb, 1.0f);
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
#include "bindless.hlsli"
|
||||
|
||||
struct FS_Input {
|
||||
float2 UV0 : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct FS_Output
|
||||
{
|
||||
float4 ColorTarget : SV_Target0;
|
||||
};
|
||||
|
||||
struct PCB
|
||||
{
|
||||
Handle CameraBuffer;
|
||||
Handle VertexBuffer;
|
||||
Handle Texture;
|
||||
};
|
||||
|
||||
[[vk::push_constant]] PCB Block;
|
||||
|
||||
FS_Output main(FS_Input StageInput) {
|
||||
FS_Output output;
|
||||
|
||||
output.ColorTarget = float4(Textures[Block.Texture.GetIndex()].Sample(Samplers[Block.Texture.GetIndex()], StageInput.UV0).rgb, 1.0);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
|
@ -15,9 +15,9 @@ struct CameraData
|
|||
};
|
||||
|
||||
struct PCB {
|
||||
DescriptorHandle<StructuredBuffer<VertexData>> vertexBuffer;
|
||||
DescriptorHandle<StructuredBuffer<CameraData>> cameraBuffer;
|
||||
DescriptorHandle<Sampler2D> texture;
|
||||
VertexData* vertexBuffer;
|
||||
CameraData* cameraBuffer;
|
||||
Sampler2D.Handle texture;
|
||||
};
|
||||
|
||||
[vk::push_constant]
|
||||
|
|
@ -43,7 +43,7 @@ func vsmain(VSIn input) -> VSOut {
|
|||
|
||||
VertexData vd = pcb.vertexBuffer[input.vertexIndex];
|
||||
|
||||
output.position = mul(mul(mul(float4(vd.position.xyz, 1.0f), pcb.cameraBuffer[0].model), pcb.cameraBuffer[0].view), pcb.cameraBuffer[0].projection);
|
||||
output.position = mul(mul(mul(float4(vd.position.xyz, 1.0f), pcb.cameraBuffer->model), pcb.cameraBuffer->view), pcb.cameraBuffer->projection);
|
||||
output.texCoord0 = vd.texCoord0;
|
||||
|
||||
return output;
|
||||
|
|
@ -52,7 +52,6 @@ func vsmain(VSIn input) -> VSOut {
|
|||
[shader("fragment")]
|
||||
func fsmain(VSOut input) -> FSOut {
|
||||
FSOut outp;
|
||||
outp.Color = pcb.vertexBuffer[0].position.rgba;
|
||||
outp.Color = float4(pcb.texture.Sample(input.texCoord0).rgb, 1.0);
|
||||
return outp;
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
#version 450
|
||||
#pragma shader_stage(vertex)
|
||||
|
||||
layout(location=0) in vec4 position;
|
||||
layout(location=1) in vec2 uv0;
|
||||
|
||||
layout(location=0) out vec2 outUV;
|
||||
|
||||
layout(binding=0) uniform Camera {
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
} ubo;
|
||||
|
||||
void main() {
|
||||
outUV = uv0;
|
||||
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(position.xyz, 1.0f);
|
||||
// outColor = vec3(0.5f, 0.3f, 0.1f);
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
#include "bindless.hlsli"
|
||||
|
||||
struct VS_Input
|
||||
{
|
||||
uint VertexIndex : SV_VertexID;
|
||||
};
|
||||
|
||||
struct VS_Output
|
||||
{
|
||||
float2 UV0 : TEXCOORD0;
|
||||
float4 VertexPosition : SV_Position;
|
||||
};
|
||||
|
||||
struct PCB
|
||||
{
|
||||
Handle CameraBuffer;
|
||||
Handle VertexBuffer;
|
||||
Handle Texture;
|
||||
};
|
||||
|
||||
[[vk::push_constant]] PCB Block;
|
||||
|
||||
VS_Output main(VS_Input StageInput) {
|
||||
VS_Output output;
|
||||
|
||||
CameraData Camera = CameraDataBuffer[Block.CameraBuffer.GetIndex()][0];
|
||||
|
||||
output.UV0 = VertexDataBuffer[Block.VertexBuffer.GetIndex()][StageInput.VertexIndex].TexCoord0;
|
||||
|
||||
float4 position = VertexDataBuffer[Block.VertexBuffer.GetIndex()][StageInput.VertexIndex].Position;
|
||||
|
||||
output.VertexPosition = mul(Camera.Projection, mul(Camera.View, mul(Camera.Model, position)));
|
||||
|
||||
return output;
|
||||
}
|
||||
|
|
@ -474,7 +474,7 @@ AssetLoader::LoadModelToGpu(cstr path, cstr name)
|
|||
eastl::hash_map<i32, systems::ResId<TextureView>> textureHandleMap;
|
||||
|
||||
eastl::vector<Material> materials;
|
||||
systems::ResId<Buffer> materialsHandle = systems::ResId<Buffer>::Null();
|
||||
Ref<Buffer> materialsBuffer;
|
||||
|
||||
if (!model.materials.empty())
|
||||
{
|
||||
|
|
@ -515,8 +515,7 @@ AssetLoader::LoadModelToGpu(cstr path, cstr name)
|
|||
}
|
||||
|
||||
usize materialsByteSize = materials.size() * sizeof materials[0];
|
||||
auto materialsBuffer = m_Device->CreateStorageBuffer(materialsByteSize, name);
|
||||
materialsHandle = m_Device->m_CommitManager->CommitBuffer(materialsBuffer);
|
||||
materialsBuffer = m_Device->CreateStorageBuffer(materialsByteSize, name);
|
||||
|
||||
context.UploadBuffer(materialsBuffer, materials);
|
||||
}
|
||||
|
|
@ -803,7 +802,6 @@ AssetLoader::LoadModelToGpu(cstr path, cstr name)
|
|||
|
||||
auto nodeBuffer = m_Device->CreateStorageBuffer(nodes.GetGlobalTransformByteSize());
|
||||
nodeBuffer->Write(0, nodes.GetGlobalTransformByteSize(), nodes.GetGlobalTransformPtr());
|
||||
systems::ResId<Buffer> nodeHandle = m_Device->m_CommitManager->CommitBuffer(nodeBuffer);
|
||||
|
||||
#pragma region Staging / Transfer / Uploads
|
||||
systems::ResId<Buffer> positionBufferHandle = systems::ResId<Buffer>::Null();
|
||||
|
|
@ -811,11 +809,9 @@ AssetLoader::LoadModelToGpu(cstr path, cstr name)
|
|||
Ref<IndexBuffer> indexBuffer;
|
||||
|
||||
auto positionBuffer = m_Device->CreateStorageBuffer(vertexPositions.size() * sizeof vertexPositions[0]);
|
||||
positionBufferHandle = m_Device->m_CommitManager->CommitBuffer(positionBuffer);
|
||||
context.UploadBuffer(positionBuffer, vertexPositions);
|
||||
|
||||
auto vertexDataBuffer = m_Device->CreateStorageBuffer(vertexData.size() * sizeof vertexData[0]);
|
||||
vertexDataHandle = m_Device->m_CommitManager->CommitBuffer(vertexDataBuffer);
|
||||
context.UploadBuffer(vertexDataBuffer, vertexData);
|
||||
|
||||
// TODO: Index buffer needs to be separated.
|
||||
|
|
@ -834,11 +830,14 @@ AssetLoader::LoadModelToGpu(cstr path, cstr name)
|
|||
m_Device->WaitOn(rcpt);
|
||||
|
||||
Model::ModelHandles handles = {
|
||||
.m_VertexPositionHandle = positionBufferHandle,
|
||||
.m_VertexDataHandle = vertexDataHandle,
|
||||
.m_MaterialsHandle = materialsHandle,
|
||||
.m_NodeHandle = nodeHandle,
|
||||
.m_VertexPositionHandle = positionBuffer,
|
||||
.m_VertexDataHandle = vertexDataBuffer,
|
||||
.m_MaterialsHandle = materialsBuffer,
|
||||
.m_NodeHandle = nodeBuffer,
|
||||
};
|
||||
Model::ModelHandlesData handlesData = handles;
|
||||
auto handlesBuffer = m_Device->CreateStorageBuffer(sizeof handlesData, "Materials");
|
||||
handlesBuffer->Write(0, sizeof handlesData, &handlesData);
|
||||
|
||||
eastl::vector<systems::ResId<TextureView>> textureHandles;
|
||||
textureHandles.reserve(textureHandleMap.size());
|
||||
|
|
@ -849,17 +848,19 @@ AssetLoader::LoadModelToGpu(cstr path, cstr name)
|
|||
}
|
||||
|
||||
return Model{
|
||||
textureHandles, std::move(nodes), nodeBuffer, handles, indexBuffer, meshPrimitives,
|
||||
textureHandles, std::move(nodes), nodeBuffer, handles, handlesBuffer, indexBuffer, meshPrimitives,
|
||||
};
|
||||
}
|
||||
|
||||
Model::Model(eastl::vector<systems::ResId<TextureView>> &textureHandles, Nodes &&nodes, Ref<Buffer> nodeBuffer,
|
||||
ModelHandles &handles, Ref<IndexBuffer> indexBuffer, eastl::vector<MeshPrimitive> const &meshPrimitives)
|
||||
ModelHandles &handles, Ref<Buffer> modelHandlesBuffer, Ref<IndexBuffer> indexBuffer,
|
||||
eastl::vector<MeshPrimitive> const &meshPrimitives)
|
||||
: m_TextureHandles(std::move(textureHandles))
|
||||
, m_Nodes(std::move(nodes))
|
||||
, m_Handles(std::move(handles))
|
||||
, m_NodeBuffer(std::move(nodeBuffer))
|
||||
, m_IndexBuffer(std::move(indexBuffer))
|
||||
, m_ModelHandlesBuffer(std::move(modelHandlesBuffer))
|
||||
, m_MeshPrimitives(meshPrimitives)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,16 +74,35 @@ struct Model
|
|||
eastl::vector<systems::ResId<TextureView>> m_TextureHandles;
|
||||
Nodes m_Nodes;
|
||||
|
||||
struct ModelHandlesData
|
||||
{
|
||||
uptr m_VertexPositionHandle;
|
||||
uptr m_VertexDataHandle;
|
||||
uptr m_MaterialsHandle;
|
||||
uptr m_NodeHandle;
|
||||
};
|
||||
|
||||
struct ModelHandles
|
||||
{
|
||||
systems::ResId<Buffer> m_VertexPositionHandle;
|
||||
systems::ResId<Buffer> m_VertexDataHandle;
|
||||
systems::ResId<Buffer> m_MaterialsHandle;
|
||||
systems::ResId<Buffer> m_NodeHandle;
|
||||
Ref<Buffer> m_VertexPositionHandle;
|
||||
Ref<Buffer> m_VertexDataHandle;
|
||||
Ref<Buffer> m_MaterialsHandle;
|
||||
Ref<Buffer> m_NodeHandle;
|
||||
|
||||
operator ModelHandlesData() const
|
||||
{
|
||||
return {
|
||||
.m_VertexPositionHandle = m_VertexPositionHandle->GetDeviceAddress(),
|
||||
.m_VertexDataHandle = m_VertexDataHandle->GetDeviceAddress(),
|
||||
.m_MaterialsHandle = m_MaterialsHandle->GetDeviceAddress(),
|
||||
.m_NodeHandle = m_NodeHandle->GetDeviceAddress(),
|
||||
};
|
||||
}
|
||||
} m_Handles;
|
||||
|
||||
Ref<Buffer> m_NodeBuffer;
|
||||
Ref<IndexBuffer> m_IndexBuffer;
|
||||
Ref<Buffer> m_ModelHandlesBuffer;
|
||||
eastl::vector<MeshPrimitive> m_MeshPrimitives;
|
||||
|
||||
[[nodiscard]] mat4 const &GetModelTransform() const;
|
||||
|
|
@ -91,7 +110,8 @@ struct Model
|
|||
void Update();
|
||||
|
||||
Model(eastl::vector<systems::ResId<TextureView>> &textureHandles, Nodes &&nodes, Ref<Buffer> nodeBuffer,
|
||||
ModelHandles &handles, Ref<IndexBuffer> indexBuffer, eastl::vector<MeshPrimitive> const &meshPrimitives);
|
||||
ModelHandles &handles, Ref<Buffer> modelHandlesBuffer, Ref<IndexBuffer> indexBuffer,
|
||||
eastl::vector<MeshPrimitive> const &meshPrimitives);
|
||||
~Model() = default;
|
||||
|
||||
Model(Model &&other) noexcept = default;
|
||||
|
|
|
|||
|
|
@ -59,35 +59,11 @@ LightManager::LightManager(systems::RenderingDevice &device)
|
|||
: m_Device{&device}
|
||||
, m_DirectionalLightCount{}
|
||||
, m_PointLightCount{}
|
||||
, m_MetaInfo{.m_LightBuffer = systems::NullId()}
|
||||
, m_MetaInfo{}
|
||||
, m_GpuBufferCapacity_{0}
|
||||
{
|
||||
}
|
||||
|
||||
LightManager::LightManager(LightManager &&other) noexcept
|
||||
: m_Device{Take(other.m_Device)}
|
||||
, m_Lights(std::move(other.m_Lights))
|
||||
, m_DirectionalLightCount(other.m_DirectionalLightCount)
|
||||
, m_PointLightCount(other.m_PointLightCount)
|
||||
, m_MetaInfo(std::move(other.m_MetaInfo))
|
||||
, m_GpuBufferCapacity_(other.m_GpuBufferCapacity_)
|
||||
{
|
||||
}
|
||||
|
||||
LightManager &
|
||||
LightManager::operator=(LightManager &&other) noexcept
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
m_Device = Take(other.m_Device);
|
||||
m_Lights = std::move(other.m_Lights);
|
||||
m_DirectionalLightCount = other.m_DirectionalLightCount;
|
||||
m_PointLightCount = other.m_PointLightCount;
|
||||
m_MetaInfo = std::move(other.m_MetaInfo);
|
||||
m_GpuBufferCapacity_ = other.m_GpuBufferCapacity_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LightHandle
|
||||
LightManager::AddDirectional(vec3 const &direction, vec3 const &color, f32 intensity)
|
||||
{
|
||||
|
|
@ -208,15 +184,14 @@ LightManager::Update()
|
|||
u16 const requiredBufferCapacity = eastl::min(static_cast<u16>(m_Lights.capacity()), MAX_LIGHTS);
|
||||
if ((m_GpuBufferCapacity_ & CAPACITY_MASK) < requiredBufferCapacity)
|
||||
{
|
||||
auto newBuffer = m_Device->CreateStorageBuffer(requiredBufferCapacity * sizeof m_Lights[0], "Light Buffer");
|
||||
m_LightBuffer = m_Device->CreateStorageBuffer(requiredBufferCapacity * sizeof m_Lights[0], "Light Buffer");
|
||||
m_GpuBufferCapacity_ = requiredBufferCapacity | UPDATE_REQUIRED_BIT;
|
||||
|
||||
m_MetaInfo.m_LightBuffer = m_Device->m_CommitManager->CommitBuffer(newBuffer);
|
||||
m_MetaInfo.m_LightBuffer = m_LightBuffer->GetDeviceAddress();
|
||||
}
|
||||
if (m_GpuBufferCapacity_ & UPDATE_REQUIRED_BIT)
|
||||
{
|
||||
auto const ref = m_Device->m_CommitManager->FetchHandle(m_MetaInfo.m_LightBuffer);
|
||||
ref->Write(0, m_Lights.size() * sizeof m_Lights[0], m_Lights.data());
|
||||
m_LightBuffer->Write(0, m_Lights.size() * sizeof m_Lights[0], m_Lights.data());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -82,15 +82,16 @@ struct LightManager
|
|||
// We can use that with Offset = 0, and point light at further offsets.
|
||||
// This way we don't need to move point lights often.
|
||||
|
||||
systems::ResId<Buffer> m_LightBuffer; // 04 04
|
||||
u16 m_PointLightMaxCount; // 02 06
|
||||
u16 m_PointLightOffset; // 02 08
|
||||
u16 m_DirectionalLightMaxCount; // 02 10
|
||||
u16 m_UnusedPadding0 = 0; // 02 12
|
||||
uptr m_LightBuffer; // 08 08
|
||||
u16 m_PointLightMaxCount; // 02 10
|
||||
u16 m_PointLightOffset; // 02 12
|
||||
u16 m_DirectionalLightMaxCount; // 02 14
|
||||
u16 m_UnusedPadding0 = 0; // 02 16
|
||||
};
|
||||
|
||||
systems::RenderingDevice *m_Device;
|
||||
eastl::vector<Light> m_Lights;
|
||||
Ref<Buffer> m_LightBuffer;
|
||||
|
||||
// We don't need a Directional Light free list. We will just brute force iterate.
|
||||
u16 m_DirectionalLightCount;
|
||||
|
|
@ -113,9 +114,9 @@ struct LightManager
|
|||
|
||||
~LightManager() = default;
|
||||
|
||||
LightManager(systems::RenderingDevice &device);
|
||||
LightManager(LightManager &&other) noexcept;
|
||||
LightManager &operator=(LightManager &&other) noexcept;
|
||||
explicit LightManager(systems::RenderingDevice &device);
|
||||
LightManager(LightManager &&other) noexcept = default;
|
||||
LightManager &operator=(LightManager &&other) noexcept = default;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(LightManager);
|
||||
};
|
||||
|
|
@ -138,7 +138,12 @@ main(int, char **)
|
|||
Window window = {"ModelRender (Aster)", {INIT_WIDTH, INIT_HEIGHT}};
|
||||
|
||||
Features enabledDeviceFeatures = {
|
||||
.m_Vulkan10Features = {.samplerAnisotropy = true, .shaderInt16 = true},
|
||||
.m_Vulkan10Features =
|
||||
{
|
||||
.samplerAnisotropy = true,
|
||||
.shaderInt64 = true,
|
||||
.shaderInt16 = true,
|
||||
},
|
||||
.m_Vulkan12Features =
|
||||
{
|
||||
.descriptorIndexing = true,
|
||||
|
|
@ -226,10 +231,8 @@ main(int, char **)
|
|||
static_cast<f32>(swapchainSize.m_Height)};
|
||||
|
||||
auto cameraBuffer = device.CreateStorageBuffer(sizeof cameraController.m_Camera, "Camera Info");
|
||||
auto cameraBufferId = device.m_CommitManager->CommitBuffer(cameraBuffer);
|
||||
auto lightManagerBuffer =
|
||||
device.CreateStorageBuffer(sizeof environment + sizeof lightManager.m_MetaInfo, "Light Info");
|
||||
auto lightsBufferId = device.m_CommitManager->CommitBuffer(lightManagerBuffer);
|
||||
lightManagerBuffer->Write(0, sizeof environment, &environment);
|
||||
lightManagerBuffer->Write(sizeof environment, sizeof lightManager.m_MetaInfo, &lightManager.m_MetaInfo);
|
||||
|
||||
|
|
@ -544,12 +547,21 @@ main(int, char **)
|
|||
}
|
||||
|
||||
u32 pcbOffset = 0;
|
||||
context.PushConstantBlock(model.m_Handles);
|
||||
pcbOffset += sizeof model.m_Handles;
|
||||
context.PushConstantBlock(pcbOffset, cameraBufferId);
|
||||
pcbOffset += sizeof cameraBufferId;
|
||||
context.PushConstantBlock(pcbOffset, lightsBufferId);
|
||||
pcbOffset += sizeof lightsBufferId;
|
||||
{
|
||||
auto modelHandlesAddr = model.m_ModelHandlesBuffer->GetDeviceAddress();
|
||||
context.PushConstantBlock(pcbOffset, modelHandlesAddr);
|
||||
pcbOffset += sizeof modelHandlesAddr;
|
||||
}
|
||||
{
|
||||
auto cameraBufferAddr = cameraBuffer->GetDeviceAddress();
|
||||
context.PushConstantBlock(pcbOffset, cameraBufferAddr);
|
||||
pcbOffset += sizeof cameraBufferAddr;
|
||||
}
|
||||
{
|
||||
auto lightsBufferAddr = lightManagerBuffer->GetDeviceAddress();
|
||||
context.PushConstantBlock(pcbOffset, lightsBufferAddr);
|
||||
pcbOffset += sizeof lightsBufferAddr;
|
||||
}
|
||||
context.PushConstantBlock(pcbOffset, flags);
|
||||
pcbOffset += sizeof flags;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ VS_Output vsmain(
|
|||
VS_Output stageOutput;
|
||||
stageOutput.vertexPosition = float4(trianglePoints[vertexId], 1.0f);
|
||||
|
||||
float4 clipSpace = mul(float4(trianglePoints[vertexId], 1.0f), pcb.camera[0].invProj);
|
||||
float4 worldSpace = mul(clipSpace / clipSpace.wwww, pcb.camera[0].invView);
|
||||
float4 clipSpace = mul(float4(trianglePoints[vertexId], 1.0f), pcb.camera->invProj);
|
||||
float4 worldSpace = mul(clipSpace / clipSpace.wwww, pcb.camera->invView);
|
||||
stageOutput.worldPosition = worldSpace.xyz;
|
||||
|
||||
return stageOutput;
|
||||
|
|
@ -35,22 +35,22 @@ VS_Output vsmain(
|
|||
[shader("fragment")]
|
||||
float4 fsmain(float3 worldPosition: World_Position) : SV_Target0
|
||||
{
|
||||
float3 direction = normalize(worldPosition - pcb.camera[0].position.xyz);
|
||||
float3 direction = normalize(worldPosition - pcb.camera->position.xyz);
|
||||
#ifndef _DEBUG
|
||||
float4 color = pcb.lights[0].environment.Sample(direction);
|
||||
float4 color = pcb.lights->environment.Sample(direction);
|
||||
#else
|
||||
float4 color;
|
||||
if (pcb.showDiffuse)
|
||||
{
|
||||
color = pcb.lights[0].diffuseIrradiance.Sample(direction);
|
||||
color = pcb.lights->diffuseIrradiance.Sample(direction);
|
||||
}
|
||||
else if (pcb.showPrefilter)
|
||||
{
|
||||
color = pcb.lights[0].prefilter.Sample(direction);
|
||||
color = pcb.lights->prefilter.Sample(direction);
|
||||
}
|
||||
else
|
||||
{
|
||||
color = pcb.lights[0].environment.Sample(direction);
|
||||
color = pcb.lights->environment.Sample(direction);
|
||||
}
|
||||
#endif
|
||||
return float4(Uncharted2Tonemap(color.rgb), color.a);
|
||||
|
|
|
|||
|
|
@ -70,11 +70,19 @@ struct Lighting
|
|||
SamplerCube.Handle diffuseIrradiance; // 16
|
||||
SamplerCube.Handle prefilter; // 24
|
||||
Sampler2D<float2>.Handle brdfLUT; // 32
|
||||
ByteAddressBuffer.Handle lights; // 40
|
||||
void* lightData; // 40
|
||||
Indexer pointLightIndexer; // 44
|
||||
Indexer dirLightIndexer; // 48
|
||||
};
|
||||
|
||||
struct ModelHandles
|
||||
{
|
||||
float4 *vertexBuffer; // 8
|
||||
VertexData* vertexData; // 16
|
||||
MaterialData* materialBuffer; // 24
|
||||
TransformData* nodeBuffer; // 32
|
||||
};
|
||||
|
||||
struct Block
|
||||
{
|
||||
static const uint USE_DIFFUSE_BIT = 1;
|
||||
|
|
@ -82,12 +90,9 @@ struct Block
|
|||
static const uint SHOW_DIFFUSE_BIT = 4;
|
||||
static const uint SHOW_PREFILTER_BIT = 8;
|
||||
|
||||
StructuredBuffer<float4>.Handle vertexBuffer; // 8
|
||||
StructuredBuffer<VertexData>.Handle vertexData; // 16
|
||||
StructuredBuffer<MaterialData>.Handle materialBuffer; // 24
|
||||
StructuredBuffer<TransformData>.Handle nodeBuffer; // 32
|
||||
StructuredBuffer<CameraData>.Handle camera; // 40
|
||||
StructuredBuffer<Lighting>.Handle lights; // 48
|
||||
ModelHandles *modelHandles;
|
||||
CameraData* camera; // 40
|
||||
Lighting* lights; // 48
|
||||
|
||||
uint debugFlags; // 52
|
||||
|
||||
|
|
|
|||
|
|
@ -2,14 +2,6 @@ import bindless;
|
|||
import ibl_common;
|
||||
import common_structs;
|
||||
|
||||
struct ModelHandles
|
||||
{
|
||||
StructuredBuffer<float4>.Handle vertexBuffer; // 8
|
||||
StructuredBuffer<VertexData>.Handle vertexData; // 16
|
||||
StructuredBuffer<MaterialData>.Handle materialBuffer; // 24
|
||||
StructuredBuffer<TransformData>.Handle nodeBuffer; // 32
|
||||
};
|
||||
|
||||
[vk::push_constant]
|
||||
uniform Block pcb;
|
||||
|
||||
|
|
@ -29,32 +21,32 @@ struct VS_Output
|
|||
|
||||
float2 GetUV(uint vertexId)
|
||||
{
|
||||
return pcb.vertexData[vertexId].uv0.xy;
|
||||
return pcb.modelHandles->vertexData[vertexId].uv0.xy;
|
||||
}
|
||||
|
||||
float4 GetPosition(uint vertexId)
|
||||
{
|
||||
return float4(pcb.vertexBuffer[vertexId].xyz, 1.0f);
|
||||
return float4(pcb.modelHandles->vertexBuffer[vertexId].xyz, 1.0f);
|
||||
}
|
||||
|
||||
float4 GetNormal(uint vertexId)
|
||||
{
|
||||
return pcb.vertexData[vertexId].normal;
|
||||
return pcb.modelHandles->vertexData[vertexId].normal;
|
||||
}
|
||||
|
||||
float4 GetColor(uint vertexId)
|
||||
{
|
||||
return pcb.vertexData[vertexId].color0;
|
||||
return pcb.modelHandles->vertexData[vertexId].color0;
|
||||
}
|
||||
|
||||
float4x4 GetNodeTransform(uint nodeIdx)
|
||||
{
|
||||
return pcb.nodeBuffer[nodeIdx].transform;
|
||||
return pcb.modelHandles->nodeBuffer[nodeIdx].transform;
|
||||
}
|
||||
|
||||
float4x4 GetNormalTransform(uint nodeIdx)
|
||||
{
|
||||
return pcb.nodeBuffer[nodeIdx].normalTransform;
|
||||
return pcb.modelHandles->nodeBuffer[nodeIdx].normalTransform;
|
||||
}
|
||||
|
||||
[shader("vertex")]
|
||||
|
|
@ -63,9 +55,9 @@ VS_Output vsmain(VS_Input stageInput)
|
|||
VS_Output stageOutput;
|
||||
|
||||
float4 worldPosition = mul(GetPosition(stageInput.vertexId), GetNodeTransform(pcb.nodeIdx));
|
||||
float4 clipSpace = mul(worldPosition, pcb.camera[0].view);
|
||||
float4 clipSpace = mul(worldPosition, pcb.camera->view);
|
||||
|
||||
stageOutput.vertexPosition = mul(clipSpace, pcb.camera[0].proj);
|
||||
stageOutput.vertexPosition = mul(clipSpace, pcb.camera->proj);
|
||||
stageOutput.worldPosition = worldPosition;
|
||||
stageOutput.uv0 = GetUV(stageInput.vertexId);
|
||||
stageOutput.vertexColor = GetColor(stageInput.vertexId);
|
||||
|
|
@ -76,23 +68,23 @@ VS_Output vsmain(VS_Input stageInput)
|
|||
|
||||
float4 GetAlbedo(float2 uv, float4 color)
|
||||
{
|
||||
float4 albedoFactor = pcb.materialBuffer[NonUniformResourceIndex(pcb.materialIdx)].albedoFactor;
|
||||
var albedoTex = pcb.materialBuffer[NonUniformResourceIndex(pcb.materialIdx)].albedoTex;
|
||||
float4 albedoFactor = pcb.modelHandles->materialBuffer[NonUniformResourceIndex(pcb.materialIdx)].albedoFactor;
|
||||
var albedoTex = pcb.modelHandles->materialBuffer[NonUniformResourceIndex(pcb.materialIdx)].albedoTex;
|
||||
|
||||
return albedoFactor * color * (IsValid(albedoTex) ? albedoTex.Sample(uv) : 1.0f.xxxx);
|
||||
}
|
||||
|
||||
float GetOcclusion(float2 uv)
|
||||
{
|
||||
var occlusionTex = pcb.materialBuffer[NonUniformResourceIndex(pcb.materialIdx)].occlusionTex;
|
||||
var occlusionTex = pcb.modelHandles->materialBuffer[NonUniformResourceIndex(pcb.materialIdx)].occlusionTex;
|
||||
|
||||
return IsValid(occlusionTex) ? occlusionTex.Sample(uv).r : 1.0f;
|
||||
}
|
||||
|
||||
float3 GetEmissive(float2 uv)
|
||||
{
|
||||
float3 emissionFactor = pcb.materialBuffer[NonUniformResourceIndex(pcb.materialIdx)].emissionFactor.rgb;
|
||||
var emissionTex = pcb.materialBuffer[NonUniformResourceIndex(pcb.materialIdx)].emissionTex;
|
||||
float3 emissionFactor = pcb.modelHandles->materialBuffer[NonUniformResourceIndex(pcb.materialIdx)].emissionFactor.rgb;
|
||||
var emissionTex = pcb.modelHandles->materialBuffer[NonUniformResourceIndex(pcb.materialIdx)].emissionTex;
|
||||
|
||||
return emissionFactor * (IsValid(emissionTex) ? emissionTex.Sample(uv).rgb : 1.0f.xxx);
|
||||
}
|
||||
|
|
@ -101,7 +93,7 @@ float3 GetNormal(float3 position, float3 normal, float2 uv)
|
|||
{
|
||||
float3 N = normalize(normal);
|
||||
|
||||
var normalTex = pcb.materialBuffer[NonUniformResourceIndex(pcb.materialIdx)].normalTex;
|
||||
var normalTex = pcb.modelHandles->materialBuffer[NonUniformResourceIndex(pcb.materialIdx)].normalTex;
|
||||
if (!IsValid(normalTex))
|
||||
{
|
||||
return N;
|
||||
|
|
@ -123,16 +115,16 @@ float3 GetNormal(float3 position, float3 normal, float2 uv)
|
|||
|
||||
float2 GetMetalRough(float2 uv)
|
||||
{
|
||||
var material = pcb.materialBuffer[NonUniformResourceIndex(pcb.materialIdx)];
|
||||
var material = pcb.modelHandles->materialBuffer[NonUniformResourceIndex(pcb.materialIdx)];
|
||||
float2 metalRough = float2(material.metalFactor, material.roughFactor);
|
||||
var metalRoughTex = pcb.materialBuffer[NonUniformResourceIndex(pcb.materialIdx)].metalRoughTex;
|
||||
var metalRoughTex = pcb.modelHandles->materialBuffer[NonUniformResourceIndex(pcb.materialIdx)].metalRoughTex;
|
||||
|
||||
return metalRough * (IsValid(metalRoughTex) ? metalRoughTex.Sample(uv).bg : 1.0f.xx); // Metal is B, Rough is G.
|
||||
}
|
||||
|
||||
float3 SampleIrradiance(float3 direction)
|
||||
{
|
||||
var diffuseIrradiance = pcb.lights[0].diffuseIrradiance;
|
||||
var diffuseIrradiance = pcb.lights->diffuseIrradiance;
|
||||
if (IsValid(diffuseIrradiance))
|
||||
{
|
||||
return diffuseIrradiance.Sample(direction).rgb;
|
||||
|
|
@ -142,7 +134,7 @@ float3 SampleIrradiance(float3 direction)
|
|||
|
||||
float3 SamplePrefiltered(float3 direction, float roughness)
|
||||
{
|
||||
var prefilter = pcb.lights[0].prefilter;
|
||||
var prefilter = pcb.lights->prefilter;
|
||||
if (!IsValid(prefilter))
|
||||
return 0.0f.xxx;
|
||||
|
||||
|
|
@ -154,7 +146,7 @@ float3 SamplePrefiltered(float3 direction, float roughness)
|
|||
|
||||
float2 SampleBrdfLut(float nDotV, float roughness)
|
||||
{
|
||||
var brdfLut = pcb.lights[0].brdfLUT;
|
||||
var brdfLut = pcb.lights->brdfLUT;
|
||||
if (IsValid(brdfLut))
|
||||
{
|
||||
return brdfLut.Sample(float2(nDotV, roughness));
|
||||
|
|
@ -206,16 +198,16 @@ float3 GetPBRContrib(float3 Albedo, float3 LightColor, float3 ViewDir, float3 No
|
|||
|
||||
float3 GetPointLightInfluence(float3 Albedo, float2 MetalRough, float3 Position, float3 Normal)
|
||||
{
|
||||
var lightData = pcb.lights[0];
|
||||
var pointLightBuffer = (StructuredBuffer<PointLight>.Handle)lightData.lights;
|
||||
Lighting* lightData = pcb.lights;
|
||||
PointLight* pointLightBuffer = (PointLight*)lightData->lightData;
|
||||
|
||||
if (!IsValid(pointLightBuffer))
|
||||
if (!pointLightBuffer)
|
||||
return 0.0f.xxx;
|
||||
|
||||
uint offset = lightData.pointLightIndexer.offset;
|
||||
uint count = lightData.pointLightIndexer.count;
|
||||
|
||||
float3 ViewDir = normalize(pcb.camera[0].position.xyz - Position);
|
||||
float3 ViewDir = normalize(pcb.camera->position.xyz - Position);
|
||||
|
||||
float Metallic = MetalRough.r;
|
||||
float Roughness = MetalRough.g;
|
||||
|
|
@ -256,15 +248,15 @@ float3 GetPointLightInfluence(float3 Albedo, float2 MetalRough, float3 Position,
|
|||
|
||||
float3 GetDirectionalLightInfluence(float3 Albedo, float2 MetalRough, float3 Position, float3 Normal)
|
||||
{
|
||||
var lightData = pcb.lights[0];
|
||||
var dirLightBuffer = (StructuredBuffer<DirectionalLight>.Handle)lightData.lights;
|
||||
Lighting* lightData = pcb.lights;
|
||||
var dirLightBuffer = (DirectionalLight*)lightData.lightData;
|
||||
|
||||
if (!IsValid(dirLightBuffer))
|
||||
if (!dirLightBuffer)
|
||||
return 0.0f.xxx;
|
||||
|
||||
uint count = lightData.dirLightIndexer.count;
|
||||
|
||||
float3 ViewDir = normalize(pcb.camera[0].position.xyz - Position);
|
||||
float3 ViewDir = normalize(pcb.camera->position.xyz - Position);
|
||||
|
||||
float Metallic = MetalRough.r;
|
||||
float Roughness = MetalRough.g;
|
||||
|
|
@ -299,7 +291,7 @@ float3 GetDirectionalLightInfluence(float3 Albedo, float2 MetalRough, float3 Pos
|
|||
|
||||
float3 GetAmbientInfluence(float3 Albedo, float2 MetalRough, float3 Position, float3 Normal, float Occlusion)
|
||||
{
|
||||
float3 ViewDir = normalize(pcb.camera[0].position.xyz - Position);
|
||||
float3 ViewDir = normalize(pcb.camera->position.xyz - Position);
|
||||
float CosineFactor = max(dot(Normal, ViewDir), 0.0f); // Normal instead of Halfway since there's no halfway in ambient.
|
||||
|
||||
float Metal = MetalRough.r;
|
||||
|
|
|
|||
Loading…
Reference in New Issue