From 452d94dd78885b79b938cbb5297f076a4d3f3a9e Mon Sep 17 00:00:00 2001 From: Petros Bantolas Date: Mon, 18 Jul 2016 09:12:08 +0100 Subject: [PATCH] dEQP-VK.sparse_resources: Fixed VkBufferImageCopy buffer offset alignment issue Fixes #433 Change-Id: I34a416670789979e967281d0ede406dd871862bc --- .../vktSparseResourcesImageMemoryAliasing.cpp | 48 +++++++------ .../vktSparseResourcesImageSparseBinding.cpp | 43 ++++++----- .../vktSparseResourcesMipmapSparseResidency.cpp | 41 ++++++----- .../vktSparseResourcesShaderIntrinsicsBase.cpp | 84 ++++++++++++---------- .../vktSparseResourcesTestsUtil.cpp | 10 ++- .../vktSparseResourcesTestsUtil.hpp | 11 ++- 6 files changed, 131 insertions(+), 106 deletions(-) diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageMemoryAliasing.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageMemoryAliasing.cpp index f137b33..27de8a4 100644 --- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageMemoryAliasing.cpp +++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageMemoryAliasing.cpp @@ -394,25 +394,33 @@ tcu::TestStatus ImageSparseMemoryAliasingInstance::iterate (void) const Unique commandPool (makeCommandPool(deviceInterface, *m_logicalDevice, computeQueue.queueFamilyIndex)); const Unique commandBuffer(makeCommandBuffer(deviceInterface, *m_logicalDevice, *commandPool)); + std::vector 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 inputBuffer(new Buffer(deviceInterface, *m_logicalDevice, *allocator, inputBufferCreateInfo, MemoryRequirement::HostVisible)); - std::vector referenceData; - referenceData.resize(imageSizeInBytes); + std::vector 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(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 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(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(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(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 diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageSparseBinding.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageSparseBinding.cpp index d0ec56d..e761990 100644 --- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageSparseBinding.cpp +++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageSparseBinding.cpp @@ -233,16 +233,26 @@ tcu::TestStatus ImageSparseBindingInstance::iterate (void) const Unique commandPool(makeCommandPool(deviceInterface, *m_logicalDevice, computeQueue.queueFamilyIndex)); const Unique commandBuffer(makeCommandBuffer(deviceInterface, *m_logicalDevice, *commandPool)); + std::vector 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(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 inputBuffer(new Buffer(deviceInterface, *m_logicalDevice, *allocator, inputBufferCreateInfo, MemoryRequirement::HostVisible)); - std::vector referenceData; - referenceData.resize(imageSizeInBytes); + std::vector 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 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(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(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 diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesMipmapSparseResidency.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesMipmapSparseResidency.cpp index 8d5fa6a..3b405c4 100644 --- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesMipmapSparseResidency.cpp +++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesMipmapSparseResidency.cpp @@ -316,16 +316,26 @@ tcu::TestStatus MipmapSparseResidencyInstance::iterate (void) const Unique commandPool(makeCommandPool(deviceInterface, *m_logicalDevice, computeQueue.queueFamilyIndex)); const Unique commandBuffer(makeCommandBuffer(deviceInterface, *m_logicalDevice, *commandPool)); + std::vector 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(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 inputBuffer(new Buffer(deviceInterface, *m_logicalDevice, *allocator, inputBufferCreateInfo, MemoryRequirement::HostVisible)); - std::vector referenceData; - referenceData.resize(imageSizeInBytes); + std::vector 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 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(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(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 diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsBase.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsBase.cpp index 32e82ac..22f3432 100644 --- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsBase.cpp +++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsBase.cpp @@ -261,8 +261,8 @@ tcu::TestStatus SparseShaderIntrinsicsInstanceBase::iterate (void) // Create sparse image memory bind semaphore const Unique 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 commandPool(makeCommandPool(deviceInterface, *m_logicalDevice, extractQueue.queueFamilyIndex)); const Unique commandBuffer(makeCommandBuffer(deviceInterface, *m_logicalDevice, *commandPool)); + std::vector 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(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 inputBuffer(new Buffer(deviceInterface, *m_logicalDevice, *allocator, inputBufferCreateInfo, MemoryRequirement::HostVisible)); // Fill input buffer with reference data - std::vector referenceData; - referenceData.resize(imageSparseSizeInBytes); + std::vector 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(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 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(bufferImageCopy.size()), &bufferImageCopy[0]); + deviceInterface.cmdCopyBufferToImage(*commandBuffer, inputBuffer->get(), *imageSparse, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, static_cast(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 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(bufferImageCopy.size()), &bufferImageCopy[0]); + deviceInterface.cmdCopyImageToBuffer(*commandBuffer, imageTexels->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, bufferTexels->get(), static_cast(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 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 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(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(bufferImageCopy.size()), &bufferImageCopy[0]); + deviceInterface.cmdCopyImageToBuffer(*commandBuffer, imageResidency->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, bufferResidency->get(), static_cast(bufferImageResidencyCopy.size()), &bufferImageResidencyCopy[0]); { VkBufferMemoryBarrier bufferOutputHostReadBarriers[2]; @@ -580,9 +582,17 @@ tcu::TestStatus SparseShaderIntrinsicsInstanceBase::iterate (void) const deUint32* bufferResidencyData = static_cast(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(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(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(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 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"); diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesTestsUtil.cpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesTestsUtil.cpp index e0f719b..44b7875 100644 --- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesTestsUtil.cpp +++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesTestsUtil.cpp @@ -762,20 +762,18 @@ deUint32 getImageMaxMipLevels (const VkImageFormatProperties& imageFormatPropert return std::min(static_cast(deFloatLog2(static_cast(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; } diff --git a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesTestsUtil.hpp b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesTestsUtil.hpp index f7e1dab..3d4fe66 100644 --- a/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesTestsUtil.hpp +++ b/external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesTestsUtil.hpp @@ -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 makeCommandPool (const vk::DeviceInterface& vk, const vk::VkDevice device, -- 2.7.4