X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=external%2Fvulkancts%2Fmodules%2Fvulkan%2Fapi%2FvktApiCopiesAndBlittingTests.cpp;h=c08e6bdabef38910f655f6649a09607f54e29c67;hb=cd69acfb3a5d9a4a32c4067ad869bc9eda1fca04;hp=5fd91a8f4b0e35a9456835c9abbeaec5b56b20f5;hpb=95b7e678dd850853354f5211bab015d900fd8e93;p=platform%2Fupstream%2FVK-GL-CTS.git diff --git a/external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp index 5fd91a8..c08e6bd 100644 --- a/external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp +++ b/external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp @@ -32,6 +32,8 @@ #include "tcuTextureUtil.hpp" #include "tcuVectorType.hpp" #include "tcuVectorUtil.hpp" +#include "tcuTestLog.hpp" +#include "tcuTexLookupVerifier.hpp" #include "vkImageUtil.hpp" #include "vkMemUtil.hpp" @@ -40,18 +42,51 @@ #include "vkRefUtil.hpp" #include "vktTestCase.hpp" #include "vktTestCaseUtil.hpp" +#include "vktTestGroupUtil.hpp" #include "vkTypeUtil.hpp" +#include + namespace vkt { namespace api { -using namespace vk; - namespace { +enum MirrorMode +{ + MIRROR_MODE_NONE = 0, + MIRROR_MODE_X = (1<<0), + MIRROR_MODE_Y = (1<<1), + MIRROR_MODE_XY = MIRROR_MODE_X | MIRROR_MODE_Y, + + MIRROR_MODE_LAST +}; + +enum AllocationKind +{ + ALLOCATION_KIND_SUBALLOCATED, + ALLOCATION_KIND_DEDICATED, +}; + +template +class BinaryCompare +{ +public: + bool operator() (const Type& a, const Type& b) const + { + return deMemCmp(&a, &b, sizeof(Type)) < 0; + } +}; + +typedef std::set > FormatSet; + +FormatSet dedicatedAllocationImageToImageFormatsToTestSet; +FormatSet dedicatedAllocationBlittingFormatsToTestSet; + +using namespace vk; VkImageAspectFlags getAspectFlags (tcu::TextureFormat format) { @@ -84,6 +119,14 @@ union CopyRegion VkImageResolve imageResolve; }; +struct ImageParms +{ + VkImageType imageType; + VkFormat format; + VkExtent3D extent; + VkImageLayout operationLayout; +}; + struct TestParams { union Data @@ -91,22 +134,99 @@ struct TestParams struct Buffer { VkDeviceSize size; - } buffer; - struct Image - { - VkFormat format; - VkExtent3D extent; - } image; - } src, dst; + } buffer; + + ImageParms image; + } src, dst; std::vector regions; + union { VkFilter filter; VkSampleCountFlagBits samples; }; + + AllocationKind allocationKind; }; +de::MovePtr allocateBuffer (const InstanceInterface& vki, + const DeviceInterface& vkd, + const VkPhysicalDevice& physDevice, + const VkDevice device, + const VkBuffer& buffer, + const MemoryRequirement requirement, + Allocator& allocator, + AllocationKind allocationKind) +{ + switch (allocationKind) + { + case ALLOCATION_KIND_SUBALLOCATED: + { + const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer); + + return allocator.allocate(memoryRequirements, requirement); + } + + case ALLOCATION_KIND_DEDICATED: + { + return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement); + } + + default: + { + TCU_THROW(InternalError, "Invalid allocation kind"); + } + } +} + +de::MovePtr allocateImage (const InstanceInterface& vki, + const DeviceInterface& vkd, + const VkPhysicalDevice& physDevice, + const VkDevice device, + const VkImage& image, + const MemoryRequirement requirement, + Allocator& allocator, + AllocationKind allocationKind) +{ + switch (allocationKind) + { + case ALLOCATION_KIND_SUBALLOCATED: + { + const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image); + + return allocator.allocate(memoryRequirements, requirement); + } + + case ALLOCATION_KIND_DEDICATED: + { + return allocateDedicated(vki, vkd, physDevice, device, image, requirement); + } + + default: + { + TCU_THROW(InternalError, "Invalid allocation kind"); + } + } +} + + +inline deUint32 getArraySize(const ImageParms& parms) +{ + return (parms.imageType == VK_IMAGE_TYPE_2D) ? parms.extent.depth : 1u; +} + +inline VkExtent3D getExtent3D(const ImageParms& parms) +{ + const VkExtent3D extent = + { + parms.extent.width, + parms.extent.height, + (parms.imageType == VK_IMAGE_TYPE_2D) ? 1u : parms.extent.depth + }; + return extent; +} + const tcu::TextureFormat mapCombinedToDepthTransferFormat (const tcu::TextureFormat& combinedFormat) { tcu::TextureFormat format; @@ -160,7 +280,7 @@ protected: void generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth = 1, FillMode = FILL_MODE_GRADIENT); virtual void generateExpectedResult (void); void uploadBuffer (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc); - void uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst); + void uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms); virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result); virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region) = 0; deUint32 calculateSize (tcu::ConstPixelBufferAccess src) const @@ -168,15 +288,20 @@ protected: return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat()); } - de::MovePtr readImage (vk::VkImage image, - vk::VkFormat format, - const VkExtent3D imageSize); + de::MovePtr readImage (vk::VkImage image, + const ImageParms& imageParms); + void submitCommandsAndWait (const DeviceInterface& vk, + const VkDevice device, + const VkQueue queue, + const VkCommandBuffer& cmdBuffer); private: void uploadImageAspect (const tcu::ConstPixelBufferAccess& src, - const VkImage& dst); + const VkImage& dst, + const ImageParms& parms); void readImageAspect (vk::VkImage src, - const tcu::PixelBufferAccess& dst); + const tcu::PixelBufferAccess& dst, + const ImageParms& parms); }; CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context, TestParams testParams) @@ -187,88 +312,97 @@ CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context, const VkDevice vkDevice = context.getDevice(); const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); - // Create command pool + if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED) { - const VkCommandPoolCreateInfo cmdPoolParams = - { - VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags; - queueFamilyIndex, // deUint32 queueFamilyIndex; - }; + const std::string extensionName("VK_KHR_dedicated_allocation"); - m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams); + if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName)) + TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str()); } - // Create command buffer - { - const VkCommandBufferAllocateInfo cmdBufferAllocateInfo = - { - VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - *m_cmdPool, // VkCommandPool commandPool; - VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; - 1u // deUint32 bufferCount; - }; + // Create command pool + m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex); - m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo); - } + // Create command buffer + m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); // Create fence - { - const VkFenceCreateInfo fenceParams = - { - VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u // VkFenceCreateFlags flags; - }; - - m_fence = createFence(vk, vkDevice, &fenceParams); - } + m_fence = createFence(vk, vkDevice); } void CopiesAndBlittingTestInstance::generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth, FillMode mode) { + const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(buffer.getFormat().type); + tcu::Vec4 maxValue (1.0f); + + if (buffer.getFormat().order == tcu::TextureFormat::S) + { + // Stencil-only is stored in the first component. Stencil is always 8 bits. + maxValue.x() = 1 << 8; + } + else if (buffer.getFormat().order == tcu::TextureFormat::DS) + { + // In a combined format, fillWithComponentGradients expects stencil in the fourth component. + maxValue.w() = 1 << 8; + } + else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) + { + // The tcu::Vectors we use as pixels are 32-bit, so clamp to that. + const tcu::IVec4 bits = tcu::min(tcu::getTextureFormatBitDepth(buffer.getFormat()), tcu::IVec4(32)); + const int signBit = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0); + + for (int i = 0; i < 4; ++i) + { + if (bits[i] != 0) + maxValue[i] = static_cast((1 << (bits[i] - signBit)) - 1); + } + } + if (mode == FILL_MODE_GRADIENT) { - tcu::fillWithComponentGradients(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); + tcu::fillWithComponentGradients(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), maxValue); return; } - const tcu::Vec4 redColor (1.0, 0.0, 0.0, 1.0); - const tcu::Vec4 greenColor (0.0, 1.0, 0.0, 1.0); - const tcu::Vec4 blueColor (0.0, 0.0, 1.0, 1.0); - const tcu::Vec4 whiteColor (1.0, 1.0, 1.0, 1.0); + const tcu::Vec4 redColor (maxValue.x(), 0.0, 0.0, maxValue.w()); + const tcu::Vec4 greenColor (0.0, maxValue.y(), 0.0, maxValue.w()); + const tcu::Vec4 blueColor (0.0, 0.0, maxValue.z(), maxValue.w()); + const tcu::Vec4 whiteColor (maxValue.x(), maxValue.y(), maxValue.z(), maxValue.w()); - for (int z = 0; z < depth; z++) + for (int z = 0; z < depth; ++z) + for (int y = 0; y < height; ++y) + for (int x = 0; x < width; ++x) { - for (int y = 0; y < height; y++) + switch (mode) { - for (int x = 0; x < width; x++) - { - switch (mode) + case FILL_MODE_WHITE: + if (tcu::isCombinedDepthStencilType(buffer.getFormat().type)) { - case FILL_MODE_WHITE: - if (tcu::isCombinedDepthStencilType(buffer.getFormat().type)) - { - buffer.setPixDepth(1.0f, x, y, z); - if (tcu::hasStencilComponent(buffer.getFormat().order)) - buffer.setPixStencil(255, x, y, z); - } - else - buffer.setPixel(whiteColor, x, y, z); - break; - case FILL_MODE_RED: - DE_ASSERT(!tcu::isCombinedDepthStencilType(buffer.getFormat().type)); // combined types cannot be accessed directly - buffer.setPixel(redColor, x, y, z); - break; - case FILL_MODE_MULTISAMPLE: - buffer.setPixel((x == y) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) : ((x > y) ? greenColor : blueColor), x, y, z); - break; - default: - break; + buffer.setPixDepth(1.0f, x, y, z); + if (tcu::hasStencilComponent(buffer.getFormat().order)) + buffer.setPixStencil(255, x, y, z); } - } + else + buffer.setPixel(whiteColor, x, y, z); + break; + + case FILL_MODE_RED: + if (tcu::isCombinedDepthStencilType(buffer.getFormat().type)) + { + buffer.setPixDepth(redColor[x % 4], x, y, z); + if (tcu::hasStencilComponent(buffer.getFormat().order)) + buffer.setPixStencil(255 * (int)redColor[y % 4], x, y, z); + } + else + buffer.setPixel(redColor, x, y, z); + break; + + case FILL_MODE_MULTISAMPLE: + buffer.setPixel((x == y) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) : ((x > y) ? greenColor : blueColor), x, y, z); + break; + + default: + break; } } } @@ -284,18 +418,20 @@ void CopiesAndBlittingTestInstance::uploadBuffer (tcu::ConstPixelBufferAccess bu flushMappedMemoryRange(vk, vkDevice, bufferAlloc.getMemory(), bufferAlloc.getOffset(), bufferSize); } -void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBufferAccess& imageAccess, const VkImage& image) +void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBufferAccess& imageAccess, const VkImage& image, const ImageParms& parms) { + const InstanceInterface& vki = m_context.getInstanceInterface(); const DeviceInterface& vk = m_context.getDeviceInterface(); + const VkPhysicalDevice vkPhysDevice = m_context.getPhysicalDevice(); const VkDevice vkDevice = m_context.getDevice(); const VkQueue queue = m_context.getUniversalQueue(); const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); Allocator& memAlloc = m_context.getDefaultAllocator(); - Move buffer; const deUint32 bufferSize = calculateSize(imageAccess); de::MovePtr bufferAlloc; - Move cmdBuffer; + const deUint32 arraySize = getArraySize(parms); + const VkExtent3D imageExtent = getExtent3D(parms); // Create source buffer { @@ -312,24 +448,10 @@ void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBuff }; buffer = createBuffer(vk, vkDevice, &bufferParams); - bufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible); + bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind); VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); } - // Create command buffer - { - const VkCommandBufferAllocateInfo cmdBufferAllocateInfo = - { - VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - *m_cmdPool, // VkCommandPool commandPool; - VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; - 1u, // deUint32 bufferCount; - }; - - cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo); - } - // Barriers for copying buffer to image const VkBufferMemoryBarrier preBufferBarrier = { @@ -344,7 +466,9 @@ void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBuff bufferSize // VkDeviceSize size; }; - const VkImageAspectFlags aspect = getAspectFlags(imageAccess.getFormat()); + const VkImageAspectFlags formatAspect = getAspectFlags(mapVkFormat(parms.format)); + const bool skipPreImageBarrier = formatAspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) && + getAspectFlags(imageAccess.getFormat()) == VK_IMAGE_ASPECT_STENCIL_BIT; const VkImageMemoryBarrier preImageBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; @@ -357,11 +481,11 @@ void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBuff VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; image, // VkImage image; { // VkImageSubresourceRange subresourceRange; - aspect, // VkImageAspectFlags aspect; - 0u, // deUint32 baseMipLevel; - 1u, // deUint32 mipLevels; - 0u, // deUint32 baseArraySlice; - 1u, // deUint32 arraySize; + formatAspect, // VkImageAspectFlags aspect; + 0u, // deUint32 baseMipLevel; + 1u, // deUint32 mipLevels; + 0u, // deUint32 baseArraySlice; + arraySize, // deUint32 arraySize; } }; @@ -377,15 +501,14 @@ void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBuff VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; image, // VkImage image; { // VkImageSubresourceRange subresourceRange; - aspect, // VkImageAspectFlags aspect; - 0u, // deUint32 baseMipLevel; - 1u, // deUint32 mipLevels; - 0u, // deUint32 baseArraySlice; - 1u, // deUint32 arraySize; + formatAspect, // VkImageAspectFlags aspect; + 0u, // deUint32 baseMipLevel; + 1u, // deUint32 mipLevels; + 0u, // deUint32 baseArraySlice; + arraySize, // deUint32 arraySize; } }; - const VkExtent3D imageExtent = { (deUint32)imageAccess.getWidth(), (deUint32)imageAccess.getHeight(), 1u }; const VkBufferImageCopy copyRegion = { 0u, // VkDeviceSize bufferOffset; @@ -395,7 +518,7 @@ void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBuff getAspectFlags(imageAccess.getFormat()), // VkImageAspectFlags aspect; 0u, // deUint32 mipLevel; 0u, // deUint32 baseArrayLayer; - 1u, // deUint32 layerCount; + arraySize, // deUint32 layerCount; }, // VkImageSubresourceLayers imageSubresource; { 0, 0, 0 }, // VkOffset3D imageOffset; imageExtent // VkExtent3D imageExtent; @@ -414,31 +537,17 @@ void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBuff (const VkCommandBufferInheritanceInfo*)DE_NULL, }; - VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); - vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier); - vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region); - vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier); - VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); - - const VkSubmitInfo submitInfo = - { - VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // deUint32 waitSemaphoreCount; - DE_NULL, // const VkSemaphore* pWaitSemaphores; - (const VkPipelineStageFlags*)DE_NULL, - 1u, // deUint32 commandBufferCount; - &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; - 0u, // deUint32 signalSemaphoreCount; - DE_NULL // const VkSemaphore* pSignalSemaphores; - }; + VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); + vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, + 1, &preBufferBarrier, (skipPreImageBarrier ? 0 : 1), (skipPreImageBarrier ? DE_NULL : &preImageBarrier)); + vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region); + vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier); + VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); - VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get())); - VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); - VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */)); + submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer); } -void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst) +void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms) { if (tcu::isCombinedDepthStencilType(src.getFormat().type)) { @@ -446,18 +555,18 @@ void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAcce { tcu::TextureLevel depthTexture (mapCombinedToDepthTransferFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth()); tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH)); - uploadImageAspect(depthTexture.getAccess(), dst); + uploadImageAspect(depthTexture.getAccess(), dst, parms); } if (tcu::hasStencilComponent(src.getFormat().order)) { tcu::TextureLevel stencilTexture (tcu::getEffectiveDepthStencilTextureFormat(src.getFormat(), tcu::Sampler::MODE_STENCIL), src.getWidth(), src.getHeight(), src.getDepth()); tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL)); - uploadImageAspect(stencilTexture.getAccess(), dst); + uploadImageAspect(stencilTexture.getAccess(), dst, parms); } } else - uploadImageAspect(src, dst); + uploadImageAspect(src, dst, parms); } tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelBufferAccess result) @@ -467,13 +576,13 @@ tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelB if (isFloatFormat(result.getFormat())) { const tcu::Vec4 threshold (0.0f); - if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expected, result, threshold, tcu::COMPARE_LOG_RESULT)) + if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT)) return tcu::TestStatus::fail("CopiesAndBlitting test"); } else { const tcu::UVec4 threshold (0u); - if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expected, result, threshold, tcu::COMPARE_LOG_RESULT)) + if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT)) return tcu::TestStatus::fail("CopiesAndBlitting test"); } @@ -487,6 +596,7 @@ void CopiesAndBlittingTestInstance::generateExpectedResult (void) m_expectedTextureLevel = de::MovePtr(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth())); tcu::copy(m_expectedTextureLevel->getAccess(), dst); + for (deUint32 i = 0; i < m_params.regions.size(); i++) copyRegionToTextureLevel(src, m_expectedTextureLevel->getAccess(), m_params.regions[i]); } @@ -504,18 +614,21 @@ public: }; void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage image, - const tcu::PixelBufferAccess& dst) + const tcu::PixelBufferAccess& dst, + const ImageParms& imageParms) { + const InstanceInterface& vki = m_context.getInstanceInterface(); const DeviceInterface& vk = m_context.getDeviceInterface(); + const VkPhysicalDevice physDevice = m_context.getPhysicalDevice(); const VkDevice device = m_context.getDevice(); const VkQueue queue = m_context.getUniversalQueue(); Allocator& allocator = m_context.getDefaultAllocator(); Move buffer; de::MovePtr bufferAlloc; - Move cmdBuffer; const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); const VkDeviceSize pixelDataSize = calculateSize(dst); + const VkExtent3D imageExtent = getExtent3D(imageParms); // Create destination buffer { @@ -532,43 +645,32 @@ void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage image, }; buffer = createBuffer(vk, device, &bufferParams); - bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible); + bufferAlloc = allocateBuffer(vki, vk, physDevice, device, *buffer, MemoryRequirement::HostVisible, allocator, m_params.allocationKind); VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); - } - - // Create command pool and buffer - { - const VkCommandBufferAllocateInfo cmdBufferAllocateInfo = - { - VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - *m_cmdPool, // VkCommandPool commandPool; - VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; - 1u // deUint32 bufferCount; - }; - cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo); + deMemset(bufferAlloc->getHostPtr(), 0, static_cast(pixelDataSize)); + flushMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize); } // Barriers for copying image to buffer - const VkImageAspectFlags aspect = getAspectFlags(dst.getFormat()); + const VkImageAspectFlags formatAspect = getAspectFlags(mapVkFormat(imageParms.format)); const VkImageMemoryBarrier imageBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; DE_NULL, // const void* pNext; VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; + imageParms.operationLayout, // VkImageLayout oldLayout; VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout; VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; image, // VkImage image; { // VkImageSubresourceRange subresourceRange; - aspect, // VkImageAspectFlags aspectMask; - 0u, // deUint32 baseMipLevel; - 1u, // deUint32 mipLevels; - 0u, // deUint32 baseArraySlice; - 1u // deUint32 arraySize; + formatAspect, // VkImageAspectFlags aspectMask; + 0u, // deUint32 baseMipLevel; + 1u, // deUint32 mipLevels; + 0u, // deUint32 baseArraySlice; + getArraySize(imageParms)// deUint32 arraySize; } }; @@ -592,21 +694,21 @@ void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage image, VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags srcAccessMask; VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout oldLayout; - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; + imageParms.operationLayout, // VkImageLayout newLayout; VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; image, // VkImage image; { - aspect, // VkImageAspectFlags aspectMask; + formatAspect, // VkImageAspectFlags aspectMask; 0u, // deUint32 baseMipLevel; 1u, // deUint32 mipLevels; 0u, // deUint32 baseArraySlice; - 1u, // deUint32 arraySize; + getArraySize(imageParms) // deUint32 arraySize; } // VkImageSubresourceRange subresourceRange; }; // Copy image to buffer - const VkExtent3D imageExtent = { (deUint32)dst.getWidth(), (deUint32)dst.getHeight(), 1u }; + const VkImageAspectFlags aspect = getAspectFlags(dst.getFormat()); const VkBufferImageCopy copyRegion = { 0u, // VkDeviceSize bufferOffset; @@ -616,7 +718,7 @@ void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage image, aspect, // VkImageAspectFlags aspect; 0u, // deUint32 mipLevel; 0u, // deUint32 baseArrayLayer; - 1u, // deUint32 layerCount; + getArraySize(imageParms), // deUint32 layerCount; }, // VkImageSubresourceLayers imageSubresource; { 0, 0, 0 }, // VkOffset3D imageOffset; imageExtent // VkExtent3D imageExtent; @@ -630,12 +732,21 @@ void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage image, (const VkCommandBufferInheritanceInfo*)DE_NULL, }; - VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); - vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier); - vk.cmdCopyImageToBuffer(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, ©Region); - vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT|VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 1, &postImageBarrier); - VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); + VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); + vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier); + vk.cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, ©Region); + vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT|VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 1, &postImageBarrier); + VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); + + submitCommandsAndWait(vk, device, queue, *m_cmdBuffer); + + // Read buffer data + invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize); + tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr())); +} +void CopiesAndBlittingTestInstance::submitCommandsAndWait (const DeviceInterface& vk, const VkDevice device, const VkQueue queue, const VkCommandBuffer& cmdBuffer) +{ const VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; @@ -644,45 +755,40 @@ void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage image, DE_NULL, // const VkSemaphore* pWaitSemaphores; (const VkPipelineStageFlags*)DE_NULL, 1u, // deUint32 commandBufferCount; - &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; + &cmdBuffer, // const VkCommandBuffer* pCommandBuffers; 0u, // deUint32 signalSemaphoreCount; DE_NULL // const VkSemaphore* pSignalSemaphores; }; VK_CHECK(vk.resetFences(device, 1, &m_fence.get())); VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); - VK_CHECK(vk.waitForFences(device, 1, &m_fence.get(), 0, ~(0ull) /* infinity */)); - - // Read buffer data - invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize); - tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr())); + VK_CHECK(vk.waitForFences(device, 1, &m_fence.get(), true, ~(0ull) /* infinity */)); } de::MovePtr CopiesAndBlittingTestInstance::readImage (vk::VkImage image, - vk::VkFormat format, - const VkExtent3D imageSize) + const ImageParms& parms) { - const tcu::TextureFormat imageFormat = mapVkFormat(format); - de::MovePtr resultLevel (new tcu::TextureLevel(imageFormat, imageSize.width, imageSize.height, imageSize.depth)); + const tcu::TextureFormat imageFormat = mapVkFormat(parms.format); + de::MovePtr resultLevel (new tcu::TextureLevel(imageFormat, parms.extent.width, parms.extent.height, parms.extent.depth)); if (tcu::isCombinedDepthStencilType(imageFormat.type)) { if (tcu::hasDepthComponent(imageFormat.order)) { - tcu::TextureLevel depthTexture (mapCombinedToDepthTransferFormat(imageFormat), imageSize.width, imageSize.height, imageSize.depth); - readImageAspect(image, depthTexture.getAccess()); + tcu::TextureLevel depthTexture (mapCombinedToDepthTransferFormat(imageFormat), parms.extent.width, parms.extent.height, parms.extent.depth); + readImageAspect(image, depthTexture.getAccess(), parms); tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_DEPTH), depthTexture.getAccess()); } if (tcu::hasStencilComponent(imageFormat.order)) { - tcu::TextureLevel stencilTexture (tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL), imageSize.width, imageSize.height, imageSize.depth); - readImageAspect(image, stencilTexture.getAccess()); + tcu::TextureLevel stencilTexture (tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL), parms.extent.width, parms.extent.height, parms.extent.depth); + readImageAspect(image, stencilTexture.getAccess(), parms); tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_STENCIL), stencilTexture.getAccess()); } } else - readImageAspect(image, resultLevel->getAccess()); + readImageAspect(image, resultLevel->getAccess(), parms); return resultLevel; } @@ -695,6 +801,10 @@ public: CopyImageToImage (Context& context, TestParams params); virtual tcu::TestStatus iterate (void); + +protected: + virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result); + private: Move m_source; de::MovePtr m_sourceImageAlloc; @@ -707,22 +817,31 @@ private: CopyImageToImage::CopyImageToImage (Context& context, TestParams params) : CopiesAndBlittingTestInstance(context, params) { + const InstanceInterface& vki = context.getInstanceInterface(); const DeviceInterface& vk = context.getDeviceInterface(); + const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice(); const VkDevice vkDevice = context.getDevice(); const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); Allocator& memAlloc = context.getDefaultAllocator(); + if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) || + (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D)) + { + if (std::find(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_maintenance1") == context.getDeviceExtensions().end()) + TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported"); + } + VkImageFormatProperties properties; if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(), m_params.src.image.format, - VK_IMAGE_TYPE_2D, + m_params.src.image.imageType, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0, &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) || (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(), m_params.dst.image.format, - VK_IMAGE_TYPE_2D, + m_params.dst.image.imageType, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0, @@ -738,11 +857,11 @@ CopyImageToImage::CopyImageToImage (Context& context, TestParams params) VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; 0u, // VkImageCreateFlags flags; - VK_IMAGE_TYPE_2D, // VkImageType imageType; + m_params.src.image.imageType, // VkImageType imageType; m_params.src.image.format, // VkFormat format; - m_params.src.image.extent, // VkExtent3D extent; + getExtent3D(m_params.src.image), // VkExtent3D extent; 1u, // deUint32 mipLevels; - 1u, // deUint32 arraySize; + getArraySize(m_params.src.image), // deUint32 arraySize; VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; VK_IMAGE_USAGE_TRANSFER_SRC_BIT | @@ -754,7 +873,7 @@ CopyImageToImage::CopyImageToImage (Context& context, TestParams params) }; m_source = createImage(vk, vkDevice, &sourceImageParams); - m_sourceImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::Any); + m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind); VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset())); } @@ -765,11 +884,11 @@ CopyImageToImage::CopyImageToImage (Context& context, TestParams params) VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; 0u, // VkImageCreateFlags flags; - VK_IMAGE_TYPE_2D, // VkImageType imageType; + m_params.dst.image.imageType, // VkImageType imageType; m_params.dst.image.format, // VkFormat format; - m_params.dst.image.extent, // VkExtent3D extent; + getExtent3D(m_params.dst.image), // VkExtent3D extent; 1u, // deUint32 mipLevels; - 1u, // deUint32 arraySize; + getArraySize(m_params.dst.image), // deUint32 arraySize; VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; VK_IMAGE_USAGE_TRANSFER_SRC_BIT | @@ -781,7 +900,7 @@ CopyImageToImage::CopyImageToImage (Context& context, TestParams params) }; m_destination = createImage(vk, vkDevice, &destinationImageParams); - m_destinationImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any); + m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind); VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset())); } } @@ -791,19 +910,19 @@ tcu::TestStatus CopyImageToImage::iterate (void) const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format); const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_params.dst.image.format); m_sourceTextureLevel = de::MovePtr(new tcu::TextureLevel(srcTcuFormat, - m_params.src.image.extent.width, - m_params.src.image.extent.height, - m_params.src.image.extent.depth)); - generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_WHITE); + (int)m_params.src.image.extent.width, + (int)m_params.src.image.extent.height, + (int)m_params.src.image.extent.depth)); + generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_RED); m_destinationTextureLevel = de::MovePtr(new tcu::TextureLevel(dstTcuFormat, - (int)m_params.dst.image.extent.width, - (int)m_params.dst.image.extent.height, - (int)m_params.dst.image.extent.depth)); + (int)m_params.dst.image.extent.width, + (int)m_params.dst.image.extent.height, + (int)m_params.dst.image.extent.depth)); generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_GRADIENT); generateExpectedResult(); - uploadImage(m_sourceTextureLevel->getAccess(), m_source.get()); - uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get()); + uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image); + uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image); const DeviceInterface& vk = m_context.getDeviceInterface(); const VkDevice vkDevice = m_context.getDevice(); @@ -822,7 +941,7 @@ tcu::TestStatus CopyImageToImage::iterate (void) VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout; + m_params.src.image.operationLayout, // VkImageLayout newLayout; VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; m_source.get(), // VkImage image; @@ -831,7 +950,7 @@ tcu::TestStatus CopyImageToImage::iterate (void) 0u, // deUint32 baseMipLevel; 1u, // deUint32 mipLevels; 0u, // deUint32 baseArraySlice; - 1u // deUint32 arraySize; + getArraySize(m_params.src.image)// deUint32 arraySize; } }, // destination image @@ -841,7 +960,7 @@ tcu::TestStatus CopyImageToImage::iterate (void) VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; + m_params.dst.image.operationLayout, // VkImageLayout newLayout; VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; m_destination.get(), // VkImage image; @@ -850,7 +969,7 @@ tcu::TestStatus CopyImageToImage::iterate (void) 0u, // deUint32 baseMipLevel; 1u, // deUint32 mipLevels; 0u, // deUint32 baseArraySlice; - 1u // deUint32 arraySize; + getArraySize(m_params.dst.image)// deUint32 arraySize; } }, }; @@ -865,46 +984,125 @@ tcu::TestStatus CopyImageToImage::iterate (void) VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers); - vk.cmdCopyImage(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), imageCopies.data()); + vk.cmdCopyImage(*m_cmdBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)m_params.regions.size(), imageCopies.data()); VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); - const VkSubmitInfo submitInfo = + submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer); + + de::MovePtr resultTextureLevel = readImage(*m_destination, m_params.dst.image); + + return checkTestResult(resultTextureLevel->getAccess()); +} + +tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result) +{ + const tcu::Vec4 fThreshold (0.0f); + const tcu::UVec4 uThreshold (0u); + + if (tcu::isCombinedDepthStencilType(result.getFormat().type)) { - VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // deUint32 waitSemaphoreCount; - DE_NULL, // const VkSemaphore* pWaitSemaphores; - (const VkPipelineStageFlags*)DE_NULL, - 1u, // deUint32 commandBufferCount; - &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; - 0u, // deUint32 signalSemaphoreCount; - DE_NULL // const VkSemaphore* pSignalSemaphores; - }; + if (tcu::hasDepthComponent(result.getFormat().order)) + { + const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH; + const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode); + const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode); - VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get())); - VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); - VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */)); + if (isFloatFormat(result.getFormat())) + { + if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT)) + return tcu::TestStatus::fail("CopiesAndBlitting test"); + } + else + { + if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT)) + return tcu::TestStatus::fail("CopiesAndBlitting test"); + } + } - de::MovePtr resultTextureLevel = readImage(*m_destination, m_params.dst.image.format, m_params.dst.image.extent); + if (tcu::hasStencilComponent(result.getFormat().order)) + { + const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL; + const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode); + const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode); - return checkTestResult(resultTextureLevel->getAccess()); + if (isFloatFormat(result.getFormat())) + { + if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT)) + return tcu::TestStatus::fail("CopiesAndBlitting test"); + } + else + { + if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT)) + return tcu::TestStatus::fail("CopiesAndBlitting test"); + } + } + } + else + { + if (isFloatFormat(result.getFormat())) + { + if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT)) + return tcu::TestStatus::fail("CopiesAndBlitting test"); + } + else if (isSnormFormat(mapTextureFormat(result.getFormat()))) + { + // There may be an ambiguity between two possible binary representations of 1.0. + // Get rid of that by expanding the data to floats and re-normalizing again. + + tcu::TextureLevel resultSnorm (result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth()); + { + tcu::TextureLevel resultFloat (tcu::TextureFormat(resultSnorm.getFormat().order, tcu::TextureFormat::FLOAT), resultSnorm.getWidth(), resultSnorm.getHeight(), resultSnorm.getDepth()); + + tcu::copy(resultFloat.getAccess(), result); + tcu::copy(resultSnorm, resultFloat.getAccess()); + } + + tcu::TextureLevel expectedSnorm (m_expectedTextureLevel->getFormat(), m_expectedTextureLevel->getWidth(), m_expectedTextureLevel->getHeight(), m_expectedTextureLevel->getDepth()); + + { + tcu::TextureLevel expectedFloat (tcu::TextureFormat(expectedSnorm.getFormat().order, tcu::TextureFormat::FLOAT), expectedSnorm.getWidth(), expectedSnorm.getHeight(), expectedSnorm.getDepth()); + + tcu::copy(expectedFloat.getAccess(), m_expectedTextureLevel->getAccess()); + tcu::copy(expectedSnorm, expectedFloat.getAccess()); + } + + if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedSnorm.getAccess(), resultSnorm.getAccess(), uThreshold, tcu::COMPARE_LOG_RESULT)) + return tcu::TestStatus::fail("CopiesAndBlitting test"); + } + else + { + if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT)) + return tcu::TestStatus::fail("CopiesAndBlitting test"); + } + } + + return tcu::TestStatus::pass("CopiesAndBlitting test"); } void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region) { - VkOffset3D srcOffset = region.imageCopy.srcOffset; - VkOffset3D dstOffset = region.imageCopy.dstOffset; - VkExtent3D extent = region.imageCopy.extent; + VkOffset3D srcOffset = region.imageCopy.srcOffset; + VkOffset3D dstOffset = region.imageCopy.dstOffset; + VkExtent3D extent = region.imageCopy.extent; + + if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D) + dstOffset.z = srcOffset.z; + if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D) + { + srcOffset.z = dstOffset.z; + extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount); + } + if (tcu::isCombinedDepthStencilType(src.getFormat().type)) { DE_ASSERT(src.getFormat() == dst.getFormat()); + // Copy depth. + if (tcu::hasDepthComponent(src.getFormat().order)) { const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH); - const tcu::PixelBufferAccess dstWithSrcFormat(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr()); - const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH); - + const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH); tcu::copy(dstSubRegion, srcSubRegion); } @@ -912,9 +1110,7 @@ void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src if (tcu::hasStencilComponent(src.getFormat().order)) { const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL); - const tcu::PixelBufferAccess dstWithSrcFormat(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr()); - const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL); - + const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL); tcu::copy(dstSubRegion, srcSubRegion); } } @@ -966,7 +1162,9 @@ private: CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params) : CopiesAndBlittingTestInstance (context, params) { + const InstanceInterface& vki = context.getInstanceInterface(); const DeviceInterface& vk = context.getDeviceInterface(); + const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice(); const VkDevice vkDevice = context.getDevice(); const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); Allocator& memAlloc = context.getDefaultAllocator(); @@ -986,7 +1184,7 @@ CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params) }; m_source = createBuffer(vk, vkDevice, &sourceBufferParams); - m_sourceBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::HostVisible); + m_sourceBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind); VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset())); } @@ -1005,7 +1203,7 @@ CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params) }; m_destination = createBuffer(vk, vkDevice, &destinationBufferParams); - m_destinationBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::HostVisible); + m_destinationBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind); VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset())); } } @@ -1072,23 +1270,9 @@ tcu::TestStatus CopyBufferToBuffer::iterate (void) vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), &bufferCopies[0]); vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &dstBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); + submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer); - const VkSubmitInfo submitInfo = - { - VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // deUint32 waitSemaphoreCount; - DE_NULL, // const VkSemaphore* pWaitSemaphores; - (const VkPipelineStageFlags*)DE_NULL, - 1u, // deUint32 commandBufferCount; - &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; - 0u, // deUint32 signalSemaphoreCount; - DE_NULL // const VkSemaphore* pSignalSemaphores; - }; - VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get())); - VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); - VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */)); // Read buffer data de::MovePtr resultLevel (new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1)); @@ -1149,7 +1333,9 @@ CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams) , m_textureFormat(mapVkFormat(testParams.src.image.format)) , m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat)) { + const InstanceInterface& vki = context.getInstanceInterface(); const DeviceInterface& vk = context.getDeviceInterface(); + const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice(); const VkDevice vkDevice = context.getDevice(); const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); Allocator& memAlloc = context.getDefaultAllocator(); @@ -1161,11 +1347,11 @@ CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams) VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; 0u, // VkImageCreateFlags flags; - VK_IMAGE_TYPE_2D, // VkImageType imageType; + m_params.src.image.imageType, // VkImageType imageType; m_params.src.image.format, // VkFormat format; - m_params.src.image.extent, // VkExtent3D extent; + getExtent3D(m_params.src.image), // VkExtent3D extent; 1u, // deUint32 mipLevels; - 1u, // deUint32 arraySize; + getArraySize(m_params.src.image), // deUint32 arraySize; VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; VK_IMAGE_USAGE_TRANSFER_SRC_BIT | @@ -1177,7 +1363,7 @@ CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams) }; m_source = createImage(vk, vkDevice, &sourceImageParams); - m_sourceImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::Any); + m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind); VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset())); } @@ -1196,7 +1382,7 @@ CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams) }; m_destination = createBuffer(vk, vkDevice, &destinationBufferParams); - m_destinationBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::HostVisible); + m_destinationBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind); VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset())); } } @@ -1207,13 +1393,13 @@ tcu::TestStatus CopyImageToBuffer::iterate (void) m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth)); - generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_RED); + generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth); m_destinationTextureLevel = de::MovePtr(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1)); generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1); generateExpectedResult(); - uploadImage(m_sourceTextureLevel->getAccess(), *m_source); + uploadImage(m_sourceTextureLevel->getAccess(), *m_source, m_params.src.image); uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc); const DeviceInterface& vk = m_context.getDeviceInterface(); @@ -1273,22 +1459,7 @@ tcu::TestStatus CopyImageToBuffer::iterate (void) vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL); VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); - const VkSubmitInfo submitInfo = - { - VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // deUint32 waitSemaphoreCount; - DE_NULL, // const VkSemaphore* pWaitSemaphores; - (const VkPipelineStageFlags*)DE_NULL, - 1u, // deUint32 commandBufferCount; - &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; - 0u, // deUint32 signalSemaphoreCount; - DE_NULL // const VkSemaphore* pSignalSemaphores; - }; - - VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get())); - VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); - VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */)); + submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer); // Read buffer data de::MovePtr resultLevel (new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1)); @@ -1370,7 +1541,9 @@ CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams) , m_textureFormat(mapVkFormat(testParams.dst.image.format)) , m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat)) { + const InstanceInterface& vki = context.getInstanceInterface(); const DeviceInterface& vk = context.getDeviceInterface(); + const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice(); const VkDevice vkDevice = context.getDevice(); const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); Allocator& memAlloc = context.getDefaultAllocator(); @@ -1390,7 +1563,7 @@ CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams) }; m_source = createBuffer(vk, vkDevice, &sourceBufferParams); - m_sourceBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::HostVisible); + m_sourceBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind); VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset())); } @@ -1401,11 +1574,11 @@ CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams) VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; 0u, // VkImageCreateFlags flags; - VK_IMAGE_TYPE_2D, // VkImageType imageType; + m_params.dst.image.imageType, // VkImageType imageType; m_params.dst.image.format, // VkFormat format; - m_params.dst.image.extent, // VkExtent3D extent; + getExtent3D(m_params.dst.image), // VkExtent3D extent; 1u, // deUint32 mipLevels; - 1u, // deUint32 arraySize; + getArraySize(m_params.dst.image), // deUint32 arraySize; VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; VK_IMAGE_USAGE_TRANSFER_SRC_BIT | @@ -1417,7 +1590,7 @@ CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams) }; m_destination = createImage(vk, vkDevice, &destinationImageParams); - m_destinationImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any); + m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind); VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset())); } } @@ -1431,12 +1604,12 @@ tcu::TestStatus CopyBufferToImage::iterate (void) m_params.dst.image.extent.height, m_params.dst.image.extent.depth)); - generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_WHITE); + generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth); generateExpectedResult(); uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc); - uploadImage(m_destinationTextureLevel->getAccess(), *m_destination); + uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image); const DeviceInterface& vk = m_context.getDeviceInterface(); const VkDevice vkDevice = m_context.getDevice(); @@ -1480,24 +1653,9 @@ tcu::TestStatus CopyBufferToImage::iterate (void) vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data()); VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); - const VkSubmitInfo submitInfo = - { - VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // deUint32 waitSemaphoreCount; - DE_NULL, // const VkSemaphore* pWaitSemaphores; - (const VkPipelineStageFlags*)DE_NULL, - 1u, // deUint32 commandBufferCount; - &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; - 0u, // deUint32 signalSemaphoreCount; - DE_NULL // const VkSemaphore* pSignalSemaphores; - }; - - VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get())); - VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); - VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */)); + submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer); - de::MovePtr resultLevel = readImage(*m_destination, m_params.dst.image.format, m_params.dst.image.extent); + de::MovePtr resultLevel = readImage(*m_destination, m_params.dst.image); return checkTestResult(resultLevel->getAccess()); } @@ -1564,10 +1722,13 @@ protected: virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region); virtual void generateExpectedResult (void); private: - bool checkClampedAndUnclampedResult (const tcu::ConstPixelBufferAccess& result, + bool checkLinearFilteredResult (const tcu::ConstPixelBufferAccess& result, const tcu::ConstPixelBufferAccess& clampedReference, const tcu::ConstPixelBufferAccess& unclampedReference, - VkImageAspectFlagBits aspect); + const tcu::TextureFormat& sourceFormat); + bool checkNearestFilteredResult (const tcu::ConstPixelBufferAccess& result, + const tcu::ConstPixelBufferAccess& source); + Move m_source; de::MovePtr m_sourceImageAlloc; Move m_destination; @@ -1579,7 +1740,9 @@ private: BlittingImages::BlittingImages (Context& context, TestParams params) : CopiesAndBlittingTestInstance(context, params) { + const InstanceInterface& vki = context.getInstanceInterface(); const DeviceInterface& vk = context.getDeviceInterface(); + const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice(); const VkDevice vkDevice = context.getDevice(); const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); Allocator& memAlloc = context.getDefaultAllocator(); @@ -1632,11 +1795,11 @@ BlittingImages::BlittingImages (Context& context, TestParams params) VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; 0u, // VkImageCreateFlags flags; - VK_IMAGE_TYPE_2D, // VkImageType imageType; + m_params.src.image.imageType, // VkImageType imageType; m_params.src.image.format, // VkFormat format; - m_params.src.image.extent, // VkExtent3D extent; + getExtent3D(m_params.src.image), // VkExtent3D extent; 1u, // deUint32 mipLevels; - 1u, // deUint32 arraySize; + getArraySize(m_params.src.image), // deUint32 arraySize; VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; VK_IMAGE_USAGE_TRANSFER_SRC_BIT | @@ -1648,7 +1811,7 @@ BlittingImages::BlittingImages (Context& context, TestParams params) }; m_source = createImage(vk, vkDevice, &sourceImageParams); - m_sourceImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::Any); + m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind); VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset())); } @@ -1659,11 +1822,11 @@ BlittingImages::BlittingImages (Context& context, TestParams params) VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; 0u, // VkImageCreateFlags flags; - VK_IMAGE_TYPE_2D, // VkImageType imageType; + m_params.dst.image.imageType, // VkImageType imageType; m_params.dst.image.format, // VkFormat format; - m_params.dst.image.extent, // VkExtent3D extent; + getExtent3D(m_params.dst.image), // VkExtent3D extent; 1u, // deUint32 mipLevels; - 1u, // deUint32 arraySize; + getArraySize(m_params.dst.image), // deUint32 arraySize; VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; VK_IMAGE_USAGE_TRANSFER_SRC_BIT | @@ -1675,7 +1838,7 @@ BlittingImages::BlittingImages (Context& context, TestParams params) }; m_destination = createImage(vk, vkDevice, &destinationImageParams); - m_destinationImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any); + m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind); VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset())); } } @@ -1696,8 +1859,8 @@ tcu::TestStatus BlittingImages::iterate (void) generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_WHITE); generateExpectedResult(); - uploadImage(m_sourceTextureLevel->getAccess(), m_source.get()); - uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get()); + uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image); + uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image); const DeviceInterface& vk = m_context.getDeviceInterface(); const VkDevice vkDevice = m_context.getDevice(); @@ -1715,7 +1878,7 @@ tcu::TestStatus BlittingImages::iterate (void) VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout; + m_params.src.image.operationLayout, // VkImageLayout newLayout; VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; m_source.get(), // VkImage image; @@ -1735,7 +1898,7 @@ tcu::TestStatus BlittingImages::iterate (void) VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; + m_params.dst.image.operationLayout, // VkImageLayout newLayout; VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; m_destination.get(), // VkImage image; @@ -1758,28 +1921,12 @@ tcu::TestStatus BlittingImages::iterate (void) VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &srcImageBarrier); - vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), ®ions[0], m_params.filter); - vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &dstImageBarrier); + vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &dstImageBarrier); + vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)m_params.regions.size(), ®ions[0], m_params.filter); VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); + submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer); - const VkSubmitInfo submitInfo = - { - VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // deUint32 waitSemaphoreCount; - DE_NULL, // const VkSemaphore* pWaitSemaphores; - (const VkPipelineStageFlags*)DE_NULL, - 1u, // deUint32 commandBufferCount; - &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; - 0u, // deUint32 signalSemaphoreCount; - DE_NULL // const VkSemaphore* pSignalSemaphores; - }; - - VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get())); - VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); - VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */)); - - de::MovePtr resultTextureLevel = readImage(*m_destination, m_params.dst.image.format, m_params.dst.image.extent); + de::MovePtr resultTextureLevel = readImage(*m_destination, m_params.dst.image); return checkTestResult(resultTextureLevel->getAccess()); } @@ -1836,52 +1983,28 @@ tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format) return threshold; } -tcu::TextureFormat getFormatAspect (VkFormat format, VkImageAspectFlagBits aspect) -{ - const tcu::TextureFormat baseFormat = mapVkFormat(format); - - if (isCombinedDepthStencilType(baseFormat.type)) - { - if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) - return getEffectiveDepthStencilTextureFormat(baseFormat, tcu::Sampler::MODE_DEPTH); - else if (aspect == VK_IMAGE_ASPECT_STENCIL_BIT) - return getEffectiveDepthStencilTextureFormat(baseFormat, tcu::Sampler::MODE_STENCIL); - else - DE_FATAL("Invalid aspect"); - } - - return baseFormat; -} - -bool BlittingImages::checkClampedAndUnclampedResult (const tcu::ConstPixelBufferAccess& result, - const tcu::ConstPixelBufferAccess& clampedExpected, - const tcu::ConstPixelBufferAccess& unclampedExpected, - VkImageAspectFlagBits aspect) +bool BlittingImages::checkLinearFilteredResult (const tcu::ConstPixelBufferAccess& result, + const tcu::ConstPixelBufferAccess& clampedExpected, + const tcu::ConstPixelBufferAccess& unclampedExpected, + const tcu::TextureFormat& srcFormat) { tcu::TestLog& log (m_context.getTestContext().getLog()); - const bool isLinear = m_params.filter == VK_FILTER_LINEAR; - const tcu::TextureFormat srcFormat = getFormatAspect(m_params.src.image.format, aspect); const tcu::TextureFormat dstFormat = result.getFormat(); bool isOk = false; - DE_ASSERT(dstFormat == getFormatAspect(m_params.dst.image.format, aspect)); - - if (isLinear) - log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image."); + log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image."); if (isFloatFormat(dstFormat)) { const bool srcIsSRGB = tcu::isSRGB(srcFormat); - const tcu::Vec4 srcMaxDiff = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2 : 1); + const tcu::Vec4 srcMaxDiff = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f); const tcu::Vec4 dstMaxDiff = getFormatThreshold(dstFormat); const tcu::Vec4 threshold = tcu::max(srcMaxDiff, dstMaxDiff); isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT); + log << tcu::TestLog::EndSection; - if (isLinear) - log << tcu::TestLog::EndSection; - - if (!isOk && isLinear) + if (!isOk) { log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image."); isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT); @@ -1897,61 +2020,318 @@ bool BlittingImages::checkClampedAndUnclampedResult (const tcu::ConstPixelBuffer threshold[i] = de::max( (0x1 << bitDepth[i]) / 256, 1); isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT); + log << tcu::TestLog::EndSection; - if (isLinear) - log << tcu::TestLog::EndSection; - - if (!isOk && isLinear) + if (!isOk) { log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image."); isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT); log << tcu::TestLog::EndSection; } } + return isOk; } -tcu::TestStatus BlittingImages::checkTestResult (tcu::ConstPixelBufferAccess result) +//! Utility to encapsulate coordinate computation and loops. +struct CompareEachPixelInEachRegion { - DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR); + virtual ~CompareEachPixelInEachRegion (void) {} + virtual bool compare (const void* pUserData, const int x, const int y, const tcu::Vec2& srcNormCoord) const = 0; - if (tcu::isCombinedDepthStencilType(result.getFormat().type)) + bool forEach (const void* pUserData, + const std::vector& regions, + const int sourceWidth, + const int sourceHeight, + const tcu::PixelBufferAccess& errorMask) const { - if (tcu::hasDepthComponent(result.getFormat().order)) + bool compareOk = true; + + for (std::vector::const_iterator regionIter = regions.begin(); regionIter != regions.end(); ++regionIter) { - const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH; - const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode); - const tcu::ConstPixelBufferAccess clampedExpected = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode); - const tcu::ConstPixelBufferAccess unclampedExpected = m_params.filter == VK_FILTER_LINEAR ? tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode) : tcu::ConstPixelBufferAccess(); + const VkImageBlit& blit = regionIter->imageBlit; + + const int dx = deSign32(blit.dstOffsets[1].x - blit.dstOffsets[0].x); + const int dy = deSign32(blit.dstOffsets[1].y - blit.dstOffsets[0].y); + const float xScale = static_cast(blit.srcOffsets[1].x - blit.srcOffsets[0].x) / static_cast(blit.dstOffsets[1].x - blit.dstOffsets[0].x); + const float yScale = static_cast(blit.srcOffsets[1].y - blit.srcOffsets[0].y) / static_cast(blit.dstOffsets[1].y - blit.dstOffsets[0].y); + const float srcInvW = 1.0f / static_cast(sourceWidth); + const float srcInvH = 1.0f / static_cast(sourceHeight); - if (!checkClampedAndUnclampedResult(depthResult, clampedExpected, unclampedExpected, VK_IMAGE_ASPECT_DEPTH_BIT)) + for (int y = blit.dstOffsets[0].y; y < blit.dstOffsets[1].y; y += dy) + for (int x = blit.dstOffsets[0].x; x < blit.dstOffsets[1].x; x += dx) { - return tcu::TestStatus::fail("CopiesAndBlitting test"); + const tcu::Vec2 srcNormCoord + ( + (xScale * (static_cast(x - blit.dstOffsets[0].x) + 0.5f) + static_cast(blit.srcOffsets[0].x)) * srcInvW, + (yScale * (static_cast(y - blit.dstOffsets[0].y) + 0.5f) + static_cast(blit.srcOffsets[0].y)) * srcInvH + ); + + if (!compare(pUserData, x, y, srcNormCoord)) + { + errorMask.setPixel(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y); + compareOk = false; + } } } + return compareOk; + } +}; - if (tcu::hasStencilComponent(result.getFormat().order)) +tcu::Vec4 getFloatOrFixedPointFormatThreshold (const tcu::TextureFormat& format) +{ + const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type); + const tcu::IVec4 bitDepth = tcu::getTextureFormatBitDepth(format); + + if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT) + { + return getFormatThreshold(format); + } + else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT || + channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT) + { + const bool isSigned = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT); + const float range = isSigned ? 1.0f - (-1.0f) + : 1.0f - 0.0f; + + tcu::Vec4 v; + for (int i = 0; i < 4; ++i) { - const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL; - const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode); - const tcu::ConstPixelBufferAccess clampedExpected = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode); - const tcu::ConstPixelBufferAccess unclampedExpected = m_params.filter == VK_FILTER_LINEAR ? tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode) : tcu::ConstPixelBufferAccess(); + if (bitDepth[i] == 0) + v[i] = 1.0f; + else + v[i] = range / static_cast((1 << bitDepth[i]) - 1); + } + return v; + } + else + { + DE_ASSERT(0); + return tcu::Vec4(); + } +} + +bool floatNearestBlitCompare (const tcu::ConstPixelBufferAccess& source, + const tcu::ConstPixelBufferAccess& result, + const tcu::PixelBufferAccess& errorMask, + const std::vector& regions) +{ + const tcu::Sampler sampler (tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST); + tcu::LookupPrecision precision; + + { + const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(result.getFormat()); + const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat()); + const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat()); + + precision.colorMask = tcu::notEqual(dstBitDepth, tcu::IVec4(0)); + precision.colorThreshold = tcu::max(srcMaxDiff, dstMaxDiff); + } + + const struct Capture + { + const tcu::ConstPixelBufferAccess& source; + const tcu::ConstPixelBufferAccess& result; + const tcu::Sampler& sampler; + const tcu::LookupPrecision& precision; + const bool isSRGB; + } capture = + { + source, result, sampler, precision, tcu::isSRGB(result.getFormat()) + }; + + const struct Loop : CompareEachPixelInEachRegion + { + Loop (void) {} + + bool compare (const void* pUserData, const int x, const int y, const tcu::Vec2& srcNormCoord) const + { + const Capture& c = *static_cast(pUserData); + const tcu::TexLookupScaleMode lookupScaleDontCare = tcu::TEX_LOOKUP_SCALE_MINIFY; + tcu::Vec4 dstColor = c.result.getPixel(x, y); + + // TexLookupVerifier performs a conversion to linear space, so we have to as well + if (c.isSRGB) + dstColor = tcu::sRGBToLinear(dstColor); + + return tcu::isLevel2DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, 0, dstColor); + } + } loop; + + return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), errorMask); +} + +bool intNearestBlitCompare (const tcu::ConstPixelBufferAccess& source, + const tcu::ConstPixelBufferAccess& result, + const tcu::PixelBufferAccess& errorMask, + const std::vector& regions) +{ + const tcu::Sampler sampler (tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST); + tcu::IntLookupPrecision precision; + + { + const tcu::IVec4 srcBitDepth = tcu::getTextureFormatBitDepth(source.getFormat()); + const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(result.getFormat()); + + for (deUint32 i = 0; i < 4; ++i) { + precision.colorThreshold[i] = de::max(de::max(srcBitDepth[i] / 8, dstBitDepth[i] / 8), 1); + precision.colorMask[i] = dstBitDepth[i] != 0; + } + } + + // Prepare a source image with a matching (converted) pixel format. Ideally, we would've used a wrapper that + // does the conversion on the fly without wasting memory, but this approach is more straightforward. + tcu::TextureLevel convertedSourceTexture (result.getFormat(), source.getWidth(), source.getHeight()); + const tcu::PixelBufferAccess convertedSource = convertedSourceTexture.getAccess(); + + for (int y = 0; y < source.getHeight(); ++y) + for (int x = 0; x < source.getWidth(); ++x) + convertedSource.setPixel(source.getPixelInt(x, y), x, y); // will be clamped to max. representable value + + const struct Capture + { + const tcu::ConstPixelBufferAccess& source; + const tcu::ConstPixelBufferAccess& result; + const tcu::Sampler& sampler; + const tcu::IntLookupPrecision& precision; + } capture = + { + convertedSource, result, sampler, precision + }; + + const struct Loop : CompareEachPixelInEachRegion + { + Loop (void) {} + + bool compare (const void* pUserData, const int x, const int y, const tcu::Vec2& srcNormCoord) const + { + const Capture& c = *static_cast(pUserData); + const tcu::TexLookupScaleMode lookupScaleDontCare = tcu::TEX_LOOKUP_SCALE_MINIFY; + const tcu::IVec4 dstColor = c.result.getPixelInt(x, y); + + return tcu::isLevel2DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, 0, dstColor); + } + } loop; + + return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), errorMask); +} + +bool BlittingImages::checkNearestFilteredResult (const tcu::ConstPixelBufferAccess& result, + const tcu::ConstPixelBufferAccess& source) +{ + tcu::TestLog& log (m_context.getTestContext().getLog()); + const tcu::TextureFormat dstFormat = result.getFormat(); + const tcu::TextureChannelClass dstChannelClass = tcu::getTextureChannelClass(dstFormat.type); + + tcu::TextureLevel errorMaskStorage (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight()); + tcu::PixelBufferAccess errorMask = errorMaskStorage.getAccess(); + tcu::Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f); + tcu::Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f); + bool ok = false; + + tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0)); + + if (dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || + dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) + { + ok = intNearestBlitCompare(source, result, errorMask, m_params.regions); + } + else + ok = floatNearestBlitCompare(source, result, errorMask, m_params.regions); + + if (result.getFormat() != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)) + tcu::computePixelScaleBias(result, pixelScale, pixelBias); + + if (!ok) + { + log << tcu::TestLog::ImageSet("Compare", "Result comparsion") + << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias) + << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask) + << tcu::TestLog::EndImageSet; + } + else + { + log << tcu::TestLog::ImageSet("Compare", "Result comparsion") + << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias) + << tcu::TestLog::EndImageSet; + } + + return ok; +} + +tcu::TestStatus BlittingImages::checkTestResult (tcu::ConstPixelBufferAccess result) +{ + DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR); + const std::string failMessage("Result image is incorrect"); + + if (m_params.filter == VK_FILTER_LINEAR) + { + if (tcu::isCombinedDepthStencilType(result.getFormat().type)) + { + if (tcu::hasDepthComponent(result.getFormat().order)) + { + const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH; + const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode); + const tcu::ConstPixelBufferAccess clampedExpected = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode); + const tcu::ConstPixelBufferAccess unclampedExpected = tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode); + const tcu::TextureFormat sourceFormat = tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode); + + if (!checkLinearFilteredResult(depthResult, clampedExpected, unclampedExpected, sourceFormat)) + return tcu::TestStatus::fail(failMessage); + } - if (!checkClampedAndUnclampedResult(stencilResult, clampedExpected, unclampedExpected, VK_IMAGE_ASPECT_STENCIL_BIT)) + if (tcu::hasStencilComponent(result.getFormat().order)) { - return tcu::TestStatus::fail("CopiesAndBlitting test"); + const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL; + const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode); + const tcu::ConstPixelBufferAccess clampedExpected = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode); + const tcu::ConstPixelBufferAccess unclampedExpected = tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode); + const tcu::TextureFormat sourceFormat = tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode); + + if (!checkLinearFilteredResult(stencilResult, clampedExpected, unclampedExpected, sourceFormat)) + return tcu::TestStatus::fail(failMessage); } } + else + { + const tcu::TextureFormat sourceFormat = mapVkFormat(m_params.src.image.format); + + if (!checkLinearFilteredResult(result, m_expectedTextureLevel->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), sourceFormat)) + return tcu::TestStatus::fail(failMessage); + } } - else + else // NEAREST filtering { - if (!checkClampedAndUnclampedResult(result, m_expectedTextureLevel->getAccess(), m_params.filter == VK_FILTER_LINEAR ? m_unclampedExpectedTextureLevel->getAccess() : tcu::ConstPixelBufferAccess(), VK_IMAGE_ASPECT_COLOR_BIT)) + if (tcu::isCombinedDepthStencilType(result.getFormat().type)) { - return tcu::TestStatus::fail("CopiesAndBlitting test"); + if (tcu::hasDepthComponent(result.getFormat().order)) + { + const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH; + const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode); + const tcu::ConstPixelBufferAccess depthSource = tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode); + + if (!checkNearestFilteredResult(depthResult, depthSource)) + return tcu::TestStatus::fail(failMessage); + } + + if (tcu::hasStencilComponent(result.getFormat().order)) + { + const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL; + const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode); + const tcu::ConstPixelBufferAccess stencilSource = tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode); + + if (!checkNearestFilteredResult(stencilResult, stencilSource)) + return tcu::TestStatus::fail(failMessage); + } + } + else + { + if (!checkNearestFilteredResult(result, m_sourceTextureLevel->getAccess())) + return tcu::TestStatus::fail(failMessage); } } - return tcu::TestStatus::pass("CopiesAndBlitting test"); + return tcu::TestStatus::pass("Pass"); } tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color) @@ -1975,8 +2355,128 @@ void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::Cons dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, (float)regionOffset.x + ((float)x+0.5f)*sX, (float)regionOffset.y + ((float)y+0.5f)*sY, 0)), x, y); } +void blit (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode) +{ + DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR); + + tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, + filter, filter, 0.0f, false); + + const float sX = (float)src.getWidth() / (float)dst.getWidth(); + const float sY = (float)src.getHeight() / (float)dst.getHeight(); + const float sZ = (float)src.getDepth() / (float)dst.getDepth(); + + tcu::Mat2 rotMatrix; + rotMatrix(0,0) = (mirrorMode & MIRROR_MODE_X) ? -1.0f : 1.0f; + rotMatrix(0,1) = 0.0f; + rotMatrix(1,0) = 0.0f; + rotMatrix(1,1) = (mirrorMode & MIRROR_MODE_Y) ? -1.0f : 1.0f; + + const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0; + const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0; + + if (dst.getDepth() == 1 && src.getDepth() == 1) + { + for (int y = 0; y < dst.getHeight(); ++y) + for (int x = 0; x < dst.getWidth(); ++x) + { + const tcu::Vec2 xy = rotMatrix * tcu::Vec2((float)x,(float)y); + dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, ((float)x+0.5f)*sX, ((float)y+0.5f)*sY, 0)), (int)round(xy[0]) + xOffset, (int)round(xy[1]) + yOffset); + } + } + else + { + for (int z = 0; z < dst.getDepth(); ++z) + for (int y = 0; y < dst.getHeight(); ++y) + for (int x = 0; x < dst.getWidth(); ++x) + { + const tcu::Vec2 xy = rotMatrix * tcu::Vec2((float)x,(float)y); + dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, ((float)x+0.5f)*sX, ((float)y+0.5f)*sY, ((float)z+0.5f)*sZ)), (int)round(xy[0]) + xOffset, (int)round(xy[1]) + yOffset, z); + } + } +} + +void flipCoordinates (CopyRegion& region, const MirrorMode mirrorMode) +{ + const VkOffset3D dstOffset0 = region.imageBlit.dstOffsets[0]; + const VkOffset3D dstOffset1 = region.imageBlit.dstOffsets[1]; + const VkOffset3D srcOffset0 = region.imageBlit.srcOffsets[0]; + const VkOffset3D srcOffset1 = region.imageBlit.srcOffsets[1]; + + if (mirrorMode > MIRROR_MODE_NONE && mirrorMode < MIRROR_MODE_LAST) + { + //sourceRegion + region.imageBlit.srcOffsets[0].x = std::min(srcOffset0.x, srcOffset1.x); + region.imageBlit.srcOffsets[0].y = std::min(srcOffset0.y, srcOffset1.y); + + region.imageBlit.srcOffsets[1].x = std::max(srcOffset0.x, srcOffset1.x); + region.imageBlit.srcOffsets[1].y = std::max(srcOffset0.y, srcOffset1.y); + + //destinationRegion + region.imageBlit.dstOffsets[0].x = std::min(dstOffset0.x, dstOffset1.x); + region.imageBlit.dstOffsets[0].y = std::min(dstOffset0.y, dstOffset1.y); + + region.imageBlit.dstOffsets[1].x = std::max(dstOffset0.x, dstOffset1.x); + region.imageBlit.dstOffsets[1].y = std::max(dstOffset0.y, dstOffset1.y); + } +} + +MirrorMode getMirrorMode(const VkOffset3D x1, const VkOffset3D x2) +{ + if (x1.x >= x2.x && x1.y >= x2.y) + { + return MIRROR_MODE_XY; + } + else if (x1.x <= x2.x && x1.y <= x2.y) + { + return MIRROR_MODE_NONE; + } + else if (x1.x <= x2.x && x1.y >= x2.y) + { + return MIRROR_MODE_Y; + } + else if (x1.x >= x2.x && x1.y <= x2.y) + { + return MIRROR_MODE_X; + } + return MIRROR_MODE_LAST; +} + +MirrorMode getMirrorMode(const VkOffset3D s1, const VkOffset3D s2, const VkOffset3D d1, const VkOffset3D d2) +{ + const MirrorMode source = getMirrorMode(s1, s2); + const MirrorMode destination = getMirrorMode(d1, d2); + + if (source == destination) + { + return MIRROR_MODE_NONE; + } + else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_X) || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_X) || + (source == MIRROR_MODE_Y && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_Y && source == MIRROR_MODE_NONE)) + { + return MIRROR_MODE_Y; + } + else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_Y) || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_Y) || + (source == MIRROR_MODE_X && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_X && source == MIRROR_MODE_NONE)) + { + return MIRROR_MODE_X; + } + else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_NONE)) + { + return MIRROR_MODE_XY; + } + return MIRROR_MODE_LAST; +} + void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region) { + const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0], + region.imageBlit.srcOffsets[1], + region.imageBlit.dstOffsets[0], + region.imageBlit.dstOffsets[1]); + + flipCoordinates(region, mirrorMode); + const VkOffset3D srcOffset = region.imageBlit.srcOffsets[0]; const VkOffset3D srcExtent = { @@ -2016,7 +2516,7 @@ void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, { const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL); const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL); - tcu::scale(dstSubRegion, srcSubRegion, filter); + blit(dstSubRegion, srcSubRegion, filter, mirrorMode); if (filter == tcu::Sampler::LINEAR) { @@ -2030,7 +2530,7 @@ void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, { const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y); const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y); - tcu::scale(dstSubRegion, srcSubRegion, filter); + blit(dstSubRegion, srcSubRegion, filter, mirrorMode); if (filter == tcu::Sampler::LINEAR) { @@ -2055,7 +2555,10 @@ void BlittingImages::generateExpectedResult (void) } for (deUint32 i = 0; i < m_params.regions.size(); i++) - copyRegionToTextureLevel(src, m_expectedTextureLevel->getAccess(), m_params.regions[i]); + { + CopyRegion region = m_params.regions[i]; + copyRegionToTextureLevel(src, m_expectedTextureLevel->getAccess(), region); + } } class BlittingTestCase : public vkt::TestCase @@ -2079,14 +2582,17 @@ private: // Resolve image to image. +enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION, COPY_MS_IMAGE_TO_MS_IMAGE, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE}; class ResolveImageToImage : public CopiesAndBlittingTestInstance { public: - ResolveImageToImage (Context& context, - TestParams params); + ResolveImageToImage (Context& context, + TestParams params, + const ResolveImageToImageOptions options); virtual tcu::TestStatus iterate (void); protected: virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result); + void copyMSImageToMSImage (void); private: Move m_multisampledImage; de::MovePtr m_multisampledImageAlloc; @@ -2094,54 +2600,55 @@ private: Move m_destination; de::MovePtr m_destinationImageAlloc; - virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region); + Move m_multisampledCopyImage; + de::MovePtr m_multisampledCopyImageAlloc; + + const ResolveImageToImageOptions m_options; + + virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, + tcu::PixelBufferAccess dst, + CopyRegion region); }; -ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params) - : CopiesAndBlittingTestInstance(context, params) +ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, const ResolveImageToImageOptions options) + : CopiesAndBlittingTestInstance (context, params) + , m_options (options) { const VkSampleCountFlagBits rasterizationSamples = m_params.samples; if (!(context.getDeviceProperties().limits.framebufferColorSampleCounts & rasterizationSamples)) throw tcu::NotSupportedError("Unsupported number of rasterization samples"); + const InstanceInterface& vki = context.getInstanceInterface(); const DeviceInterface& vk = context.getDeviceInterface(); + const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice(); const VkDevice vkDevice = context.getDevice(); const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); Allocator& memAlloc = m_context.getDefaultAllocator(); const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - - Move sourceAttachmentView; - Move renderPass; - Move framebuffer; - Move vertexShaderModule; - Move fragmentShaderModule; + Move vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0); + Move fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0); + std::vector vertices; Move vertexBuffer; - std::vector vertices; de::MovePtr vertexBufferAlloc; Move pipelineLayout; Move graphicsPipeline; - Move cmdPool; - Move cmdBuffer; - - Move fence; - VkImageFormatProperties properties; if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(), m_params.src.image.format, - VK_IMAGE_TYPE_2D, + m_params.src.image.imageType, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0, &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) || (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(), m_params.dst.image.format, - VK_IMAGE_TYPE_2D, + m_params.dst.image.imageType, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0, &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)) @@ -2151,30 +2658,57 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params) // Create color image. { - const VkImageCreateInfo colorImageParams = - { - VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // VkImageCreateFlags flags; - VK_IMAGE_TYPE_2D, // VkImageType imageType; - m_params.src.image.format, // VkFormat format; - m_params.src.image.extent, // VkExtent3D extent; - 1u, // deUint32 mipLevels; - 1u, // deUint32 arrayLayers; - rasterizationSamples, // VkSampleCountFlagBits samples; - VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; - VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; - 1u, // deUint32 queueFamilyIndexCount; - &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; - VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; + VkImageCreateInfo colorImageParams = + { + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkImageCreateFlags flags; + m_params.src.image.imageType, // VkImageType imageType; + m_params.src.image.format, // VkFormat format; + getExtent3D(m_params.src.image), // VkExtent3D extent; + 1u, // deUint32 mipLevels; + getArraySize(m_params.src.image), // deUint32 arrayLayers; + rasterizationSamples, // VkSampleCountFlagBits samples; + VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; + VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; + 1u, // deUint32 queueFamilyIndexCount; + &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; + VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; }; - m_multisampledImage = createImage(vk, vkDevice, &colorImageParams); + m_multisampledImage = createImage(vk, vkDevice, &colorImageParams); // Allocate and bind color image memory. - m_multisampledImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_multisampledImage), MemoryRequirement::Any); + m_multisampledImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind); VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledImage, m_multisampledImageAlloc->getMemory(), m_multisampledImageAlloc->getOffset())); + + switch (m_options) + { + case COPY_MS_IMAGE_TO_MS_IMAGE: + { + colorImageParams.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + m_multisampledCopyImage = createImage(vk, vkDevice, &colorImageParams); + // Allocate and bind color image memory. + m_multisampledCopyImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind); + VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset())); + break; + } + + case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE: + { + colorImageParams.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + colorImageParams.arrayLayers = getArraySize(m_params.dst.image); + m_multisampledCopyImage = createImage(vk, vkDevice, &colorImageParams); + // Allocate and bind color image memory. + m_multisampledCopyImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind); + VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset())); + break; + } + + default : + break; + } } // Create destination image. @@ -2184,11 +2718,11 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params) VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; 0u, // VkImageCreateFlags flags; - VK_IMAGE_TYPE_2D, // VkImageType imageType; + m_params.dst.image.imageType, // VkImageType imageType; m_params.dst.image.format, // VkFormat format; - m_params.dst.image.extent, // VkExtent3D extent; + getExtent3D(m_params.dst.image), // VkExtent3D extent; 1u, // deUint32 mipLevels; - 1u, // deUint32 arraySize; + getArraySize(m_params.dst.image), // deUint32 arraySize; VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; VK_IMAGE_USAGE_TRANSFER_SRC_BIT | @@ -2200,28 +2734,32 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params) }; m_destination = createImage(vk, vkDevice, &destinationImageParams); - m_destinationImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any); + m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind); VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset())); } - // Create color attachment view. + // Barriers for copying image to buffer + VkImageMemoryBarrier srcImageBarrier = { - const VkImageViewCreateInfo colorAttachmentViewParams = - { - VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // VkImageViewCreateFlags flags; - *m_multisampledImage, // VkImage image; - VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; - m_params.src.image.format, // VkFormat format; - componentMappingRGBA, // VkComponentMapping components; - { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; - }; - - sourceAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams); - } + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkAccessFlags srcAccessMask; + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; + VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; + VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; + VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; + m_multisampledImage.get(), // VkImage image; + { // VkImageSubresourceRange subresourceRange; + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // deUint32 baseMipLevel; + 1u, // deUint32 mipLevels; + 0u, // deUint32 baseArraySlice; + getArraySize(m_params.src.image) // deUint32 arraySize; + } + }; - // Create render pass. + // Create render pass. { const VkAttachmentDescription attachmentDescriptions[1] = { @@ -2274,29 +2812,6 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params) renderPass = createRenderPass(vk, vkDevice, &renderPassParams); } - // Create framebuffer - { - const VkImageView attachments[1] = - { - *sourceAttachmentView, - }; - - const VkFramebufferCreateInfo framebufferParams = - { - VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // VkFramebufferCreateFlags flags; - *renderPass, // VkRenderPass renderPass; - 1u, // deUint32 attachmentCount; - attachments, // const VkImageView* pAttachments; - m_params.src.image.extent.width, // deUint32 width; - m_params.src.image.extent.height, // deUint32 height; - 1u // deUint32 layers; - }; - - framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams); - } - // Create pipeline layout { const VkPipelineLayoutCreateInfo pipelineLayoutParams = @@ -2313,197 +2828,19 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params) pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams); } - // Create shaders + // Create upper half triangle. { - vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0); - fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0); - } - - // Create pipeline - { - const VkPipelineShaderStageCreateInfo shaderStageParams[2] = - { - { - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // VkPipelineShaderStageCreateFlags flags; - VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage; - *vertexShaderModule, // VkShaderModule module; - "main", // const char* pName; - DE_NULL // const VkSpecializationInfo* pSpecializationInfo; - }, - { - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // VkPipelineShaderStageCreateFlags flags; - VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage; - *fragmentShaderModule, // VkShaderModule module; - "main", // const char* pName; - DE_NULL // const VkSpecializationInfo* pSpecializationInfo; - } - }; - - const VkVertexInputBindingDescription vertexInputBindingDescription = - { - 0u, // deUint32 binding; - sizeof(tcu::Vec4), // deUint32 stride; - VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate; - }; - - const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[1] = - { - { - 0u, // deUint32 location; - 0u, // deUint32 binding; - VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; - 0u // deUint32 offset; - } - }; - - const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = - { - VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // VkPipelineVertexInputStateCreateFlags flags; - 1u, // deUint32 vertexBindingDescriptionCount; - &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; - 1u, // deUint32 vertexAttributeDescriptionCount; - vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; - }; - - const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = - { - VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // VkPipelineInputAssemblyStateCreateFlags flags; - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology; - false // VkBool32 primitiveRestartEnable; - }; - - const VkViewport viewport = - { - 0.0f, // float x; - 0.0f, // float y; - (float)m_params.src.image.extent.width, // float width; - (float)m_params.src.image.extent.height, // float height; - 0.0f, // float minDepth; - 1.0f // float maxDepth; - }; - - const VkRect2D scissor = - { - { 0, 0 }, // VkOffset2D offset; - { m_params.src.image.extent.width, m_params.src.image.extent.height } // VkExtent2D extent; - }; - - const VkPipelineViewportStateCreateInfo viewportStateParams = - { - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // VkPipelineViewportStateCreateFlags flags; - 1u, // deUint32 viewportCount; - &viewport, // const VkViewport* pViewports; - 1u, // deUint32 scissorCount; - &scissor // const VkRect2D* pScissors; - }; - - const VkPipelineRasterizationStateCreateInfo rasterStateParams = - { - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // VkPipelineRasterizationStateCreateFlags flags; - false, // VkBool32 depthClampEnable; - false, // VkBool32 rasterizerDiscardEnable; - VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; - VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; - VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; - VK_FALSE, // VkBool32 depthBiasEnable; - 0.0f, // float depthBiasConstantFactor; - 0.0f, // float depthBiasClamp; - 0.0f, // float depthBiasSlopeFactor; - 1.0f // float lineWidth; - }; - - const VkPipelineMultisampleStateCreateInfo multisampleStateParams = - { - VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // VkPipelineMultisampleStateCreateFlags flags; - rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; - VK_FALSE, // VkBool32 sampleShadingEnable; - 0.0f, // float minSampleShading; - DE_NULL, // const VkSampleMask* pSampleMask; - VK_FALSE, // VkBool32 alphaToCoverageEnable; - VK_FALSE // VkBool32 alphaToOneEnable; - }; - - const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = - { - false, // VkBool32 blendEnable; - VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor; - VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor; - VK_BLEND_OP_ADD, // VkBlendOp blendOpColor; - VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha; - VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha; - VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha; - (VK_COLOR_COMPONENT_R_BIT | - VK_COLOR_COMPONENT_G_BIT | - VK_COLOR_COMPONENT_B_BIT | - VK_COLOR_COMPONENT_A_BIT) // VkChannelFlags channelWriteMask; - }; - - const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = - { - VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // VkPipelineColorBlendStateCreateFlags flags; - false, // VkBool32 logicOpEnable; - VK_LOGIC_OP_COPY, // VkLogicOp logicOp; - 1u, // deUint32 attachmentCount; - &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; - { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4]; - }; - - const VkGraphicsPipelineCreateInfo graphicsPipelineParams = - { - VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // VkPipelineCreateFlags flags; - 2u, // deUint32 stageCount; - shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages; - &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; - &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; - DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; - &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; - &rasterStateParams, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; - &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; - DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; - &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; - DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; - *pipelineLayout, // VkPipelineLayout layout; - *renderPass, // VkRenderPass renderPass; - 0u, // deUint32 subpass; - 0u, // VkPipeline basePipelineHandle; - 0u // deInt32 basePipelineIndex; - }; - - graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams); + const tcu::Vec4 a (-1.0, -1.0, 0.0, 1.0); + const tcu::Vec4 b (1.0, -1.0, 0.0, 1.0); + const tcu::Vec4 c (1.0, 1.0, 0.0, 1.0); + // Add triangle. + vertices.push_back(a); + vertices.push_back(c); + vertices.push_back(b); } // Create vertex buffer. { - // Create upper half triangle. - { - const tcu::Vec4 a (-1.0, -1.0, 0.0, 1.0); - const tcu::Vec4 b (1.0, -1.0, 0.0, 1.0); - const tcu::Vec4 c (1.0, 1.0, 0.0, 1.0); - - // Add triangle. - vertices.push_back(a); - vertices.push_back(c); - vertices.push_back(b); - } - const VkDeviceSize vertexDataSize = vertices.size() * sizeof(tcu::Vec4); const VkBufferCreateInfo vertexBufferParams = { @@ -2518,8 +2855,7 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params) }; vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams); - vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible); - + vertexBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind); VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset())); // Load vertices into vertex buffer. @@ -2527,128 +2863,268 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params) flushMappedMemoryRange(vk, vkDevice, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset(), vertexDataSize); } - // Create command pool { - const VkCommandPoolCreateInfo cmdPoolParams = - { - VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags; - queueFamilyIndex, // deUint32 queueFamilyIndex; - }; + Move framebuffer; + Move sourceAttachmentView; - cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams); - } - - // Create command buffer - { - const VkCommandBufferAllocateInfo cmdBufferAllocateInfo = + // Create color attachment view. { - VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - *cmdPool, // VkCommandPool commandPool; - VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; - 1u // deUint32 bufferCount; - }; + const VkImageViewCreateInfo colorAttachmentViewParams = + { + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkImageViewCreateFlags flags; + *m_multisampledImage, // VkImage image; + VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; + m_params.src.image.format, // VkFormat format; + componentMappingRGBA, // VkComponentMapping components; + { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; + }; + sourceAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams); + } - const VkCommandBufferBeginInfo cmdBufferBeginInfo = + // Create framebuffer { - VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // VkCommandBufferUsageFlags flags; - (const VkCommandBufferInheritanceInfo*)DE_NULL, - }; + const VkImageView attachments[1] = + { + *sourceAttachmentView, + }; - const VkClearValue clearValue = makeClearValueColorF32(0.0f, 0.0f, 1.0f, 1.0f); + const VkFramebufferCreateInfo framebufferParams = + { + VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkFramebufferCreateFlags flags; + *renderPass, // VkRenderPass renderPass; + 1u, // deUint32 attachmentCount; + attachments, // const VkImageView* pAttachments; + m_params.src.image.extent.width, // deUint32 width; + m_params.src.image.extent.height, // deUint32 height; + 1u // deUint32 layers; + }; - const VkClearValue clearValues[1] = - { - clearValue - }; + framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams); + } - const VkRenderPassBeginInfo renderPassBeginInfo = + // Create pipeline { - VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - *renderPass, // VkRenderPass renderPass; - *framebuffer, // VkFramebuffer framebuffer; + const VkPipelineShaderStageCreateInfo shaderStageParams[2] = { - { 0, 0 }, - { m_params.src.image.extent.width, m_params.src.image.extent.height } - }, // VkRect2D renderArea; - 1u, // deUint32 clearValueCount; - clearValues // const VkClearValue* pClearValues; - }; + { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkPipelineShaderStageCreateFlags flags; + VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage; + *vertexShaderModule, // VkShaderModule module; + "main", // const char* pName; + DE_NULL // const VkSpecializationInfo* pSpecializationInfo; + }, + { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkPipelineShaderStageCreateFlags flags; + VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage; + *fragmentShaderModule, // VkShaderModule module; + "main", // const char* pName; + DE_NULL // const VkSpecializationInfo* pSpecializationInfo; + } + }; - // Barriers for copying image to buffer - const VkImageMemoryBarrier srcImageBarrier = - { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // VkAccessFlags srcAccessMask; - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; - VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; - VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; - VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; - m_multisampledImage.get(), // VkImage image; - { // VkImageSubresourceRange subresourceRange; - VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; - 0u, // deUint32 baseMipLevel; - 1u, // deUint32 mipLevels; - 0u, // deUint32 baseArraySlice; - 1u // deUint32 arraySize; - } - }; + const VkVertexInputBindingDescription vertexInputBindingDescription = + { + 0u, // deUint32 binding; + sizeof(tcu::Vec4), // deUint32 stride; + VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate; + }; - cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo); + const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[1] = + { + { + 0u, // deUint32 location; + 0u, // deUint32 binding; + VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; + 0u // deUint32 offset; + } + }; - VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo)); - vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &srcImageBarrier); - vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); + const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = + { + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkPipelineVertexInputStateCreateFlags flags; + 1u, // deUint32 vertexBindingDescriptionCount; + &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; + 1u, // deUint32 vertexAttributeDescriptionCount; + vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; + }; - const VkDeviceSize vertexBufferOffset = 0u; + const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = + { + VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkPipelineInputAssemblyStateCreateFlags flags; + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology; + false // VkBool32 primitiveRestartEnable; + }; - vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline); - vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset); - vk.cmdDraw(*cmdBuffer, (deUint32)vertices.size(), 1, 0, 0); + const VkViewport viewport = + { + 0.0f, // float x; + 0.0f, // float y; + (float)m_params.src.image.extent.width, // float width; + (float)m_params.src.image.extent.height,// float height; + 0.0f, // float minDepth; + 1.0f // float maxDepth; + }; - vk.cmdEndRenderPass(*cmdBuffer); + const VkRect2D scissor = + { + { 0, 0 }, // VkOffset2D offset; + { m_params.src.image.extent.width, m_params.src.image.extent.height } // VkExtent2D extent; + }; - VK_CHECK(vk.endCommandBuffer(*cmdBuffer)); - } + const VkPipelineViewportStateCreateInfo viewportStateParams = + { + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkPipelineViewportStateCreateFlags flags; + 1u, // deUint32 viewportCount; + &viewport, // const VkViewport* pViewports; + 1u, // deUint32 scissorCount; + &scissor // const VkRect2D* pScissors; + }; - // Create fence - { - const VkFenceCreateInfo fenceParams = - { - VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u // VkFenceCreateFlags flags; - }; + const VkPipelineRasterizationStateCreateInfo rasterStateParams = + { + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkPipelineRasterizationStateCreateFlags flags; + false, // VkBool32 depthClampEnable; + false, // VkBool32 rasterizerDiscardEnable; + VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; + VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; + VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; + VK_FALSE, // VkBool32 depthBiasEnable; + 0.0f, // float depthBiasConstantFactor; + 0.0f, // float depthBiasClamp; + 0.0f, // float depthBiasSlopeFactor; + 1.0f // float lineWidth; + }; - fence = createFence(vk, vkDevice, &fenceParams); - } + const VkPipelineMultisampleStateCreateInfo multisampleStateParams = + { + VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkPipelineMultisampleStateCreateFlags flags; + rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples; + VK_FALSE, // VkBool32 sampleShadingEnable; + 0.0f, // float minSampleShading; + DE_NULL, // const VkSampleMask* pSampleMask; + VK_FALSE, // VkBool32 alphaToCoverageEnable; + VK_FALSE // VkBool32 alphaToOneEnable; + }; - // Queue submit. - { - const VkQueue queue = m_context.getUniversalQueue(); - const VkSubmitInfo submitInfo = + const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = + { + false, // VkBool32 blendEnable; + VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor; + VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor; + VK_BLEND_OP_ADD, // VkBlendOp blendOpColor; + VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha; + VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha; + VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha; + (VK_COLOR_COMPONENT_R_BIT | + VK_COLOR_COMPONENT_G_BIT | + VK_COLOR_COMPONENT_B_BIT | + VK_COLOR_COMPONENT_A_BIT) // VkChannelFlags channelWriteMask; + }; + + const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = + { + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkPipelineColorBlendStateCreateFlags flags; + false, // VkBool32 logicOpEnable; + VK_LOGIC_OP_COPY, // VkLogicOp logicOp; + 1u, // deUint32 attachmentCount; + &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; + { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4]; + }; + + const VkGraphicsPipelineCreateInfo graphicsPipelineParams = + { + VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkPipelineCreateFlags flags; + 2u, // deUint32 stageCount; + shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages; + &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; + &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; + DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; + &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; + &rasterStateParams, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; + &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; + DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; + &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; + DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; + *pipelineLayout, // VkPipelineLayout layout; + *renderPass, // VkRenderPass renderPass; + 0u, // deUint32 subpass; + 0u, // VkPipeline basePipelineHandle; + 0u // deInt32 basePipelineIndex; + }; + + graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams); + } + + // Create command buffer { - VK_STRUCTURE_TYPE_SUBMIT_INFO, - DE_NULL, - 0u, - (const VkSemaphore*)DE_NULL, - (const VkPipelineStageFlags*)DE_NULL, - 1u, - &cmdBuffer.get(), - 0u, - (const VkSemaphore*)DE_NULL, - }; + const VkCommandBufferBeginInfo cmdBufferBeginInfo = + { + VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkCommandBufferUsageFlags flags; + (const VkCommandBufferInheritanceInfo*)DE_NULL, + }; + + const VkClearValue clearValues[1] = + { + makeClearValueColorF32(0.0f, 0.0f, 1.0f, 1.0f), + }; + + const VkRenderPassBeginInfo renderPassBeginInfo = + { + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + *renderPass, // VkRenderPass renderPass; + *framebuffer, // VkFramebuffer framebuffer; + { + { 0, 0 }, + { m_params.src.image.extent.width, m_params.src.image.extent.height } + }, // VkRect2D renderArea; + 1u, // deUint32 clearValueCount; + clearValues // const VkClearValue* pClearValues; + }; - VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get())); - VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence)); - VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */)); + VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); + vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &srcImageBarrier); + vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); + + const VkDeviceSize vertexBufferOffset = 0u; + + vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline); + vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset); + vk.cmdDraw(*m_cmdBuffer, (deUint32)vertices.size(), 1, 0, 0); + + vk.cmdEndRenderPass(*m_cmdBuffer); + VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); + } + + // Queue submit. + { + const VkQueue queue = m_context.getUniversalQueue(); + submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer); + } } } @@ -2657,19 +3133,31 @@ tcu::TestStatus ResolveImageToImage::iterate (void) const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format); const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_params.dst.image.format); - m_sourceTextureLevel = de::MovePtr(new tcu::TextureLevel(srcTcuFormat, - m_params.src.image.extent.width, - m_params.src.image.extent.height, - m_params.src.image.extent.depth)); - generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_MULTISAMPLE); - m_destinationTextureLevel = de::MovePtr(new tcu::TextureLevel(dstTcuFormat, - (int)m_params.dst.image.extent.width, - (int)m_params.dst.image.extent.height, - (int)m_params.dst.image.extent.depth)); + // upload the destination image + m_destinationTextureLevel = de::MovePtr(new tcu::TextureLevel(dstTcuFormat, + (int)m_params.dst.image.extent.width, + (int)m_params.dst.image.extent.height, + (int)m_params.dst.image.extent.depth)); generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth); + uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image); + + m_sourceTextureLevel = de::MovePtr(new tcu::TextureLevel(srcTcuFormat, + (int)m_params.src.image.extent.width, + (int)m_params.src.image.extent.height, + (int)m_params.dst.image.extent.depth)); + + generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_MULTISAMPLE); generateExpectedResult(); - uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get()); + switch (m_options) + { + case COPY_MS_IMAGE_TO_MS_IMAGE: + case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE: + copyMSImageToMSImage(); + break; + default: + break; + } const DeviceInterface& vk = m_context.getDeviceInterface(); const VkDevice vkDevice = m_context.getDevice(); @@ -2685,7 +3173,7 @@ tcu::TestStatus ResolveImageToImage::iterate (void) { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; DE_NULL, // const void* pNext; - 0u, // VkAccessFlags srcAccessMask; + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask; VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout; VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout; @@ -2693,11 +3181,11 @@ tcu::TestStatus ResolveImageToImage::iterate (void) VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; m_multisampledImage.get(), // VkImage image; { // VkImageSubresourceRange subresourceRange; - getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask; - 0u, // deUint32 baseMipLevel; - 1u, // deUint32 mipLevels; - 0u, // deUint32 baseArraySlice; - 1u // deUint32 arraySize; + getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask; + 0u, // deUint32 baseMipLevel; + 1u, // deUint32 mipLevels; + 0u, // deUint32 baseArraySlice; + getArraySize(m_params.dst.image) // deUint32 arraySize; } }, // destination image @@ -2706,17 +3194,17 @@ tcu::TestStatus ResolveImageToImage::iterate (void) DE_NULL, // const void* pNext; 0u, // VkAccessFlags srcAccessMask; VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; - VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; m_destination.get(), // VkImage image; { // VkImageSubresourceRange subresourceRange; - getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask; - 0u, // deUint32 baseMipLevel; - 1u, // deUint32 mipLevels; - 0u, // deUint32 baseArraySlice; - 1u // deUint32 arraySize; + getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask; + 0u, // deUint32 baseMipLevel; + 1u, // deUint32 mipLevels; + 0u, // deUint32 baseArraySlice; + getArraySize(m_params.dst.image) // deUint32 arraySize; } }, }; @@ -2737,7 +3225,7 @@ tcu::TestStatus ResolveImageToImage::iterate (void) 0u, // deUint32 baseMipLevel; 1u, // deUint32 mipLevels; 0u, // deUint32 baseArraySlice; - 1u // deUint32 arraySize; + getArraySize(m_params.dst.image) // deUint32 arraySize; } }; @@ -2754,25 +3242,9 @@ tcu::TestStatus ResolveImageToImage::iterate (void) vk.cmdResolveImage(*m_cmdBuffer, m_multisampledImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), imageResolves.data()); vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier); VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); + submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer); - const VkSubmitInfo submitInfo = - { - VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u, // deUint32 waitSemaphoreCount; - DE_NULL, // const VkSemaphore* pWaitSemaphores; - (const VkPipelineStageFlags*)DE_NULL, - 1u, // deUint32 commandBufferCount; - &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; - 0u, // deUint32 signalSemaphoreCount; - DE_NULL // const VkSemaphore* pSignalSemaphores; - }; - - VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get())); - VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); - VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */)); - - de::MovePtr resultTextureLevel = readImage(*m_destination, m_params.dst.image.format, m_params.dst.image.extent); + de::MovePtr resultTextureLevel = readImage(*m_destination, m_params.dst.image); return checkTestResult(resultTextureLevel->getAccess()); } @@ -2782,579 +3254,249 @@ tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAcces const tcu::ConstPixelBufferAccess expected = m_expectedTextureLevel->getAccess(); const float fuzzyThreshold = 0.01f; - if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expected, result, fuzzyThreshold, tcu::COMPARE_LOG_RESULT)) - return tcu::TestStatus::fail("CopiesAndBlitting test"); + for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx) + { + const tcu::ConstPixelBufferAccess expectedSub = getSubregion (expected, 0, 0, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u); + const tcu::ConstPixelBufferAccess resultSub = getSubregion (result, 0, 0, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u); + if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT)) + return tcu::TestStatus::fail("CopiesAndBlitting test"); + } return tcu::TestStatus::pass("CopiesAndBlitting test"); } void ResolveImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region) { - VkOffset3D srcOffset = region.imageCopy.srcOffset; - VkOffset3D dstOffset = region.imageCopy.dstOffset; - VkExtent3D extent = region.imageCopy.extent; + VkOffset3D srcOffset = region.imageResolve.srcOffset; + srcOffset.z = region.imageResolve.srcSubresource.baseArrayLayer; + VkOffset3D dstOffset = region.imageResolve.dstOffset; + dstOffset.z = region.imageResolve.dstSubresource.baseArrayLayer; + VkExtent3D extent = region.imageResolve.extent; - const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y, extent.width, extent.height); + const tcu::ConstPixelBufferAccess srcSubRegion = getSubregion (src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth); // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy. const tcu::PixelBufferAccess dstWithSrcFormat (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr()); - const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, extent.width, extent.height); + const tcu::PixelBufferAccess dstSubRegion = getSubregion (dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth); tcu::copy(dstSubRegion, srcSubRegion); } -class ResolveImageToImageTestCase : public vkt::TestCase -{ -public: - ResolveImageToImageTestCase (tcu::TestContext& testCtx, - const std::string& name, - const std::string& description, - const TestParams params) - : vkt::TestCase (testCtx, name, description) - , m_params (params) - {} - virtual void initPrograms (SourceCollections& programCollection) const; - - virtual TestInstance* createInstance (Context& context) const - { - return new ResolveImageToImage(context, m_params); - } -private: - TestParams m_params; -}; - -void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollection) const -{ - programCollection.glslSources.add("vert") << glu::VertexSource( - "#version 310 es\n" - "layout (location = 0) in highp vec4 a_position;\n" - "void main()\n" - "{\n" - " gl_Position = a_position;\n" - "}\n"); - - - programCollection.glslSources.add("frag") << glu::FragmentSource( - "#version 310 es\n" - "layout (location = 0) out highp vec4 o_color;\n" - "void main()\n" - "{\n" - " o_color = vec4(0.0, 1.0, 0.0, 1.0);\n" - "}\n"); -} - -std::string getSampleCountCaseName (VkSampleCountFlagBits sampleFlag) -{ - return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16)); -} - -std::string getFormatCaseName (VkFormat format) +void ResolveImageToImage::copyMSImageToMSImage (void) { - return de::toLower(de::toString(getFormatStr(format)).substr(10)); -} + const DeviceInterface& vk = m_context.getDeviceInterface(); + const VkDevice vkDevice = m_context.getDevice(); + const VkQueue queue = m_context.getUniversalQueue(); + const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format); + std::vector imageCopies; -void addCopyImageTestsAllFormats (tcu::TestCaseGroup* testCaseGroup, - tcu::TestContext& testCtx, - TestParams& params) -{ - const VkFormat compatibleFormats8Bit[] = + for (deUint32 layerNdx = 0; layerNdx < getArraySize(m_params.dst.image); ++layerNdx) { - VK_FORMAT_R4G4_UNORM_PACK8, - VK_FORMAT_R8_UNORM, - VK_FORMAT_R8_SNORM, - VK_FORMAT_R8_USCALED, - VK_FORMAT_R8_SSCALED, - VK_FORMAT_R8_UINT, - VK_FORMAT_R8_SINT, - VK_FORMAT_R8_SRGB, + const VkImageSubresourceLayers sourceSubresourceLayers = + { + getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + 0u, // uint32_t baseArrayLayer; + 1u // uint32_t layerCount; + }; - VK_FORMAT_LAST - }; - const VkFormat compatibleFormats16Bit[] = - { - VK_FORMAT_R4G4B4A4_UNORM_PACK16, - VK_FORMAT_B4G4R4A4_UNORM_PACK16, - VK_FORMAT_R5G6B5_UNORM_PACK16, - VK_FORMAT_B5G6R5_UNORM_PACK16, - VK_FORMAT_R5G5B5A1_UNORM_PACK16, - VK_FORMAT_B5G5R5A1_UNORM_PACK16, - VK_FORMAT_A1R5G5B5_UNORM_PACK16, - VK_FORMAT_R8G8_UNORM, - VK_FORMAT_R8G8_SNORM, - VK_FORMAT_R8G8_USCALED, - VK_FORMAT_R8G8_SSCALED, - VK_FORMAT_R8G8_UINT, - VK_FORMAT_R8G8_SINT, - VK_FORMAT_R8G8_SRGB, - VK_FORMAT_R16_UNORM, - VK_FORMAT_R16_SNORM, - VK_FORMAT_R16_USCALED, - VK_FORMAT_R16_SSCALED, - VK_FORMAT_R16_UINT, - VK_FORMAT_R16_SINT, - VK_FORMAT_R16_SFLOAT, - - VK_FORMAT_LAST - }; - const VkFormat compatibleFormats24Bit[] = - { - VK_FORMAT_R8G8B8_UNORM, - VK_FORMAT_R8G8B8_SNORM, - VK_FORMAT_R8G8B8_USCALED, - VK_FORMAT_R8G8B8_SSCALED, - VK_FORMAT_R8G8B8_UINT, - VK_FORMAT_R8G8B8_SINT, - VK_FORMAT_R8G8B8_SRGB, - VK_FORMAT_B8G8R8_UNORM, - VK_FORMAT_B8G8R8_SNORM, - VK_FORMAT_B8G8R8_USCALED, - VK_FORMAT_B8G8R8_SSCALED, - VK_FORMAT_B8G8R8_UINT, - VK_FORMAT_B8G8R8_SINT, - VK_FORMAT_B8G8R8_SRGB, - - VK_FORMAT_LAST - }; - const VkFormat compatibleFormats32Bit[] = - { - VK_FORMAT_R8G8B8A8_UNORM, - VK_FORMAT_R8G8B8A8_SNORM, - VK_FORMAT_R8G8B8A8_USCALED, - VK_FORMAT_R8G8B8A8_SSCALED, - VK_FORMAT_R8G8B8A8_UINT, - VK_FORMAT_R8G8B8A8_SINT, - VK_FORMAT_R8G8B8A8_SRGB, - VK_FORMAT_B8G8R8A8_UNORM, - VK_FORMAT_B8G8R8A8_SNORM, - VK_FORMAT_B8G8R8A8_USCALED, - VK_FORMAT_B8G8R8A8_SSCALED, - VK_FORMAT_B8G8R8A8_UINT, - VK_FORMAT_B8G8R8A8_SINT, - VK_FORMAT_B8G8R8A8_SRGB, - VK_FORMAT_A8B8G8R8_UNORM_PACK32, - VK_FORMAT_A8B8G8R8_SNORM_PACK32, - VK_FORMAT_A8B8G8R8_USCALED_PACK32, - VK_FORMAT_A8B8G8R8_SSCALED_PACK32, - VK_FORMAT_A8B8G8R8_UINT_PACK32, - VK_FORMAT_A8B8G8R8_SINT_PACK32, - VK_FORMAT_A8B8G8R8_SRGB_PACK32, - VK_FORMAT_A2R10G10B10_UNORM_PACK32, - VK_FORMAT_A2R10G10B10_SNORM_PACK32, - VK_FORMAT_A2R10G10B10_USCALED_PACK32, - VK_FORMAT_A2R10G10B10_SSCALED_PACK32, - VK_FORMAT_A2R10G10B10_UINT_PACK32, - VK_FORMAT_A2R10G10B10_SINT_PACK32, - VK_FORMAT_A2B10G10R10_UNORM_PACK32, - VK_FORMAT_A2B10G10R10_SNORM_PACK32, - VK_FORMAT_A2B10G10R10_USCALED_PACK32, - VK_FORMAT_A2B10G10R10_SSCALED_PACK32, - VK_FORMAT_A2B10G10R10_UINT_PACK32, - VK_FORMAT_A2B10G10R10_SINT_PACK32, - VK_FORMAT_R16G16_UNORM, - VK_FORMAT_R16G16_SNORM, - VK_FORMAT_R16G16_USCALED, - VK_FORMAT_R16G16_SSCALED, - VK_FORMAT_R16G16_UINT, - VK_FORMAT_R16G16_SINT, - VK_FORMAT_R16G16_SFLOAT, - VK_FORMAT_R32_UINT, - VK_FORMAT_R32_SINT, - VK_FORMAT_R32_SFLOAT, - - VK_FORMAT_LAST - }; - const VkFormat compatibleFormats48Bit[] = - { - VK_FORMAT_R16G16B16_UNORM, - VK_FORMAT_R16G16B16_SNORM, - VK_FORMAT_R16G16B16_USCALED, - VK_FORMAT_R16G16B16_SSCALED, - VK_FORMAT_R16G16B16_UINT, - VK_FORMAT_R16G16B16_SINT, - VK_FORMAT_R16G16B16_SFLOAT, - - VK_FORMAT_LAST - }; - const VkFormat compatibleFormats64Bit[] = - { - VK_FORMAT_R16G16B16A16_UNORM, - VK_FORMAT_R16G16B16A16_SNORM, - VK_FORMAT_R16G16B16A16_USCALED, - VK_FORMAT_R16G16B16A16_SSCALED, - VK_FORMAT_R16G16B16A16_UINT, - VK_FORMAT_R16G16B16A16_SINT, - VK_FORMAT_R16G16B16A16_SFLOAT, - VK_FORMAT_R32G32_UINT, - VK_FORMAT_R32G32_SINT, - VK_FORMAT_R32G32_SFLOAT, - VK_FORMAT_R64_UINT, - VK_FORMAT_R64_SINT, - VK_FORMAT_R64_SFLOAT, - - VK_FORMAT_LAST - }; - const VkFormat compatibleFormats96Bit[] = - { - VK_FORMAT_R32G32B32_UINT, - VK_FORMAT_R32G32B32_SINT, - VK_FORMAT_R32G32B32_SFLOAT, - - VK_FORMAT_LAST - }; - const VkFormat compatibleFormats128Bit[] = - { - VK_FORMAT_R32G32B32A32_UINT, - VK_FORMAT_R32G32B32A32_SINT, - VK_FORMAT_R32G32B32A32_SFLOAT, - VK_FORMAT_R64G64_UINT, - VK_FORMAT_R64G64_SINT, - VK_FORMAT_R64G64_SFLOAT, - - VK_FORMAT_LAST - }; - const VkFormat compatibleFormats192Bit[] = - { - VK_FORMAT_R64G64B64_UINT, - VK_FORMAT_R64G64B64_SINT, - VK_FORMAT_R64G64B64_SFLOAT, - - VK_FORMAT_LAST - }; - const VkFormat compatibleFormats256Bit[] = - { - VK_FORMAT_R64G64B64A64_UINT, - VK_FORMAT_R64G64B64A64_SINT, - VK_FORMAT_R64G64B64A64_SFLOAT, - - VK_FORMAT_LAST - }; + const VkImageSubresourceLayers destinationSubresourceLayers = + { + getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;//getAspectFlags(dstTcuFormat) + 0u, // uint32_t mipLevel; + layerNdx, // uint32_t baseArrayLayer; + 1u // uint32_t layerCount; + }; - const VkFormat* colorImageFormatsToTest[] = - { - compatibleFormats8Bit, - compatibleFormats16Bit, - compatibleFormats24Bit, - compatibleFormats32Bit, - compatibleFormats48Bit, - compatibleFormats64Bit, - compatibleFormats96Bit, - compatibleFormats128Bit, - compatibleFormats192Bit, - compatibleFormats256Bit, - }; - const size_t numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest); + const VkImageCopy imageCopy = + { + sourceSubresourceLayers, // VkImageSubresourceLayers srcSubresource; + {0, 0, 0}, // VkOffset3D srcOffset; + destinationSubresourceLayers, // VkImageSubresourceLayers dstSubresource; + {0, 0, 0}, // VkOffset3D dstOffset; + getExtent3D(m_params.src.image), // VkExtent3D extent; + }; + imageCopies.push_back(imageCopy); + } - for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex) + const VkImageMemoryBarrier imageBarriers[] = { - const VkFormat* compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex]; - for (size_t srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_LAST; ++srcFormatIndex) + // source image { - params.src.image.format = compatibleFormats[srcFormatIndex]; - for (size_t dstFormatIndex = 0; compatibleFormats[dstFormatIndex] != VK_FORMAT_LAST; ++dstFormatIndex) - { - params.dst.image.format = compatibleFormats[dstFormatIndex]; - - if (!isSupportedByFramework(params.src.image.format) || !isSupportedByFramework(params.dst.image.format)) - continue; - - std::ostringstream testName; - testName << getFormatCaseName(params.src.image.format) << "_" << getFormatCaseName(params.dst.image.format); - std::ostringstream description; - description << "Copy from src " << params.src.image.format << " to dst " << params.dst.image.format; - - testCaseGroup->addChild(new CopyImageToImageTestCase(testCtx, testName.str(), description.str(), params)); + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; + DE_NULL, // const void* pNext; + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask; + VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask; + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout; + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout; + VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; + VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; + m_multisampledImage.get(), // VkImage image; + { // VkImageSubresourceRange subresourceRange; + getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask; + 0u, // deUint32 baseMipLevel; + 1u, // deUint32 mipLevels; + 0u, // deUint32 baseArraySlice; + getArraySize(m_params.src.image) // deUint32 arraySize; } - } - } -} - -void addBlittingTestsAllFormats (tcu::TestCaseGroup* testCaseGroup, - tcu::TestContext& testCtx, - TestParams& params) -{ - // Test Image formats. - const VkFormat compatibleFormatsUInts[] = - { - VK_FORMAT_R8_UINT, - VK_FORMAT_R8G8_UINT, - VK_FORMAT_R8G8B8_UINT, - VK_FORMAT_B8G8R8_UINT, - VK_FORMAT_R8G8B8A8_UINT, - VK_FORMAT_B8G8R8A8_UINT, - VK_FORMAT_A8B8G8R8_UINT_PACK32, - VK_FORMAT_A2R10G10B10_UINT_PACK32, - VK_FORMAT_A2B10G10R10_UINT_PACK32, - VK_FORMAT_R16_UINT, - VK_FORMAT_R16G16_UINT, - VK_FORMAT_R16G16B16_UINT, - VK_FORMAT_R16G16B16A16_UINT, - VK_FORMAT_R32_UINT, - VK_FORMAT_R32G32_UINT, - VK_FORMAT_R32G32B32_UINT, - VK_FORMAT_R32G32B32A32_UINT, - VK_FORMAT_R64_UINT, - VK_FORMAT_R64G64_UINT, - VK_FORMAT_R64G64B64_UINT, - VK_FORMAT_R64G64B64A64_UINT, - - VK_FORMAT_LAST - }; - const VkFormat compatibleFormatsSInts[] = - { - VK_FORMAT_R8_SINT, - VK_FORMAT_R8G8_SINT, - VK_FORMAT_R8G8B8_SINT, - VK_FORMAT_B8G8R8_SINT, - VK_FORMAT_R8G8B8A8_SINT, - VK_FORMAT_B8G8R8A8_SINT, - VK_FORMAT_A8B8G8R8_SINT_PACK32, - VK_FORMAT_A2R10G10B10_SINT_PACK32, - VK_FORMAT_A2B10G10R10_SINT_PACK32, - VK_FORMAT_R16_SINT, - VK_FORMAT_R16G16_SINT, - VK_FORMAT_R16G16B16_SINT, - VK_FORMAT_R16G16B16A16_SINT, - VK_FORMAT_R32_SINT, - VK_FORMAT_R32G32_SINT, - VK_FORMAT_R32G32B32_SINT, - VK_FORMAT_R32G32B32A32_SINT, - VK_FORMAT_R64_SINT, - VK_FORMAT_R64G64_SINT, - VK_FORMAT_R64G64B64_SINT, - VK_FORMAT_R64G64B64A64_SINT, - - VK_FORMAT_LAST - }; - const VkFormat compatibleFormatsFloats[] = - { - VK_FORMAT_R4G4_UNORM_PACK8, - VK_FORMAT_R4G4B4A4_UNORM_PACK16, - VK_FORMAT_B4G4R4A4_UNORM_PACK16, - VK_FORMAT_R5G6B5_UNORM_PACK16, - VK_FORMAT_B5G6R5_UNORM_PACK16, - VK_FORMAT_R5G5B5A1_UNORM_PACK16, - VK_FORMAT_B5G5R5A1_UNORM_PACK16, - VK_FORMAT_A1R5G5B5_UNORM_PACK16, - VK_FORMAT_R8_UNORM, - VK_FORMAT_R8_SNORM, - VK_FORMAT_R8_USCALED, - VK_FORMAT_R8_SSCALED, - VK_FORMAT_R8G8_UNORM, - VK_FORMAT_R8G8_SNORM, - VK_FORMAT_R8G8_USCALED, - VK_FORMAT_R8G8_SSCALED, - VK_FORMAT_R8G8B8_UNORM, - VK_FORMAT_R8G8B8_SNORM, - VK_FORMAT_R8G8B8_USCALED, - VK_FORMAT_R8G8B8_SSCALED, - VK_FORMAT_B8G8R8_UNORM, - VK_FORMAT_B8G8R8_SNORM, - VK_FORMAT_B8G8R8_USCALED, - VK_FORMAT_B8G8R8_SSCALED, - VK_FORMAT_R8G8B8A8_UNORM, - VK_FORMAT_R8G8B8A8_SNORM, - VK_FORMAT_R8G8B8A8_USCALED, - VK_FORMAT_R8G8B8A8_SSCALED, - VK_FORMAT_B8G8R8A8_UNORM, - VK_FORMAT_B8G8R8A8_SNORM, - VK_FORMAT_B8G8R8A8_USCALED, - VK_FORMAT_B8G8R8A8_SSCALED, - VK_FORMAT_A8B8G8R8_UNORM_PACK32, - VK_FORMAT_A8B8G8R8_SNORM_PACK32, - VK_FORMAT_A8B8G8R8_USCALED_PACK32, - VK_FORMAT_A8B8G8R8_SSCALED_PACK32, - VK_FORMAT_A2R10G10B10_UNORM_PACK32, - VK_FORMAT_A2R10G10B10_SNORM_PACK32, - VK_FORMAT_A2R10G10B10_USCALED_PACK32, - VK_FORMAT_A2R10G10B10_SSCALED_PACK32, - VK_FORMAT_A2B10G10R10_UNORM_PACK32, - VK_FORMAT_A2B10G10R10_SNORM_PACK32, - VK_FORMAT_A2B10G10R10_USCALED_PACK32, - VK_FORMAT_A2B10G10R10_SSCALED_PACK32, - VK_FORMAT_R16_UNORM, - VK_FORMAT_R16_SNORM, - VK_FORMAT_R16_USCALED, - VK_FORMAT_R16_SSCALED, - VK_FORMAT_R16_SFLOAT, - VK_FORMAT_R16G16_UNORM, - VK_FORMAT_R16G16_SNORM, - VK_FORMAT_R16G16_USCALED, - VK_FORMAT_R16G16_SSCALED, - VK_FORMAT_R16G16_SFLOAT, - VK_FORMAT_R16G16B16_UNORM, - VK_FORMAT_R16G16B16_SNORM, - VK_FORMAT_R16G16B16_USCALED, - VK_FORMAT_R16G16B16_SSCALED, - VK_FORMAT_R16G16B16_SFLOAT, - VK_FORMAT_R16G16B16A16_UNORM, - VK_FORMAT_R16G16B16A16_SNORM, - VK_FORMAT_R16G16B16A16_USCALED, - VK_FORMAT_R16G16B16A16_SSCALED, - VK_FORMAT_R16G16B16A16_SFLOAT, - VK_FORMAT_R32_SFLOAT, - VK_FORMAT_R32G32_SFLOAT, - VK_FORMAT_R32G32B32_SFLOAT, - VK_FORMAT_R32G32B32A32_SFLOAT, - VK_FORMAT_R64_SFLOAT, - VK_FORMAT_R64G64_SFLOAT, - VK_FORMAT_R64G64B64_SFLOAT, - VK_FORMAT_R64G64B64A64_SFLOAT, -// VK_FORMAT_B10G11R11_UFLOAT_PACK32, -// VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, -// VK_FORMAT_BC1_RGB_UNORM_BLOCK, -// VK_FORMAT_BC1_RGBA_UNORM_BLOCK, -// VK_FORMAT_BC2_UNORM_BLOCK, -// VK_FORMAT_BC3_UNORM_BLOCK, -// VK_FORMAT_BC4_UNORM_BLOCK, -// VK_FORMAT_BC4_SNORM_BLOCK, -// VK_FORMAT_BC5_UNORM_BLOCK, -// VK_FORMAT_BC5_SNORM_BLOCK, -// VK_FORMAT_BC6H_UFLOAT_BLOCK, -// VK_FORMAT_BC6H_SFLOAT_BLOCK, -// VK_FORMAT_BC7_UNORM_BLOCK, -// VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, -// VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, -// VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, -// VK_FORMAT_EAC_R11_UNORM_BLOCK, -// VK_FORMAT_EAC_R11_SNORM_BLOCK, -// VK_FORMAT_EAC_R11G11_UNORM_BLOCK, -// VK_FORMAT_EAC_R11G11_SNORM_BLOCK, -// VK_FORMAT_ASTC_4x4_UNORM_BLOCK, -// VK_FORMAT_ASTC_5x4_UNORM_BLOCK, -// VK_FORMAT_ASTC_5x5_UNORM_BLOCK, -// VK_FORMAT_ASTC_6x5_UNORM_BLOCK, -// VK_FORMAT_ASTC_6x6_UNORM_BLOCK, -// VK_FORMAT_ASTC_8x5_UNORM_BLOCK, -// VK_FORMAT_ASTC_8x6_UNORM_BLOCK, -// VK_FORMAT_ASTC_8x8_UNORM_BLOCK, -// VK_FORMAT_ASTC_10x5_UNORM_BLOCK, -// VK_FORMAT_ASTC_10x6_UNORM_BLOCK, -// VK_FORMAT_ASTC_10x8_UNORM_BLOCK, -// VK_FORMAT_ASTC_10x10_UNORM_BLOCK, -// VK_FORMAT_ASTC_12x10_UNORM_BLOCK, -// VK_FORMAT_ASTC_12x12_UNORM_BLOCK, - - VK_FORMAT_LAST - }; - const VkFormat compatibleFormatsSrgb[] = - { - VK_FORMAT_R8_SRGB, - VK_FORMAT_R8G8_SRGB, - VK_FORMAT_R8G8B8_SRGB, - VK_FORMAT_B8G8R8_SRGB, - VK_FORMAT_R8G8B8A8_SRGB, - VK_FORMAT_B8G8R8A8_SRGB, - VK_FORMAT_A8B8G8R8_SRGB_PACK32, -// VK_FORMAT_BC1_RGB_SRGB_BLOCK, -// VK_FORMAT_BC1_RGBA_SRGB_BLOCK, -// VK_FORMAT_BC2_SRGB_BLOCK, -// VK_FORMAT_BC3_SRGB_BLOCK, -// VK_FORMAT_BC7_SRGB_BLOCK, -// VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, -// VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, -// VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, -// VK_FORMAT_ASTC_4x4_SRGB_BLOCK, -// VK_FORMAT_ASTC_5x4_SRGB_BLOCK, -// VK_FORMAT_ASTC_5x5_SRGB_BLOCK, -// VK_FORMAT_ASTC_6x5_SRGB_BLOCK, -// VK_FORMAT_ASTC_6x6_SRGB_BLOCK, -// VK_FORMAT_ASTC_8x5_SRGB_BLOCK, -// VK_FORMAT_ASTC_8x6_SRGB_BLOCK, -// VK_FORMAT_ASTC_8x8_SRGB_BLOCK, -// VK_FORMAT_ASTC_10x5_SRGB_BLOCK, -// VK_FORMAT_ASTC_10x6_SRGB_BLOCK, -// VK_FORMAT_ASTC_10x8_SRGB_BLOCK, -// VK_FORMAT_ASTC_10x10_SRGB_BLOCK, -// VK_FORMAT_ASTC_12x10_SRGB_BLOCK, -// VK_FORMAT_ASTC_12x12_SRGB_BLOCK, - - VK_FORMAT_LAST + }, + // destination image + { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0, // VkAccessFlags srcAccessMask; + VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask; + VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout; + VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; + VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; + m_multisampledCopyImage.get(), // VkImage image; + { // VkImageSubresourceRange subresourceRange; + getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask; + 0u, // deUint32 baseMipLevel; + 1u, // deUint32 mipLevels; + 0u, // deUint32 baseArraySlice; + getArraySize(m_params.dst.image) // deUint32 arraySize; + } + }, }; - const struct { - const VkFormat* compatibleFormats; - const bool onlyNearest; - } colorImageFormatsToTest[] = + const VkImageMemoryBarrier postImageBarriers = + // source image { - { compatibleFormatsUInts, true }, - { compatibleFormatsSInts, true }, - { compatibleFormatsFloats, false }, - { compatibleFormatsSrgb, false }, + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; + DE_NULL, // const void* pNext; + VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask; + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout; + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; + VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; + VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; + m_multisampledCopyImage.get(), // VkImage image; + { // VkImageSubresourceRange subresourceRange; + getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask; + 0u, // deUint32 baseMipLevel; + 1u, // deUint32 mipLevels; + 0u, // deUint32 baseArraySlice; + getArraySize(m_params.dst.image) // deUint32 arraySize; + } }; - const size_t numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest); - for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex) + const VkCommandBufferBeginInfo cmdBufferBeginInfo = { - const VkFormat* compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex].compatibleFormats; - const bool onlyNearest = colorImageFormatsToTest[compatibleFormatsIndex].onlyNearest; - for (size_t srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_LAST; ++srcFormatIndex) - { - params.src.image.format = compatibleFormats[srcFormatIndex]; - for (size_t dstFormatIndex = 0; compatibleFormats[dstFormatIndex] != VK_FORMAT_LAST; ++dstFormatIndex) - { - params.dst.image.format = compatibleFormats[dstFormatIndex]; - - if (!isSupportedByFramework(params.src.image.format) || !isSupportedByFramework(params.dst.image.format)) - continue; + VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; + (const VkCommandBufferInheritanceInfo*)DE_NULL, + }; - std::ostringstream testName; - testName << getFormatCaseName(params.src.image.format) << "_" << getFormatCaseName(params.dst.image.format); - std::ostringstream description; - description << "Blit image from src " << params.src.image.format << " to dst " << params.dst.image.format; + VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); + vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers); + vk.cmdCopyImage(*m_cmdBuffer, m_multisampledImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_multisampledCopyImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)imageCopies.size(), imageCopies.data()); + vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarriers); + VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); - params.filter = VK_FILTER_NEAREST; - testCaseGroup->addChild(new BlittingTestCase(testCtx, testName.str() + "_nearest", description.str(), params)); + submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer); - if (!onlyNearest) - { - params.filter = VK_FILTER_LINEAR; - testCaseGroup->addChild(new BlittingTestCase(testCtx, testName.str() + "_linear", description.str(), params)); - } - } - } - } + m_multisampledImage = m_multisampledCopyImage; } -} // anonymous - -tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx) +class ResolveImageToImageTestCase : public vkt::TestCase { - de::MovePtr copiesAndBlittingTests (new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests")); +public: + ResolveImageToImageTestCase (tcu::TestContext& testCtx, + const std::string& name, + const std::string& description, + const TestParams params, + const ResolveImageToImageOptions options = NO_OPTIONAL_OPERATION) + : vkt::TestCase (testCtx, name, description) + , m_params (params) + , m_options (options) + {} + virtual void initPrograms (SourceCollections& programCollection) const; + + virtual TestInstance* createInstance (Context& context) const + { + return new ResolveImageToImage(context, m_params, m_options); + } +private: + TestParams m_params; + const ResolveImageToImageOptions m_options; +}; - de::MovePtr imageToImageTests (new tcu::TestCaseGroup(testCtx, "image_to_image", "Copy from image to image")); - de::MovePtr imgToImgSimpleTests (new tcu::TestCaseGroup(testCtx, "simple_tests", "Copy from image to image simple tests")); - de::MovePtr imgToImgAllFormatsTests (new tcu::TestCaseGroup(testCtx, "all_formats", "Copy from image to image with all compatible formats")); +void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollection) const +{ + programCollection.glslSources.add("vert") << glu::VertexSource( + "#version 310 es\n" + "layout (location = 0) in highp vec4 a_position;\n" + "void main()\n" + "{\n" + " gl_Position = a_position;\n" + "}\n"); - de::MovePtr imageToBufferTests (new tcu::TestCaseGroup(testCtx, "image_to_buffer", "Copy from image to buffer")); - de::MovePtr bufferToImageTests (new tcu::TestCaseGroup(testCtx, "buffer_to_image", "Copy from buffer to image")); - de::MovePtr bufferToBufferTests (new tcu::TestCaseGroup(testCtx, "buffer_to_buffer", "Copy from buffer to buffer")); - de::MovePtr blittingImageTests (new tcu::TestCaseGroup(testCtx, "blit_image", "Blitting image")); - de::MovePtr blitImgSimpleTests (new tcu::TestCaseGroup(testCtx, "simple_tests", "Blitting image simple tests")); - de::MovePtr blitImgAllFormatsTests (new tcu::TestCaseGroup(testCtx, "all_formats", "Blitting image with all compatible formats")); + programCollection.glslSources.add("frag") << glu::FragmentSource( + "#version 310 es\n" + "layout (location = 0) out highp vec4 o_color;\n" + "void main()\n" + "{\n" + " o_color = vec4(0.0, 1.0, 0.0, 1.0);\n" + "}\n"); +} - de::MovePtr resolveImageTests (new tcu::TestCaseGroup(testCtx, "resolve_image", "Resolve image")); +std::string getSampleCountCaseName (VkSampleCountFlagBits sampleFlag) +{ + return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16)); +} - const deInt32 defaultSize = 64; - const deInt32 defaultHalfSize = defaultSize / 2; - const deInt32 defaultFourthSize = defaultSize / 4; - const VkExtent3D defaultExtent = {defaultSize, defaultSize, 1}; - const VkExtent3D defaultHalfExtent = {defaultHalfSize, defaultHalfSize, 1}; +std::string getFormatCaseName (VkFormat format) +{ + return de::toLower(de::toString(getFormatStr(format)).substr(10)); +} - const VkImageSubresourceLayers defaultSourceLayer = +std::string getImageLayoutCaseName (VkImageLayout layout) +{ + switch (layout) { - VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; - 0u, // uint32_t mipLevel; - 0u, // uint32_t baseArrayLayer; - 1u, // uint32_t layerCount; - }; + case VK_IMAGE_LAYOUT_GENERAL: + return "general"; + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: + return "optimal"; + default: + DE_ASSERT(false); + return ""; + } +} + +const deInt32 defaultSize = 64; +const deInt32 defaultHalfSize = defaultSize / 2; +const deInt32 defaultFourthSize = defaultSize / 4; +const VkExtent3D defaultExtent = {defaultSize, defaultSize, 1}; +const VkExtent3D defaultHalfExtent = {defaultHalfSize, defaultHalfSize, 1}; + +const VkImageSubresourceLayers defaultSourceLayer = +{ + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + 0u, // uint32_t baseArrayLayer; + 1u, // uint32_t layerCount; +}; + +void addImageToImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + tcu::TestContext& testCtx = group->getTestContext(); - // Copy image to image testcases. { - TestParams params; - params.src.image.format = VK_FORMAT_R8G8B8A8_UINT; - params.src.image.extent = defaultExtent; - params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; - params.dst.image.extent = defaultExtent; + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UINT; + params.src.image.extent = defaultExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; + params.dst.image.extent = defaultExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; { const VkImageCopy testCopy = @@ -3372,15 +3514,20 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx) params.regions.push_back(imageCopy); } - imgToImgSimpleTests->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", "Whole image", params)); + group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", "Whole image", params)); } { - TestParams params; - params.src.image.format = VK_FORMAT_R8G8B8A8_UINT; - params.src.image.extent = defaultExtent; - params.dst.image.format = VK_FORMAT_R32_UINT; - params.dst.image.extent = defaultExtent; + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UINT; + params.src.image.extent = defaultExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.format = VK_FORMAT_R32_UINT; + params.dst.image.extent = defaultExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; { const VkImageCopy testCopy = @@ -3398,15 +3545,20 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx) params.regions.push_back(imageCopy); } - imgToImgSimpleTests->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_fromat", "Whole image with different format", params)); + group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_fromat", "Whole image with different format", params)); } { - TestParams params; - params.src.image.format = VK_FORMAT_R8G8B8A8_UINT; - params.src.image.extent = defaultExtent; - params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; - params.dst.image.extent = defaultExtent; + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UINT; + params.src.image.extent = defaultExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; + params.dst.image.extent = defaultExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; { const VkImageCopy testCopy = @@ -3424,15 +3576,20 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx) params.regions.push_back(imageCopy); } - imgToImgSimpleTests->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", "Partial image", params)); + group->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", "Partial image", params)); } { - TestParams params; - params.src.image.format = VK_FORMAT_D32_SFLOAT; - params.src.image.extent = defaultExtent; - params.dst.image.format = VK_FORMAT_D32_SFLOAT; - params.dst.image.extent = defaultExtent; + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_D32_SFLOAT; + params.src.image.extent = defaultExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.format = VK_FORMAT_D32_SFLOAT; + params.dst.image.extent = defaultExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; { const VkImageSubresourceLayers sourceLayer = @@ -3457,15 +3614,20 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx) params.regions.push_back(imageCopy); } - imgToImgSimpleTests->addChild(new CopyImageToImageTestCase(testCtx, "depth", "With depth", params)); + group->addChild(new CopyImageToImageTestCase(testCtx, "depth", "With depth", params)); } { - TestParams params; - params.src.image.format = VK_FORMAT_S8_UINT; - params.src.image.extent = defaultExtent; - params.dst.image.format = VK_FORMAT_S8_UINT; - params.dst.image.extent = defaultExtent; + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_S8_UINT; + params.src.image.extent = defaultExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.format = VK_FORMAT_S8_UINT; + params.dst.image.extent = defaultExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; { const VkImageSubresourceLayers sourceLayer = @@ -3490,133 +3652,1029 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx) params.regions.push_back(imageCopy); } - imgToImgSimpleTests->addChild(new CopyImageToImageTestCase(testCtx, "stencil", "With stencil", params)); + group->addChild(new CopyImageToImageTestCase(testCtx, "stencil", "With stencil", params)); } +} + +struct CopyColorTestParams +{ + TestParams params; + const VkFormat* compatibleFormats; +}; +void addImageToImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, TestParams params) +{ + const VkImageLayout copySrcLayouts[] = { - TestParams params; - params.src.image.extent = defaultExtent; - params.dst.image.extent = defaultExtent; + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_IMAGE_LAYOUT_GENERAL + }; + const VkImageLayout copyDstLayouts[] = + { + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_GENERAL + }; - for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize) - { - const VkImageCopy testCopy = - { - defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; - {0, 0, 0}, // VkOffset3D srcOffset; - defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; - {i, defaultSize - i - defaultFourthSize, 0}, // VkOffset3D dstOffset; - {defaultFourthSize, defaultFourthSize, 1}, // VkExtent3D extent; - }; + for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx) + { + params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx]; - CopyRegion imageCopy; - imageCopy.imageCopy = testCopy; + for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx) + { + params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx]; - params.regions.push_back(imageCopy); + const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" + + getImageLayoutCaseName(params.dst.image.operationLayout); + const std::string description = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) + + " to " + getImageLayoutCaseName(params.dst.image.operationLayout); + group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params)); } - - addCopyImageTestsAllFormats(imgToImgAllFormatsTests.get(), testCtx, params); } - imageToImageTests->addChild(imgToImgSimpleTests.release()); - imageToImageTests->addChild(imgToImgAllFormatsTests.release()); +} + +bool isAllowedImageToImageAllFormatsColorSrcFormatTests(CopyColorTestParams& testParams) +{ + bool result = true; - // Copy image to buffer testcases. + if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED) { - TestParams params; - params.src.image.format = VK_FORMAT_R8G8B8A8_UINT; - params.src.image.extent = defaultExtent; - params.dst.buffer.size = defaultSize * defaultSize; + DE_ASSERT(!dedicatedAllocationImageToImageFormatsToTestSet.empty()); - const VkBufferImageCopy bufferImageCopy = - { - 0u, // VkDeviceSize bufferOffset; - 0u, // uint32_t bufferRowLength; - 0u, // uint32_t bufferImageHeight; - defaultSourceLayer, // VkImageSubresourceLayers imageSubresource; - {0, 0, 0}, // VkOffset3D imageOffset; - {defaultFourthSize, defaultFourthSize, 1} // VkExtent3D imageExtent; - }; - CopyRegion copyRegion; - copyRegion.bufferImageCopy = bufferImageCopy; + result = + de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.dst.image.format) || + de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.src.image.format); + } - params.regions.push_back(copyRegion); + return result; +} + +void addImageToImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, CopyColorTestParams testParams) +{ + for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex) + { + testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex]; + if (!isSupportedByFramework(testParams.params.dst.image.format)) + continue; + + if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams)) + continue; - imageToBufferTests->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params)); + const std::string description = "Copy to destination format " + getFormatCaseName(testParams.params.dst.image.format); + addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addImageToImageAllFormatsColorSrcFormatDstFormatTests, testParams.params); } +} - // Copy buffer to image testcases. - { - TestParams params; - params.src.buffer.size = defaultSize * defaultSize; - params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; - params.dst.image.extent = defaultExtent; +const VkFormat compatibleFormats8Bit[] = +{ + VK_FORMAT_R4G4_UNORM_PACK8, + VK_FORMAT_R8_UNORM, + VK_FORMAT_R8_SNORM, + VK_FORMAT_R8_USCALED, + VK_FORMAT_R8_SSCALED, + VK_FORMAT_R8_UINT, + VK_FORMAT_R8_SINT, + VK_FORMAT_R8_SRGB, + + VK_FORMAT_UNDEFINED +}; +const VkFormat compatibleFormats16Bit[] = +{ + VK_FORMAT_R4G4B4A4_UNORM_PACK16, + VK_FORMAT_B4G4R4A4_UNORM_PACK16, + VK_FORMAT_R5G6B5_UNORM_PACK16, + VK_FORMAT_B5G6R5_UNORM_PACK16, + VK_FORMAT_R5G5B5A1_UNORM_PACK16, + VK_FORMAT_B5G5R5A1_UNORM_PACK16, + VK_FORMAT_A1R5G5B5_UNORM_PACK16, + VK_FORMAT_R8G8_UNORM, + VK_FORMAT_R8G8_SNORM, + VK_FORMAT_R8G8_USCALED, + VK_FORMAT_R8G8_SSCALED, + VK_FORMAT_R8G8_UINT, + VK_FORMAT_R8G8_SINT, + VK_FORMAT_R8G8_SRGB, + VK_FORMAT_R16_UNORM, + VK_FORMAT_R16_SNORM, + VK_FORMAT_R16_USCALED, + VK_FORMAT_R16_SSCALED, + VK_FORMAT_R16_UINT, + VK_FORMAT_R16_SINT, + VK_FORMAT_R16_SFLOAT, + + VK_FORMAT_UNDEFINED +}; +const VkFormat compatibleFormats24Bit[] = +{ + VK_FORMAT_R8G8B8_UNORM, + VK_FORMAT_R8G8B8_SNORM, + VK_FORMAT_R8G8B8_USCALED, + VK_FORMAT_R8G8B8_SSCALED, + VK_FORMAT_R8G8B8_UINT, + VK_FORMAT_R8G8B8_SINT, + VK_FORMAT_R8G8B8_SRGB, + VK_FORMAT_B8G8R8_UNORM, + VK_FORMAT_B8G8R8_SNORM, + VK_FORMAT_B8G8R8_USCALED, + VK_FORMAT_B8G8R8_SSCALED, + VK_FORMAT_B8G8R8_UINT, + VK_FORMAT_B8G8R8_SINT, + VK_FORMAT_B8G8R8_SRGB, + + VK_FORMAT_UNDEFINED +}; +const VkFormat compatibleFormats32Bit[] = +{ + VK_FORMAT_R8G8B8A8_UNORM, + VK_FORMAT_R8G8B8A8_SNORM, + VK_FORMAT_R8G8B8A8_USCALED, + VK_FORMAT_R8G8B8A8_SSCALED, + VK_FORMAT_R8G8B8A8_UINT, + VK_FORMAT_R8G8B8A8_SINT, + VK_FORMAT_R8G8B8A8_SRGB, + VK_FORMAT_B8G8R8A8_UNORM, + VK_FORMAT_B8G8R8A8_SNORM, + VK_FORMAT_B8G8R8A8_USCALED, + VK_FORMAT_B8G8R8A8_SSCALED, + VK_FORMAT_B8G8R8A8_UINT, + VK_FORMAT_B8G8R8A8_SINT, + VK_FORMAT_B8G8R8A8_SRGB, + VK_FORMAT_A8B8G8R8_UNORM_PACK32, + VK_FORMAT_A8B8G8R8_SNORM_PACK32, + VK_FORMAT_A8B8G8R8_USCALED_PACK32, + VK_FORMAT_A8B8G8R8_SSCALED_PACK32, + VK_FORMAT_A8B8G8R8_UINT_PACK32, + VK_FORMAT_A8B8G8R8_SINT_PACK32, + VK_FORMAT_A8B8G8R8_SRGB_PACK32, + VK_FORMAT_A2R10G10B10_UNORM_PACK32, + VK_FORMAT_A2R10G10B10_SNORM_PACK32, + VK_FORMAT_A2R10G10B10_USCALED_PACK32, + VK_FORMAT_A2R10G10B10_SSCALED_PACK32, + VK_FORMAT_A2R10G10B10_UINT_PACK32, + VK_FORMAT_A2R10G10B10_SINT_PACK32, + VK_FORMAT_A2B10G10R10_UNORM_PACK32, + VK_FORMAT_A2B10G10R10_SNORM_PACK32, + VK_FORMAT_A2B10G10R10_USCALED_PACK32, + VK_FORMAT_A2B10G10R10_SSCALED_PACK32, + VK_FORMAT_A2B10G10R10_UINT_PACK32, + VK_FORMAT_A2B10G10R10_SINT_PACK32, + VK_FORMAT_R16G16_UNORM, + VK_FORMAT_R16G16_SNORM, + VK_FORMAT_R16G16_USCALED, + VK_FORMAT_R16G16_SSCALED, + VK_FORMAT_R16G16_UINT, + VK_FORMAT_R16G16_SINT, + VK_FORMAT_R16G16_SFLOAT, + VK_FORMAT_R32_UINT, + VK_FORMAT_R32_SINT, + VK_FORMAT_R32_SFLOAT, + + VK_FORMAT_UNDEFINED +}; +const VkFormat compatibleFormats48Bit[] = +{ + VK_FORMAT_R16G16B16_UNORM, + VK_FORMAT_R16G16B16_SNORM, + VK_FORMAT_R16G16B16_USCALED, + VK_FORMAT_R16G16B16_SSCALED, + VK_FORMAT_R16G16B16_UINT, + VK_FORMAT_R16G16B16_SINT, + VK_FORMAT_R16G16B16_SFLOAT, + + VK_FORMAT_UNDEFINED +}; +const VkFormat compatibleFormats64Bit[] = +{ + VK_FORMAT_R16G16B16A16_UNORM, + VK_FORMAT_R16G16B16A16_SNORM, + VK_FORMAT_R16G16B16A16_USCALED, + VK_FORMAT_R16G16B16A16_SSCALED, + VK_FORMAT_R16G16B16A16_UINT, + VK_FORMAT_R16G16B16A16_SINT, + VK_FORMAT_R16G16B16A16_SFLOAT, + VK_FORMAT_R32G32_UINT, + VK_FORMAT_R32G32_SINT, + VK_FORMAT_R32G32_SFLOAT, + VK_FORMAT_R64_UINT, + VK_FORMAT_R64_SINT, + VK_FORMAT_R64_SFLOAT, + + VK_FORMAT_UNDEFINED +}; +const VkFormat compatibleFormats96Bit[] = +{ + VK_FORMAT_R32G32B32_UINT, + VK_FORMAT_R32G32B32_SINT, + VK_FORMAT_R32G32B32_SFLOAT, - const VkBufferImageCopy bufferImageCopy = - { - 0u, // VkDeviceSize bufferOffset; - 0u, // uint32_t bufferRowLength; - 0u, // uint32_t bufferImageHeight; - defaultSourceLayer, // VkImageSubresourceLayers imageSubresource; - {0, 0, 0}, // VkOffset3D imageOffset; - {defaultFourthSize, defaultFourthSize, 1} // VkExtent3D imageExtent; - }; - CopyRegion copyRegion; - copyRegion.bufferImageCopy = bufferImageCopy; + VK_FORMAT_UNDEFINED +}; +const VkFormat compatibleFormats128Bit[] = +{ + VK_FORMAT_R32G32B32A32_UINT, + VK_FORMAT_R32G32B32A32_SINT, + VK_FORMAT_R32G32B32A32_SFLOAT, + VK_FORMAT_R64G64_UINT, + VK_FORMAT_R64G64_SINT, + VK_FORMAT_R64G64_SFLOAT, + + VK_FORMAT_UNDEFINED +}; +const VkFormat compatibleFormats192Bit[] = +{ + VK_FORMAT_R64G64B64_UINT, + VK_FORMAT_R64G64B64_SINT, + VK_FORMAT_R64G64B64_SFLOAT, - params.regions.push_back(copyRegion); + VK_FORMAT_UNDEFINED +}; +const VkFormat compatibleFormats256Bit[] = +{ + VK_FORMAT_R64G64B64A64_UINT, + VK_FORMAT_R64G64B64A64_SINT, + VK_FORMAT_R64G64B64A64_SFLOAT, - bufferToImageTests->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params)); - } + VK_FORMAT_UNDEFINED +}; - // Copy buffer to buffer testcases. - { - TestParams params; - params.src.buffer.size = defaultSize; - params.dst.buffer.size = defaultSize; +const VkFormat* colorImageFormatsToTest[] = +{ + compatibleFormats8Bit, + compatibleFormats16Bit, + compatibleFormats24Bit, + compatibleFormats32Bit, + compatibleFormats48Bit, + compatibleFormats64Bit, + compatibleFormats96Bit, + compatibleFormats128Bit, + compatibleFormats192Bit, + compatibleFormats256Bit, +}; - const VkBufferCopy bufferCopy = +const VkFormat dedicatedAllocationImageToImageFormatsToTest[] = +{ + // From compatibleFormats8Bit + VK_FORMAT_R4G4_UNORM_PACK8, + VK_FORMAT_R8_SRGB, + + // From compatibleFormats16Bit + VK_FORMAT_R4G4B4A4_UNORM_PACK16, + VK_FORMAT_R16_SFLOAT, + + // From compatibleFormats24Bit + VK_FORMAT_R8G8B8_UNORM, + VK_FORMAT_B8G8R8_SRGB, + + // From compatibleFormats32Bit + VK_FORMAT_R8G8B8A8_UNORM, + VK_FORMAT_R32_SFLOAT, + + // From compatibleFormats48Bit + VK_FORMAT_R16G16B16_UNORM, + VK_FORMAT_R16G16B16_SFLOAT, + + // From compatibleFormats64Bit + VK_FORMAT_R16G16B16A16_UNORM, + VK_FORMAT_R64_SFLOAT, + + // From compatibleFormats96Bit + VK_FORMAT_R32G32B32_UINT, + VK_FORMAT_R32G32B32_SFLOAT, + + // From compatibleFormats128Bit + VK_FORMAT_R32G32B32A32_UINT, + VK_FORMAT_R64G64_SFLOAT, + + // From compatibleFormats192Bit + VK_FORMAT_R64G64B64_UINT, + VK_FORMAT_R64G64B64_SFLOAT, + + // From compatibleFormats256Bit + VK_FORMAT_R64G64B64A64_UINT, + VK_FORMAT_R64G64B64A64_SFLOAT, +}; + +void addImageToImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.extent = defaultExtent; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.extent = defaultExtent; + params.allocationKind = allocationKind; + + for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize) + { + const VkImageCopy testCopy = { - 0u, // VkDeviceSize srcOffset; - 0u, // VkDeviceSize dstOffset; - defaultSize, // VkDeviceSize size; + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; + {0, 0, 0}, // VkOffset3D srcOffset; + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + {i, defaultSize - i - defaultFourthSize, 0}, // VkOffset3D dstOffset; + {defaultFourthSize, defaultFourthSize, 1}, // VkExtent3D extent; }; - CopyRegion copyRegion; - copyRegion.bufferCopy = bufferCopy; - params.regions.push_back(copyRegion); + CopyRegion imageCopy; + imageCopy.imageCopy = testCopy; - bufferToBufferTests->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params)); + params.regions.push_back(imageCopy); } + if (allocationKind == ALLOCATION_KIND_DEDICATED) { - TestParams params; - params.src.buffer.size = defaultFourthSize; - params.dst.buffer.size = defaultFourthSize; + const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest); + for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex) + dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]); + } - const VkBufferCopy bufferCopy = + const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest); + for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex) + { + const VkFormat* compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex]; + for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex) { - 12u, // VkDeviceSize srcOffset; - 4u, // VkDeviceSize dstOffset; - 1u, // VkDeviceSize size; - }; + params.src.image.format = compatibleFormats[srcFormatIndex]; + if (!isSupportedByFramework(params.src.image.format)) + continue; - CopyRegion copyRegion; - copyRegion.bufferCopy = bufferCopy; - params.regions.push_back(copyRegion); + CopyColorTestParams testParams; + testParams.params = params; + testParams.compatibleFormats = compatibleFormats; - bufferToBufferTests->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params)); + const std::string description = "Copy from source format " + getFormatCaseName(params.src.image.format); + addTestGroup(group, getFormatCaseName(params.src.image.format), description, addImageToImageAllFormatsColorSrcFormatTests, testParams); + } } +} +void addImageToImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params) +{ + const VkImageLayout copySrcLayouts[] = { - const deUint32 size = 16; - TestParams params; - params.src.buffer.size = size; - params.dst.buffer.size = size * (size + 1); + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_IMAGE_LAYOUT_GENERAL + }; + const VkImageLayout copyDstLayouts[] = + { + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_GENERAL + }; - // Copy region with size 1..size - for (unsigned int i = 1; i <= size; i++) + for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx) + { + params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx]; + for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx) { - const VkBufferCopy bufferCopy = + params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx]; + + const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" + + getImageLayoutCaseName(params.dst.image.operationLayout); + const std::string description = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) + + " to " + getImageLayoutCaseName(params.dst.image.operationLayout); + group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params)); + } + } +} + +void addImageToImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + const VkFormat depthAndStencilFormats[] = + { + VK_FORMAT_D16_UNORM, + VK_FORMAT_X8_D24_UNORM_PACK32, + VK_FORMAT_D32_SFLOAT, + VK_FORMAT_S8_UINT, + VK_FORMAT_D16_UNORM_S8_UINT, + VK_FORMAT_D24_UNORM_S8_UINT, + VK_FORMAT_D32_SFLOAT_S8_UINT, + }; + + for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex) + { + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.extent = defaultExtent; + params.dst.image.extent = defaultExtent; + params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex]; + params.dst.image.format = params.src.image.format; + params.allocationKind = allocationKind; + + const VkImageSubresourceLayers defaultDepthSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u }; + const VkImageSubresourceLayers defaultStencilSourceLayer = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u }; + + for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize) + { + CopyRegion copyRegion; + const VkOffset3D srcOffset = {0, 0, 0}; + const VkOffset3D dstOffset = {i, defaultSize - i - defaultFourthSize, 0}; + const VkExtent3D extent = {defaultFourthSize, defaultFourthSize, 1}; + + if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order)) + { + const VkImageCopy testCopy = + { + defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource; + srcOffset, // VkOffset3D srcOffset; + defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource; + dstOffset, // VkOffset3D dstOffset; + extent, // VkExtent3D extent; + }; + + copyRegion.imageCopy = testCopy; + params.regions.push_back(copyRegion); + } + if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order)) + { + const VkImageCopy testCopy = + { + defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource; + srcOffset, // VkOffset3D srcOffset; + defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource; + dstOffset, // VkOffset3D dstOffset; + extent, // VkExtent3D extent; + }; + + copyRegion.imageCopy = testCopy; + params.regions.push_back(copyRegion); + } + } + + const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format); + const std::string description = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format); + addTestGroup(group, testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params); + } +} + +void addImageToImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + addTestGroup(group, "color", "Copy image to image with color formats", addImageToImageAllFormatsColorTests, allocationKind); + addTestGroup(group, "depth_stencil", "Copy image to image with depth/stencil formats", addImageToImageAllFormatsDepthStencilTests, allocationKind); +} + +void addImageToImage3dImagesTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + tcu::TestContext& testCtx = group->getTestContext(); + + { + TestParams params3DTo2D; + const deUint32 slicesLayers = 16u; + params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D; + params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT; + params3DTo2D.src.image.extent = defaultHalfExtent; + params3DTo2D.src.image.extent.depth = slicesLayers; + params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D; + params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; + params3DTo2D.dst.image.extent = defaultHalfExtent; + params3DTo2D.dst.image.extent.depth = slicesLayers; + params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params3DTo2D.allocationKind = allocationKind; + + for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx) + { + const VkImageSubresourceLayers sourceLayer = + { + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + 0u, // uint32_t baseArrayLayer; + 1u // uint32_t layerCount; + }; + + const VkImageSubresourceLayers destinationLayer = + { + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + slicesLayersNdx, // uint32_t baseArrayLayer; + 1u // uint32_t layerCount; + }; + + const VkImageCopy testCopy = + { + sourceLayer, // VkImageSubresourceLayers srcSubresource; + {0, 0, (deInt32)slicesLayersNdx}, // VkOffset3D srcOffset; + destinationLayer, // VkImageSubresourceLayers dstSubresource; + {0, 0, 0}, // VkOffset3D dstOffset; + defaultHalfExtent, // VkExtent3D extent; + }; + + CopyRegion imageCopy; + imageCopy.imageCopy = testCopy; + + params3DTo2D.regions.push_back(imageCopy); + } + group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_by_slices", "copy 2d layers to 3d slices one by one", params3DTo2D)); + } + + { + TestParams params2DTo3D; + const deUint32 slicesLayers = 16u; + params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D; + params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT; + params2DTo3D.src.image.extent = defaultHalfExtent; + params2DTo3D.src.image.extent.depth = slicesLayers; + params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D; + params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; + params2DTo3D.dst.image.extent = defaultHalfExtent; + params2DTo3D.dst.image.extent.depth = slicesLayers; + params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params2DTo3D.allocationKind = allocationKind; + + for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx) + { + const VkImageSubresourceLayers sourceLayer = + { + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + slicesLayersNdx, // uint32_t baseArrayLayer; + 1u // uint32_t layerCount; + }; + + const VkImageSubresourceLayers destinationLayer = + { + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + 0u, // uint32_t baseArrayLayer; + 1u // uint32_t layerCount; + }; + + const VkImageCopy testCopy = + { + sourceLayer, // VkImageSubresourceLayers srcSubresource; + {0, 0, 0}, // VkOffset3D srcOffset; + destinationLayer, // VkImageSubresourceLayers dstSubresource; + {0, 0, (deInt32)slicesLayersNdx}, // VkOffset3D dstOffset; + defaultHalfExtent, // VkExtent3D extent; + }; + + CopyRegion imageCopy; + imageCopy.imageCopy = testCopy; + + params2DTo3D.regions.push_back(imageCopy); + } + + group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_by_layers", "copy 3d slices to 2d layers one by one", params2DTo3D)); + } + + { + TestParams params3DTo2D; + const deUint32 slicesLayers = 16u; + params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D; + params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT; + params3DTo2D.src.image.extent = defaultHalfExtent; + params3DTo2D.src.image.extent.depth = slicesLayers; + params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D; + params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; + params3DTo2D.dst.image.extent = defaultHalfExtent; + params3DTo2D.dst.image.extent.depth = slicesLayers; + params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params3DTo2D.allocationKind = allocationKind; + + { + const VkImageSubresourceLayers sourceLayer = + { + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + 0u, // uint32_t baseArrayLayer; + 1u // uint32_t layerCount; + }; + + const VkImageSubresourceLayers destinationLayer = + { + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + 0, // uint32_t baseArrayLayer; + slicesLayers // uint32_t layerCount; + }; + + const VkImageCopy testCopy = + { + sourceLayer, // VkImageSubresourceLayers srcSubresource; + {0, 0, 0}, // VkOffset3D srcOffset; + destinationLayer, // VkImageSubresourceLayers dstSubresource; + {0, 0, 0}, // VkOffset3D dstOffset; + params3DTo2D.src.image.extent // VkExtent3D extent; + }; + + CopyRegion imageCopy; + imageCopy.imageCopy = testCopy; + + params3DTo2D.regions.push_back(imageCopy); + } + group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_whole", "copy 3d slices to 2d layers all at once", params3DTo2D)); + } + + { + TestParams params2DTo3D; + const deUint32 slicesLayers = 16u; + params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D; + params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT; + params2DTo3D.src.image.extent = defaultHalfExtent; + params2DTo3D.src.image.extent.depth = slicesLayers; + params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D; + params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; + params2DTo3D.dst.image.extent = defaultHalfExtent; + params2DTo3D.dst.image.extent.depth = slicesLayers; + params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params2DTo3D.allocationKind = allocationKind; + + { + const VkImageSubresourceLayers sourceLayer = + { + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + 0u, // uint32_t baseArrayLayer; + slicesLayers // uint32_t layerCount; + }; + + const VkImageSubresourceLayers destinationLayer = + { + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + 0u, // uint32_t baseArrayLayer; + 1u // uint32_t layerCount; + }; + + const VkImageCopy testCopy = + { + sourceLayer, // VkImageSubresourceLayers srcSubresource; + {0, 0, 0}, // VkOffset3D srcOffset; + destinationLayer, // VkImageSubresourceLayers dstSubresource; + {0, 0, 0}, // VkOffset3D dstOffset; + params2DTo3D.dst.image.extent, // VkExtent3D extent; + }; + + CopyRegion imageCopy; + imageCopy.imageCopy = testCopy; + + params2DTo3D.regions.push_back(imageCopy); + } + + group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_whole", "copy 2d layers to 3d slices all at once", params2DTo3D)); + } + + { + TestParams params3DTo2D; + const deUint32 slicesLayers = 16u; + params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D; + params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT; + params3DTo2D.src.image.extent = defaultHalfExtent; + params3DTo2D.src.image.extent.depth = slicesLayers; + params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D; + params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; + params3DTo2D.dst.image.extent = defaultHalfExtent; + params3DTo2D.dst.image.extent.depth = slicesLayers; + params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params3DTo2D.allocationKind = allocationKind; + + const deUint32 regionWidth = defaultHalfExtent.width / slicesLayers -1; + const deUint32 regionHeight = defaultHalfExtent.height / slicesLayers -1 ; + + for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx) + { + const VkImageSubresourceLayers sourceLayer = + { + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + 0u, // uint32_t baseArrayLayer; + 1u // uint32_t layerCount; + }; + + const VkImageSubresourceLayers destinationLayer = + { + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + slicesLayersNdx, // uint32_t baseArrayLayer; + 1u // uint32_t layerCount; + }; + + + const VkImageCopy testCopy = + { + sourceLayer, // VkImageSubresourceLayers srcSubresource; + {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)slicesLayersNdx}, // VkOffset3D srcOffset; + destinationLayer, // VkImageSubresourceLayers dstSubresource; + {(deInt32)(regionWidth*slicesLayersNdx), 0, 0}, // VkOffset3D dstOffset; + { + (defaultHalfExtent.width - regionWidth*slicesLayersNdx), + (defaultHalfExtent.height - regionHeight*slicesLayersNdx), + 1 + } // VkExtent3D extent; + }; + + CopyRegion imageCopy; + imageCopy.imageCopy = testCopy; + params3DTo2D.regions.push_back(imageCopy); + } + group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_regions", "copy 3d slices regions to 2d layers", params3DTo2D)); + } + + { + TestParams params2DTo3D; + const deUint32 slicesLayers = 16u; + params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D; + params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT; + params2DTo3D.src.image.extent = defaultHalfExtent; + params2DTo3D.src.image.extent.depth = slicesLayers; + params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D; + params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; + params2DTo3D.dst.image.extent = defaultHalfExtent; + params2DTo3D.dst.image.extent.depth = slicesLayers; + params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params2DTo3D.allocationKind = allocationKind; + + const deUint32 regionWidth = defaultHalfExtent.width / slicesLayers -1; + const deUint32 regionHeight = defaultHalfExtent.height / slicesLayers -1 ; + + for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx) + { + const VkImageSubresourceLayers sourceLayer = + { + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + slicesLayersNdx, // uint32_t baseArrayLayer; + 1u // uint32_t layerCount; + }; + + const VkImageSubresourceLayers destinationLayer = + { + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + 0u, // uint32_t baseArrayLayer; + 1u // uint32_t layerCount; + }; + + const VkImageCopy testCopy = + { + sourceLayer, // VkImageSubresourceLayers srcSubresource; + {(deInt32)(regionWidth*slicesLayersNdx), 0, 0}, // VkOffset3D srcOffset; + destinationLayer, // VkImageSubresourceLayers dstSubresource; + {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)(slicesLayersNdx)}, // VkOffset3D dstOffset; + { + defaultHalfExtent.width - regionWidth*slicesLayersNdx, + defaultHalfExtent.height - regionHeight*slicesLayersNdx, + 1 + } // VkExtent3D extent; + }; + + CopyRegion imageCopy; + imageCopy.imageCopy = testCopy; + + params2DTo3D.regions.push_back(imageCopy); + } + + group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_regions", "copy 2d layers regions to 3d slices", params2DTo3D)); + } +} + +void addImageToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + addTestGroup(group, "simple_tests", "Copy from image to image simple tests", addImageToImageSimpleTests, allocationKind); + addTestGroup(group, "all_formats", "Copy from image to image with all compatible formats", addImageToImageAllFormatsTests, allocationKind); + addTestGroup(group, "3d_images", "Coping operations on 3d images", addImageToImage3dImagesTests, allocationKind); +} + +void addImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + tcu::TestContext& testCtx = group->getTestContext(); + + { + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.src.image.extent = defaultExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.buffer.size = defaultSize * defaultSize; + params.allocationKind = allocationKind; + + const VkBufferImageCopy bufferImageCopy = + { + 0u, // VkDeviceSize bufferOffset; + 0u, // uint32_t bufferRowLength; + 0u, // uint32_t bufferImageHeight; + defaultSourceLayer, // VkImageSubresourceLayers imageSubresource; + {0, 0, 0}, // VkOffset3D imageOffset; + defaultExtent // VkExtent3D imageExtent; + }; + CopyRegion copyRegion; + copyRegion.bufferImageCopy = bufferImageCopy; + + params.regions.push_back(copyRegion); + + group->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params)); + } + + { + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.src.image.extent = defaultExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.buffer.size = defaultSize * defaultSize; + params.allocationKind = allocationKind; + + const VkBufferImageCopy bufferImageCopy = + { + defaultSize * defaultHalfSize, // VkDeviceSize bufferOffset; + 0u, // uint32_t bufferRowLength; + 0u, // uint32_t bufferImageHeight; + defaultSourceLayer, // VkImageSubresourceLayers imageSubresource; + {defaultFourthSize, defaultFourthSize, 0}, // VkOffset3D imageOffset; + defaultHalfExtent // VkExtent3D imageExtent; + }; + CopyRegion copyRegion; + copyRegion.bufferImageCopy = bufferImageCopy; + + params.regions.push_back(copyRegion); + + group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params)); + } + + { + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.src.image.extent = defaultExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.buffer.size = defaultSize * defaultSize; + params.allocationKind = allocationKind; + + const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format)); + const VkDeviceSize bufferSize = pixelSize * params.dst.buffer.size; + const VkDeviceSize offsetSize = pixelSize * defaultFourthSize * defaultFourthSize; + deUint32 divisor = 1; + for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor) + { + const deUint32 bufferRowLength = defaultFourthSize; + const deUint32 bufferImageHeight = defaultFourthSize; + const VkExtent3D imageExtent = {defaultFourthSize / divisor, defaultFourthSize, 1}; + DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width); + DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height); + DE_ASSERT(imageExtent.width * imageExtent.height *imageExtent.depth <= offsetSize); + + CopyRegion region; + const VkBufferImageCopy bufferImageCopy = + { + offset, // VkDeviceSize bufferOffset; + bufferRowLength, // uint32_t bufferRowLength; + bufferImageHeight, // uint32_t bufferImageHeight; + defaultSourceLayer, // VkImageSubresourceLayers imageSubresource; + {0, 0, 0}, // VkOffset3D imageOffset; + imageExtent // VkExtent3D imageExtent; + }; + region.bufferImageCopy = bufferImageCopy; + params.regions.push_back(region); + } + + group->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params)); + } +} + +void addBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + tcu::TestContext& testCtx = group->getTestContext(); + + { + TestParams params; + params.src.buffer.size = defaultSize * defaultSize; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT; + params.dst.image.extent = defaultExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; + + const VkBufferImageCopy bufferImageCopy = + { + 0u, // VkDeviceSize bufferOffset; + 0u, // uint32_t bufferRowLength; + 0u, // uint32_t bufferImageHeight; + defaultSourceLayer, // VkImageSubresourceLayers imageSubresource; + {0, 0, 0}, // VkOffset3D imageOffset; + defaultExtent // VkExtent3D imageExtent; + }; + CopyRegion copyRegion; + copyRegion.bufferImageCopy = bufferImageCopy; + + params.regions.push_back(copyRegion); + + group->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params)); + } + + { + TestParams params; + params.src.buffer.size = defaultSize * defaultSize; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.dst.image.extent = defaultExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; + + CopyRegion region; + deUint32 divisor = 1; + for (int offset = 0; (offset + defaultFourthSize / divisor < defaultSize) && (defaultFourthSize > divisor); offset += defaultFourthSize / divisor++) + { + const VkBufferImageCopy bufferImageCopy = + { + 0u, // VkDeviceSize bufferOffset; + 0u, // uint32_t bufferRowLength; + 0u, // uint32_t bufferImageHeight; + defaultSourceLayer, // VkImageSubresourceLayers imageSubresource; + {offset, defaultHalfSize, 0}, // VkOffset3D imageOffset; + {defaultFourthSize / divisor, defaultFourthSize / divisor, 1} // VkExtent3D imageExtent; + }; + region.bufferImageCopy = bufferImageCopy; + params.regions.push_back(region); + } + + group->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params)); + } + + { + TestParams params; + params.src.buffer.size = defaultSize * defaultSize; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.dst.image.extent = defaultExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; + + const VkBufferImageCopy bufferImageCopy = + { + defaultFourthSize, // VkDeviceSize bufferOffset; + defaultHalfSize + defaultFourthSize, // uint32_t bufferRowLength; + defaultHalfSize + defaultFourthSize, // uint32_t bufferImageHeight; + defaultSourceLayer, // VkImageSubresourceLayers imageSubresource; + {defaultFourthSize, defaultFourthSize, 0}, // VkOffset3D imageOffset; + defaultHalfExtent // VkExtent3D imageExtent; + }; + CopyRegion copyRegion; + copyRegion.bufferImageCopy = bufferImageCopy; + + params.regions.push_back(copyRegion); + + group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params)); + } +} + +void addBufferToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + tcu::TestContext& testCtx = group->getTestContext(); + + { + TestParams params; + params.src.buffer.size = defaultSize; + params.dst.buffer.size = defaultSize; + params.allocationKind = allocationKind; + + const VkBufferCopy bufferCopy = + { + 0u, // VkDeviceSize srcOffset; + 0u, // VkDeviceSize dstOffset; + defaultSize, // VkDeviceSize size; + }; + + CopyRegion copyRegion; + copyRegion.bufferCopy = bufferCopy; + params.regions.push_back(copyRegion); + + group->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params)); + } + + { + TestParams params; + params.src.buffer.size = defaultFourthSize; + params.dst.buffer.size = defaultFourthSize; + params.allocationKind = allocationKind; + + const VkBufferCopy bufferCopy = + { + 12u, // VkDeviceSize srcOffset; + 4u, // VkDeviceSize dstOffset; + 1u, // VkDeviceSize size; + }; + + CopyRegion copyRegion; + copyRegion.bufferCopy = bufferCopy; + params.regions.push_back(copyRegion); + + group->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params)); + } + + { + const deUint32 size = 16; + TestParams params; + params.src.buffer.size = size; + params.dst.buffer.size = size * (size + 1); + params.allocationKind = allocationKind; + + // Copy region with size 1..size + for (unsigned int i = 1; i <= size; i++) + { + const VkBufferCopy bufferCopy = { 0, // VkDeviceSize srcOffset; i * size, // VkDeviceSize dstOffset; @@ -3628,629 +4686,1590 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx) params.regions.push_back(copyRegion); } - bufferToBufferTests->addChild(new BufferToBufferTestCase(testCtx, "regions", "Multiple regions", params)); + group->addChild(new BufferToBufferTestCase(testCtx, "regions", "Multiple regions", params)); + } +} + +void addBlittingImageSimpleWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + tcu::TestContext& testCtx = group->getTestContext(); + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.src.image.extent = defaultExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.extent = defaultExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; + + { + const VkImageBlit imageBlit = + { + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; + { + { 0, 0, 0 }, + { defaultSize, defaultSize, 1 } + }, // VkOffset3D srcOffsets[2]; + + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + { 0, 0, 0 }, + { defaultSize, defaultSize, 1 } + } // VkOffset3D dstOffset[2]; + }; + + CopyRegion region; + region.imageBlit = imageBlit; + params.regions.push_back(region); } - // Blitting testcases. + // Filter is VK_FILTER_NEAREST. { - const std::string description ("Blit without scaling (whole)"); - const std::string testName ("whole"); + params.filter = VK_FILTER_NEAREST; + const std::string description = "Nearest filter"; - TestParams params; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = defaultExtent; - params.dst.image.extent = defaultExtent; + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "nearest", description, params)); + + params.dst.image.format = VK_FORMAT_R32_SFLOAT; + const std::string descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); + + params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; + const std::string descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); + } + + // Filter is VK_FILTER_LINEAR. + { + params.filter = VK_FILTER_LINEAR; + const std::string description = "Linear filter"; + + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "linear", description, params)); + + params.dst.image.format = VK_FORMAT_R32_SFLOAT; + const std::string descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); + params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; + const std::string descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); + } +} + +void addBlittingImageSimpleMirrorXYTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + tcu::TestContext& testCtx = group->getTestContext(); + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.src.image.extent = defaultExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.extent = defaultExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; + + { + const VkImageBlit imageBlit = { - const VkImageBlit imageBlit = + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; { - defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; - { - {0, 0, 0}, - {defaultSize, defaultSize, 1} - }, // VkOffset3D srcOffsets[2]; + {0, 0, 0}, + {defaultSize, defaultSize, 1} + }, // VkOffset3D srcOffsets[2]; - defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; - { - {0, 0, 0}, - {defaultSize, defaultSize, 1} - } // VkOffset3D dstOffset[2]; - }; + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {defaultSize, defaultSize, 0}, + {0, 0, 1} + } // VkOffset3D dstOffset[2]; + }; - CopyRegion region; - region.imageBlit = imageBlit; - params.regions.push_back(region); - } + CopyRegion region; + region.imageBlit = imageBlit; + params.regions.push_back(region); + } + + // Filter is VK_FILTER_NEAREST. + { + params.filter = VK_FILTER_NEAREST; + const std::string description = "Nearest filter"; + + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "nearest", description, params)); + + params.dst.image.format = VK_FORMAT_R32_SFLOAT; + const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); + + params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; + const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); + } + + // Filter is VK_FILTER_LINEAR. + { + params.filter = VK_FILTER_LINEAR; + const std::string description = "Linear filter"; + + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "linear", description, params)); + + params.dst.image.format = VK_FORMAT_R32_SFLOAT; + const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); + + params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; + const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); + } +} - // Filter is VK_FILTER_NEAREST. +void addBlittingImageSimpleMirrorXTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + tcu::TestContext& testCtx = group->getTestContext(); + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.src.image.extent = defaultExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.extent = defaultExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; + + { + const VkImageBlit imageBlit = { - params.filter = VK_FILTER_NEAREST; + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; + { + {0, 0, 0}, + {defaultSize, defaultSize, 1} + }, // VkOffset3D srcOffsets[2]; + + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {defaultSize, 0, 0}, + {0, defaultSize, 1} + } // VkOffset3D dstOffset[2]; + }; + + CopyRegion region; + region.imageBlit = imageBlit; + params.regions.push_back(region); + } - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params)); + // Filter is VK_FILTER_NEAREST. + { + params.filter = VK_FILTER_NEAREST; + const std::string description = "Nearest filter"; + + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "nearest", description, params)); - params.dst.image.format = VK_FORMAT_R32_SFLOAT; - const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); + params.dst.image.format = VK_FORMAT_R32_SFLOAT; + const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); - params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; - const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); - } + params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; + const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); + } + + // Filter is VK_FILTER_LINEAR. + { + params.filter = VK_FILTER_LINEAR; + const std::string description = "Linear filter"; + + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "linear", description, params)); + + params.dst.image.format = VK_FORMAT_R32_SFLOAT; + const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); + + params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; + const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); + } +} - // Filter is VK_FILTER_LINEAR. +void addBlittingImageSimpleMirrorYTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + tcu::TestContext& testCtx = group->getTestContext(); + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.src.image.extent = defaultExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.extent = defaultExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; + + { + const VkImageBlit imageBlit = { - params.filter = VK_FILTER_LINEAR; + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; + { + {0, 0, 0}, + {defaultSize, defaultSize, 1} + }, // VkOffset3D srcOffsets[2]; - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params)); + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {0, defaultSize, 0}, + {defaultSize, 0, 1} + } // VkOffset3D dstOffset[2]; + }; - params.dst.image.format = VK_FORMAT_R32_SFLOAT; - const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); + CopyRegion region; + region.imageBlit = imageBlit; + params.regions.push_back(region); + } - params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; - const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); - } + // Filter is VK_FILTER_NEAREST. + { + params.filter = VK_FILTER_NEAREST; + const std::string description = "Nearest filter"; + + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "nearest", description, params)); + + params.dst.image.format = VK_FORMAT_R32_SFLOAT; + const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); + + params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; + const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); } + // Filter is VK_FILTER_LINEAR. { - const std::string description ("Blit with scaling (whole, src extent bigger)"); - const std::string testName ("scaling_whole1"); + params.filter = VK_FILTER_LINEAR; + const std::string description = "Linear filter"; - TestParams params; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = defaultExtent; - params.dst.image.extent = defaultHalfExtent; + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "linear", description, params)); + + params.dst.image.format = VK_FORMAT_R32_SFLOAT; + const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); + + params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; + const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); + } +} +void addBlittingImageSimpleMirrorSubregionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + tcu::TestContext& testCtx = group->getTestContext(); + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.src.image.extent = defaultExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.extent = defaultExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; + + // No mirroring. + { + const VkImageBlit imageBlit = { - const VkImageBlit imageBlit = + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; { - defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; - { - {0, 0, 0}, - {defaultSize, defaultSize, 1} - }, // VkOffset3D srcOffsets[2]; + {0, 0, 0}, + {defaultHalfSize, defaultHalfSize, 1} + }, // VkOffset3D srcOffsets[2]; - defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; - { - {0, 0, 0}, - {defaultHalfSize, defaultHalfSize, 1} - } // VkOffset3D dstOffset[2]; - }; + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {0, 0, 0}, + {defaultHalfSize, defaultHalfSize, 1} + } // VkOffset3D dstOffset[2]; + }; - CopyRegion region; - region.imageBlit = imageBlit; - params.regions.push_back(region); - } + CopyRegion region; + region.imageBlit = imageBlit; + params.regions.push_back(region); + } - // Filter is VK_FILTER_NEAREST. + // Flipping y coordinates. + { + const VkImageBlit imageBlit = { - params.filter = VK_FILTER_NEAREST; + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; + { + {defaultHalfSize, 0, 0}, + {defaultSize, defaultHalfSize, 1} + }, // VkOffset3D srcOffsets[2]; - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params)); + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {defaultHalfSize, defaultHalfSize, 0}, + {defaultSize, 0, 1} + } // VkOffset3D dstOffset[2]; + }; - params.dst.image.format = VK_FORMAT_R32_SFLOAT; - const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); + CopyRegion region; + region.imageBlit = imageBlit; + params.regions.push_back(region); + } - params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; - const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); - } + // Flipping x coordinates. + { + const VkImageBlit imageBlit = + { + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; + { + {0, defaultHalfSize, 0}, + {defaultHalfSize, defaultSize, 1} + }, // VkOffset3D srcOffsets[2]; + + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {defaultHalfSize, defaultHalfSize, 0}, + {0, defaultSize, 1} + } // VkOffset3D dstOffset[2]; + }; - // Filter is VK_FILTER_LINEAR. + CopyRegion region; + region.imageBlit = imageBlit; + params.regions.push_back(region); + } + + // Flipping x and y coordinates. + { + const VkImageBlit imageBlit = { - params.filter = VK_FILTER_LINEAR; + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; + { + {defaultHalfSize, defaultHalfSize, 0}, + {defaultSize, defaultSize, 1} + }, // VkOffset3D srcOffsets[2]; - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params)); + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {defaultSize, defaultSize, 0}, + {defaultHalfSize, defaultHalfSize, 1} + } // VkOffset3D dstOffset[2]; + }; - params.dst.image.format = VK_FORMAT_R32_SFLOAT; - const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); + CopyRegion region; + region.imageBlit = imageBlit; + params.regions.push_back(region); + } - params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; - const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); - } + // Filter is VK_FILTER_NEAREST. + { + params.filter = VK_FILTER_NEAREST; + const std::string description = "Nearest filter"; + + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "nearest", description, params)); + + params.dst.image.format = VK_FORMAT_R32_SFLOAT; + const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); + + params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; + const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); } + // Filter is VK_FILTER_LINEAR. { - const std::string description ("Blit with scaling (whole, dst extent bigger)"); - const std::string testName ("scaling_whole2"); + params.filter = VK_FILTER_LINEAR; + const std::string description = "Linear filter"; - TestParams params; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = defaultHalfExtent; - params.dst.image.extent = defaultExtent; + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "linear", description, params)); + + params.dst.image.format = VK_FORMAT_R32_SFLOAT; + const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); + + params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; + const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); + } +} + +void addBlittingImageSimpleScalingWhole1Tests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + tcu::TestContext& testCtx = group->getTestContext(); + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.src.image.extent = defaultExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.extent = defaultHalfExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; + + { + const VkImageBlit imageBlit = + { + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; + { + {0, 0, 0}, + {defaultSize, defaultSize, 1} + }, // VkOffset3D srcOffsets[2]; + + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {0, 0, 0}, + {defaultHalfSize, defaultHalfSize, 1} + } // VkOffset3D dstOffset[2]; + }; + + CopyRegion region; + region.imageBlit = imageBlit; + params.regions.push_back(region); + } + + // Filter is VK_FILTER_NEAREST. + { + params.filter = VK_FILTER_NEAREST; + const std::string description = "Nearest filter"; + + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "nearest", description, params)); + + params.dst.image.format = VK_FORMAT_R32_SFLOAT; + const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); + + params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; + const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); + } + + // Filter is VK_FILTER_LINEAR. + { + params.filter = VK_FILTER_LINEAR; + const std::string description = "Linear filter"; + + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "linear", description, params)); + + params.dst.image.format = VK_FORMAT_R32_SFLOAT; + const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)" ); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); + + params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; + const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); + } +} + +void addBlittingImageSimpleScalingWhole2Tests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + tcu::TestContext& testCtx = group->getTestContext(); + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.src.image.extent = defaultHalfExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.extent = defaultExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; + + { + const VkImageBlit imageBlit = + { + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; + { + {0, 0, 0}, + {defaultHalfSize, defaultHalfSize, 1} + }, // VkOffset3D srcOffsets[2]; + + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {0, 0, 0}, + {defaultSize, defaultSize, 1} + } // VkOffset3D dstOffset[2]; + }; + + CopyRegion region; + region.imageBlit = imageBlit; + params.regions.push_back(region); + } + + // Filter is VK_FILTER_NEAREST. + { + params.filter = VK_FILTER_NEAREST; + const std::string description = "Nearest filter"; + + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "nearest", description, params)); + + params.dst.image.format = VK_FORMAT_R32_SFLOAT; + const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); + + params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; + const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); + } + + // Filter is VK_FILTER_LINEAR. + { + params.filter = VK_FILTER_LINEAR; + const std::string description = "Linear filter"; + + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "linear", description, params)); + + params.dst.image.format = VK_FORMAT_R32_SFLOAT; + const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); + + params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; + const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); + } +} + +void addBlittingImageSimpleScalingAndOffsetTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + tcu::TestContext& testCtx = group->getTestContext(); + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.src.image.extent = defaultExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.extent = defaultExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; + + { + const VkImageBlit imageBlit = + { + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; + { + {defaultFourthSize, defaultFourthSize, 0}, + {defaultFourthSize*3, defaultFourthSize*3, 1} + }, // VkOffset3D srcOffsets[2]; + + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {0, 0, 0}, + {defaultSize, defaultSize, 1} + } // VkOffset3D dstOffset[2]; + }; + + CopyRegion region; + region.imageBlit = imageBlit; + params.regions.push_back(region); + } + // Filter is VK_FILTER_NEAREST. + { + params.filter = VK_FILTER_NEAREST; + const std::string description = "Nearest filter"; + + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "nearest", description, params)); + + params.dst.image.format = VK_FORMAT_R32_SFLOAT; + const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); + + params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; + const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); + } + + // Filter is VK_FILTER_LINEAR. + { + params.filter = VK_FILTER_LINEAR; + const std::string description = "Linear filter"; + + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "linear", description, params)); + + params.dst.image.format = VK_FORMAT_R32_SFLOAT; + const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); + + params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; + const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); + } +} + +void addBlittingImageSimpleWithoutScalingPartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + tcu::TestContext& testCtx = group->getTestContext(); + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.src.image.extent = defaultExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.extent = defaultExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; + + { + CopyRegion region; + for (int i = 0; i < defaultSize; i += defaultFourthSize) { - const VkImageBlit imageBlit = + const VkImageBlit imageBlit = { defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; { - {0, 0, 0}, - {defaultHalfSize, defaultHalfSize, 1} + {defaultSize - defaultFourthSize - i, defaultSize - defaultFourthSize - i, 0}, + {defaultSize - i, defaultSize - i, 1} }, // VkOffset3D srcOffsets[2]; defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; { - {0, 0, 0}, - {defaultSize, defaultSize, 1} + {i, i, 0}, + {i + defaultFourthSize, i + defaultFourthSize, 1} } // VkOffset3D dstOffset[2]; }; - - CopyRegion region; region.imageBlit = imageBlit; params.regions.push_back(region); } + } - // Filter is VK_FILTER_NEAREST. - { - params.filter = VK_FILTER_NEAREST; + // Filter is VK_FILTER_NEAREST. + { + params.filter = VK_FILTER_NEAREST; + const std::string description = "Nearest filter"; + + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "nearest", description, params)); + + + params.dst.image.format = VK_FORMAT_R32_SFLOAT; + const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); + + params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; + const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); + } + + // Filter is VK_FILTER_LINEAR. + { + params.filter = VK_FILTER_LINEAR; + const std::string description = "Linear filter"; + + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "linear", description, params)); + + params.dst.image.format = VK_FORMAT_R32_SFLOAT; + const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); + + params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; + const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); + } +} + +void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + addTestGroup(group, "whole", "Blit without scaling (whole)", addBlittingImageSimpleWholeTests, allocationKind); + addTestGroup(group, "mirror_xy", "Flipping x and y coordinates (whole)", addBlittingImageSimpleMirrorXYTests, allocationKind); + addTestGroup(group, "mirror_x", "Flipping x coordinates (whole)", addBlittingImageSimpleMirrorXTests, allocationKind); + addTestGroup(group, "mirror_y", "Flipping y coordinates (whole)", addBlittingImageSimpleMirrorYTests, allocationKind); + addTestGroup(group, "mirror_subregions", "Mirroring subregions in image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, allocationKind); + addTestGroup(group, "scaling_whole1", "Blit with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, allocationKind); + addTestGroup(group, "scaling_whole2", "Blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, allocationKind); + addTestGroup(group, "scaling_and_offset", "Blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, allocationKind); + addTestGroup(group, "without_scaling_partial", "Blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, allocationKind); +} + +struct BlitColorTestParams +{ + TestParams params; + const VkFormat* compatibleFormats; + bool onlyNearest; +}; + +bool isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams& testParams) +{ + bool result = true; + + if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED) + { + DE_ASSERT(!dedicatedAllocationBlittingFormatsToTestSet.empty()); + + result = + de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.dst.image.format) || + de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.src.image.format); + } + + return result; +} - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params)); - params.dst.image.format = VK_FORMAT_R32_SFLOAT; - const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); +void addBlittingImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams) +{ + tcu::TestContext& testCtx = group->getTestContext(); - params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; - const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); - } + const VkImageLayout blitSrcLayouts[] = + { + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_IMAGE_LAYOUT_GENERAL + }; + const VkImageLayout blitDstLayouts[] = + { + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_GENERAL + }; - // Filter is VK_FILTER_LINEAR. + for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx) + { + testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx]; + for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx) { - params.filter = VK_FILTER_LINEAR; - - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params)); + testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx]; - params.dst.image.format = VK_FORMAT_R32_SFLOAT; - const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); + testParams.params.filter = VK_FILTER_NEAREST; + const std::string testName = getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" + + getImageLayoutCaseName(testParams.params.dst.image.operationLayout); + const std::string description = "Blit from layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) + + " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout); + group->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, testParams.params)); - params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; - const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); + if (!testParams.onlyNearest) + { + testParams.params.filter = VK_FILTER_LINEAR; + group->addChild(new BlittingTestCase(testCtx, testName + "_linear", description, testParams.params)); + } } } +} +void addBlittingImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams) +{ + for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex) { - const std::string description ("Blit with scaling and offset (whole, dst extent bigger)"); - const std::string testName ("scaling_and_offset"); + testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex]; + if (!isSupportedByFramework(testParams.params.dst.image.format)) + continue; - TestParams params; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = defaultExtent; - params.dst.image.extent = defaultExtent; - - { - const VkImageBlit imageBlit = - { - defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; - { - {defaultFourthSize, defaultFourthSize, 0}, - {defaultFourthSize*3, defaultFourthSize*3, 1} - }, // VkOffset3D srcOffsets[2]; + if (!isAllowedBlittingAllFormatsColorSrcFormatTests(testParams)) + continue; - defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; - { - {0, 0, 0}, - {defaultSize, defaultSize, 1} - } // VkOffset3D dstOffset[2]; - }; + const std::string description = "Blit destination format " + getFormatCaseName(testParams.params.dst.image.format); + addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams); + } +} - CopyRegion region; - region.imageBlit = imageBlit; - params.regions.push_back(region); - } +const VkFormat compatibleFormatsUInts[] = +{ + VK_FORMAT_R8_UINT, + VK_FORMAT_R8G8_UINT, + VK_FORMAT_R8G8B8_UINT, + VK_FORMAT_B8G8R8_UINT, + VK_FORMAT_R8G8B8A8_UINT, + VK_FORMAT_B8G8R8A8_UINT, + VK_FORMAT_A8B8G8R8_UINT_PACK32, + VK_FORMAT_A2R10G10B10_UINT_PACK32, + VK_FORMAT_A2B10G10R10_UINT_PACK32, + VK_FORMAT_R16_UINT, + VK_FORMAT_R16G16_UINT, + VK_FORMAT_R16G16B16_UINT, + VK_FORMAT_R16G16B16A16_UINT, + VK_FORMAT_R32_UINT, + VK_FORMAT_R32G32_UINT, + VK_FORMAT_R32G32B32_UINT, + VK_FORMAT_R32G32B32A32_UINT, + VK_FORMAT_R64_UINT, + VK_FORMAT_R64G64_UINT, + VK_FORMAT_R64G64B64_UINT, + VK_FORMAT_R64G64B64A64_UINT, + + VK_FORMAT_UNDEFINED +}; +const VkFormat compatibleFormatsSInts[] = +{ + VK_FORMAT_R8_SINT, + VK_FORMAT_R8G8_SINT, + VK_FORMAT_R8G8B8_SINT, + VK_FORMAT_B8G8R8_SINT, + VK_FORMAT_R8G8B8A8_SINT, + VK_FORMAT_B8G8R8A8_SINT, + VK_FORMAT_A8B8G8R8_SINT_PACK32, + VK_FORMAT_A2R10G10B10_SINT_PACK32, + VK_FORMAT_A2B10G10R10_SINT_PACK32, + VK_FORMAT_R16_SINT, + VK_FORMAT_R16G16_SINT, + VK_FORMAT_R16G16B16_SINT, + VK_FORMAT_R16G16B16A16_SINT, + VK_FORMAT_R32_SINT, + VK_FORMAT_R32G32_SINT, + VK_FORMAT_R32G32B32_SINT, + VK_FORMAT_R32G32B32A32_SINT, + VK_FORMAT_R64_SINT, + VK_FORMAT_R64G64_SINT, + VK_FORMAT_R64G64B64_SINT, + VK_FORMAT_R64G64B64A64_SINT, + + VK_FORMAT_UNDEFINED +}; +const VkFormat compatibleFormatsFloats[] = +{ + VK_FORMAT_R4G4_UNORM_PACK8, + VK_FORMAT_R4G4B4A4_UNORM_PACK16, + VK_FORMAT_B4G4R4A4_UNORM_PACK16, + VK_FORMAT_R5G6B5_UNORM_PACK16, + VK_FORMAT_B5G6R5_UNORM_PACK16, + VK_FORMAT_R5G5B5A1_UNORM_PACK16, + VK_FORMAT_B5G5R5A1_UNORM_PACK16, + VK_FORMAT_A1R5G5B5_UNORM_PACK16, + VK_FORMAT_R8_UNORM, + VK_FORMAT_R8_SNORM, + VK_FORMAT_R8_USCALED, + VK_FORMAT_R8_SSCALED, + VK_FORMAT_R8G8_UNORM, + VK_FORMAT_R8G8_SNORM, + VK_FORMAT_R8G8_USCALED, + VK_FORMAT_R8G8_SSCALED, + VK_FORMAT_R8G8B8_UNORM, + VK_FORMAT_R8G8B8_SNORM, + VK_FORMAT_R8G8B8_USCALED, + VK_FORMAT_R8G8B8_SSCALED, + VK_FORMAT_B8G8R8_UNORM, + VK_FORMAT_B8G8R8_SNORM, + VK_FORMAT_B8G8R8_USCALED, + VK_FORMAT_B8G8R8_SSCALED, + VK_FORMAT_R8G8B8A8_UNORM, + VK_FORMAT_R8G8B8A8_SNORM, + VK_FORMAT_R8G8B8A8_USCALED, + VK_FORMAT_R8G8B8A8_SSCALED, + VK_FORMAT_B8G8R8A8_UNORM, + VK_FORMAT_B8G8R8A8_SNORM, + VK_FORMAT_B8G8R8A8_USCALED, + VK_FORMAT_B8G8R8A8_SSCALED, + VK_FORMAT_A8B8G8R8_UNORM_PACK32, + VK_FORMAT_A8B8G8R8_SNORM_PACK32, + VK_FORMAT_A8B8G8R8_USCALED_PACK32, + VK_FORMAT_A8B8G8R8_SSCALED_PACK32, + VK_FORMAT_A2R10G10B10_UNORM_PACK32, + VK_FORMAT_A2R10G10B10_SNORM_PACK32, + VK_FORMAT_A2R10G10B10_USCALED_PACK32, + VK_FORMAT_A2R10G10B10_SSCALED_PACK32, + VK_FORMAT_A2B10G10R10_UNORM_PACK32, + VK_FORMAT_A2B10G10R10_SNORM_PACK32, + VK_FORMAT_A2B10G10R10_USCALED_PACK32, + VK_FORMAT_A2B10G10R10_SSCALED_PACK32, + VK_FORMAT_R16_UNORM, + VK_FORMAT_R16_SNORM, + VK_FORMAT_R16_USCALED, + VK_FORMAT_R16_SSCALED, + VK_FORMAT_R16_SFLOAT, + VK_FORMAT_R16G16_UNORM, + VK_FORMAT_R16G16_SNORM, + VK_FORMAT_R16G16_USCALED, + VK_FORMAT_R16G16_SSCALED, + VK_FORMAT_R16G16_SFLOAT, + VK_FORMAT_R16G16B16_UNORM, + VK_FORMAT_R16G16B16_SNORM, + VK_FORMAT_R16G16B16_USCALED, + VK_FORMAT_R16G16B16_SSCALED, + VK_FORMAT_R16G16B16_SFLOAT, + VK_FORMAT_R16G16B16A16_UNORM, + VK_FORMAT_R16G16B16A16_SNORM, + VK_FORMAT_R16G16B16A16_USCALED, + VK_FORMAT_R16G16B16A16_SSCALED, + VK_FORMAT_R16G16B16A16_SFLOAT, + VK_FORMAT_R32_SFLOAT, + VK_FORMAT_R32G32_SFLOAT, + VK_FORMAT_R32G32B32_SFLOAT, + VK_FORMAT_R32G32B32A32_SFLOAT, + VK_FORMAT_R64_SFLOAT, + VK_FORMAT_R64G64_SFLOAT, + VK_FORMAT_R64G64B64_SFLOAT, + VK_FORMAT_R64G64B64A64_SFLOAT, +// VK_FORMAT_B10G11R11_UFLOAT_PACK32, +// VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, +// VK_FORMAT_BC1_RGB_UNORM_BLOCK, +// VK_FORMAT_BC1_RGBA_UNORM_BLOCK, +// VK_FORMAT_BC2_UNORM_BLOCK, +// VK_FORMAT_BC3_UNORM_BLOCK, +// VK_FORMAT_BC4_UNORM_BLOCK, +// VK_FORMAT_BC4_SNORM_BLOCK, +// VK_FORMAT_BC5_UNORM_BLOCK, +// VK_FORMAT_BC5_SNORM_BLOCK, +// VK_FORMAT_BC6H_UFLOAT_BLOCK, +// VK_FORMAT_BC6H_SFLOAT_BLOCK, +// VK_FORMAT_BC7_UNORM_BLOCK, +// VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, +// VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, +// VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, +// VK_FORMAT_EAC_R11_UNORM_BLOCK, +// VK_FORMAT_EAC_R11_SNORM_BLOCK, +// VK_FORMAT_EAC_R11G11_UNORM_BLOCK, +// VK_FORMAT_EAC_R11G11_SNORM_BLOCK, +// VK_FORMAT_ASTC_4x4_UNORM_BLOCK, +// VK_FORMAT_ASTC_5x4_UNORM_BLOCK, +// VK_FORMAT_ASTC_5x5_UNORM_BLOCK, +// VK_FORMAT_ASTC_6x5_UNORM_BLOCK, +// VK_FORMAT_ASTC_6x6_UNORM_BLOCK, +// VK_FORMAT_ASTC_8x5_UNORM_BLOCK, +// VK_FORMAT_ASTC_8x6_UNORM_BLOCK, +// VK_FORMAT_ASTC_8x8_UNORM_BLOCK, +// VK_FORMAT_ASTC_10x5_UNORM_BLOCK, +// VK_FORMAT_ASTC_10x6_UNORM_BLOCK, +// VK_FORMAT_ASTC_10x8_UNORM_BLOCK, +// VK_FORMAT_ASTC_10x10_UNORM_BLOCK, +// VK_FORMAT_ASTC_12x10_UNORM_BLOCK, +// VK_FORMAT_ASTC_12x12_UNORM_BLOCK, + + VK_FORMAT_UNDEFINED +}; +const VkFormat compatibleFormatsSrgb[] = +{ + VK_FORMAT_R8_SRGB, + VK_FORMAT_R8G8_SRGB, + VK_FORMAT_R8G8B8_SRGB, + VK_FORMAT_B8G8R8_SRGB, + VK_FORMAT_R8G8B8A8_SRGB, + VK_FORMAT_B8G8R8A8_SRGB, + VK_FORMAT_A8B8G8R8_SRGB_PACK32, +// VK_FORMAT_BC1_RGB_SRGB_BLOCK, +// VK_FORMAT_BC1_RGBA_SRGB_BLOCK, +// VK_FORMAT_BC2_SRGB_BLOCK, +// VK_FORMAT_BC3_SRGB_BLOCK, +// VK_FORMAT_BC7_SRGB_BLOCK, +// VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, +// VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, +// VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, +// VK_FORMAT_ASTC_4x4_SRGB_BLOCK, +// VK_FORMAT_ASTC_5x4_SRGB_BLOCK, +// VK_FORMAT_ASTC_5x5_SRGB_BLOCK, +// VK_FORMAT_ASTC_6x5_SRGB_BLOCK, +// VK_FORMAT_ASTC_6x6_SRGB_BLOCK, +// VK_FORMAT_ASTC_8x5_SRGB_BLOCK, +// VK_FORMAT_ASTC_8x6_SRGB_BLOCK, +// VK_FORMAT_ASTC_8x8_SRGB_BLOCK, +// VK_FORMAT_ASTC_10x5_SRGB_BLOCK, +// VK_FORMAT_ASTC_10x6_SRGB_BLOCK, +// VK_FORMAT_ASTC_10x8_SRGB_BLOCK, +// VK_FORMAT_ASTC_10x10_SRGB_BLOCK, +// VK_FORMAT_ASTC_12x10_SRGB_BLOCK, +// VK_FORMAT_ASTC_12x12_SRGB_BLOCK, + + VK_FORMAT_UNDEFINED +}; - // Filter is VK_FILTER_NEAREST. - { - params.filter = VK_FILTER_NEAREST; +const VkFormat dedicatedAllocationBlittingFormatsToTest[] = +{ + // compatibleFormatsUInts + VK_FORMAT_R8_UINT, + VK_FORMAT_R64G64B64A64_UINT, - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params)); + // compatibleFormatsSInts + VK_FORMAT_R8_SINT, + VK_FORMAT_R64G64B64A64_SINT, + // compatibleFormatsFloats + VK_FORMAT_R4G4_UNORM_PACK8, + VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, - params.dst.image.format = VK_FORMAT_R32_SFLOAT; - const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); + // compatibleFormatsSrgb + VK_FORMAT_R8_SRGB, + VK_FORMAT_A8B8G8R8_SRGB_PACK32, +}; - params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; - const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); - } +void addBlittingImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + const struct { + const VkFormat* compatibleFormats; + const bool onlyNearest; + } colorImageFormatsToTestBlit[] = + { + { compatibleFormatsUInts, true }, + { compatibleFormatsSInts, true }, + { compatibleFormatsFloats, false }, + { compatibleFormatsSrgb, false }, + }; - // Filter is VK_FILTER_LINEAR. - { - params.filter = VK_FILTER_LINEAR; + const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit); - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params)); + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.extent = defaultExtent; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.extent = defaultExtent; + params.allocationKind = allocationKind; - params.dst.image.format = VK_FORMAT_R32_SFLOAT; - const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); + CopyRegion region; + for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++) + { + const VkImageBlit imageBlit = + { + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; + { + {0, 0, 0}, + {defaultSize, defaultSize, 1} + }, // VkOffset3D srcOffsets[2]; - params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; - const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); - } + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {i, 0, 0}, + {i + defaultFourthSize / j, defaultFourthSize / j, 1} + } // VkOffset3D dstOffset[2]; + }; + region.imageBlit = imageBlit; + params.regions.push_back(region); } - + for (int i = 0; i < defaultSize; i += defaultFourthSize) { - const std::string description ("Blit without scaling (partial)"); - const std::string testName ("without_scaling_partial"); - - TestParams params; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = defaultExtent; - params.dst.image.extent = defaultExtent; - + const VkImageBlit imageBlit = { - CopyRegion region; - for (int i = 0; i < defaultSize; i += defaultFourthSize) + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; { - const VkImageBlit imageBlit = - { - defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; - { - {defaultSize - defaultFourthSize - i, defaultSize - defaultFourthSize - i, 0}, - {defaultSize - i, defaultSize - i, 1} - }, // VkOffset3D srcOffsets[2]; + {i, i, 0}, + {i + defaultFourthSize, i + defaultFourthSize, 1} + }, // VkOffset3D srcOffsets[2]; - defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; - { - {i, i, 0}, - {i + defaultFourthSize, i + defaultFourthSize, 1} - } // VkOffset3D dstOffset[2]; - }; - region.imageBlit = imageBlit; - params.regions.push_back(region); - } - } + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {i, defaultSize / 2, 0}, + {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1} + } // VkOffset3D dstOffset[2]; + }; + region.imageBlit = imageBlit; + params.regions.push_back(region); + } + + if (allocationKind == ALLOCATION_KIND_DEDICATED) + { + const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest); + for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex) + dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]); + } - // Filter is VK_FILTER_NEAREST. + for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex) + { + const VkFormat* compatibleFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats; + const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest; + for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex) { - params.filter = VK_FILTER_NEAREST; + params.src.image.format = compatibleFormats[srcFormatIndex]; + if (!isSupportedByFramework(params.src.image.format)) + continue; - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params)); + BlitColorTestParams testParams; + testParams.params = params; + testParams.compatibleFormats = compatibleFormats; + testParams.onlyNearest = onlyNearest; + const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format); + addTestGroup(group, getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams); + } + } +} - params.dst.image.format = VK_FORMAT_R32_SFLOAT; - const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params)); +void addBlittingImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params) +{ + const VkImageLayout blitSrcLayouts[] = + { + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_IMAGE_LAYOUT_GENERAL + }; + const VkImageLayout blitDstLayouts[] = + { + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_GENERAL + }; - params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; - const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); - } + for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx) + { + params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx]; - // Filter is VK_FILTER_LINEAR. + for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx) { - params.filter = VK_FILTER_LINEAR; + params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx]; + params.filter = VK_FILTER_NEAREST; - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params)); + const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" + + getImageLayoutCaseName(params.dst.image.operationLayout); + const std::string description = "Blit from " + getImageLayoutCaseName(params.src.image.operationLayout) + + " to " + getImageLayoutCaseName(params.dst.image.operationLayout); - params.dst.image.format = VK_FORMAT_R32_SFLOAT; - const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params)); - - params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM; - const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); + group->addChild(new BlittingTestCase(group->getTestContext(), testName + "_nearest", description, params)); } } +} + +void addBlittingImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + const VkFormat depthAndStencilFormats[] = + { + VK_FORMAT_D16_UNORM, + VK_FORMAT_X8_D24_UNORM_PACK32, + VK_FORMAT_D32_SFLOAT, + VK_FORMAT_S8_UINT, + VK_FORMAT_D16_UNORM_S8_UINT, + VK_FORMAT_D24_UNORM_S8_UINT, + VK_FORMAT_D32_SFLOAT_S8_UINT, + }; + + const VkImageSubresourceLayers defaultDepthSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u }; + const VkImageSubresourceLayers defaultStencilSourceLayer = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u }; + for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex) { - const std::string description ("Blit with scaling (partial)"); - const std::string testName ("scaling_partial"); + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.extent = defaultExtent; + params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex]; + params.dst.image.extent = defaultExtent; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.format = params.src.image.format; + params.allocationKind = allocationKind; - // Test Color formats. + CopyRegion region; + for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++) { - TestParams params; - params.src.image.extent = defaultExtent; - params.dst.image.extent = defaultExtent; + const VkOffset3D srcOffset0 = {0, 0, 0}; + const VkOffset3D srcOffset1 = {defaultSize, defaultSize, 1}; + const VkOffset3D dstOffset0 = {i, 0, 0}; + const VkOffset3D dstOffset1 = {i + defaultFourthSize / j, defaultFourthSize / j, 1}; - CopyRegion region; - for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++) + if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order)) { const VkImageBlit imageBlit = { - defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; - { - {0, 0, 0}, - {defaultSize, defaultSize, 1} - }, // VkOffset3D srcOffsets[2]; - - defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; - { - {i, 0, 0}, - {i + defaultFourthSize / j, defaultFourthSize / j, 1} - } // VkOffset3D dstOffset[2]; + defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource; + { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2]; + defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource; + { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2]; }; region.imageBlit = imageBlit; params.regions.push_back(region); } - for (int i = 0; i < defaultSize; i += defaultFourthSize) + if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order)) { const VkImageBlit imageBlit = { - defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; - { - {i, i, 0}, - {i + defaultFourthSize, i + defaultFourthSize, 1} - }, // VkOffset3D srcOffsets[2]; - - defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; - { - {i, defaultSize / 2, 0}, - {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1} - } // VkOffset3D dstOffset[2]; + defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource; + { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2]; + defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource; + { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2]; }; region.imageBlit = imageBlit; params.regions.push_back(region); } - - addBlittingTestsAllFormats(blitImgAllFormatsTests.get(), testCtx, params); } - - // Test Depth and Stencil formats. + for (int i = 0; i < defaultSize; i += defaultFourthSize) { - const VkFormat compatibleDepthAndStencilFormats[] = - { - VK_FORMAT_D16_UNORM, - VK_FORMAT_X8_D24_UNORM_PACK32, - VK_FORMAT_D32_SFLOAT, - VK_FORMAT_S8_UINT, - VK_FORMAT_D16_UNORM_S8_UINT, - VK_FORMAT_D24_UNORM_S8_UINT, - VK_FORMAT_D32_SFLOAT_S8_UINT, - }; + const VkOffset3D srcOffset0 = {i, i, 0}; + const VkOffset3D srcOffset1 = {i + defaultFourthSize, i + defaultFourthSize, 1}; + const VkOffset3D dstOffset0 = {i, defaultSize / 2, 0}; + const VkOffset3D dstOffset1 = {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1}; - for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(compatibleDepthAndStencilFormats); ++compatibleFormatsIndex) + if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order)) { - TestParams params; - - params.src.image.extent = defaultExtent; - params.dst.image.extent = defaultExtent; - params.src.image.format = compatibleDepthAndStencilFormats[compatibleFormatsIndex]; - params.dst.image.format = params.src.image.format; - std::ostringstream oss; - oss << testName << "_" << getFormatCaseName(params.src.image.format) << "_" << getFormatCaseName(params.dst.image.format); - - const VkImageSubresourceLayers defaultDepthSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u }; - const VkImageSubresourceLayers defaultStencilSourceLayer = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u }; - - CopyRegion region; - for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++) + const VkImageBlit imageBlit = { - const VkOffset3D srcOffset0 = {0, 0, 0}; - const VkOffset3D srcOffset1 = {defaultSize, defaultSize, 1}; - const VkOffset3D dstOffset0 = {i, 0, 0}; - const VkOffset3D dstOffset1 = {i + defaultFourthSize / j, defaultFourthSize / j, 1}; - - if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order)) - { - const VkImageBlit imageBlit = - { - defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource; - { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2]; - defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource; - { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2]; - }; - region.imageBlit = imageBlit; - params.regions.push_back(region); - } - if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order)) - { - const VkImageBlit imageBlit = - { - defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource; - { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2]; - defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource; - { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2]; - }; - region.imageBlit = imageBlit; - params.regions.push_back(region); - } - } - for (int i = 0; i < defaultSize; i += defaultFourthSize) + defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource; + { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2]; + defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource; + { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2]; + }; + region.imageBlit = imageBlit; + params.regions.push_back(region); + } + if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order)) + { + const VkImageBlit imageBlit = { - const VkOffset3D srcOffset0 = {i, i, 0}; - const VkOffset3D srcOffset1 = {i + defaultFourthSize, i + defaultFourthSize, 1}; - const VkOffset3D dstOffset0 = {i, defaultSize / 2, 0}; - const VkOffset3D dstOffset1 = {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1}; - - if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order)) - { - const VkImageBlit imageBlit = - { - defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource; - { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2]; - defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource; - { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2]; - }; - region.imageBlit = imageBlit; - params.regions.push_back(region); - } - if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order)) - { - const VkImageBlit imageBlit = - { - defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource; - { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2]; - defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource; - { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2]; - }; - region.imageBlit = imageBlit; - params.regions.push_back(region); - } - } - - params.filter = VK_FILTER_NEAREST; - blitImgAllFormatsTests->addChild(new BlittingTestCase(testCtx, oss.str() + "_nearest", description, params)); + defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource; + { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2]; + defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource; + { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2]; + }; + region.imageBlit = imageBlit; + params.regions.push_back(region); } } - } - blittingImageTests->addChild(blitImgSimpleTests.release()); - blittingImageTests->addChild(blitImgAllFormatsTests.release()); + const std::string testName = getFormatCaseName(params.src.image.format) + "_" + + getFormatCaseName(params.dst.image.format); + const std::string description = "Blit from " + getFormatCaseName(params.src.image.format) + + " to " + getFormatCaseName(params.dst.image.format); + addTestGroup(group, testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params); + } +} - // Resolve image to image testcases. - const VkSampleCountFlagBits samples[] = - { - VK_SAMPLE_COUNT_2_BIT, - VK_SAMPLE_COUNT_4_BIT, - VK_SAMPLE_COUNT_8_BIT, - VK_SAMPLE_COUNT_16_BIT, - VK_SAMPLE_COUNT_32_BIT, - VK_SAMPLE_COUNT_64_BIT - }; - const VkExtent3D resolveExtent = {256u, 256u, 1}; +void addBlittingImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + addTestGroup(group, "color", "Blitting image with color formats", addBlittingImageAllFormatsColorTests, allocationKind); + addTestGroup(group, "depth_stencil", "Blitting image with depth/stencil formats", addBlittingImageAllFormatsDepthStencilTests, allocationKind); +} - { - const std::string description ("Resolve from image to image"); - const std::string testName ("whole"); +void addBlittingImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + addTestGroup(group, "simple_tests", "Blitting image simple tests", addBlittingImageSimpleTests, allocationKind); + addTestGroup(group, "all_formats", "Blitting image with all compatible formats", addBlittingImageAllFormatsTests, allocationKind); +} - TestParams params; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = resolveExtent; - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.dst.image.extent = resolveExtent; +const VkSampleCountFlagBits samples[] = +{ + VK_SAMPLE_COUNT_2_BIT, + VK_SAMPLE_COUNT_4_BIT, + VK_SAMPLE_COUNT_8_BIT, + VK_SAMPLE_COUNT_16_BIT, + VK_SAMPLE_COUNT_32_BIT, + VK_SAMPLE_COUNT_64_BIT +}; +const VkExtent3D resolveExtent = {256u, 256u, 1}; +void addResolveImageWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.src.image.extent = resolveExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.dst.image.extent = resolveExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; + + { + const VkImageSubresourceLayers sourceLayer = { - const VkImageSubresourceLayers sourceLayer = - { - VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; - 0u, // uint32_t mipLevel; - 0u, // uint32_t baseArrayLayer; - 1u // uint32_t layerCount; - }; - const VkImageResolve testResolve = - { - sourceLayer, // VkImageSubresourceLayers srcSubresource; - {0, 0, 0}, // VkOffset3D srcOffset; - sourceLayer, // VkImageSubresourceLayers dstSubresource; - {0, 0, 0}, // VkOffset3D dstOffset; - resolveExtent, // VkExtent3D extent; - }; + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + 0u, // uint32_t baseArrayLayer; + 1u // uint32_t layerCount; + }; + const VkImageResolve testResolve = + { + sourceLayer, // VkImageSubresourceLayers srcSubresource; + {0, 0, 0}, // VkOffset3D srcOffset; + sourceLayer, // VkImageSubresourceLayers dstSubresource; + {0, 0, 0}, // VkOffset3D dstOffset; + resolveExtent, // VkExtent3D extent; + }; - CopyRegion imageResolve; - imageResolve.imageResolve = testResolve; - params.regions.push_back(imageResolve); - } + CopyRegion imageResolve; + imageResolve.imageResolve = testResolve; + params.regions.push_back(imageResolve); + } - for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex) + for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex) + { + params.samples = samples[samplesIndex]; + const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]); + group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params)); + } +} + +void addResolveImagePartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.src.image.extent = resolveExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.dst.image.extent = resolveExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; + + { + const VkImageSubresourceLayers sourceLayer = { - params.samples = samples[samplesIndex]; - std::ostringstream caseName; - caseName << testName << "_" << getSampleCountCaseName(samples[samplesIndex]); - resolveImageTests->addChild(new ResolveImageToImageTestCase(testCtx, caseName.str(), description, params)); - } + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + 0u, // uint32_t baseArrayLayer; + 1u // uint32_t layerCount; + }; + const VkImageResolve testResolve = + { + sourceLayer, // VkImageSubresourceLayers srcSubresource; + {0, 0, 0}, // VkOffset3D srcOffset; + sourceLayer, // VkImageSubresourceLayers dstSubresource; + {64u, 64u, 0}, // VkOffset3D dstOffset; + {128u, 128u, 1u}, // VkExtent3D extent; + }; + + CopyRegion imageResolve; + imageResolve.imageResolve = testResolve; + params.regions.push_back(imageResolve); } + for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex) { - const std::string description ("Resolve from image to image"); - const std::string testName ("partial"); + params.samples = samples[samplesIndex]; + const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]); + group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params)); + } +} - TestParams params; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = resolveExtent; - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.dst.image.extent = resolveExtent; +void addResolveImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.src.image.extent = resolveExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.dst.image.extent = resolveExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; + + { + const VkImageSubresourceLayers sourceLayer = + { + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + 0u, // uint32_t baseArrayLayer; + 1u // uint32_t layerCount; + }; + for (int i = 0; i < 256; i += 64) { - const VkImageSubresourceLayers sourceLayer = - { - VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; - 0u, // uint32_t mipLevel; - 0u, // uint32_t baseArrayLayer; - 1u // uint32_t layerCount; - }; const VkImageResolve testResolve = { sourceLayer, // VkImageSubresourceLayers srcSubresource; - {0, 0, 0}, // VkOffset3D srcOffset; + {i, i, 0}, // VkOffset3D srcOffset; sourceLayer, // VkImageSubresourceLayers dstSubresource; - {64u, 64u, 0}, // VkOffset3D dstOffset; - {128u, 128u, 1u}, // VkExtent3D extent; + {i, 0, 0}, // VkOffset3D dstOffset; + {64u, 64u, 1u}, // VkExtent3D extent; }; CopyRegion imageResolve; imageResolve.imageResolve = testResolve; params.regions.push_back(imageResolve); } + } - for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex) + for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex) + { + params.samples = samples[samplesIndex]; + const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]); + group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params)); + } +} + +void addResolveImageWholeCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.src.image.extent = defaultExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.dst.image.extent = defaultExtent; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; + + { + const VkImageSubresourceLayers sourceLayer = { - params.samples = samples[samplesIndex]; - std::ostringstream caseName; - caseName << testName << "_" << getSampleCountCaseName(samples[samplesIndex]); - resolveImageTests->addChild(new ResolveImageToImageTestCase(testCtx, caseName.str(), description, params)); - } + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + 0u, // uint32_t baseArrayLayer; + 1u // uint32_t layerCount; + }; + + const VkImageResolve testResolve = + { + sourceLayer, // VkImageSubresourceLayers srcSubresource; + {0, 0, 0}, // VkOffset3D srcOffset; + sourceLayer, // VkImageSubresourceLayers dstSubresource; + {0, 0, 0}, // VkOffset3D dstOffset; + defaultExtent, // VkExtent3D extent; + }; + + CopyRegion imageResolve; + imageResolve.imageResolve = testResolve; + params.regions.push_back(imageResolve); } + for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex) { - const std::string description ("Resolve from image to image"); - const std::string testName ("with_regions"); + params.samples = samples[samplesIndex]; + const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]); + group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE)); + } +} - TestParams params; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = resolveExtent; - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.dst.image.extent = resolveExtent; +void addResolveImageWholeArrayImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.src.image.extent = defaultExtent; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.dst.image.extent = defaultExtent; + params.dst.image.extent.depth = 5u; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; + + for (deUint32 layerNdx=0; layerNdx < params.dst.image.extent.depth; ++layerNdx) + { + const VkImageSubresourceLayers sourceLayer = + { + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + layerNdx, // uint32_t baseArrayLayer; + 1u // uint32_t layerCount; + }; + const VkImageResolve testResolve = { - const VkImageSubresourceLayers sourceLayer = - { - VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; - 0u, // uint32_t mipLevel; - 0u, // uint32_t baseArrayLayer; - 1u // uint32_t layerCount; - }; + sourceLayer, // VkImageSubresourceLayers srcSubresource; + {0, 0, 0}, // VkOffset3D srcOffset; + sourceLayer, // VkImageSubresourceLayers dstSubresource; + {0, 0, 0}, // VkOffset3D dstOffset; + defaultExtent, // VkExtent3D extent; + }; - for (int i = 0; i < 256; i += 64) - { - const VkImageResolve testResolve = - { - sourceLayer, // VkImageSubresourceLayers srcSubresource; - {i, i, 0}, // VkOffset3D srcOffset; - sourceLayer, // VkImageSubresourceLayers dstSubresource; - {i, 0, 0}, // VkOffset3D dstOffset; - {64u, 64u, 1u}, // VkExtent3D extent; - }; + CopyRegion imageResolve; + imageResolve.imageResolve = testResolve; + params.regions.push_back(imageResolve); + } - CopyRegion imageResolve; - imageResolve.imageResolve = testResolve; - params.regions.push_back(imageResolve); - } - } + for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex) + { + params.samples = samples[samplesIndex]; + const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]); + group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE)); + } +} + +void addResolveImageDiffImageSizeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + tcu::TestContext& testCtx = group->getTestContext(); + TestParams params; + params.src.image.imageType = VK_IMAGE_TYPE_2D; + params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + params.dst.image.imageType = VK_IMAGE_TYPE_2D; + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + params.allocationKind = allocationKind; + + { + const VkImageSubresourceLayers sourceLayer = + { + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + 0u, // uint32_t baseArrayLayer; + 1u // uint32_t layerCount; + }; + const VkImageResolve testResolve = + { + sourceLayer, // VkImageSubresourceLayers srcSubresource; + {0, 0, 0}, // VkOffset3D srcOffset; + sourceLayer, // VkImageSubresourceLayers dstSubresource; + {0, 0, 0}, // VkOffset3D dstOffset; + resolveExtent, // VkExtent3D extent; + }; + CopyRegion imageResolve; + imageResolve.imageResolve = testResolve; + params.regions.push_back(imageResolve); + } + + const VkExtent3D imageExtents[] = + { + { resolveExtent.width + 10, resolveExtent.height, resolveExtent.depth }, + { resolveExtent.width, resolveExtent.height * 2, resolveExtent.depth }, + { resolveExtent.width, resolveExtent.height, resolveExtent.depth + 10 } + }; + for (int srcImageExtentIndex = 0; srcImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++srcImageExtentIndex) + { + const VkExtent3D& srcImageSize = imageExtents[srcImageExtentIndex]; + params.src.image.extent = srcImageSize; + params.dst.image.extent = resolveExtent; + for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex) + { + params.samples = samples[samplesIndex]; + std::ostringstream testName; + testName << "src_" << srcImageSize.width << "_" << srcImageSize.height << "_" << srcImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]); + std::ostringstream description; + description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and source image size (" + << srcImageSize.width << ", " << srcImageSize.height << ", " << srcImageSize.depth << ")"; + group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params)); + } + } + for (int dstImageExtentIndex = 0; dstImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++dstImageExtentIndex) + { + const VkExtent3D& dstImageSize = imageExtents[dstImageExtentIndex]; + params.src.image.extent = resolveExtent; + params.dst.image.extent = dstImageSize; for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex) { - params.samples = samples[samplesIndex]; - std::ostringstream caseName; - caseName << testName << "_" << getSampleCountCaseName(samples[samplesIndex]); - resolveImageTests->addChild(new ResolveImageToImageTestCase(testCtx, caseName.str(), description, params)); + params.samples = samples[samplesIndex]; + std::ostringstream testName; + testName << "dst_" << dstImageSize.width << "_" << dstImageSize.height << "_" << dstImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]); + std::ostringstream description; + description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and destination image size (" + << dstImageSize.width << ", " << dstImageSize.height << ", " << dstImageSize.depth << ")"; + group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params)); } } +} + +void addResolveImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + addTestGroup(group, "whole", "Resolve from image to image (whole)", addResolveImageWholeTests, allocationKind); + addTestGroup(group, "partial", "Resolve from image to image (partial)", addResolveImagePartialTests, allocationKind); + addTestGroup(group, "with_regions", "Resolve from image to image (with regions)", addResolveImageWithRegionsTests, allocationKind); + addTestGroup(group, "whole_copy_before_resolving", "Resolve from image to image (whole copy before resolving)", addResolveImageWholeCopyBeforeResolvingTests, allocationKind); + addTestGroup(group, "whole_array_image", "Resolve from image to image (whole array image)", addResolveImageWholeArrayImageTests, allocationKind); + addTestGroup(group, "diff_image_size", "Resolve from image to image of different size", addResolveImageDiffImageSizeTests, allocationKind); +} + +void addCopiesAndBlittingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + addTestGroup(group, "image_to_image", "Copy from image to image", addImageToImageTests, allocationKind); + addTestGroup(group, "image_to_buffer", "Copy from image to buffer", addImageToBufferTests, allocationKind); + addTestGroup(group, "buffer_to_image", "Copy from buffer to image", addBufferToImageTests, allocationKind); + addTestGroup(group, "buffer_to_buffer", "Copy from buffer to buffer", addBufferToBufferTests, allocationKind); + addTestGroup(group, "blit_image", "Blitting image", addBlittingImageTests, allocationKind); + addTestGroup(group, "resolve_image", "Resolve image", addResolveImageTests, allocationKind); +} + +void addCoreCopiesAndBlittingTests (tcu::TestCaseGroup* group) +{ + addCopiesAndBlittingTests(group, ALLOCATION_KIND_SUBALLOCATED); +} + +void addDedicatedAllocationCopiesAndBlittingTests (tcu::TestCaseGroup* group) +{ + addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED); +} + +} // anonymous + +tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx) +{ + de::MovePtr copiesAndBlittingTests(new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests")); - copiesAndBlittingTests->addChild(imageToImageTests.release()); - copiesAndBlittingTests->addChild(imageToBufferTests.release()); - copiesAndBlittingTests->addChild(bufferToImageTests.release()); - copiesAndBlittingTests->addChild(bufferToBufferTests.release()); - copiesAndBlittingTests->addChild(blittingImageTests.release()); - copiesAndBlittingTests->addChild(resolveImageTests.release()); + copiesAndBlittingTests->addChild(createTestGroup(testCtx, "core", "Core Copies And Blitting Tests", addCoreCopiesAndBlittingTests)); + copiesAndBlittingTests->addChild(createTestGroup(testCtx, "dedicated_allocation", "Copies And Blitting Tests For Dedicated Memory Allocation", addDedicatedAllocationCopiesAndBlittingTests)); return copiesAndBlittingTests.release(); }