Prepare for doing indirect draw calls

This commit is contained in:
dpjudas 2023-09-24 01:37:00 +02:00 committed by Christoph Oelckers
parent ad97b5408a
commit 7edaf68eea
2 changed files with 77 additions and 2 deletions

View file

@ -35,6 +35,7 @@ VkLightmap::VkLightmap(VulkanRenderDevice* fb) : fb(fb)
CreateUniformBuffer(); CreateUniformBuffer();
CreateLightBuffer(); CreateLightBuffer();
CreateTileBuffer(); CreateTileBuffer();
CreateDrawIndexedBuffer();
CreateShaders(); CreateShaders();
CreateRaytracePipeline(); CreateRaytracePipeline();
@ -50,6 +51,10 @@ VkLightmap::~VkLightmap()
lights.Buffer->Unmap(); lights.Buffer->Unmap();
if (copytiles.Buffer) if (copytiles.Buffer)
copytiles.Buffer->Unmap(); copytiles.Buffer->Unmap();
if (drawindexed.CommandsBuffer)
drawindexed.CommandsBuffer->Unmap();
if (drawindexed.ConstantsBuffer)
drawindexed.ConstantsBuffer->Unmap();
} }
void VkLightmap::SetLevelMesh(LevelMesh* level) void VkLightmap::SetLevelMesh(LevelMesh* level)
@ -66,6 +71,7 @@ void VkLightmap::BeginFrame()
{ {
lights.Pos = 0; lights.Pos = 0;
lights.ResetCounter++; lights.ResetCounter++;
drawindexed.Pos = 0;
} }
void VkLightmap::Raytrace(const TArray<LevelMeshSurface*>& surfaces) void VkLightmap::Raytrace(const TArray<LevelMeshSurface*>& surfaces)
@ -230,8 +236,21 @@ void VkLightmap::Render()
pc.LightStart = surface->LightListPos; pc.LightStart = surface->LightListPos;
pc.LightEnd = pc.LightStart + surface->LightListCount; pc.LightEnd = pc.LightStart + surface->LightListCount;
#ifdef USE_DRAWINDIRECT
VkDrawIndexedIndirectCommand cmd;
cmd.indexCount = surface->numElements;
cmd.instanceCount = 1;
cmd.firstIndex = surface->startElementIndex;
cmd.vertexOffset = 0;
cmd.firstInstance = pos;
drawindexed.Constants[drawindexed.Pos] = pc;
drawindexed.Commands[drawindexed.Pos] = cmd;
drawindexed.Pos++;
#else
cmdbuffer->pushConstants(raytrace.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(LightmapRaytracePC), &pc); cmdbuffer->pushConstants(raytrace.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(LightmapRaytracePC), &pc);
cmdbuffer->drawIndexed(surface->numElements, 1, surface->startElementIndex, 0, 0); cmdbuffer->drawIndexed(surface->numElements, 1, surface->startElementIndex, 0, 0);
#endif
} }
if (buffersFull) if (buffersFull)
@ -247,6 +266,10 @@ void VkLightmap::Render()
selectedSurface.Rendered = true; selectedSurface.Rendered = true;
} }
#ifdef USE_DRAWINDIRECT
cmdbuffer->drawIndexedIndirect(drawindexed.CommandsBuffer->buffer, 0, drawindexed.Pos, sizeof(VkDrawIndexedIndirectCommand));
#endif
cmdbuffer->endRenderPass(); cmdbuffer->endRenderPass();
fb->GetCommands()->PopGroup(cmdbuffer); fb->GetCommands()->PopGroup(cmdbuffer);
@ -515,6 +538,9 @@ void VkLightmap::CreateShaders()
traceprefix += "#extension GL_EXT_ray_query : require\r\n"; traceprefix += "#extension GL_EXT_ray_query : require\r\n";
traceprefix += "#define USE_RAYQUERY\r\n"; traceprefix += "#define USE_RAYQUERY\r\n";
} }
#ifdef USE_DRAWINDIRECT
traceprefix += "#define USE_DRAWINDIRECT\r\n";
#endif
shaders.vertRaytrace = ShaderBuilder() shaders.vertRaytrace = ShaderBuilder()
.Type(ShaderType::Vertex) .Type(ShaderType::Vertex)
@ -588,6 +614,9 @@ void VkLightmap::CreateRaytracePipeline()
.AddBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT) .AddBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT)
.AddBinding(3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT) .AddBinding(3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT)
.AddBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT) .AddBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT)
#ifdef USE_DRAWINDIRECT
.AddBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT)
#endif
.DebugName("raytrace.descriptorSetLayout0") .DebugName("raytrace.descriptorSetLayout0")
.Create(fb->GetDevice()); .Create(fb->GetDevice());
@ -614,7 +643,9 @@ void VkLightmap::CreateRaytracePipeline()
.AddSetLayout(raytrace.descriptorSetLayout0.get()) .AddSetLayout(raytrace.descriptorSetLayout0.get())
.AddSetLayout(raytrace.descriptorSetLayout1.get()) .AddSetLayout(raytrace.descriptorSetLayout1.get())
.AddSetLayout(fb->GetDescriptorSetManager()->GetBindlessSetLayout()) .AddSetLayout(fb->GetDescriptorSetManager()->GetBindlessSetLayout())
#ifndef USE_DRAWINDIRECT
.AddPushConstantRange(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(LightmapRaytracePC)) .AddPushConstantRange(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(LightmapRaytracePC))
#endif
.DebugName("raytrace.pipelineLayout") .DebugName("raytrace.pipelineLayout")
.Create(fb->GetDevice()); .Create(fb->GetDevice());
@ -653,7 +684,7 @@ void VkLightmap::CreateRaytracePipeline()
raytrace.descriptorPool0 = DescriptorPoolBuilder() raytrace.descriptorPool0 = DescriptorPoolBuilder()
.AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1) .AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1)
.AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 4) .AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 5)
.MaxSets(1) .MaxSets(1)
.DebugName("raytrace.descriptorPool0") .DebugName("raytrace.descriptorPool0")
.Create(fb->GetDevice()); .Create(fb->GetDevice());
@ -708,8 +739,10 @@ void VkLightmap::UpdateAccelStructDescriptors()
.AddBuffer(raytrace.descriptorSet0.get(), 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetRaytrace()->GetSurfaceBuffer()) .AddBuffer(raytrace.descriptorSet0.get(), 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetRaytrace()->GetSurfaceBuffer())
.AddBuffer(raytrace.descriptorSet0.get(), 3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, lights.Buffer.get()) .AddBuffer(raytrace.descriptorSet0.get(), 3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, lights.Buffer.get())
.AddBuffer(raytrace.descriptorSet0.get(), 4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetRaytrace()->GetPortalBuffer()) .AddBuffer(raytrace.descriptorSet0.get(), 4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetRaytrace()->GetPortalBuffer())
#ifdef USE_DRAWINDIRECT
.AddBuffer(raytrace.descriptorSet0.get(), 5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, drawindexed.ConstantsBuffer.get(), 0, BufferSize * sizeof(LightmapRaytracePC))
#endif
.Execute(fb->GetDevice()); .Execute(fb->GetDevice());
} }
void VkLightmap::CreateResolvePipeline() void VkLightmap::CreateResolvePipeline()
@ -1015,3 +1048,34 @@ void VkLightmap::CreateTileBuffer()
copytiles.Tiles = (CopyTileInfo*)copytiles.Buffer->Map(0, size); copytiles.Tiles = (CopyTileInfo*)copytiles.Buffer->Map(0, size);
} }
void VkLightmap::CreateDrawIndexedBuffer()
{
size_t size1 = sizeof(VkDrawIndexedIndirectCommand) * drawindexed.BufferSize;
size_t size2 = sizeof(LightmapRaytracePC) * drawindexed.BufferSize;
drawindexed.CommandsBuffer = BufferBuilder()
.Usage(
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
VMA_MEMORY_USAGE_UNKNOWN, VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT)
.MemoryType(
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
.Size(size1)
.DebugName("DrawIndexed.CommandsBuffer")
.Create(fb->GetDevice());
drawindexed.ConstantsBuffer = BufferBuilder()
.Usage(
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
VMA_MEMORY_USAGE_UNKNOWN, VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT)
.MemoryType(
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
.Size(size2)
.DebugName("DrawIndexed.ConstantsBuffer")
.Create(fb->GetDevice());
drawindexed.Commands = (VkDrawIndexedIndirectCommand*)drawindexed.CommandsBuffer->Map(0, size1);
drawindexed.Constants = (LightmapRaytracePC*)drawindexed.ConstantsBuffer->Map(0, size2);
}

View file

@ -146,6 +146,7 @@ private:
void CreateUniformBuffer(); void CreateUniformBuffer();
void CreateLightBuffer(); void CreateLightBuffer();
void CreateTileBuffer(); void CreateTileBuffer();
void CreateDrawIndexedBuffer();
void CreateBakeImage(); void CreateBakeImage();
static FVector2 ToUV(const FVector3& vert, const LevelMeshSurface* targetSurface); static FVector2 ToUV(const FVector3& vert, const LevelMeshSurface* targetSurface);
@ -188,6 +189,16 @@ private:
CopyTileInfo* Tiles = nullptr; CopyTileInfo* Tiles = nullptr;
} copytiles; } copytiles;
struct
{
const int BufferSize = 100'000;
std::unique_ptr<VulkanBuffer> CommandsBuffer;
std::unique_ptr<VulkanBuffer> ConstantsBuffer;
VkDrawIndexedIndirectCommand* Commands = nullptr;
LightmapRaytracePC* Constants = nullptr;
int Pos = 0;
} drawindexed;
struct struct
{ {
std::unique_ptr<VulkanShader> vertRaytrace; std::unique_ptr<VulkanShader> vertRaytrace;