+ params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
+
+ const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
+ getImageLayoutCaseName(params.dst.image.operationLayout);
+ const std::string description = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
+ " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
+ group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
+ }
+ }
+}
+
+void addImageToImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+ const VkFormat depthAndStencilFormats[] =
+ {
+ VK_FORMAT_D16_UNORM,
+ VK_FORMAT_X8_D24_UNORM_PACK32,
+ VK_FORMAT_D32_SFLOAT,
+ VK_FORMAT_S8_UINT,
+ VK_FORMAT_D16_UNORM_S8_UINT,
+ VK_FORMAT_D24_UNORM_S8_UINT,
+ VK_FORMAT_D32_SFLOAT_S8_UINT,
+ };
+
+ for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
+ {
+ TestParams params;
+ params.src.image.imageType = VK_IMAGE_TYPE_2D;
+ params.dst.image.imageType = VK_IMAGE_TYPE_2D;
+ params.src.image.extent = defaultExtent;
+ params.dst.image.extent = defaultExtent;
+ params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
+ params.dst.image.format = params.src.image.format;
+ params.allocationKind = allocationKind;
+
+ const VkImageSubresourceLayers defaultDepthSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
+ const VkImageSubresourceLayers defaultStencilSourceLayer = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
+
+ for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
+ {
+ CopyRegion copyRegion;
+ const VkOffset3D srcOffset = {0, 0, 0};
+ const VkOffset3D dstOffset = {i, defaultSize - i - defaultFourthSize, 0};
+ const VkExtent3D extent = {defaultFourthSize, defaultFourthSize, 1};
+
+ if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order))
+ {
+ const VkImageCopy testCopy =
+ {
+ defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
+ srcOffset, // VkOffset3D srcOffset;
+ defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
+ dstOffset, // VkOffset3D dstOffset;
+ extent, // VkExtent3D extent;
+ };
+
+ copyRegion.imageCopy = testCopy;
+ params.regions.push_back(copyRegion);
+ }
+ if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order))
+ {
+ const VkImageCopy testCopy =
+ {
+ defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
+ srcOffset, // VkOffset3D srcOffset;
+ defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
+ dstOffset, // VkOffset3D dstOffset;
+ extent, // VkExtent3D extent;
+ };
+
+ copyRegion.imageCopy = testCopy;
+ params.regions.push_back(copyRegion);
+ }
+ }
+
+ const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
+ const std::string description = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
+ addTestGroup(group, testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
+ }
+}
+
+void addImageToImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+ addTestGroup(group, "color", "Copy image to image with color formats", addImageToImageAllFormatsColorTests, allocationKind);
+ addTestGroup(group, "depth_stencil", "Copy image to image with depth/stencil formats", addImageToImageAllFormatsDepthStencilTests, allocationKind);
+}
+
+void addImageToImage3dImagesTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+ tcu::TestContext& testCtx = group->getTestContext();
+
+ {
+ TestParams params3DTo2D;
+ const deUint32 slicesLayers = 16u;
+ params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D;
+ params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
+ params3DTo2D.src.image.extent = defaultHalfExtent;
+ params3DTo2D.src.image.extent.depth = slicesLayers;
+ params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+ params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D;
+ params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
+ params3DTo2D.dst.image.extent = defaultHalfExtent;
+ params3DTo2D.dst.image.extent.depth = slicesLayers;
+ params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ params3DTo2D.allocationKind = allocationKind;
+
+ for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
+ {
+ const VkImageSubresourceLayers sourceLayer =
+ {
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
+ 0u, // uint32_t mipLevel;
+ 0u, // uint32_t baseArrayLayer;
+ 1u // uint32_t layerCount;
+ };
+
+ const VkImageSubresourceLayers destinationLayer =
+ {
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
+ 0u, // uint32_t mipLevel;
+ slicesLayersNdx, // uint32_t baseArrayLayer;
+ 1u // uint32_t layerCount;
+ };
+
+ const VkImageCopy testCopy =
+ {
+ sourceLayer, // VkImageSubresourceLayers srcSubresource;
+ {0, 0, (deInt32)slicesLayersNdx}, // VkOffset3D srcOffset;
+ destinationLayer, // VkImageSubresourceLayers dstSubresource;
+ {0, 0, 0}, // VkOffset3D dstOffset;
+ defaultHalfExtent, // VkExtent3D extent;
+ };
+
+ CopyRegion imageCopy;
+ imageCopy.imageCopy = testCopy;
+
+ params3DTo2D.regions.push_back(imageCopy);
+ }
+ group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_by_slices", "copy 2d layers to 3d slices one by one", params3DTo2D));
+ }
+
+ {
+ TestParams params2DTo3D;
+ const deUint32 slicesLayers = 16u;
+ params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D;
+ params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
+ params2DTo3D.src.image.extent = defaultHalfExtent;
+ params2DTo3D.src.image.extent.depth = slicesLayers;
+ params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+ params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D;
+ params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
+ params2DTo3D.dst.image.extent = defaultHalfExtent;
+ params2DTo3D.dst.image.extent.depth = slicesLayers;
+ params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ params2DTo3D.allocationKind = allocationKind;
+
+ for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
+ {
+ const VkImageSubresourceLayers sourceLayer =
+ {
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
+ 0u, // uint32_t mipLevel;
+ slicesLayersNdx, // uint32_t baseArrayLayer;
+ 1u // uint32_t layerCount;
+ };
+
+ const VkImageSubresourceLayers destinationLayer =
+ {
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
+ 0u, // uint32_t mipLevel;
+ 0u, // uint32_t baseArrayLayer;
+ 1u // uint32_t layerCount;
+ };
+
+ const VkImageCopy testCopy =
+ {
+ sourceLayer, // VkImageSubresourceLayers srcSubresource;
+ {0, 0, 0}, // VkOffset3D srcOffset;
+ destinationLayer, // VkImageSubresourceLayers dstSubresource;
+ {0, 0, (deInt32)slicesLayersNdx}, // VkOffset3D dstOffset;
+ defaultHalfExtent, // VkExtent3D extent;
+ };
+
+ CopyRegion imageCopy;
+ imageCopy.imageCopy = testCopy;
+
+ params2DTo3D.regions.push_back(imageCopy);
+ }
+
+ group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_by_layers", "copy 3d slices to 2d layers one by one", params2DTo3D));
+ }
+
+ {
+ TestParams params3DTo2D;
+ const deUint32 slicesLayers = 16u;
+ params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D;
+ params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
+ params3DTo2D.src.image.extent = defaultHalfExtent;
+ params3DTo2D.src.image.extent.depth = slicesLayers;
+ params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+ params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D;
+ params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
+ params3DTo2D.dst.image.extent = defaultHalfExtent;
+ params3DTo2D.dst.image.extent.depth = slicesLayers;
+ params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ params3DTo2D.allocationKind = allocationKind;
+
+ {
+ const VkImageSubresourceLayers sourceLayer =
+ {
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
+ 0u, // uint32_t mipLevel;
+ 0u, // uint32_t baseArrayLayer;
+ 1u // uint32_t layerCount;
+ };
+
+ const VkImageSubresourceLayers destinationLayer =
+ {
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
+ 0u, // uint32_t mipLevel;
+ 0, // uint32_t baseArrayLayer;
+ slicesLayers // uint32_t layerCount;
+ };
+
+ const VkImageCopy testCopy =
+ {
+ sourceLayer, // VkImageSubresourceLayers srcSubresource;
+ {0, 0, 0}, // VkOffset3D srcOffset;
+ destinationLayer, // VkImageSubresourceLayers dstSubresource;
+ {0, 0, 0}, // VkOffset3D dstOffset;
+ params3DTo2D.src.image.extent // VkExtent3D extent;
+ };
+
+ CopyRegion imageCopy;
+ imageCopy.imageCopy = testCopy;
+
+ params3DTo2D.regions.push_back(imageCopy);
+ }
+ group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_whole", "copy 3d slices to 2d layers all at once", params3DTo2D));
+ }
+
+ {
+ TestParams params2DTo3D;
+ const deUint32 slicesLayers = 16u;
+ params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D;
+ params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
+ params2DTo3D.src.image.extent = defaultHalfExtent;
+ params2DTo3D.src.image.extent.depth = slicesLayers;
+ params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+ params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D;
+ params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
+ params2DTo3D.dst.image.extent = defaultHalfExtent;
+ params2DTo3D.dst.image.extent.depth = slicesLayers;
+ params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ params2DTo3D.allocationKind = allocationKind;
+
+ {
+ const VkImageSubresourceLayers sourceLayer =
+ {
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
+ 0u, // uint32_t mipLevel;
+ 0u, // uint32_t baseArrayLayer;
+ slicesLayers // uint32_t layerCount;
+ };
+
+ const VkImageSubresourceLayers destinationLayer =
+ {
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
+ 0u, // uint32_t mipLevel;
+ 0u, // uint32_t baseArrayLayer;
+ 1u // uint32_t layerCount;
+ };
+
+ const VkImageCopy testCopy =
+ {
+ sourceLayer, // VkImageSubresourceLayers srcSubresource;
+ {0, 0, 0}, // VkOffset3D srcOffset;
+ destinationLayer, // VkImageSubresourceLayers dstSubresource;
+ {0, 0, 0}, // VkOffset3D dstOffset;
+ params2DTo3D.dst.image.extent, // VkExtent3D extent;
+ };
+
+ CopyRegion imageCopy;
+ imageCopy.imageCopy = testCopy;
+
+ params2DTo3D.regions.push_back(imageCopy);
+ }
+
+ group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_whole", "copy 2d layers to 3d slices all at once", params2DTo3D));
+ }
+
+ {
+ TestParams params3DTo2D;
+ const deUint32 slicesLayers = 16u;
+ params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D;
+ params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
+ params3DTo2D.src.image.extent = defaultHalfExtent;
+ params3DTo2D.src.image.extent.depth = slicesLayers;
+ params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+ params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D;
+ params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
+ params3DTo2D.dst.image.extent = defaultHalfExtent;
+ params3DTo2D.dst.image.extent.depth = slicesLayers;
+ params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ params3DTo2D.allocationKind = allocationKind;
+
+ const deUint32 regionWidth = defaultHalfExtent.width / slicesLayers -1;
+ const deUint32 regionHeight = defaultHalfExtent.height / slicesLayers -1 ;
+
+ for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
+ {
+ const VkImageSubresourceLayers sourceLayer =
+ {
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
+ 0u, // uint32_t mipLevel;
+ 0u, // uint32_t baseArrayLayer;
+ 1u // uint32_t layerCount;
+ };
+
+ const VkImageSubresourceLayers destinationLayer =
+ {
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
+ 0u, // uint32_t mipLevel;
+ slicesLayersNdx, // uint32_t baseArrayLayer;
+ 1u // uint32_t layerCount;
+ };
+
+
+ const VkImageCopy testCopy =
+ {
+ sourceLayer, // VkImageSubresourceLayers srcSubresource;
+ {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)slicesLayersNdx}, // VkOffset3D srcOffset;
+ destinationLayer, // VkImageSubresourceLayers dstSubresource;
+ {(deInt32)(regionWidth*slicesLayersNdx), 0, 0}, // VkOffset3D dstOffset;
+ {
+ (defaultHalfExtent.width - regionWidth*slicesLayersNdx),
+ (defaultHalfExtent.height - regionHeight*slicesLayersNdx),
+ 1
+ } // VkExtent3D extent;
+ };
+
+ CopyRegion imageCopy;
+ imageCopy.imageCopy = testCopy;
+ params3DTo2D.regions.push_back(imageCopy);
+ }
+ group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_regions", "copy 3d slices regions to 2d layers", params3DTo2D));
+ }
+
+ {
+ TestParams params2DTo3D;
+ const deUint32 slicesLayers = 16u;
+ params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D;
+ params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
+ params2DTo3D.src.image.extent = defaultHalfExtent;
+ params2DTo3D.src.image.extent.depth = slicesLayers;
+ params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+ params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D;
+ params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
+ params2DTo3D.dst.image.extent = defaultHalfExtent;
+ params2DTo3D.dst.image.extent.depth = slicesLayers;
+ params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ params2DTo3D.allocationKind = allocationKind;
+
+ const deUint32 regionWidth = defaultHalfExtent.width / slicesLayers -1;
+ const deUint32 regionHeight = defaultHalfExtent.height / slicesLayers -1 ;
+
+ for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
+ {
+ const VkImageSubresourceLayers sourceLayer =
+ {
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
+ 0u, // uint32_t mipLevel;
+ slicesLayersNdx, // uint32_t baseArrayLayer;
+ 1u // uint32_t layerCount;
+ };
+
+ const VkImageSubresourceLayers destinationLayer =
+ {
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
+ 0u, // uint32_t mipLevel;
+ 0u, // uint32_t baseArrayLayer;
+ 1u // uint32_t layerCount;
+ };
+
+ const VkImageCopy testCopy =
+ {
+ sourceLayer, // VkImageSubresourceLayers srcSubresource;
+ {(deInt32)(regionWidth*slicesLayersNdx), 0, 0}, // VkOffset3D srcOffset;
+ destinationLayer, // VkImageSubresourceLayers dstSubresource;
+ {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)(slicesLayersNdx)}, // VkOffset3D dstOffset;
+ {
+ defaultHalfExtent.width - regionWidth*slicesLayersNdx,
+ defaultHalfExtent.height - regionHeight*slicesLayersNdx,
+ 1
+ } // VkExtent3D extent;
+ };
+
+ CopyRegion imageCopy;
+ imageCopy.imageCopy = testCopy;
+
+ params2DTo3D.regions.push_back(imageCopy);
+ }
+
+ group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_regions", "copy 2d layers regions to 3d slices", params2DTo3D));
+ }
+}
+
+void addImageToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+ addTestGroup(group, "simple_tests", "Copy from image to image simple tests", addImageToImageSimpleTests, allocationKind);
+ addTestGroup(group, "all_formats", "Copy from image to image with all compatible formats", addImageToImageAllFormatsTests, allocationKind);
+ addTestGroup(group, "3d_images", "Coping operations on 3d images", addImageToImage3dImagesTests, allocationKind);
+}
+
+void addImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+ tcu::TestContext& testCtx = group->getTestContext();
+
+ {
+ TestParams params;
+ params.src.image.imageType = VK_IMAGE_TYPE_2D;
+ params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+ params.src.image.extent = defaultExtent;
+ params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+ params.dst.buffer.size = defaultSize * defaultSize;
+ params.allocationKind = allocationKind;
+
+ const VkBufferImageCopy bufferImageCopy =
+ {
+ 0u, // VkDeviceSize bufferOffset;
+ 0u, // uint32_t bufferRowLength;
+ 0u, // uint32_t bufferImageHeight;
+ defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
+ {0, 0, 0}, // VkOffset3D imageOffset;
+ defaultExtent // VkExtent3D imageExtent;
+ };
+ CopyRegion copyRegion;
+ copyRegion.bufferImageCopy = bufferImageCopy;
+
+ params.regions.push_back(copyRegion);
+
+ group->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params));
+ }
+
+ {
+ TestParams params;
+ params.src.image.imageType = VK_IMAGE_TYPE_2D;
+ params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+ params.src.image.extent = defaultExtent;
+ params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+ params.dst.buffer.size = defaultSize * defaultSize;
+ params.allocationKind = allocationKind;
+
+ const VkBufferImageCopy bufferImageCopy =
+ {
+ defaultSize * defaultHalfSize, // VkDeviceSize bufferOffset;
+ 0u, // uint32_t bufferRowLength;
+ 0u, // uint32_t bufferImageHeight;
+ defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
+ {defaultFourthSize, defaultFourthSize, 0}, // VkOffset3D imageOffset;
+ defaultHalfExtent // VkExtent3D imageExtent;
+ };
+ CopyRegion copyRegion;
+ copyRegion.bufferImageCopy = bufferImageCopy;
+
+ params.regions.push_back(copyRegion);
+
+ group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params));
+ }
+
+ {
+ TestParams params;
+ params.src.image.imageType = VK_IMAGE_TYPE_2D;
+ params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+ params.src.image.extent = defaultExtent;
+ params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+ params.dst.buffer.size = defaultSize * defaultSize;
+ params.allocationKind = allocationKind;
+
+ const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
+ const VkDeviceSize bufferSize = pixelSize * params.dst.buffer.size;
+ const VkDeviceSize offsetSize = pixelSize * defaultFourthSize * defaultFourthSize;
+ deUint32 divisor = 1;
+ for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor)
+ {
+ const deUint32 bufferRowLength = defaultFourthSize;
+ const deUint32 bufferImageHeight = defaultFourthSize;
+ const VkExtent3D imageExtent = {defaultFourthSize / divisor, defaultFourthSize, 1};
+ DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width);
+ DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height);
+ DE_ASSERT(imageExtent.width * imageExtent.height *imageExtent.depth <= offsetSize);
+
+ CopyRegion region;
+ const VkBufferImageCopy bufferImageCopy =
+ {
+ offset, // VkDeviceSize bufferOffset;
+ bufferRowLength, // uint32_t bufferRowLength;
+ bufferImageHeight, // uint32_t bufferImageHeight;
+ defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
+ {0, 0, 0}, // VkOffset3D imageOffset;
+ imageExtent // VkExtent3D imageExtent;
+ };
+ region.bufferImageCopy = bufferImageCopy;
+ params.regions.push_back(region);
+ }
+
+ group->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params));
+ }
+}
+
+void addBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+ tcu::TestContext& testCtx = group->getTestContext();
+
+ {
+ TestParams params;
+ params.src.buffer.size = defaultSize * defaultSize;
+ params.dst.image.imageType = VK_IMAGE_TYPE_2D;
+ params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
+ params.dst.image.extent = defaultExtent;
+ params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ params.allocationKind = allocationKind;
+
+ const VkBufferImageCopy bufferImageCopy =
+ {
+ 0u, // VkDeviceSize bufferOffset;
+ 0u, // uint32_t bufferRowLength;
+ 0u, // uint32_t bufferImageHeight;
+ defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
+ {0, 0, 0}, // VkOffset3D imageOffset;
+ defaultExtent // VkExtent3D imageExtent;
+ };
+ CopyRegion copyRegion;
+ copyRegion.bufferImageCopy = bufferImageCopy;
+
+ params.regions.push_back(copyRegion);
+
+ group->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params));
+ }
+
+ {
+ TestParams params;
+ params.src.buffer.size = defaultSize * defaultSize;
+ params.dst.image.imageType = VK_IMAGE_TYPE_2D;
+ params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+ params.dst.image.extent = defaultExtent;
+ params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ params.allocationKind = allocationKind;
+
+ CopyRegion region;
+ deUint32 divisor = 1;
+ for (int offset = 0; (offset + defaultFourthSize / divisor < defaultSize) && (defaultFourthSize > divisor); offset += defaultFourthSize / divisor++)
+ {
+ const VkBufferImageCopy bufferImageCopy =
+ {
+ 0u, // VkDeviceSize bufferOffset;
+ 0u, // uint32_t bufferRowLength;
+ 0u, // uint32_t bufferImageHeight;
+ defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
+ {offset, defaultHalfSize, 0}, // VkOffset3D imageOffset;
+ {defaultFourthSize / divisor, defaultFourthSize / divisor, 1} // VkExtent3D imageExtent;
+ };
+ region.bufferImageCopy = bufferImageCopy;
+ params.regions.push_back(region);
+ }
+
+ group->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params));
+ }
+
+ {
+ TestParams params;
+ params.src.buffer.size = defaultSize * defaultSize;
+ params.dst.image.imageType = VK_IMAGE_TYPE_2D;
+ params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
+ params.dst.image.extent = defaultExtent;
+ params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ params.allocationKind = allocationKind;
+
+ const VkBufferImageCopy bufferImageCopy =
+ {
+ defaultFourthSize, // VkDeviceSize bufferOffset;
+ defaultHalfSize + defaultFourthSize, // uint32_t bufferRowLength;
+ defaultHalfSize + defaultFourthSize, // uint32_t bufferImageHeight;
+ defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
+ {defaultFourthSize, defaultFourthSize, 0}, // VkOffset3D imageOffset;
+ defaultHalfExtent // VkExtent3D imageExtent;
+ };
+ CopyRegion copyRegion;
+ copyRegion.bufferImageCopy = bufferImageCopy;
+
+ params.regions.push_back(copyRegion);
+
+ group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params));
+ }
+}
+
+void addBufferToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+ tcu::TestContext& testCtx = group->getTestContext();
+
+ {
+ TestParams params;
+ params.src.buffer.size = defaultSize;
+ params.dst.buffer.size = defaultSize;
+ params.allocationKind = allocationKind;
+
+ const VkBufferCopy bufferCopy =
+ {
+ 0u, // VkDeviceSize srcOffset;
+ 0u, // VkDeviceSize dstOffset;
+ defaultSize, // VkDeviceSize size;
+ };
+
+ CopyRegion copyRegion;
+ copyRegion.bufferCopy = bufferCopy;
+ params.regions.push_back(copyRegion);
+
+ group->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params));
+ }
+
+ {
+ TestParams params;
+ params.src.buffer.size = defaultFourthSize;
+ params.dst.buffer.size = defaultFourthSize;
+ params.allocationKind = allocationKind;
+
+ const VkBufferCopy bufferCopy =
+ {
+ 12u, // VkDeviceSize srcOffset;
+ 4u, // VkDeviceSize dstOffset;
+ 1u, // VkDeviceSize size;
+ };
+
+ CopyRegion copyRegion;
+ copyRegion.bufferCopy = bufferCopy;
+ params.regions.push_back(copyRegion);
+
+ group->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params));
+ }
+
+ {
+ const deUint32 size = 16;
+ TestParams params;
+ params.src.buffer.size = size;
+ params.dst.buffer.size = size * (size + 1);
+ params.allocationKind = allocationKind;
+
+ // Copy region with size 1..size
+ for (unsigned int i = 1; i <= size; i++)
+ {
+ const VkBufferCopy bufferCopy =