SSBOLayoutCase: Make proper use of array descriptors
authorJason Ekstrand <jason.ekstrand@intel.com>
Sun, 21 Feb 2016 02:32:43 +0000 (18:32 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Thu, 25 Feb 2016 18:12:34 +0000 (10:12 -0800)
Previously, the SSBO tests were using arrays of blocks in the shader but
declaring them as individual descriptors in the descriptor set layout.
This is in violation of the spec and was causing issues on some
implementations.

As a side-effect of this change, we now update most of the bindings in a
single update.  The Vulkan spec allows descriptor writes that go over the
bounds of the current binding to spill into the next as long as the
bindings have the same type.  This makes updating substantially simpler
especially when we have bindings with different numbers of descriptors.

external/vulkancts/modules/vulkan/ssbo/vktSSBOLayoutCase.cpp

index 9817caa..b9e6415 100644 (file)
@@ -1221,14 +1221,10 @@ string generateComputeShader (const ShaderInterface& interface, const BufferLayo
                src << glu::declare(*structIter) << ";\n";
 
        {
-               int bindingPoint = 1;
-
                for (int blockNdx = 0; blockNdx < interface.getNumBlocks(); blockNdx++)
                {
                        const BufferBlock& block = interface.getBlock(blockNdx);
-                       generateDeclaration(src, block, bindingPoint);
-
-                       bindingPoint += block.isArray() ? block.getArraySize() : 1;
+                       generateDeclaration(src, block, 1 + blockNdx);
                }
        }
 
@@ -1863,11 +1859,23 @@ tcu::TestStatus SSBOLayoutCaseInstance::iterate (void)
        setLayoutBuilder
                .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
 
-       const int numBlocks     = (int)m_refLayout.blocks.size();
-       for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++)
+       int numBlocks = 0;
+       const int numBindings = m_interface.getNumBlocks();
+       for (int bindingNdx = 0; bindingNdx < numBindings; bindingNdx++)
        {
-               setLayoutBuilder
-                       .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
+               const BufferBlock& block = m_interface.getBlock(bindingNdx);
+               if (block.isArray())
+               {
+                       setLayoutBuilder
+                               .addArrayBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, block.getArraySize(), vk::VK_SHADER_STAGE_COMPUTE_BIT);
+                       numBlocks += block.getArraySize();
+               }
+               else
+               {
+                       setLayoutBuilder
+                               .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
+                       numBlocks += 1;
+               }
        }
 
        poolBuilder
@@ -1923,10 +1931,10 @@ tcu::TestStatus SSBOLayoutCaseInstance::iterate (void)
 
                                m_uniformBuffers.push_back(VkBufferSp(new vk::Unique<vk::VkBuffer>(buffer)));
                                m_uniformAllocs.push_back(AllocationSp(alloc.release()));
-
-                               setUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(blockNdx + 1),
-                                                                                       vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptors[blockNdx]);
                        }
+
+                       setUpdateBuilder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1),
+                                                                               vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, numBlocks, &descriptors[0]);
                }
                else
                {
@@ -1960,11 +1968,11 @@ tcu::TestStatus SSBOLayoutCaseInstance::iterate (void)
                                const deUint32                                          offset          = blockLocations[blockNdx].offset;
 
                                descriptors[blockNdx] = makeDescriptorBufferInfo(*buffer, offset, bufferSize);
-
-                               setUpdateBuilder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(blockNdx + 1),
-                                                                               vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptors[blockNdx]);
                        }
 
+                       setUpdateBuilder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1),
+                                                                               vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, numBlocks, &descriptors[0]);
+
                        m_uniformBuffers.push_back(VkBufferSp(new vk::Unique<vk::VkBuffer>(buffer)));
                        m_uniformAllocs.push_back(AllocationSp(alloc.release()));
                }