From 5a6c1361ce5a7d315ac6bd537668ee95e86b6475 Mon Sep 17 00:00:00 2001 From: kingscallop <54776947+kingscallop@users.noreply.github.com> Date: Sat, 16 Jan 2021 22:00:40 +0000 Subject: [PATCH] Fix compute on Vulkan when there is only one buffer but no uniforms (#2359) When using this compute shader, the following validation errors appear. This patch fixes the issue. BUFFER_WR(cBuffer, uint, 1); NUM_THREADS(1u, 1u, 1u) void main() { cBuffer[0] = 0u; } ../../../src/renderer_vk.cpp (628): BGFX ---E- CommandBuffer, Validation, 0: Validation Error: [ VUID-vkCmdBindDescriptorSets-dynamicOffsetCount-00359 ] Object 0: handle = 0x7fffe453ec88, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0x82756c54 | vkCmdBindDescriptorSets(): Attempting to bind 1 descriptorSets with 0 dynamic descriptors, but dynamicOffsetCount is 1. It should exactly match the number of dynamic descriptors. The Vulkan spec states: dynamicOffsetCount must be equal to the total number of dynamic descriptors in pDescriptorSets (https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/ vkspec.html#VUID-vkCmdBindDescriptorSets-dynamicOffsetCount-00359) ../../../src/renderer_vk.cpp (628): BGFX ---E- Pipeline, Validation, 0: Validation Error: [ VUID-vkCmdDispatch-None-02697 ] Object 0: handle = 0xcd00000000cd, type = VK_OBJECT_TYPE_PIPELINE; Object 1: handle = 0x630000000063, type = VK_OBJECT_TYPE_PIPELINE_LAYOUT; Object 2: VK_NULL_HANDLE, type = VK_OBJECT_TYPE_PIPELINE_LAYOUT; | MessageID = 0xfd9e3152 | vkCmdDispatch(): VkPipeline 0xcd00000000cd[] defined with VkPipelineLayout 0x630000000063[] is not compatible for maximum set statically used 0 with bound descriptor sets, last bound with VkPipelineLayout 0x0[] The Vulkan spec states: For each set n that is statically used by the VkPipeline bound to the pipeline bind point used by this command, a descriptor set must have been bound to n at the same pipeline bind point, with a VkPipelineLayout that is compatible for set n, with the VkPipelineLayout used to create the current VkPipeline, as described in Pipeline Layout Compatibility (https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/ vkspec.html#VUID-vkCmdDispatch-None-02697) ../../../src/renderer_vk.cpp (628): BGFX ---E- CommandBuffer, Validation, 0: Validation Error: [ UNASSIGNED-CoreValidation-DrawState-DescriptorSetNotBound ] Object 0: handle = 0x7fffe453ec88, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0xcde11083 | VkPipeline 0xcd00000000cd[] uses set #0 but that set is not bound. --- src/renderer_vk.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp index 32fdba259..4d07cc626 100644 --- a/src/renderer_vk.cpp +++ b/src/renderer_vk.cpp @@ -6808,6 +6808,7 @@ VK_DESTROY allocDescriptorSet(program, renderBind, scratchBuffer); } + uint32_t numOffset = 0; uint32_t offset = 0; if (constantsChanged @@ -6816,11 +6817,15 @@ VK_DESTROY const uint32_t align = uint32_t(m_deviceProperties.limits.minUniformBufferOffsetAlignment); const uint32_t vsize = bx::strideAlign(program.m_vsh->m_size, align); - offset = scratchBuffer.m_pos; + if (vsize > 0) + { + offset = scratchBuffer.m_pos; + ++numOffset; - bx::memCopy(&scratchBuffer.m_data[scratchBuffer.m_pos], m_vsScratch, program.m_vsh->m_size); + bx::memCopy(&scratchBuffer.m_data[scratchBuffer.m_pos], m_vsScratch, program.m_vsh->m_size); - scratchBuffer.m_pos += vsize; + scratchBuffer.m_pos += vsize; + } } vkCmdBindDescriptorSets( @@ -6830,7 +6835,7 @@ VK_DESTROY , 0 , 1 , &scratchBuffer.getCurrentDS() - , constantsChanged || hasPredefined ? 1 : 0 + , numOffset , &offset ); }