dEQP-VK.sparse_resources: Fixed VkBufferImageCopy buffer offset alignment issue
authorPetros Bantolas <petros.bantolas@imgtec.com>
Mon, 18 Jul 2016 08:12:08 +0000 (09:12 +0100)
committerPyry Haulos <phaulos@google.com>
Tue, 16 Aug 2016 10:53:37 +0000 (12:53 +0200)
Fixes #433

Change-Id: I34a416670789979e967281d0ede406dd871862bc

external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageMemoryAliasing.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageSparseBinding.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesMipmapSparseResidency.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsBase.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesTestsUtil.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesTestsUtil.hpp

index f137b3313e33a9587b7c531ccd2d60e7dc79d782..27de8a444dfd6ac93a9054af600916ce4df2ecf1 100644 (file)
@@ -394,25 +394,33 @@ tcu::TestStatus ImageSparseMemoryAliasingInstance::iterate (void)
        const Unique<VkCommandPool>       commandPool  (makeCommandPool(deviceInterface, *m_logicalDevice, computeQueue.queueFamilyIndex));
        const Unique<VkCommandBuffer> commandBuffer(makeCommandBuffer(deviceInterface, *m_logicalDevice, *commandPool));
 
+       std::vector<VkBufferImageCopy> bufferImageCopy(imageSparseInfo.mipLevels);
+
+       {
+               deUint32 bufferOffset = 0u;
+               for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
+               {
+                       bufferImageCopy[mipLevelNdx] = makeBufferImageCopy(mipLevelExtents(imageSparseInfo.extent, mipLevelNdx), imageSparseInfo.arrayLayers, mipLevelNdx, bufferOffset);
+                       bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipLevelNdx, MEM_ALIGN_BUFFERIMAGECOPY_OFFSET);
+               }
+       }
+
        // Start recording commands
        beginCommandBuffer(deviceInterface, *commandBuffer);
 
-       const deUint32                          imageSizeInBytes                = getImageSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, imageSparseInfo.mipLevels);
+       const deUint32                          imageSizeInBytes                = getImageSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, imageSparseInfo.mipLevels, MEM_ALIGN_BUFFERIMAGECOPY_OFFSET);
        const VkBufferCreateInfo        inputBufferCreateInfo   = makeBufferCreateInfo(imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
 
        const de::UniquePtr<Buffer>     inputBuffer(new Buffer(deviceInterface, *m_logicalDevice, *allocator, inputBufferCreateInfo, MemoryRequirement::HostVisible));
 
-       std::vector<deUint8> referenceData;
-       referenceData.resize(imageSizeInBytes);
+       std::vector<deUint8> referenceData(imageSizeInBytes);
 
-       deUint32 bufferOffset = 0u;
        for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
        {
-               const deUint32 mipLevelSizeInBytes = getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipLevelNdx);
+               const deUint32 mipLevelSizeInBytes      = getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipLevelNdx);
+               const deUint32 bufferOffset                     = static_cast<deUint32>(bufferImageCopy[mipLevelNdx].bufferOffset);
 
                deMemset(&referenceData[bufferOffset], mipLevelNdx + 1u, mipLevelSizeInBytes);
-
-               bufferOffset += mipLevelSizeInBytes;
        }
 
        deMemcpy(inputBuffer->getAllocation().getHostPtr(), &referenceData[0], imageSizeInBytes);
@@ -448,16 +456,6 @@ tcu::TestStatus ImageSparseMemoryAliasingInstance::iterate (void)
                deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageSparseTransferDstBarrier);
        }
 
-       std::vector<VkBufferImageCopy> bufferImageCopy;
-       bufferImageCopy.resize(imageSparseInfo.mipLevels);
-
-       bufferOffset = 0u;
-       for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
-       {
-               bufferImageCopy[mipLevelNdx] = makeBufferImageCopy(mipLevelExtents(imageSparseInfo.extent, mipLevelNdx), imageSparseInfo.arrayLayers, mipLevelNdx, bufferOffset);
-               bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipLevelNdx);
-       }
-
        deviceInterface.cmdCopyBufferToImage(*commandBuffer, inputBuffer->get(), *imageRead, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, static_cast<deUint32>(bufferImageCopy.size()), &bufferImageCopy[0]);
 
        {
@@ -602,10 +600,10 @@ tcu::TestStatus ImageSparseMemoryAliasingInstance::iterate (void)
        // Wait for sparse queue to become idle
        deviceInterface.queueWaitIdle(sparseQueue.queueHandle);
 
-       bufferOffset = 0u;
        for (deUint32 mipLevelNdx = 0; mipLevelNdx < aspectRequirements.imageMipTailFirstLod; ++mipLevelNdx)
        {
                const tcu::UVec3                                  gridSize              = getShaderGridSize(m_imageType, m_imageSize, mipLevelNdx);
+               const deUint32                                    bufferOffset  = static_cast<deUint32>(bufferImageCopy[mipLevelNdx].bufferOffset);
                const tcu::ConstPixelBufferAccess pixelBuffer   = tcu::ConstPixelBufferAccess(m_format, gridSize.x(), gridSize.y(), gridSize.z(), outputData + bufferOffset);
 
                for (deUint32 offsetZ = 0u; offsetZ < gridSize.z(); ++offsetZ)
@@ -619,14 +617,18 @@ tcu::TestStatus ImageSparseMemoryAliasingInstance::iterate (void)
                        if (deMemCmp(&outputValue, &referenceValue, sizeof(deUint32) * getNumUsedChannels(m_format.order)) != 0)
                                return tcu::TestStatus::fail("Failed");
                }
+       }
+
+       for (deUint32 mipLevelNdx = aspectRequirements.imageMipTailFirstLod; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
+       {
+               const deUint32 mipLevelSizeInBytes      = getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipLevelNdx);
+               const deUint32 bufferOffset                     = static_cast<deUint32>(bufferImageCopy[mipLevelNdx].bufferOffset);
 
-               bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipLevelNdx);
+               if (deMemCmp(outputData + bufferOffset, &referenceData[bufferOffset], mipLevelSizeInBytes) != 0)
+                       return tcu::TestStatus::fail("Failed");
        }
 
-       if (deMemCmp(outputData + bufferOffset, &referenceData[bufferOffset], imageSizeInBytes - bufferOffset) != 0)
-               return tcu::TestStatus::fail("Failed");
-       else
-               return tcu::TestStatus::pass("Passed");
+       return tcu::TestStatus::pass("Passed");
 }
 
 void ImageSparseMemoryAliasingCase::initPrograms(SourceCollections&    sourceCollections) const
index d0ec56da6d457768c2e094321ed461e0f7d05647..e761990686f4234af0114f86759a158a77f8d17e 100644 (file)
@@ -233,16 +233,26 @@ tcu::TestStatus ImageSparseBindingInstance::iterate (void)
        const Unique<VkCommandPool>       commandPool(makeCommandPool(deviceInterface, *m_logicalDevice, computeQueue.queueFamilyIndex));
        const Unique<VkCommandBuffer> commandBuffer(makeCommandBuffer(deviceInterface, *m_logicalDevice, *commandPool));
 
+       std::vector<VkBufferImageCopy> bufferImageCopy(imageSparseInfo.mipLevels);
+
+       {
+               deUint32 bufferOffset = 0;
+               for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; mipmapNdx++)
+               {
+                       bufferImageCopy[mipmapNdx] = makeBufferImageCopy(mipLevelExtents(imageSparseInfo.extent, mipmapNdx), imageSparseInfo.arrayLayers, mipmapNdx, static_cast<VkDeviceSize>(bufferOffset));
+                       bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipmapNdx, MEM_ALIGN_BUFFERIMAGECOPY_OFFSET);
+               }
+       }
+
        // Start recording commands
        beginCommandBuffer(deviceInterface, *commandBuffer);
 
-       const deUint32                          imageSizeInBytes = getImageSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, imageSparseInfo.mipLevels);
-       const VkBufferCreateInfo        inputBufferCreateInfo = makeBufferCreateInfo(imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
+       const deUint32                          imageSizeInBytes                = getImageSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, imageSparseInfo.mipLevels, MEM_ALIGN_BUFFERIMAGECOPY_OFFSET);
+       const VkBufferCreateInfo        inputBufferCreateInfo   = makeBufferCreateInfo(imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
 
        const de::UniquePtr<Buffer>     inputBuffer(new Buffer(deviceInterface, *m_logicalDevice, *allocator, inputBufferCreateInfo, MemoryRequirement::HostVisible));
 
-       std::vector<deUint8> referenceData;
-       referenceData.resize(imageSizeInBytes);
+       std::vector<deUint8> referenceData(imageSizeInBytes);
 
        for (deUint32 valueNdx = 0; valueNdx < imageSizeInBytes; ++valueNdx)
        {
@@ -282,17 +292,6 @@ tcu::TestStatus ImageSparseBindingInstance::iterate (void)
                deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageSparseTransferDstBarrier);
        }
 
-       std::vector <VkBufferImageCopy> bufferImageCopy;
-       bufferImageCopy.resize(imageSparseInfo.mipLevels);
-
-       VkDeviceSize bufferOffset = 0;
-       for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; mipmapNdx++)
-       {
-               bufferImageCopy[mipmapNdx] = makeBufferImageCopy(mipLevelExtents(imageSparseInfo.extent, mipmapNdx), imageSparseInfo.arrayLayers, mipmapNdx, bufferOffset);
-
-               bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipmapNdx);
-       }
-
        deviceInterface.cmdCopyBufferToImage(*commandBuffer, inputBuffer->get(), *imageSparse, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, static_cast<deUint32>(bufferImageCopy.size()), &bufferImageCopy[0]);
 
        {
@@ -344,10 +343,16 @@ tcu::TestStatus ImageSparseBindingInstance::iterate (void)
        // Wait for sparse queue to become idle
        deviceInterface.queueWaitIdle(sparseQueue.queueHandle);
 
-       if (deMemCmp(outputData, &referenceData[0], imageSizeInBytes) != 0)
-               return tcu::TestStatus::fail("Failed");
-       else
-               return tcu::TestStatus::pass("Passed");;
+       for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+       {
+               const deUint32 mipLevelSizeInBytes      = getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipmapNdx);
+               const deUint32 bufferOffset                     = static_cast<deUint32>(bufferImageCopy[mipmapNdx].bufferOffset);
+
+               if (deMemCmp(outputData + bufferOffset, &referenceData[bufferOffset], mipLevelSizeInBytes) != 0)
+                       return tcu::TestStatus::fail("Failed");
+       }
+
+       return tcu::TestStatus::pass("Passed");
 }
 
 TestInstance* ImageSparseBindingCase::createInstance (Context& context) const
index 8d5fa6ad0bc5cf34233cded0833be11c3e2b8cff..3b405c4525cb8d4963240440a1a57c9c86bc18ae 100644 (file)
@@ -316,16 +316,26 @@ tcu::TestStatus MipmapSparseResidencyInstance::iterate (void)
        const Unique<VkCommandPool>       commandPool(makeCommandPool(deviceInterface, *m_logicalDevice, computeQueue.queueFamilyIndex));
        const Unique<VkCommandBuffer> commandBuffer(makeCommandBuffer(deviceInterface, *m_logicalDevice, *commandPool));
 
+       std::vector <VkBufferImageCopy> bufferImageCopy(imageSparseInfo.mipLevels);
+
+       {
+               deUint32 bufferOffset = 0;
+               for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; mipmapNdx++)
+               {
+                       bufferImageCopy[mipmapNdx] = makeBufferImageCopy(mipLevelExtents(imageSparseInfo.extent, mipmapNdx), imageSparseInfo.arrayLayers, mipmapNdx, static_cast<VkDeviceSize>(bufferOffset));
+                       bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipmapNdx, MEM_ALIGN_BUFFERIMAGECOPY_OFFSET);
+               }
+       }
+
        // Start recording commands
        beginCommandBuffer(deviceInterface, *commandBuffer);
 
-       const deUint32                          imageSizeInBytes                = getImageSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, imageSparseInfo.mipLevels);
+       const deUint32                          imageSizeInBytes                = getImageSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, imageSparseInfo.mipLevels, MEM_ALIGN_BUFFERIMAGECOPY_OFFSET);
        const VkBufferCreateInfo        inputBufferCreateInfo   = makeBufferCreateInfo(imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
 
        const de::UniquePtr<Buffer>     inputBuffer(new Buffer(deviceInterface, *m_logicalDevice, *allocator, inputBufferCreateInfo, MemoryRequirement::HostVisible));
 
-       std::vector<deUint8> referenceData;
-       referenceData.resize(imageSizeInBytes);
+       std::vector<deUint8> referenceData(imageSizeInBytes);
 
        const VkMemoryRequirements imageMemoryRequirements = getImageMemoryRequirements(deviceInterface, *m_logicalDevice, *imageSparse);
 
@@ -367,17 +377,6 @@ tcu::TestStatus MipmapSparseResidencyInstance::iterate (void)
                deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageSparseTransferDstBarrier);
        }
 
-       std::vector <VkBufferImageCopy> bufferImageCopy;
-       bufferImageCopy.resize(imageSparseInfo.mipLevels);
-
-       VkDeviceSize bufferOffset = 0;
-       for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; mipmapNdx++)
-       {
-               bufferImageCopy[mipmapNdx] = makeBufferImageCopy(mipLevelExtents(imageSparseInfo.extent, mipmapNdx), imageSparseInfo.arrayLayers, mipmapNdx, bufferOffset);
-
-               bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipmapNdx);
-       }
-
        deviceInterface.cmdCopyBufferToImage(*commandBuffer, inputBuffer->get(), *imageSparse, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, static_cast<deUint32>(bufferImageCopy.size()), &bufferImageCopy[0]);
 
        {
@@ -429,10 +428,16 @@ tcu::TestStatus MipmapSparseResidencyInstance::iterate (void)
        // Wait for sparse queue to become idle
        deviceInterface.queueWaitIdle(sparseQueue.queueHandle);
 
-       if (deMemCmp(outputData, &referenceData[0], imageSizeInBytes) != 0)
-               return tcu::TestStatus::fail("Failed");
-       else
-               return tcu::TestStatus::pass("Passed");
+       for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+       {
+               const deUint32 mipLevelSizeInBytes      = getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipmapNdx);
+               const deUint32 bufferOffset                     = static_cast<deUint32>(bufferImageCopy[mipmapNdx].bufferOffset);
+
+               if (deMemCmp(outputData + bufferOffset, &referenceData[bufferOffset], mipLevelSizeInBytes) != 0)
+                       return tcu::TestStatus::fail("Failed");
+       }
+
+       return tcu::TestStatus::pass("Passed");
 }
 
 TestInstance* MipmapSparseResidencyCase::createInstance (Context& context) const
index 32e82ac78df0bd2c6b4c887e6a51096a5d8a6018..22f34324839fce3d584b7c81a089fa6a29eec10f 100644 (file)
@@ -261,8 +261,8 @@ tcu::TestStatus SparseShaderIntrinsicsInstanceBase::iterate (void)
        // Create sparse image memory bind semaphore
        const Unique<VkSemaphore> memoryBindSemaphore(makeSemaphore(deviceInterface, *m_logicalDevice));
 
-       const deUint32                    imageSparseSizeInBytes        = getImageSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, imageSparseInfo.mipLevels);
-       const deUint32                    imageSizeInPixels                     = imageSparseSizeInBytes / tcu::getPixelSize(m_format);
+       const deUint32                    imageSparseSizeInBytes                = getImageSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, imageSparseInfo.mipLevels, MEM_ALIGN_BUFFERIMAGECOPY_OFFSET);
+       const deUint32                    imageSizeInPixels                             = getImageSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, imageSparseInfo.mipLevels) / tcu::getPixelSize(m_format);
 
        residencyReferenceData.assign(imageSizeInPixels, MEMORY_BLOCK_NOT_BOUND_VALUE);
 
@@ -443,6 +443,17 @@ tcu::TestStatus SparseShaderIntrinsicsInstanceBase::iterate (void)
        const Unique<VkCommandPool>       commandPool(makeCommandPool(deviceInterface, *m_logicalDevice, extractQueue.queueFamilyIndex));
        const Unique<VkCommandBuffer> commandBuffer(makeCommandBuffer(deviceInterface, *m_logicalDevice, *commandPool));
 
+       std::vector <VkBufferImageCopy> bufferImageSparseCopy(imageSparseInfo.mipLevels);
+
+       {
+               deUint32 bufferOffset = 0u;
+               for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
+               {
+                       bufferImageSparseCopy[mipLevelNdx] = makeBufferImageCopy(mipLevelExtents(imageSparseInfo.extent, mipLevelNdx), imageSparseInfo.arrayLayers, mipLevelNdx, static_cast<VkDeviceSize>(bufferOffset));
+                       bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipLevelNdx, MEM_ALIGN_BUFFERIMAGECOPY_OFFSET);
+               }
+       }
+
        // Start recording commands
        beginCommandBuffer(deviceInterface, *commandBuffer);
 
@@ -451,20 +462,17 @@ tcu::TestStatus SparseShaderIntrinsicsInstanceBase::iterate (void)
        const de::UniquePtr<Buffer>     inputBuffer(new Buffer(deviceInterface, *m_logicalDevice, *allocator, inputBufferCreateInfo, MemoryRequirement::HostVisible));
 
        // Fill input buffer with reference data
-       std::vector<deUint8> referenceData;
-       referenceData.resize(imageSparseSizeInBytes);
+       std::vector<deUint8> referenceData(imageSparseSizeInBytes);
 
-       deUint32 bufferOffset = 0u;
        for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
        {
-               const deUint32 mipLevelSizeinBytes = getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipLevelNdx);
+               const deUint32 mipLevelSizeinBytes      = getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipLevelNdx);
+               const deUint32 bufferOffset                     = static_cast<deUint32>(bufferImageSparseCopy[mipLevelNdx].bufferOffset);
 
                for (deUint32 byteNdx = 0u; byteNdx < mipLevelSizeinBytes; ++byteNdx)
                {
                        referenceData[bufferOffset + byteNdx] = (deUint8)(mipLevelNdx + byteNdx);
                }
-
-               bufferOffset += mipLevelSizeinBytes;
        }
 
        deMemcpy(inputBuffer->getAllocation().getHostPtr(), &referenceData[0], imageSparseSizeInBytes);
@@ -504,17 +512,7 @@ tcu::TestStatus SparseShaderIntrinsicsInstanceBase::iterate (void)
        }
 
        // Copy reference data from input buffer to sparse image
-       std::vector <VkBufferImageCopy> bufferImageCopy;
-       bufferImageCopy.resize(imageSparseInfo.mipLevels);
-
-       bufferOffset = 0u;
-       for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
-       {
-               bufferImageCopy[mipLevelNdx] = makeBufferImageCopy(mipLevelExtents(imageSparseInfo.extent, mipLevelNdx), imageSparseInfo.arrayLayers, mipLevelNdx, bufferOffset);
-               bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipLevelNdx);
-       }
-
-       deviceInterface.cmdCopyBufferToImage(*commandBuffer, inputBuffer->get(), *imageSparse, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, static_cast<deUint32>(bufferImageCopy.size()), &bufferImageCopy[0]);
+       deviceInterface.cmdCopyBufferToImage(*commandBuffer, inputBuffer->get(), *imageSparse, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, static_cast<deUint32>(bufferImageSparseCopy.size()), &bufferImageSparseCopy[0]);
 
        recordCommands(*allocator, *commandBuffer, imageSparseInfo, *imageSparse, imageTexels->get(), imageResidency->get());
 
@@ -522,22 +520,26 @@ tcu::TestStatus SparseShaderIntrinsicsInstanceBase::iterate (void)
        const de::UniquePtr<Buffer>     bufferTexels(new Buffer(deviceInterface, *m_logicalDevice, *allocator, bufferTexelsInfo, MemoryRequirement::HostVisible));
 
        // Copy data from texels image to buffer
-       deviceInterface.cmdCopyImageToBuffer(*commandBuffer, imageTexels->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, bufferTexels->get(), static_cast<deUint32>(bufferImageCopy.size()), &bufferImageCopy[0]);
+       deviceInterface.cmdCopyImageToBuffer(*commandBuffer, imageTexels->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, bufferTexels->get(), static_cast<deUint32>(bufferImageSparseCopy.size()), &bufferImageSparseCopy[0]);
 
-       const deUint32                          imageResidencySizeInBytes = getImageSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_residencyFormat, imageSparseInfo.mipLevels);
+       const deUint32                          imageResidencySizeInBytes = getImageSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_residencyFormat, imageSparseInfo.mipLevels, MEM_ALIGN_BUFFERIMAGECOPY_OFFSET);
 
        const VkBufferCreateInfo        bufferResidencyInfo = makeBufferCreateInfo(imageResidencySizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
        const de::UniquePtr<Buffer>     bufferResidency(new Buffer(deviceInterface, *m_logicalDevice, *allocator, bufferResidencyInfo, MemoryRequirement::HostVisible));
 
        // Copy data from residency image to buffer
-       bufferOffset = 0u;
-       for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
+       std::vector <VkBufferImageCopy> bufferImageResidencyCopy(imageSparseInfo.mipLevels);
+
        {
-               bufferImageCopy[mipLevelNdx] = makeBufferImageCopy(mipLevelExtents(imageSparseInfo.extent, mipLevelNdx), imageSparseInfo.arrayLayers, mipLevelNdx, bufferOffset);
-               bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_residencyFormat, mipLevelNdx);
+               deUint32 bufferOffset = 0u;
+               for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
+               {
+                       bufferImageResidencyCopy[mipLevelNdx] = makeBufferImageCopy(mipLevelExtents(imageSparseInfo.extent, mipLevelNdx), imageSparseInfo.arrayLayers, mipLevelNdx, static_cast<VkDeviceSize>(bufferOffset));
+                       bufferOffset += getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_residencyFormat, mipLevelNdx, MEM_ALIGN_BUFFERIMAGECOPY_OFFSET);
+               }
        }
 
-       deviceInterface.cmdCopyImageToBuffer(*commandBuffer, imageResidency->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, bufferResidency->get(), static_cast<deUint32>(bufferImageCopy.size()), &bufferImageCopy[0]);
+       deviceInterface.cmdCopyImageToBuffer(*commandBuffer, imageResidency->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, bufferResidency->get(), static_cast<deUint32>(bufferImageResidencyCopy.size()), &bufferImageResidencyCopy[0]);
 
        {
                VkBufferMemoryBarrier bufferOutputHostReadBarriers[2];
@@ -580,9 +582,17 @@ tcu::TestStatus SparseShaderIntrinsicsInstanceBase::iterate (void)
 
        const deUint32* bufferResidencyData = static_cast<const deUint32*>(bufferResidencyAllocation.getHostPtr());
 
-       if (deMemCmp(&bufferResidencyData[0], &residencyReferenceData[0], imageResidencySizeInBytes) != 0)
-               return tcu::TestStatus::fail("Failed");
+       deUint32 pixelOffsetNotAligned = 0u;
+       for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
+       {
+               const deUint32 mipLevelSizeInBytes      = getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_residencyFormat, mipmapNdx);
+               const deUint32 pixelOffsetAligned       = static_cast<deUint32>(bufferImageResidencyCopy[mipmapNdx].bufferOffset) / tcu::getPixelSize(m_residencyFormat);
 
+               if (deMemCmp(&bufferResidencyData[pixelOffsetAligned], &residencyReferenceData[pixelOffsetNotAligned], mipLevelSizeInBytes) != 0)
+                       return tcu::TestStatus::fail("Failed");
+
+               pixelOffsetNotAligned += mipLevelSizeInBytes / tcu::getPixelSize(m_residencyFormat);
+       }
 
        // Retrieve data from texels buffer to host memory
        const Allocation& bufferTexelsAllocation = bufferTexels->getAllocation();
@@ -590,16 +600,16 @@ tcu::TestStatus SparseShaderIntrinsicsInstanceBase::iterate (void)
 
        const deUint8* bufferTexelsData = static_cast<const deUint8*>(bufferTexelsAllocation.getHostPtr());
 
-       deUint32 dataOffset = 0u;
-       for (deUint32 mipLevelNdx = 0; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
+       for (deUint32 mipmapNdx = 0; mipmapNdx < imageSparseInfo.mipLevels; ++mipmapNdx)
        {
-               const deUint32 mipLevelSizeInBytes      = getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipLevelNdx);
+               const deUint32 mipLevelSizeInBytes      = getImageMipLevelSizeInBytes(imageSparseInfo.extent, imageSparseInfo.arrayLayers, m_format, mipmapNdx);
+               const deUint32 bufferOffset                     = static_cast<deUint32>(bufferImageSparseCopy[mipmapNdx].bufferOffset);
 
-               if (mipLevelNdx < aspectRequirements.imageMipTailFirstLod)
+               if (mipmapNdx < aspectRequirements.imageMipTailFirstLod)
                {
-                       if (mipLevelNdx % MEMORY_BLOCK_TYPE_COUNT == MEMORY_BLOCK_BOUND)
+                       if (mipmapNdx % MEMORY_BLOCK_TYPE_COUNT == MEMORY_BLOCK_BOUND)
                        {
-                               if (deMemCmp(&bufferTexelsData[dataOffset], &referenceData[dataOffset], mipLevelSizeInBytes) != 0)
+                               if (deMemCmp(&bufferTexelsData[bufferOffset], &referenceData[bufferOffset], mipLevelSizeInBytes) != 0)
                                        return tcu::TestStatus::fail("Failed");
                        }
                        else if (getPhysicalDeviceProperties(instance, physicalDevice).sparseProperties.residencyNonResidentStrict)
@@ -607,17 +617,15 @@ tcu::TestStatus SparseShaderIntrinsicsInstanceBase::iterate (void)
                                std::vector<deUint8> zeroData;
                                zeroData.assign(mipLevelSizeInBytes, 0u);
 
-                               if (deMemCmp(&bufferTexelsData[dataOffset], &zeroData[0], mipLevelSizeInBytes) != 0)
+                               if (deMemCmp(&bufferTexelsData[bufferOffset], &zeroData[0], mipLevelSizeInBytes) != 0)
                                        return tcu::TestStatus::fail("Failed");
                        }
                }
                else
                {
-                       if (deMemCmp(&bufferTexelsData[dataOffset], &referenceData[dataOffset], mipLevelSizeInBytes) != 0)
+                       if (deMemCmp(&bufferTexelsData[bufferOffset], &referenceData[bufferOffset], mipLevelSizeInBytes) != 0)
                                return tcu::TestStatus::fail("Failed");
                }
-
-               dataOffset      += mipLevelSizeInBytes;
        }
 
        return tcu::TestStatus::pass("Passed");
index e0f719bc3df83ff9c3f7eaccee1434a66181ebf4..44b7875a53591028166a4537463ab067aa04f1b9 100644 (file)
@@ -762,20 +762,18 @@ deUint32 getImageMaxMipLevels (const VkImageFormatProperties& imageFormatPropert
        return std::min(static_cast<deUint32>(deFloatLog2(static_cast<float>(widestEdge))) + 1u, imageFormatProperties.maxMipLevels);
 }
 
-deUint32 getImageMipLevelSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel)
+deUint32 getImageMipLevelSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment)
 {
        const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel);
 
-       return extents.width * extents.height * extents.depth * layersCount * tcu::getPixelSize(format);
+       return deAlign32(extents.width * extents.height * extents.depth * layersCount * tcu::getPixelSize(format), mipmapMemoryAlignment);
 }
 
-deUint32 getImageSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount)
+deUint32 getImageSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment)
 {
        deUint32 imageSizeInBytes = 0;
        for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
-       {
-               imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel);
-       }
+               imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel, mipmapMemoryAlignment);
 
        return imageSizeInBytes;
 }
index f7e1dab262e4c6c0aedf7ec39a3d4f889e6fd1d4..3d4fe6616380b32276282b32c5d8a5afc33586c8 100644 (file)
@@ -51,6 +51,11 @@ enum ImageType
        IMAGE_TYPE_LAST
 };
 
+enum MemoryAlignment
+{
+       MEM_ALIGN_BUFFERIMAGECOPY_OFFSET = 4u
+};
+
 class Buffer
 {
 public:
@@ -203,12 +208,14 @@ deUint32                  getImageMaxMipLevels                    (const vk::VkImageFormatProperties& imageForma
 deUint32                       getImageMipLevelSizeInBytes             (const vk::VkExtent3D&                          baseExtents,
                                                                                                         const deUint32                                         layersCount,
                                                                                                         const tcu::TextureFormat&                      format,
-                                                                                                        const deUint32                                         mipmapLevel);
+                                                                                                        const deUint32                                         mipmapLevel,
+                                                                                                        const deUint32                                         mipmapMemoryAlignment   = 1u);
 
 deUint32                       getImageSizeInBytes                             (const vk::VkExtent3D&                          baseExtents,
                                                                                                         const deUint32                                         layersCount,
                                                                                                         const tcu::TextureFormat&                      format,
-                                                                                                        const deUint32                                         mipmapLevelsCount = 1u);
+                                                                                                        const deUint32                                         mipmapLevelsCount               = 1u,
+                                                                                                        const deUint32                                         mipmapMemoryAlignment   = 1u);
 
 vk::Move<vk::VkCommandPool>            makeCommandPool                                 (const vk::DeviceInterface&                     vk,
                                                                                                                                 const vk::VkDevice                                     device,