diff --git a/data/shaders/glsl/computecullandlod/cull.comp b/data/shaders/glsl/computecullandlod/cull.comp index 95668391..a804c822 100644 --- a/data/shaders/glsl/computecullandlod/cull.comp +++ b/data/shaders/glsl/computecullandlod/cull.comp @@ -78,16 +78,6 @@ void main() { 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); // Check if object is within current viewing frustum diff --git a/data/shaders/glsl/computecullandlod/cull.comp.spv b/data/shaders/glsl/computecullandlod/cull.comp.spv index 2191acc7..a90380f9 100644 Binary files a/data/shaders/glsl/computecullandlod/cull.comp.spv and b/data/shaders/glsl/computecullandlod/cull.comp.spv differ diff --git a/examples/computecullandlod/computecullandlod.cpp b/examples/computecullandlod/computecullandlod.cpp index 5b5296d5..c9ce4c3f 100644 --- a/examples/computecullandlod/computecullandlod.cpp +++ b/examples/computecullandlod/computecullandlod.cpp @@ -1,7 +1,7 @@ /* * 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) * @@ -282,6 +282,23 @@ public: 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); + // 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 // 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. @@ -460,7 +477,7 @@ public: stagingBuffer.destroy(); 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, &indirectDrawCountBuffer, sizeof(indirectStats)));