Round up vertex buffer size to stride multiple to fix OOB attribute reads
authorNoah Fredriks <Noah.Fredriks@amd.com>
Fri, 3 Nov 2017 18:20:06 +0000 (14:20 -0400)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Wed, 10 Jan 2018 11:10:18 +0000 (06:10 -0500)
Partial stride multiple vertex buffer elements are now considered OOB
to accomodate implementations that fetch stride-sized elements

Affects: dEQP-VK.texture.*

Components: Vulkan

VK-GL-CTS issue: 812

Change-Id: I72a2143146b4ea0d893d70d41b7ca2c84c34542a
(cherry picked from commit 50c0544ec8c2e99158bf8a375eacfc9baf364a91)

external/vulkancts/modules/vulkan/texture/vktTextureTestUtil.cpp

index 2548e97..5911f82 100644 (file)
@@ -1094,8 +1094,8 @@ void TextureRenderer::renderQuad (tcu::Surface&                                                                   result,
        else
                DE_ASSERT(DE_FALSE);
 
-       Unique<VkShaderModule>                                  vertexShaderModule              (createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("vertext_" + std::string(getProgramName(progSpec))), 0));
-       Unique<VkShaderModule>                                  fragmentShaderModule    (createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("fragment_" + std::string(getProgramName(progSpec))), 0));
+       Unique<VkShaderModule>                                  vertexShaderModule                      (createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("vertext_" + std::string(getProgramName(progSpec))), 0));
+       Unique<VkShaderModule>                                  fragmentShaderModule            (createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("fragment_" + std::string(getProgramName(progSpec))), 0));
 
        Move<VkSampler>                                                 sampler;
        Move<VkDescriptorSet>                                   descriptorSet[2];
@@ -1106,10 +1106,14 @@ void TextureRenderer::renderQuad (tcu::Surface&                                                                 result,
        Move<VkPipeline>                                                graphicsPipeline;
        Move<VkBuffer>                                                  vertexBuffer;
        de::MovePtr<Allocation>                                 vertexBufferMemory;
-       const deUint32                                                  positionDataSize                = deUint32(sizeof(float) * 4 * 4);
-       const deUint32                                                  textureCoordDataSize    = deUint32(sizeof(float) * numComps * 4);
 
-       const VkPhysicalDeviceProperties                properties                              = m_context.getDeviceProperties();
+       const VkDeviceSize                                              vertexBufferOffset                      = 0;
+       const deUint32                                                  vertexPositionStrideSize        = deUint32(sizeof(tcu::Vec4));
+       const deUint32                                                  vertexTextureStrideSize         = deUint32(numComps * sizeof(float));
+       const deUint32                                                  positionDataSize                        = vertexPositionStrideSize * 4u;
+       const deUint32                                                  textureCoordDataSize            = vertexTextureStrideSize * 4u;
+
+       const VkPhysicalDeviceProperties                properties                                      = m_context.getDeviceProperties();
 
        if (positionDataSize > properties.limits.maxVertexInputAttributeOffset)
        {
@@ -1142,9 +1146,6 @@ void TextureRenderer::renderQuad (tcu::Surface&                                                                   result,
                        }
                };
 
-               const deUint32                                                  vertexPositionStrideSize                        = deUint32(sizeof(tcu::Vec4));
-               const deUint32                                                  vertexTextureStrideSize                         = deUint32(numComps * sizeof(float));
-
                const VkVertexInputBindingDescription   vertexInputBindingDescription[2]        =
                {
                        {
@@ -1395,12 +1396,17 @@ void TextureRenderer::renderQuad (tcu::Surface&                                                                 result,
 
        // Create Vertex Buffer
        {
+               VkDeviceSize bufferSize = positionDataSize + textureCoordDataSize;
+
+               // Pad the buffer size to a stride multiple for the last element so that it isn't out of bounds
+               bufferSize += vertexTextureStrideSize - ((bufferSize - vertexBufferOffset) % vertexTextureStrideSize);
+
                const VkBufferCreateInfo                        vertexBufferParams              =
                {
                        VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
                        DE_NULL,                                                                        // const void*                  pNext;
                        0u,                                                                                     // VkBufferCreateFlags  flags;
-                       positionDataSize + textureCoordDataSize,        // VkDeviceSize                 size;
+                       bufferSize,                                                                     // VkDeviceSize                 size;
                        VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      // VkBufferUsageFlags   usage;
                        VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
                        1u,                                                                                     // deUint32                             queueFamilyCount;
@@ -1453,8 +1459,6 @@ void TextureRenderer::renderQuad (tcu::Surface&                                                                   result,
                vkd.cmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
        }
 
-       const VkDeviceSize                                              vertexBufferOffset              = 0;
-
        vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
        vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1, &descriptorSet[0].get(), 0u, DE_NULL);
        vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 1u, 1, &descriptorSet[1].get(), 0u, DE_NULL);