Fill stats and draw count buffer with zeroes

Fixes #748
This commit is contained in:
Sascha Willems 2022-12-31 16:01:11 +01:00
parent e0a49c20e8
commit 6e68f76456
3 changed files with 19 additions and 12 deletions

View file

@ -78,16 +78,6 @@ void main()
{ {
uint idx = gl_GlobalInvocationID.x + gl_GlobalInvocationID.y * gl_NumWorkGroups.x * gl_WorkGroupSize.x; uint idx = gl_GlobalInvocationID.x + gl_GlobalInvocationID.y * gl_NumWorkGroups.x * gl_WorkGroupSize.x;
// Clear stats on first invocation
if (idx == 0)
{
atomicExchange(uboOut.drawCount, 0);
for (uint i = 0; i < MAX_LOD_LEVEL + 1; i++)
{
atomicExchange(uboOut.lodCount[i], 0);
}
}
vec4 pos = vec4(instances[idx].pos.xyz, 1.0); vec4 pos = vec4(instances[idx].pos.xyz, 1.0);
// Check if object is within current viewing frustum // Check if object is within current viewing frustum

View file

@ -1,7 +1,7 @@
/* /*
* Vulkan Example - Compute shader culling and LOD using indirect rendering * Vulkan Example - Compute shader culling and LOD using indirect rendering
* *
* Copyright (C) 2016 by Sascha Willems - www.saschawillems.de * Copyright (C) 2016-2022 by Sascha Willems - www.saschawillems.de
* *
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
* *
@ -282,6 +282,23 @@ public:
vkCmdBindPipeline(compute.commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute.pipeline); vkCmdBindPipeline(compute.commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute.pipeline);
vkCmdBindDescriptorSets(compute.commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute.pipelineLayout, 0, 1, &compute.descriptorSet, 0, 0); vkCmdBindDescriptorSets(compute.commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute.pipelineLayout, 0, 1, &compute.descriptorSet, 0, 0);
// Clear the buffer that the compute shader pass will write statistics and draw calls to
vkCmdFillBuffer(compute.commandBuffer, indirectDrawCountBuffer.buffer, 0, indirectCommandsBuffer.descriptor.range, 0);
// This barrier ensures that the fill command is finished before the compute shader can start writing to the buffer
VkMemoryBarrier memoryBarrier = vks::initializers::memoryBarrier();
memoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
memoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
vkCmdPipelineBarrier(
compute.commandBuffer,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
VK_FLAGS_NONE,
1, &memoryBarrier,
0, nullptr,
0, nullptr);
// Dispatch the compute job // Dispatch the compute job
// The compute shader will do the frustum culling and adjust the indirect draw calls depending on object visibility. // The compute shader will do the frustum culling and adjust the indirect draw calls depending on object visibility.
// It also determines the lod to use depending on distance to the viewer. // It also determines the lod to use depending on distance to the viewer.
@ -460,7 +477,7 @@ public:
stagingBuffer.destroy(); stagingBuffer.destroy();
VK_CHECK_RESULT(vulkanDevice->createBuffer( VK_CHECK_RESULT(vulkanDevice->createBuffer(
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
&indirectDrawCountBuffer, &indirectDrawCountBuffer,
sizeof(indirectStats))); sizeof(indirectStats)));