Fix undersized buffer use in extend operands tests
authorReed Koser <rkoser@nvidia.com>
Thu, 5 Sep 2019 20:48:11 +0000 (13:48 -0700)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Thu, 10 Oct 2019 13:30:52 +0000 (09:30 -0400)
Prior to this patch, the dEQP.image.extend_operands_spirv1p4.* tests
used the size of the input image as the buffer size. Since the tests
reuse the buffer to read back the output image (which is potentially
much larger, due to the unconditional use of R32G32B32A32_*INT formats),
this resulted in corruption of device memory.

Affects: dEQP-VK.image.extend_operands_spirv1p4.*

Components: Vulkan

VK-GL-CTS issue: 1980

Change-Id: I8d07cd7d54cc305635b9674074a7eafa52bf6dfa
(cherry picked from commit b38bedda7faf25272716ee234812d432637972e3)

external/vulkancts/modules/vulkan/image/vktImageLoadStoreTests.cpp

index 12e9799..97a8a13 100644 (file)
@@ -1527,13 +1527,14 @@ protected:
 
        de::MovePtr<Image>                              m_imageSrc;                             // source image
        SharedVkImageView                               m_imageSrcView;
+       VkDeviceSize                                    m_imageSrcSize;
 
        de::MovePtr<Image>                              m_imageDst;                             // dest image
        SharedVkImageView                               m_imageDstView;
        VkFormat                                                m_imageDstFormat;
+       VkDeviceSize                                    m_imageDstSize;
 
        de::MovePtr<Buffer>                             m_buffer;                               // result buffer
-       VkDeviceSize                                    m_bufferSizeBytes;
 
        Move<VkDescriptorSetLayout>             m_descriptorSetLayout;
        Move<VkDescriptorPool>                  m_descriptorPool;
@@ -1573,21 +1574,25 @@ ImageExtendOperandTestInstance::ImageExtendOperandTestInstance (Context& context
                MemoryRequirement::Any));
 
        // Create destination image
-       m_bufferSizeBytes       = width * height * tcu::getPixelSize(textureFormat);
        m_imageDstFormat        = m_isSigned ? VK_FORMAT_R32G32B32A32_SINT : VK_FORMAT_R32G32B32A32_UINT;
        m_imageDst = de::MovePtr<Image>(new Image(
                vk, device, allocator,
                makeImageCreateInfo(m_texture, m_imageDstFormat, VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0u),
                MemoryRequirement::Any));
 
+       // Compute image and buffer sizes
+       m_imageSrcSize                                  = width * height * tcu::getPixelSize(textureFormat);
+       m_imageDstSize                                  = width * height * tcu::getPixelSize(mapVkFormat(m_imageDstFormat));
+       VkDeviceSize bufferSizeBytes    = de::max(m_imageSrcSize, m_imageDstSize);
+
        // Create helper buffer able to store input data and image write result
        m_buffer = de::MovePtr<Buffer>(new Buffer(
                vk, device, allocator,
-               makeBufferCreateInfo(m_bufferSizeBytes, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT),
+               makeBufferCreateInfo(bufferSizeBytes, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT),
                MemoryRequirement::HostVisible));
 
        const Allocation& alloc = m_buffer->getAllocation();
-       deMemcpy(alloc.getHostPtr(), m_inputImageData.getAccess().getDataPtr(), static_cast<size_t>(m_bufferSizeBytes));
+       deMemcpy(alloc.getHostPtr(), m_inputImageData.getAccess().getDataPtr(), static_cast<size_t>(m_imageSrcSize));
        flushAlloc(vk, device, alloc);
 }
 
@@ -1655,7 +1660,7 @@ void ImageExtendOperandTestInstance::commandBeforeCompute (const VkCommandBuffer
 
                const VkBufferMemoryBarrier barrierFlushHostWriteBeforeCopy = makeBufferMemoryBarrier(
                        VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
-                       m_buffer->get(), 0ull, m_bufferSizeBytes);
+                       m_buffer->get(), 0ull, m_imageSrcSize);
 
                vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT,
                        (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &barrierFlushHostWriteBeforeCopy, DE_LENGTH_OF_ARRAY(preCopyImageBarriers), preCopyImageBarriers);
@@ -1680,7 +1685,7 @@ void ImageExtendOperandTestInstance::commandBetweenShaderInvocations (const VkCo
 
 void ImageExtendOperandTestInstance::commandAfterCompute (const VkCommandBuffer cmdBuffer)
 {
-       commandCopyImageToBuffer(m_context, cmdBuffer, m_imageDst->get(), m_buffer->get(), m_bufferSizeBytes, m_texture);
+       commandCopyImageToBuffer(m_context, cmdBuffer, m_imageDst->get(), m_buffer->get(), m_imageDstSize, m_texture);
 }
 
 tcu::TestStatus ImageExtendOperandTestInstance::verifyResult (void)