X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=external%2Fvulkancts%2Fmodules%2Fvulkan%2Fapi%2FvktApiCopiesAndBlittingTests.cpp;h=c08e6bdabef38910f655f6649a09607f54e29c67;hb=cd69acfb3a5d9a4a32c4067ad869bc9eda1fca04;hp=98a8285c4db254da37b5ccef7fd4cf1988e58560;hpb=0eeb76f803a02e3d04b0c35630f64f625c76952e;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 98a8285..c08e6bd 100644 --- a/external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp +++ b/external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp @@ -26,13 +26,14 @@ #include "deStringUtil.hpp" #include "deUniquePtr.hpp" -#include "deMath.h" #include "tcuImageCompare.hpp" #include "tcuTexture.hpp" #include "tcuTextureUtil.hpp" #include "tcuVectorType.hpp" #include "tcuVectorUtil.hpp" +#include "tcuTestLog.hpp" +#include "tcuTexLookupVerifier.hpp" #include "vkImageUtil.hpp" #include "vkMemUtil.hpp" @@ -41,8 +42,11 @@ #include "vkRefUtil.hpp" #include "vktTestCase.hpp" #include "vktTestCaseUtil.hpp" +#include "vktTestGroupUtil.hpp" #include "vkTypeUtil.hpp" +#include + namespace vkt { @@ -61,12 +65,28 @@ enum MirrorMode MIRROR_MODE_LAST }; -} - -using namespace vk; +enum AllocationKind +{ + ALLOCATION_KIND_SUBALLOCATED, + ALLOCATION_KIND_DEDICATED, +}; -namespace +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) { @@ -104,13 +124,14 @@ struct ImageParms VkImageType imageType; VkFormat format; VkExtent3D extent; + VkImageLayout operationLayout; }; struct TestParams { - union + union Data { - struct + struct Buffer { VkDeviceSize size; } buffer; @@ -125,8 +146,71 @@ struct TestParams 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; @@ -228,94 +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_RESET_COMMAND_BUFFER_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: - 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; + 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; } } } @@ -333,12 +420,13 @@ void CopiesAndBlittingTestInstance::uploadBuffer (tcu::ConstPixelBufferAccess bu 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; @@ -360,7 +448,7 @@ 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())); } @@ -378,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; @@ -391,7 +481,7 @@ void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBuff VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; image, // VkImage image; { // VkImageSubresourceRange subresourceRange; - aspect, // VkImageAspectFlags aspect; + formatAspect, // VkImageAspectFlags aspect; 0u, // deUint32 baseMipLevel; 1u, // deUint32 mipLevels; 0u, // deUint32 baseArraySlice; @@ -411,7 +501,7 @@ void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBuff VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex; image, // VkImage image; { // VkImageSubresourceRange subresourceRange; - aspect, // VkImageAspectFlags aspect; + formatAspect, // VkImageAspectFlags aspect; 0u, // deUint32 baseMipLevel; 1u, // deUint32 mipLevels; 0u, // deUint32 baseArraySlice; @@ -448,7 +538,8 @@ void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBuff }; 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, 1, &preImageBarrier); + 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)); @@ -485,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"); } @@ -526,7 +617,9 @@ void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage image, 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(); @@ -552,7 +645,7 @@ 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())); deMemset(bufferAlloc->getHostPtr(), 0, static_cast(pixelDataSize)); @@ -560,20 +653,20 @@ void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage image, } // 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; + formatAspect, // VkImageAspectFlags aspectMask; 0u, // deUint32 baseMipLevel; 1u, // deUint32 mipLevels; 0u, // deUint32 baseArraySlice; @@ -601,12 +694,12 @@ 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; @@ -615,6 +708,7 @@ void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage image, }; // Copy image to buffer + const VkImageAspectFlags aspect = getAspectFlags(dst.getFormat()); const VkBufferImageCopy copyRegion = { 0u, // VkDeviceSize bufferOffset; @@ -723,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, @@ -754,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 | @@ -770,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())); } @@ -781,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 | @@ -797,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())); } } @@ -807,14 +910,14 @@ 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)); + (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(); @@ -838,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; @@ -847,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 @@ -857,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; @@ -866,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; } }, }; @@ -881,7 +984,7 @@ 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)); submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer); @@ -906,12 +1009,12 @@ tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess r if (isFloatFormat(result.getFormat())) { - if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT)) + 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 comparsion", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT)) + if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT)) return tcu::TestStatus::fail("CopiesAndBlitting test"); } } @@ -924,12 +1027,12 @@ tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess r if (isFloatFormat(result.getFormat())) { - if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT)) + 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 comparsion", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT)) + if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT)) return tcu::TestStatus::fail("CopiesAndBlitting test"); } } @@ -938,12 +1041,37 @@ tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess r { if (isFloatFormat(result.getFormat())) { - if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", m_expectedTextureLevel->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT)) + 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 comparsion", m_expectedTextureLevel->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT)) + 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"); } } @@ -953,9 +1081,18 @@ tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess r void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region) { - const VkOffset3D srcOffset = region.imageCopy.srcOffset; - const VkOffset3D dstOffset = region.imageCopy.dstOffset; - const 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)) { @@ -1025,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(); @@ -1045,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())); } @@ -1064,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())); } } @@ -1131,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)); @@ -1208,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(); @@ -1220,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 | @@ -1236,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())); } @@ -1255,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())); } } @@ -1414,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(); @@ -1434,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())); } @@ -1445,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 | @@ -1461,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())); } } @@ -1593,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; @@ -1608,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(); @@ -1661,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 | @@ -1677,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())); } @@ -1688,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 | @@ -1704,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())); } } @@ -1744,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; @@ -1764,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; @@ -1787,11 +1921,10 @@ 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); + submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer); de::MovePtr resultTextureLevel = readImage(*m_destination, m_params.dst.image); @@ -1850,38 +1983,16 @@ 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)) { @@ -1891,11 +2002,9 @@ bool BlittingImages::checkClampedAndUnclampedResult (const tcu::ConstPixelBuffer 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); @@ -1911,116 +2020,373 @@ 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; - if (!checkClampedAndUnclampedResult(depthResult, clampedExpected, unclampedExpected, VK_IMAGE_ASPECT_DEPTH_BIT)) + 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); + + 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)) - { - 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(); +tcu::Vec4 getFloatOrFixedPointFormatThreshold (const tcu::TextureFormat& format) +{ + const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type); + const tcu::IVec4 bitDepth = tcu::getTextureFormatBitDepth(format); - if (!checkClampedAndUnclampedResult(stencilResult, clampedExpected, unclampedExpected, VK_IMAGE_ASPECT_STENCIL_BIT)) - { - return tcu::TestStatus::fail("CopiesAndBlitting test"); - } - } + if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT) + { + return getFormatThreshold(format); } - else + else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT || + channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT) { - if (!checkClampedAndUnclampedResult(result, m_expectedTextureLevel->getAccess(), m_params.filter == VK_FILTER_LINEAR ? m_unclampedExpectedTextureLevel->getAccess() : tcu::ConstPixelBufferAccess(), VK_IMAGE_ASPECT_COLOR_BIT)) + 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) { - return tcu::TestStatus::fail("CopiesAndBlitting test"); + 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(); } - - return tcu::TestStatus::pass("CopiesAndBlitting test"); } -tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color) +bool floatNearestBlitCompare (const tcu::ConstPixelBufferAccess& source, + const tcu::ConstPixelBufferAccess& result, + const tcu::PixelBufferAccess& errorMask, + const std::vector& regions) { - return isSRGB(format) ? linearToSRGB(color) : color; -} + 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; -void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const VkOffset3D regionOffset, const VkOffset3D regionExtent, tcu::Sampler::FilterMode filter) -{ - DE_ASSERT(filter == tcu::Sampler::LINEAR); - DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1); + { + const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(result.getFormat()); + const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat()); + const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat()); - tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, - filter, filter, 0.0f, false); + precision.colorMask = tcu::notEqual(dstBitDepth, tcu::IVec4(0)); + precision.colorThreshold = tcu::max(srcMaxDiff, dstMaxDiff); + } - float sX = (float)regionExtent.x / (float)dst.getWidth(); - float sY = (float)regionExtent.y / (float)dst.getHeight(); + 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()) + }; - for (int y = 0; y < dst.getHeight(); y++) - for (int x = 0; x < dst.getWidth(); x++) - 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); + 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); } -void blit (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode) +bool intNearestBlitCompare (const tcu::ConstPixelBufferAccess& source, + const tcu::ConstPixelBufferAccess& result, + const tcu::PixelBufferAccess& errorMask, + const std::vector& regions) { - DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR); + 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; - tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, - filter, filter, 0.0f, false); + { + const tcu::IVec4 srcBitDepth = tcu::getTextureFormatBitDepth(source.getFormat()); + const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(result.getFormat()); - 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(); + 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; + } + } - 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; + // 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(); - const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0; - const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0; + 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 - if (dst.getDepth() == 1 && src.getDepth() == 1) + const struct Capture { - for (int y = 0; y < dst.getHeight(); ++y) - for (int x = 0; x < dst.getWidth(); ++x) + 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 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); + 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); } - } - else - { - for (int z = 0; z < dst.getDepth(); ++z) + } 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 (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 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 // NEAREST filtering + { + 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 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("Pass"); +} + +tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color) +{ + return isSRGB(format) ? linearToSRGB(color) : color; +} + +void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const VkOffset3D regionOffset, const VkOffset3D regionExtent, tcu::Sampler::FilterMode filter) +{ + DE_ASSERT(filter == tcu::Sampler::LINEAR); + DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1); + + tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, + filter, filter, 0.0f, false); + + float sX = (float)regionExtent.x / (float)dst.getWidth(); + float sY = (float)regionExtent.y / (float)dst.getHeight(); + + for (int y = 0; y < dst.getHeight(); y++) + for (int x = 0; x < dst.getWidth(); x++) + 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) { @@ -2253,7 +2619,9 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c 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(); @@ -2309,10 +2677,10 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c 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) @@ -2322,7 +2690,7 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c 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 = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_multisampledCopyImage), MemoryRequirement::Any); + 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; } @@ -2333,7 +2701,7 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c colorImageParams.arrayLayers = getArraySize(m_params.dst.image); m_multisampledCopyImage = createImage(vk, vkDevice, &colorImageParams); // Allocate and bind color image memory. - m_multisampledCopyImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_multisampledCopyImage), MemoryRequirement::Any); + 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; } @@ -2366,7 +2734,7 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c }; 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())); } @@ -2460,6 +2828,7 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams); } + // 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); @@ -2486,8 +2855,7 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c }; 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. @@ -2498,7 +2866,6 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c { Move framebuffer; Move sourceAttachmentView; - const VkExtent3D extent3D = getExtent3D(m_params.src.image); // Create color attachment view. { @@ -2520,20 +2887,20 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c { const VkImageView attachments[1] = { - *sourceAttachmentView, + *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; - extent3D.width, // deUint32 width; - extent3D.height, // deUint32 height; - 1u // deUint32 layers; + 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); @@ -2565,9 +2932,9 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c const VkVertexInputBindingDescription vertexInputBindingDescription = { - 0u, // deUint32 binding; - sizeof(tcu::Vec4), // deUint32 stride; - VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate; + 0u, // deUint32 binding; + sizeof(tcu::Vec4), // deUint32 stride; + VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate; }; const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[1] = @@ -2582,13 +2949,13 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c 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; + 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 = @@ -2602,74 +2969,74 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c const VkViewport viewport = { - 0.0f, // float x; - 0.0f, // float y; - (float)extent3D.width, // float width; - (float)extent3D.height, // float height; - 0.0f, // float minDepth; - 1.0f // float maxDepth; + 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; - { extent3D.width, extent3D.height } // VkExtent2D extent; + { 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; + 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; + 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; + 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; + 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; + VK_COLOR_COMPONENT_G_BIT | + VK_COLOR_COMPONENT_B_BIT | + VK_COLOR_COMPONENT_A_BIT) // VkChannelFlags channelWriteMask; }; const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = @@ -2733,7 +3100,7 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c *framebuffer, // VkFramebuffer framebuffer; { { 0, 0 }, - { extent3D.width, extent3D.height } + { m_params.src.image.extent.width, m_params.src.image.extent.height } }, // VkRect2D renderArea; 1u, // deUint32 clearValueCount; clearValues // const VkClearValue* pClearValues; @@ -2742,11 +3109,12 @@ ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, c 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.cmdDraw(*m_cmdBuffer, (deUint32)vertices.size(), 1, 0, 0); vk.cmdEndRenderPass(*m_cmdBuffer); VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); @@ -2766,20 +3134,20 @@ tcu::TestStatus ResolveImageToImage::iterate (void) const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_params.dst.image.format); // 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_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)); + 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(); + 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(); switch (m_options) { @@ -2826,7 +3194,7 @@ 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; @@ -2852,13 +3220,13 @@ tcu::TestStatus ResolveImageToImage::iterate (void) 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; - getArraySize(m_params.dst.image)// deUint32 arraySize; - } + { // VkImageSubresourceRange subresourceRange; + getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask; + 0u, // deUint32 baseMipLevel; + 1u, // deUint32 mipLevels; + 0u, // deUint32 baseArraySlice; + getArraySize(m_params.dst.image) // deUint32 arraySize; + } }; const VkCommandBufferBeginInfo cmdBufferBeginInfo = @@ -2874,17 +3242,11 @@ 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); - submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer); - - // check the result of resolving image - { - de::MovePtr resultTextureLevel = readImage(*m_destination, m_params.dst.image); + de::MovePtr resultTextureLevel = readImage(*m_destination, m_params.dst.image); - if (QP_TEST_RESULT_PASS != checkTestResult(resultTextureLevel->getAccess()).getCode()) - return tcu::TestStatus::fail("CopiesAndBlitting test"); - } - return tcu::TestStatus::pass("CopiesAndBlitting test"); + return checkTestResult(resultTextureLevel->getAccess()); } tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result) @@ -2958,7 +3320,7 @@ void ResolveImageToImage::copyMSImageToMSImage (void) const VkImageMemoryBarrier imageBarriers[] = { - //// source image + // source image { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; DE_NULL, // const void* pNext; @@ -3071,6 +3433,7 @@ void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollec " 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" @@ -3090,521 +3453,50 @@ std::string getFormatCaseName (VkFormat format) return de::toLower(de::toString(getFormatStr(format)).substr(10)); } -void addCopyImageTestsAllFormats (tcu::TestCaseGroup* testCaseGroup, - tcu::TestContext& testCtx, - TestParams& params) +std::string getImageLayoutCaseName (VkImageLayout layout) { - 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, - - 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, - - VK_FORMAT_UNDEFINED - }; - const VkFormat compatibleFormats256Bit[] = - { - VK_FORMAT_R64G64B64A64_UINT, - VK_FORMAT_R64G64B64A64_SINT, - VK_FORMAT_R64G64B64A64_SFLOAT, - - VK_FORMAT_UNDEFINED - }; - - const VkFormat* colorImageFormatsToTest[] = - { - compatibleFormats8Bit, - compatibleFormats16Bit, - compatibleFormats24Bit, - compatibleFormats32Bit, - compatibleFormats48Bit, - compatibleFormats64Bit, - compatibleFormats96Bit, - compatibleFormats128Bit, - compatibleFormats192Bit, - compatibleFormats256Bit, - }; - const size_t numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest); - - for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex) - { - const VkFormat* compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex]; - for (size_t srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex) - { - params.src.image.format = compatibleFormats[srcFormatIndex]; - for (size_t dstFormatIndex = 0; compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++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)); - } - } - } -} - -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_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 - }; - - const struct { - const VkFormat* compatibleFormats; - const bool onlyNearest; - } colorImageFormatsToTest[] = - { - { compatibleFormatsUInts, true }, - { compatibleFormatsSInts, true }, - { compatibleFormatsFloats, false }, - { compatibleFormatsSrgb, false }, - }; - const size_t numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest); - - for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex) + switch (layout) { - const VkFormat* compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex].compatibleFormats; - const bool onlyNearest = colorImageFormatsToTest[compatibleFormatsIndex].onlyNearest; - for (size_t srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex) - { - params.src.image.format = compatibleFormats[srcFormatIndex]; - for (size_t dstFormatIndex = 0; compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++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 << "Blit image from src " << params.src.image.format << " to dst " << params.dst.image.format; - - params.filter = VK_FILTER_NEAREST; - testCaseGroup->addChild(new BlittingTestCase(testCtx, testName.str() + "_nearest", description.str(), params)); - - if (!onlyNearest) - { - params.filter = VK_FILTER_LINEAR; - testCaseGroup->addChild(new BlittingTestCase(testCtx, testName.str() + "_linear", description.str(), params)); - } - } - } + 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 ""; } } -} // anonymous +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}; -tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx) +const VkImageSubresourceLayers defaultSourceLayer = { - de::MovePtr copiesAndBlittingTests (new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests")); - - 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")); - - 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")); - - de::MovePtr resolveImageTests (new tcu::TestCaseGroup(testCtx, "resolve_image", "Resolve image")); - - 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; - }; + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + 0u, // uint32_t baseArrayLayer; + 1u, // uint32_t layerCount; +}; - 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, - }; +void addImageToImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind) +{ + tcu::TestContext& testCtx = group->getTestContext(); - // Copy image to image testcases. { - TestParams params; - params.src.image.imageType = VK_IMAGE_TYPE_2D; - 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 = @@ -3622,17 +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.imageType = VK_IMAGE_TYPE_2D; - params.src.image.format = VK_FORMAT_R8G8B8A8_UINT; - params.src.image.extent = defaultExtent; - params.dst.image.imageType = VK_IMAGE_TYPE_2D; - 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 = @@ -3650,17 +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.imageType = VK_IMAGE_TYPE_2D; - params.src.image.format = VK_FORMAT_R8G8B8A8_UINT; - params.src.image.extent = defaultExtent; - params.dst.image.imageType = VK_IMAGE_TYPE_2D; - 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 = @@ -3678,17 +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.imageType = VK_IMAGE_TYPE_2D; - params.src.image.format = VK_FORMAT_D32_SFLOAT; - params.src.image.extent = defaultExtent; - params.dst.image.imageType = VK_IMAGE_TYPE_2D; - 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 = @@ -3713,17 +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.imageType = VK_IMAGE_TYPE_2D; - params.src.image.format = VK_FORMAT_S8_UINT; - params.src.image.extent = defaultExtent; - params.dst.image.imageType = VK_IMAGE_TYPE_2D; - 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 = @@ -3748,115 +3652,809 @@ 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)); } +} - { - // Test Color formats. - { - 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; +struct CopyColorTestParams +{ + TestParams params; + const VkFormat* compatibleFormats; +}; - 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; - }; +void addImageToImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, TestParams params) +{ + const VkImageLayout copySrcLayouts[] = + { + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_IMAGE_LAYOUT_GENERAL + }; + const VkImageLayout copyDstLayouts[] = + { + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_GENERAL + }; - CopyRegion imageCopy; - imageCopy.imageCopy = testCopy; + for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx) + { + params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx]; - params.regions.push_back(imageCopy); - } + for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx) + { + params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx]; - addCopyImageTestsAllFormats(imgToImgAllFormatsTests.get(), testCtx, params); + 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)); } + } +} - // Test Depth and Stencil formats. - { - const std::string description ("Copy image to image with depth/stencil formats "); - const std::string testName ("depth_stencil"); +bool isAllowedImageToImageAllFormatsColorSrcFormatTests(CopyColorTestParams& testParams) +{ + bool result = true; - for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex) - { - TestParams params; + if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED) + { + DE_ASSERT(!dedicatedAllocationImageToImageFormatsToTestSet.empty()); - 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; - std::ostringstream oss; - oss << testName << "_" << getFormatCaseName(params.src.image.format) << "_" << getFormatCaseName(params.dst.image.format); + result = + de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.dst.image.format) || + de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.src.image.format); + } - const VkImageSubresourceLayers defaultDepthSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u }; - const VkImageSubresourceLayers defaultStencilSourceLayer = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u }; + return result; +} - 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}; +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 (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); - } - } + if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams)) + continue; - imgToImgAllFormatsTests->addChild(new CopyImageToImageTestCase(testCtx, oss.str(), description, 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); } - imageToImageTests->addChild(imgToImgSimpleTests.release()); - imageToImageTests->addChild(imgToImgAllFormatsTests.release()); - - // Copy image to buffer testcases. - { - TestParams params; - params.src.image.imageType = VK_IMAGE_TYPE_2D; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = defaultExtent; - params.dst.buffer.size = defaultSize * defaultSize; +} - const VkBufferImageCopy bufferImageCopy = - { - 0u, // VkDeviceSize bufferOffset; - 0u, // uint32_t bufferRowLength; +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, + + 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, + + VK_FORMAT_UNDEFINED +}; +const VkFormat compatibleFormats256Bit[] = +{ + VK_FORMAT_R64G64B64A64_UINT, + VK_FORMAT_R64G64B64A64_SINT, + VK_FORMAT_R64G64B64A64_SFLOAT, + + VK_FORMAT_UNDEFINED +}; + +const VkFormat* colorImageFormatsToTest[] = +{ + compatibleFormats8Bit, + compatibleFormats16Bit, + compatibleFormats24Bit, + compatibleFormats32Bit, + compatibleFormats48Bit, + compatibleFormats64Bit, + compatibleFormats96Bit, + compatibleFormats128Bit, + compatibleFormats192Bit, + compatibleFormats256Bit, +}; + +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 = + { + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; + {0, 0, 0}, // VkOffset3D srcOffset; + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + {i, defaultSize - i - defaultFourthSize, 0}, // VkOffset3D dstOffset; + {defaultFourthSize, defaultFourthSize, 1}, // VkExtent3D extent; + }; + + CopyRegion imageCopy; + imageCopy.imageCopy = testCopy; + + params.regions.push_back(imageCopy); + } + + if (allocationKind == ALLOCATION_KIND_DEDICATED) + { + const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest); + for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex) + dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]); + } + + 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) + { + params.src.image.format = compatibleFormats[srcFormatIndex]; + if (!isSupportedByFramework(params.src.image.format)) + continue; + + CopyColorTestParams testParams; + testParams.params = params; + testParams.compatibleFormats = compatibleFormats; + + 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[] = + { + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_IMAGE_LAYOUT_GENERAL + }; + const VkImageLayout copyDstLayouts[] = + { + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_GENERAL + }; + + 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) + { + 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; @@ -3867,15 +4465,17 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx) params.regions.push_back(copyRegion); - imageToBufferTests->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params)); + 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.dst.buffer.size = defaultSize * defaultSize; + 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 = { @@ -3891,15 +4491,17 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx) params.regions.push_back(copyRegion); - imageToBufferTests->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params)); + 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.dst.buffer.size = defaultSize * defaultSize; + 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; @@ -3928,16 +4530,22 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx) params.regions.push_back(region); } - imageToBufferTests->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params)); + 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(); - // Copy buffer to image testcases. { 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.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 = { @@ -3953,15 +4561,17 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx) params.regions.push_back(copyRegion); - bufferToImageTests->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params)); + 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.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; @@ -3980,15 +4590,17 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx) params.regions.push_back(region); } - bufferToImageTests->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params)); + 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.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 = { @@ -4004,14 +4616,19 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx) params.regions.push_back(copyRegion); - bufferToImageTests->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params)); + 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(); - // Copy buffer to buffer testcases. { TestParams params; params.src.buffer.size = defaultSize; params.dst.buffer.size = defaultSize; + params.allocationKind = allocationKind; const VkBufferCopy bufferCopy = { @@ -4024,13 +4641,14 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx) copyRegion.bufferCopy = bufferCopy; params.regions.push_back(copyRegion); - bufferToBufferTests->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params)); + 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 = { @@ -4043,7 +4661,7 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx) copyRegion.bufferCopy = bufferCopy; params.regions.push_back(copyRegion); - bufferToBufferTests->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params)); + group->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params)); } { @@ -4051,6 +4669,7 @@ tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx) 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++) @@ -4067,1052 +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); + } + + // 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 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 = + { + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; + { + {0, 0, 0}, + {defaultSize, defaultSize, 1} + }, // VkOffset3D srcOffsets[2]; + + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {defaultSize, defaultSize, 0}, + {0, 0, 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)); } - // Blitting testcases. + // Filter is VK_FILTER_LINEAR. { - const std::string description ("Blit without scaling (whole)"); - const std::string testName ("whole"); - - TestParams params; - params.src.image.imageType = VK_IMAGE_TYPE_2D; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = defaultExtent; - params.dst.image.imageType = VK_IMAGE_TYPE_2D; - params.dst.image.extent = defaultExtent; + params.filter = VK_FILTER_LINEAR; + const std::string description = "Linear filter"; - { - const VkImageBlit imageBlit = - { - defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; - { - {0, 0, 0}, - {defaultSize, defaultSize, 1} - }, // VkOffset3D srcOffsets[2]; + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "linear", description, params)); - defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; - { - {0, 0, 0}, - {defaultSize, defaultSize, 1} - } // VkOffset3D dstOffset[2]; - }; + 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)); - 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)"); + 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; - - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params)); + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; + { + {0, 0, 0}, + {defaultSize, defaultSize, 1} + }, // VkOffset3D srcOffsets[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)); + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {defaultSize, 0, 0}, + {0, defaultSize, 1} + } // VkOffset3D dstOffset[2]; + }; - 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)); - } + CopyRegion region; + region.imageBlit = imageBlit; + params.regions.push_back(region); + } - // Filter is VK_FILTER_LINEAR. - { - params.filter = VK_FILTER_LINEAR; + // Filter is VK_FILTER_NEAREST. + { + params.filter = VK_FILTER_NEAREST; + const std::string description = "Nearest filter"; - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params)); + 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)" + " (VK_FILTER_LINEAR)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", 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)" + " (VK_FILTER_LINEAR)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", 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. { - const std::string description ("Flipping x and y coordinates (whole)"); - const std::string testName ("mirror_xy"); + params.filter = VK_FILTER_LINEAR; + const std::string description = "Linear filter"; - TestParams params; - params.src.image.imageType = VK_IMAGE_TYPE_2D; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = defaultExtent; - params.dst.image.imageType = VK_IMAGE_TYPE_2D; - 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 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 = { - 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; - { - {defaultSize, defaultSize, 1}, - {0, 0, 0} - } // VkOffset3D dstOffset[2]; - }; + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {0, defaultSize, 0}, + {defaultSize, 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; + // Filter is VK_FILTER_NEAREST. + { + params.filter = VK_FILTER_NEAREST; + const std::string description = "Nearest filter"; - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params)); + 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; + // Filter is VK_FILTER_LINEAR. + { + params.filter = VK_FILTER_LINEAR; + const std::string description = "Linear filter"; - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params)); + 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)" + " (VK_FILTER_LINEAR)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", 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) + "_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)); - } + 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)); } +} - { - const std::string description ("Flipping x coordinates (whole)"); - const std::string testName ("mirror_x"); +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 = + { + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; + { + {0, 0, 0}, + {defaultHalfSize, defaultHalfSize, 1} + }, // VkOffset3D srcOffsets[2]; - TestParams params; - params.src.image.imageType = VK_IMAGE_TYPE_2D; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = defaultExtent; - params.dst.image.imageType = VK_IMAGE_TYPE_2D; - params.dst.image.extent = defaultExtent; + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {0, 0, 0}, + {defaultHalfSize, defaultHalfSize, 1} + } // VkOffset3D dstOffset[2]; + }; + + CopyRegion region; + region.imageBlit = imageBlit; + params.regions.push_back(region); + } + // Flipping y coordinates. + { + const VkImageBlit imageBlit = { - const VkImageBlit imageBlit = + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; { - defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; - { - {0, 0, 0}, - {defaultSize, defaultSize, 1} - }, // VkOffset3D srcOffsets[2]; + {defaultHalfSize, 0, 0}, + {defaultSize, defaultHalfSize, 1} + }, // VkOffset3D srcOffsets[2]; - defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; - { - {defaultSize, 0, 0}, - {0, defaultSize, 1} - } // VkOffset3D dstOffset[2]; - }; + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {defaultHalfSize, defaultHalfSize, 0}, + {defaultSize, 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. + // Flipping x coordinates. + { + const VkImageBlit imageBlit = { - params.filter = VK_FILTER_NEAREST; - - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params)); + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; + { + {0, defaultHalfSize, 0}, + {defaultHalfSize, defaultSize, 1} + }, // VkOffset3D srcOffsets[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)); + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {defaultHalfSize, defaultHalfSize, 0}, + {0, defaultSize, 1} + } // VkOffset3D dstOffset[2]; + }; - 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)); - } + CopyRegion region; + region.imageBlit = imageBlit; + params.regions.push_back(region); + } - // Filter is VK_FILTER_LINEAR. + // Flipping x and y coordinates. + { + const VkImageBlit imageBlit = { - 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)); + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; + { + {defaultHalfSize, defaultHalfSize, 0}, + {defaultSize, defaultSize, 1} + }, // VkOffset3D srcOffsets[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)); + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {defaultSize, defaultSize, 0}, + {defaultHalfSize, defaultHalfSize, 1} + } // VkOffset3D dstOffset[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)); - } + CopyRegion region; + region.imageBlit = imageBlit; + params.regions.push_back(region); } + // Filter is VK_FILTER_NEAREST. { - const std::string description ("Flipping Y coordinates (whole)"); - const std::string testName ("mirror_y"); + params.filter = VK_FILTER_NEAREST; + const std::string description = "Nearest filter"; - TestParams params; - params.src.image.imageType = VK_IMAGE_TYPE_2D; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = defaultExtent; - params.dst.image.imageType = VK_IMAGE_TYPE_2D; - params.dst.image.extent = defaultExtent; - - { - const VkImageBlit imageBlit = - { - defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; - { - {0, 0, 0}, - {defaultSize, defaultSize, 1} - }, // VkOffset3D srcOffsets[2]; + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "nearest", description, params)); - defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; - { - {0, defaultSize, 1}, - {defaultSize, 0, 0} - } // VkOffset3D dstOffset[2]; - }; + 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)); - 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)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params)); + } - // Filter is VK_FILTER_NEAREST. - { - params.filter = VK_FILTER_NEAREST; + // Filter is VK_FILTER_LINEAR. + { + params.filter = VK_FILTER_LINEAR; + const std::string description = "Linear filter"; - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params)); + 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)"); - 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) + "_linear", 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) + "_linear", descriptionOfRGBAToBGRA, params)); + } +} - // Filter is VK_FILTER_LINEAR. +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 = { - 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)); + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; + { + {0, 0, 0}, + {defaultSize, defaultSize, 1} + }, // VkOffset3D srcOffsets[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)); + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {0, 0, 0}, + {defaultHalfSize, defaultHalfSize, 1} + } // VkOffset3D dstOffset[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)); - } + CopyRegion region; + region.imageBlit = imageBlit; + params.regions.push_back(region); } + // Filter is VK_FILTER_NEAREST. { - const std::string description ("Mirroring subregions in image (no flip ,y flip ,x flip, xy flip)"); - const std::string testName ("mirror_subregions"); + params.filter = VK_FILTER_NEAREST; + const std::string description = "Nearest filter"; - TestParams params; - params.src.image.imageType = VK_IMAGE_TYPE_2D; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = defaultExtent; - params.dst.image.imageType = VK_IMAGE_TYPE_2D; - params.dst.image.extent = defaultExtent; + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "nearest", description, params)); - // No mirroring. - { - const VkImageBlit imageBlit = - { - defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; - { - {0, 0, 0}, - {defaultHalfSize, defaultHalfSize, 1} - }, // VkOffset3D srcOffsets[2]; + 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)); - defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; - { - {0, 0, 0}, - {defaultHalfSize, defaultHalfSize, 1} - } // VkOffset3D dstOffset[2]; - }; + 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)); + } - CopyRegion region; - region.imageBlit = imageBlit; - params.regions.push_back(region); - } + // Filter is VK_FILTER_LINEAR. + { + params.filter = VK_FILTER_LINEAR; + const std::string description = "Linear filter"; - // Flipping y coordinates. - { - const VkImageBlit imageBlit = - { - defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; - { - {defaultHalfSize, 0, 0}, - {defaultSize, defaultHalfSize, 1} - }, // VkOffset3D srcOffsets[2]; + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "linear", 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)" ); + group->addChild(new BlittingTestCase(testCtx, 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)"); + group->addChild(new BlittingTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params)); + } +} - // Flipping x coordinates. +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 = { - const VkImageBlit imageBlit = + defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; { - defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; - { - {0, defaultHalfSize, 0}, - {defaultHalfSize, defaultSize, 1} - }, // VkOffset3D srcOffsets[2]; + {0, 0, 0}, + {defaultHalfSize, defaultHalfSize, 1} + }, // VkOffset3D srcOffsets[2]; - defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; - { - {defaultHalfSize, defaultHalfSize, 0}, - {0, defaultSize, 1} - } // VkOffset3D dstOffset[2]; - }; + defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; + { + {0, 0, 0}, + {defaultSize, defaultSize, 1} + } // VkOffset3D dstOffset[2]; + }; - CopyRegion region; - region.imageBlit = imageBlit; - params.regions.push_back(region); - } + CopyRegion region; + region.imageBlit = imageBlit; + params.regions.push_back(region); + } - // Flipping x and y coordinates. - { - const VkImageBlit imageBlit = - { - defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; - { - {defaultHalfSize, defaultHalfSize, 0}, - {defaultSize, defaultSize, 1} - }, // VkOffset3D srcOffsets[2]; + // Filter is VK_FILTER_NEAREST. + { + params.filter = VK_FILTER_NEAREST; + const std::string description = "Nearest filter"; - defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; - { - {defaultSize, defaultSize, 0}, - {defaultHalfSize, defaultHalfSize, 1} - } // VkOffset3D dstOffset[2]; - }; + params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "nearest", description, params)); - CopyRegion region; - region.imageBlit = imageBlit; - params.regions.push_back(region); - } + 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)); - // Filter is VK_FILTER_NEAREST. - { - params.filter = VK_FILTER_NEAREST; + 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; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params)); + 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)"); - 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) + "_linear", 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) + "_linear", descriptionOfRGBAToBGRA, params)); + } +} - // Filter is VK_FILTER_LINEAR. +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 = { - params.filter = VK_FILTER_LINEAR; + 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); + } - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params)); + // Filter is VK_FILTER_NEAREST. + { + params.filter = VK_FILTER_NEAREST; + const std::string description = "Nearest filter"; - 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_R8G8B8A8_UNORM; + group->addChild(new BlittingTestCase(testCtx, "nearest", description, 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)); - } + 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.imageType = VK_IMAGE_TYPE_2D; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = defaultExtent; - params.dst.image.imageType = VK_IMAGE_TYPE_2D; - 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 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}, - {defaultSize, defaultSize, 1} + {defaultSize - defaultFourthSize - i, defaultSize - defaultFourthSize - i, 0}, + {defaultSize - i, defaultSize - i, 1} }, // VkOffset3D srcOffsets[2]; defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; { - {0, 0, 0}, - {defaultHalfSize, defaultHalfSize, 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; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params)); + 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_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_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)); - // Filter is VK_FILTER_LINEAR. - { - params.filter = VK_FILTER_LINEAR; + 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; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params)); + 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)" + " (VK_FILTER_LINEAR)"); - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", 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) + "_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)); - } + 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)); } +} - { - const std::string description ("Blit with scaling (whole, dst extent bigger)"); - const std::string testName ("scaling_whole2"); +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); +} - TestParams params; - params.src.image.imageType = VK_IMAGE_TYPE_2D; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = defaultHalfExtent; - params.dst.image.imageType = VK_IMAGE_TYPE_2D; - params.dst.image.extent = defaultExtent; +struct BlitColorTestParams +{ + TestParams params; + const VkFormat* compatibleFormats; + bool onlyNearest; +}; - { - const VkImageBlit imageBlit = - { - defaultSourceLayer, // VkImageSubresourceLayers srcSubresource; - { - {0, 0, 0}, - {defaultHalfSize, defaultHalfSize, 1} - }, // VkOffset3D srcOffsets[2]; +bool isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams& testParams) +{ + bool result = true; - defaultSourceLayer, // VkImageSubresourceLayers dstSubresource; - { - {0, 0, 0}, - {defaultSize, defaultSize, 1} - } // VkOffset3D dstOffset[2]; - }; + if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED) + { + DE_ASSERT(!dedicatedAllocationBlittingFormatsToTestSet.empty()); - CopyRegion region; - region.imageBlit = imageBlit; - params.regions.push_back(region); - } + result = + de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.dst.image.format) || + de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.src.image.format); + } - // Filter is VK_FILTER_NEAREST. - { - params.filter = VK_FILTER_NEAREST; + 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; - params.src.image.imageType = VK_IMAGE_TYPE_2D; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = defaultExtent; - params.dst.image.imageType = VK_IMAGE_TYPE_2D; - params.dst.image.extent = defaultExtent; + testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex]; + if (!isSupportedByFramework(testParams.params.dst.image.format)) + continue; - { - 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]; - }; + if (!isAllowedBlittingAllFormatsColorSrcFormatTests(testParams)) + continue; - CopyRegion region; - region.imageBlit = imageBlit; - params.regions.push_back(region); - } + const std::string description = "Blit destination format " + getFormatCaseName(testParams.params.dst.image.format); + addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams); + } +} - // Filter is VK_FILTER_NEAREST. - { - params.filter = VK_FILTER_NEAREST; +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 +}; - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params)); +const VkFormat dedicatedAllocationBlittingFormatsToTest[] = +{ + // compatibleFormatsUInts + VK_FORMAT_R8_UINT, + VK_FORMAT_R64G64B64A64_UINT, - 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)); + // compatibleFormatsSInts + VK_FORMAT_R8_SINT, + VK_FORMAT_R64G64B64A64_SINT, - 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)); - } + // compatibleFormatsFloats + VK_FORMAT_R4G4_UNORM_PACK8, + VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, - // Filter is VK_FILTER_LINEAR. - { - params.filter = VK_FILTER_LINEAR; + // compatibleFormatsSrgb + VK_FORMAT_R8_SRGB, + VK_FORMAT_A8B8G8R8_SRGB_PACK32, +}; - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", 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 }, + }; - 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)); + const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit); - 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)); - } - } + 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; + CopyRegion region; + for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++) { - const std::string description ("Blit without scaling (partial)"); - const std::string testName ("without_scaling_partial"); - - TestParams params; - params.src.image.imageType = VK_IMAGE_TYPE_2D; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = defaultExtent; - params.dst.image.imageType = VK_IMAGE_TYPE_2D; - params.dst.image.extent = defaultExtent; + 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]; + }; + region.imageBlit = imageBlit; + params.regions.push_back(region); + } + for (int i = 0; i < defaultSize; i += defaultFourthSize) + { + 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); + } - // Filter is VK_FILTER_NEAREST. - { - params.filter = VK_FILTER_NEAREST; + if (allocationKind == ALLOCATION_KIND_DEDICATED) + { + const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest); + for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex) + dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]); + } - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params)); + 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.src.image.format = compatibleFormats[srcFormatIndex]; + if (!isSupportedByFramework(params.src.image.format)) + continue; - 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)); + BlitColorTestParams testParams; + testParams.params = params; + testParams.compatibleFormats = compatibleFormats; + testParams.onlyNearest = onlyNearest; - 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 std::string description = "Blit source format " + getFormatCaseName(params.src.image.format); + addTestGroup(group, getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams); } + } +} - // Filter is VK_FILTER_LINEAR. - { - params.filter = VK_FILTER_LINEAR; +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 + }; + + for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx) + { + params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx]; - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params)); + for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx) + { + params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx]; + params.filter = VK_FILTER_NEAREST; - 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)); + 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_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.imageType = VK_IMAGE_TYPE_2D; - params.src.image.extent = defaultExtent; - params.dst.image.imageType = VK_IMAGE_TYPE_2D; - 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) { - for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex) + 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)) { - TestParams params; - - params.src.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.imageType = VK_IMAGE_TYPE_2D; - 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); } } + + 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); } - blittingImageTests->addChild(blitImgSimpleTests.release()); - blittingImageTests->addChild(blitImgAllFormatsTests.release()); +} - // 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.imageType = VK_IMAGE_TYPE_2D; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = resolveExtent; - params.dst.image.imageType = VK_IMAGE_TYPE_2D; - 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.imageType = VK_IMAGE_TYPE_2D; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = resolveExtent; - params.dst.image.imageType = VK_IMAGE_TYPE_2D; - 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) - { - params.samples = samples[samplesIndex]; - std::ostringstream caseName; - caseName << testName << "_" << getSampleCountCaseName(samples[samplesIndex]); - resolveImageTests->addChild(new ResolveImageToImageTestCase(testCtx, caseName.str(), description, params)); - } } + 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)); + } +} - TestParams params; - params.src.image.imageType = VK_IMAGE_TYPE_2D; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = resolveExtent; - params.dst.image.imageType = VK_IMAGE_TYPE_2D; - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.dst.image.extent = resolveExtent; +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 = + { + VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; + 0u, // uint32_t mipLevel; + 0u, // 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_MS_IMAGE)); + } +} - for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex) +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 = { - 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; + layerNdx, // 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 ("whole_copy_before_resolving"); - - TestParams params; - params.src.image.imageType = VK_IMAGE_TYPE_2D; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = defaultExtent; - params.dst.image.imageType = VK_IMAGE_TYPE_2D; - params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.dst.image.extent = defaultExtent; + 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 = { - const VkImageSubresourceLayers sourceLayer = - { - VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; - 0u, // uint32_t mipLevel; - 0u, // uint32_t baseArrayLayer; - 1u // uint32_t layerCount; - }; + 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 VkImageResolve testResolve = - { - sourceLayer, // VkImageSubresourceLayers srcSubresource; - {0, 0, 0}, // VkOffset3D srcOffset; - sourceLayer, // VkImageSubresourceLayers dstSubresource; - {0, 0, 0}, // VkOffset3D dstOffset; - defaultExtent, // VkExtent3D extent; - }; + const VkExtent3D imageExtents[] = + { + { resolveExtent.width + 10, resolveExtent.height, resolveExtent.depth }, + { resolveExtent.width, resolveExtent.height * 2, resolveExtent.depth }, + { resolveExtent.width, resolveExtent.height, resolveExtent.depth + 10 } + }; - CopyRegion imageResolve; - imageResolve.imageResolve = testResolve; - params.regions.push_back(imageResolve); + 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, COPY_MS_IMAGE_TO_MS_IMAGE)); + 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)); } } +} - { - const std::string description ("Resolve from image to image"); - const std::string testName ("whole_array_image"); +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); +} - TestParams params; - params.src.image.imageType = VK_IMAGE_TYPE_2D; - params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM; - params.src.image.extent = defaultExtent; - 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; +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); +} - 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; - }; +void addCoreCopiesAndBlittingTests (tcu::TestCaseGroup* group) +{ + addCopiesAndBlittingTests(group, ALLOCATION_KIND_SUBALLOCATED); +} - const VkImageResolve testResolve = - { - sourceLayer, // VkImageSubresourceLayers srcSubresource; - {0, 0, 0}, // VkOffset3D srcOffset; - sourceLayer, // VkImageSubresourceLayers dstSubresource; - {0, 0, 0}, // VkOffset3D dstOffset; - defaultExtent, // VkExtent3D extent; - }; +void addDedicatedAllocationCopiesAndBlittingTests (tcu::TestCaseGroup* group) +{ + addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED); +} - CopyRegion imageResolve; - imageResolve.imageResolve = testResolve; - params.regions.push_back(imageResolve); - } +} // anonymous - 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, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE)); - } - } +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(); }