From e6f0fec1b8c2da30ce8f3c981a38bf072969e497 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 24 Sep 2023 12:40:04 +0200 Subject: [PATCH] Finish and enable the indirect draw calls, reducing the direct command buffer draw calls in the lightmapper to 5 --- libraries/ZVulkan/src/vulkanbuilders.cpp | 4 +- .../vulkan/accelstructs/vk_lightmap.cpp | 9 +++-- .../shaders/lightmap/frag_raytrace.glsl | 38 +++++++++++++++++- .../shaders/lightmap/vert_raytrace.glsl | 40 +++++++++++++++++++ 4 files changed, 86 insertions(+), 5 deletions(-) diff --git a/libraries/ZVulkan/src/vulkanbuilders.cpp b/libraries/ZVulkan/src/vulkanbuilders.cpp index 67af25170..41bb4f7a5 100644 --- a/libraries/ZVulkan/src/vulkanbuilders.cpp +++ b/libraries/ZVulkan/src/vulkanbuilders.cpp @@ -1824,7 +1824,8 @@ std::vector VulkanDeviceBuilder::FindDevices(const std:: // Check if all required features are there if (info.Features.Features.samplerAnisotropy != VK_TRUE || - info.Features.Features.fragmentStoresAndAtomics != VK_TRUE) + info.Features.Features.fragmentStoresAndAtomics != VK_TRUE || + info.Features.Features.multiDrawIndirect != VK_TRUE) continue; VulkanCompatibleDevice dev; @@ -1847,6 +1848,7 @@ std::vector VulkanDeviceBuilder::FindDevices(const std:: enabledFeatures.Features.fragmentStoresAndAtomics = deviceFeatures.Features.fragmentStoresAndAtomics; enabledFeatures.Features.depthClamp = deviceFeatures.Features.depthClamp; enabledFeatures.Features.shaderClipDistance = deviceFeatures.Features.shaderClipDistance; + enabledFeatures.Features.multiDrawIndirect = deviceFeatures.Features.multiDrawIndirect; enabledFeatures.BufferDeviceAddress.bufferDeviceAddress = deviceFeatures.BufferDeviceAddress.bufferDeviceAddress; enabledFeatures.AccelerationStructure.accelerationStructure = deviceFeatures.AccelerationStructure.accelerationStructure; enabledFeatures.RayQuery.rayQuery = deviceFeatures.RayQuery.rayQuery; diff --git a/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp b/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp index f90ecd5d9..61e6ce643 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp +++ b/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp @@ -9,6 +9,8 @@ #include "halffloat.h" #include "filesystem.h" +#define USE_DRAWINDIRECT + static int lastSurfaceCount; static glcycle_t lightmapRaytraceLast; @@ -242,7 +244,7 @@ void VkLightmap::Render() cmd.instanceCount = 1; cmd.firstIndex = surface->startElementIndex; cmd.vertexOffset = 0; - cmd.firstInstance = pos; + cmd.firstInstance = drawindexed.Pos; drawindexed.Constants[drawindexed.Pos] = pc; drawindexed.Commands[drawindexed.Pos] = cmd; drawindexed.Pos++; @@ -538,6 +540,7 @@ void VkLightmap::CreateShaders() traceprefix += "#define USE_RAYQUERY\r\n"; } #ifdef USE_DRAWINDIRECT + prefix += "#define USE_DRAWINDIRECT\r\n"; traceprefix += "#define USE_DRAWINDIRECT\r\n"; #endif @@ -740,7 +743,7 @@ void VkLightmap::UpdateAccelStructDescriptors() .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()) #ifdef USE_DRAWINDIRECT - .AddBuffer(raytrace.descriptorSet0.get(), 5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, drawindexed.ConstantsBuffer.get(), 0, BufferSize * sizeof(LightmapRaytracePC)) + .AddBuffer(raytrace.descriptorSet0.get(), 5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, drawindexed.ConstantsBuffer.get(), 0, drawindexed.BufferSize * sizeof(LightmapRaytracePC)) #endif .Execute(fb->GetDevice()); } @@ -1056,7 +1059,7 @@ void VkLightmap::CreateDrawIndexedBuffer() drawindexed.CommandsBuffer = BufferBuilder() .Usage( - VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, + VK_BUFFER_USAGE_INDIRECT_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, diff --git a/wadsrc/static/shaders/lightmap/frag_raytrace.glsl b/wadsrc/static/shaders/lightmap/frag_raytrace.glsl index 978463c8b..bd8b5cbdf 100644 --- a/wadsrc/static/shaders/lightmap/frag_raytrace.glsl +++ b/wadsrc/static/shaders/lightmap/frag_raytrace.glsl @@ -77,7 +77,33 @@ layout(set = 0, binding = 2) buffer SurfaceBuffer { SurfaceInfo surfaces[]; }; layout(set = 0, binding = 3) buffer LightBuffer { LightInfo lights[]; }; layout(set = 0, binding = 4) buffer PortalBuffer { PortalInfo portals[]; }; -layout(set = 2, binding = 0) uniform sampler2D textures[]; +#if defined(USE_DRAWINDIRECT) + +struct LightmapRaytracePC +{ + uint LightStart; + uint LightEnd; + int SurfaceIndex; + int PushPadding1; + vec3 WorldToLocal; + float TextureSize; + vec3 ProjLocalToU; + float PushPadding2; + vec3 ProjLocalToV; + float PushPadding3; + float TileX; + float TileY; + float TileWidth; + float TileHeight; +}; + +layout(std430, set = 0, binding = 5) buffer ConstantsBuffer { LightmapRaytracePC constants[]; }; + +layout(location = 1) in flat int InstanceIndex; + +int SurfaceIndex; + +#else layout(push_constant) uniform PushConstants { @@ -97,6 +123,10 @@ layout(push_constant) uniform PushConstants float TileHeight; }; +#endif + +layout(set = 2, binding = 0) uniform sampler2D textures[]; + layout(location = 0) centroid in vec3 worldpos; layout(location = 0) out vec4 fragcolor; @@ -116,6 +146,12 @@ vec4 rayColor; void main() { +#if defined(USE_DRAWINDIRECT) + uint LightStart = constants[InstanceIndex].LightStart; + uint LightEnd = constants[InstanceIndex].LightEnd; + SurfaceIndex = constants[InstanceIndex].SurfaceIndex; +#endif + vec3 normal = surfaces[SurfaceIndex].Normal; vec3 origin = worldpos + normal * 0.1; diff --git a/wadsrc/static/shaders/lightmap/vert_raytrace.glsl b/wadsrc/static/shaders/lightmap/vert_raytrace.glsl index 556c7b73c..ba2978a41 100644 --- a/wadsrc/static/shaders/lightmap/vert_raytrace.glsl +++ b/wadsrc/static/shaders/lightmap/vert_raytrace.glsl @@ -1,4 +1,30 @@ +#if defined(USE_DRAWINDIRECT) + +struct LightmapRaytracePC +{ + uint LightStart; + uint LightEnd; + int SurfaceIndex; + int PushPadding1; + vec3 WorldToLocal; + float TextureSize; + vec3 ProjLocalToU; + float PushPadding2; + vec3 ProjLocalToV; + float PushPadding3; + float TileX; + float TileY; + float TileWidth; + float TileHeight; +}; + +layout(std430, set = 0, binding = 5) buffer ConstantsBuffer { LightmapRaytracePC constants[]; }; + +layout(location = 1) out flat int InstanceIndex; + +#else + layout(push_constant) uniform PushConstants { uint LightStart; @@ -17,11 +43,25 @@ layout(push_constant) uniform PushConstants float TileHeight; }; +#endif + layout(location = 0) in vec3 aPosition; layout(location = 0) out vec3 worldpos; void main() { +#if defined(USE_DRAWINDIRECT) + vec3 WorldToLocal = constants[gl_InstanceIndex].WorldToLocal; + float TextureSize = constants[gl_InstanceIndex].TextureSize; + vec3 ProjLocalToU = constants[gl_InstanceIndex].ProjLocalToU; + vec3 ProjLocalToV = constants[gl_InstanceIndex].ProjLocalToV; + float TileX = constants[gl_InstanceIndex].TileX; + float TileY = constants[gl_InstanceIndex].TileY; + float TileWidth = constants[gl_InstanceIndex].TileWidth; + float TileHeight = constants[gl_InstanceIndex].TileHeight; + InstanceIndex = gl_InstanceIndex; +#endif + worldpos = aPosition; // Project to position relative to tile