// Resolve image to image.
-enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION, COPY_MS_IMAGE_TO_MS_IMAGE, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE};
+enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION,
+ COPY_MS_IMAGE_TO_MS_IMAGE,
+ COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE,
+ COPY_MS_IMAGE_LAYER_TO_MS_IMAGE,
+ COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION};
class ResolveImageToImage : public CopiesAndBlittingTestInstance
{
public:
VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT // VkImageUsageFlags usage;
| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
+ | VK_IMAGE_USAGE_TRANSFER_DST_BIT
| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1u, // deUint32 queueFamilyIndexCount;
switch (m_options)
{
+ case COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION:
case COPY_MS_IMAGE_TO_MS_IMAGE:
{
colorImageParams.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
break;
}
-
+ case COPY_MS_IMAGE_LAYER_TO_MS_IMAGE:
case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
{
colorImageParams.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
}
- // Barriers for copying image to buffer
- VkImageMemoryBarrier srcImageBarrier =
+ // Barriers for image clearing.
+ std::vector<VkImageMemoryBarrier> srcImageBarriers;
+
+ const VkImageMemoryBarrier m_multisampledImageBarrier =
{
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
DE_NULL, // const void* pNext;
0u, // VkAccessFlags srcAccessMask;
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
- VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
m_multisampledImage.get(), // VkImage image;
{ // VkImageSubresourceRange subresourceRange;
- VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
- 0u, // deUint32 baseMipLevel;
- 1u, // deUint32 mipLevels;
- 0u, // deUint32 baseArraySlice;
- getArraySize(m_params.src.image) // deUint32 arraySize;
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
+ 0u, // deUint32 baseMipLevel;
+ 1u, // deUint32 mipLevels;
+ 0u, // deUint32 baseArraySlice;
+ getArraySize(m_params.src.image) // deUint32 arraySize;
+ }
+ };
+ const VkImageMemoryBarrier m_multisampledCopyImageBarrier =
+ {
+ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkAccessFlags srcAccessMask;
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
+ VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
+ VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
+ VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
+ m_multisampledCopyImage.get(), // VkImage image;
+ { // VkImageSubresourceRange subresourceRange;
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
+ 0u, // deUint32 baseMipLevel;
+ 1u, // deUint32 mipLevels;
+ 0u, // deUint32 baseArraySlice;
+ getArraySize(m_params.dst.image) // deUint32 arraySize;
}
};
+ // Only use one barrier if no options have been given.
+ if (m_options != DE_NULL)
+ {
+ srcImageBarriers.push_back(m_multisampledImageBarrier);
+ srcImageBarriers.push_back(m_multisampledCopyImageBarrier);
+
+ }
+ else
+ {
+ srcImageBarriers.push_back(m_multisampledImageBarrier);
+ }
+
// Create render pass.
{
const VkAttachmentDescription attachmentDescriptions[1] =
VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
- VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
- VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout initialLayout;
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL // VkImageLayout finalLayout;
},
};
Move<VkFramebuffer> framebuffer;
Move<VkImageView> sourceAttachmentView;
+ uint32_t baseArrayLayer = m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE ? 2u : 0u;
+
// Create color attachment view.
{
const VkImageViewCreateInfo colorAttachmentViewParams =
{
- VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- 0u, // VkImageViewCreateFlags flags;
- *m_multisampledImage, // VkImage image;
- VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
- m_params.src.image.format, // VkFormat format;
- componentMappingRGBA, // VkComponentMapping components;
- { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
+ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkImageViewCreateFlags flags;
+ *m_multisampledImage, // VkImage image;
+ VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
+ m_params.src.image.format, // VkFormat format;
+ componentMappingRGBA, // VkComponentMapping components;
+ { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, baseArrayLayer, 1u } // VkImageSubresourceRange subresourceRange;
};
sourceAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
}
// Create command buffer
{
beginCommandBuffer(vk, *m_cmdBuffer, 0u);
- 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);
+
+ // Change the image layouts.
+ 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, uint32_t(srcImageBarriers.size()), srcImageBarriers.data());
+
+ if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
+ {
+ // Clear the 'm_multisampledImage'.
+ {
+ const VkClearColorValue clearValue = {{0.0f, 0.0f, 0.0f, 1.0f}};
+ const auto clearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_params.src.image.extent.depth);
+ vk.cmdClearColorImage(*m_cmdBuffer, m_multisampledImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1u, &clearRange);
+ }
+
+ // Clear the 'm_multisampledCopyImage' with different color.
+ {
+ const VkClearColorValue clearValue = {{1.0f, 1.0f, 1.0f, 1.0f}};
+ const auto clearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_params.src.image.extent.depth);
+ vk.cmdClearColorImage(*m_cmdBuffer, m_multisampledCopyImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1u, &clearRange);
+
+ const auto postClearMemoryBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT);
+ vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 1u, &postClearMemoryBarrier, 0, (const VkBufferMemoryBarrier*)DE_NULL, 0u, (const VkImageMemoryBarrier*)DE_NULL);
+ }
+ }
+
beginRenderPass(vk, *m_cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, m_params.src.image.extent.width, m_params.src.image.extent.height), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
const VkDeviceSize vertexBufferOffset = 0u;
switch (m_options)
{
+ case COPY_MS_IMAGE_LAYER_TO_MS_IMAGE:
case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
// Duplicate the multisampled image to a multisampled image array
sourceArraySize = getArraySize(m_params.dst.image); // fall through
+ case COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION:
case COPY_MS_IMAGE_TO_MS_IMAGE:
copyMSImageToMSImage(sourceArraySize);
sourceImage = m_multisampledCopyImage.get();
std::vector<VkImageResolve> imageResolves;
std::vector<VkImageResolve2KHR> imageResolves2KHR;
- for (deUint32 i = 0; i < m_params.regions.size(); i++)
+ for (CopyRegion region : m_params.regions)
{
- if (m_params.extensionUse == EXTENSION_USE_NONE)
+ // If copying multiple regions, make sure that the same regions are
+ // used for resolving as the ones used for copying.
+ if(m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
{
- imageResolves.push_back(m_params.regions[i].imageResolve);
+ VkExtent3D partialExtent = {getExtent3D(m_params.src.image).width / 2,
+ getExtent3D(m_params.src.image).height / 2,
+ getExtent3D(m_params.src.image).depth};
+
+ const VkImageResolve imageResolve =
+ {
+ region.imageResolve.srcSubresource, // VkImageSubresourceLayers srcSubresource;
+ region.imageResolve.dstOffset, // VkOffset3D srcOffset;
+ region.imageResolve.dstSubresource, // VkImageSubresourceLayers dstSubresource;
+ region.imageResolve.dstOffset, // VkOffset3D dstOffset;
+ partialExtent, // VkExtent3D extent;
+ };
+
+ if (m_params.extensionUse == EXTENSION_USE_NONE)
+ {
+ imageResolves.push_back(imageResolve);
+ }
+ else
+ {
+ DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
+ imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(imageResolve));
+ }
}
else
{
- DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
- imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(m_params.regions[i].imageResolve));
+ if (m_params.extensionUse == EXTENSION_USE_NONE)
+ {
+ imageResolves.push_back(region.imageResolve);
+ }
+ else
+ {
+ DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
+ imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(region.imageResolve));
+ }
}
}
de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image);
- if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE)
+ if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE || m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
{
// Verify the intermediate multisample copy operation happens properly instead of, for example, shuffling samples around or
// resolving the image and giving every sample the same value.
const tcu::ConstPixelBufferAccess expected = m_expectedTextureLevel[0]->getAccess();
const float fuzzyThreshold = 0.01f;
- for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
+ if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
{
- const tcu::ConstPixelBufferAccess expectedSub = getSubregion (expected, 0, 0, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
- const tcu::ConstPixelBufferAccess resultSub = getSubregion (result, 0, 0, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
+ // Check that all the layers that have not been written to are solid white.
+ tcu::Vec4 expectedColor (1.0f, 1.0f, 1.0f, 1.0f);
+ for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image) - 1; ++arrayLayerNdx)
+ {
+ const tcu::ConstPixelBufferAccess resultSub = getSubregion (result, 0u, 0u, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
+ if(resultSub.getPixel(0, 0) != expectedColor)
+ return tcu::TestStatus::fail("CopiesAndBlitting test. Layers image differs from initialized value.");
+ }
+
+ // Check that the layer that has been copied to is the same as the layer that has been copied from.
+ const tcu::ConstPixelBufferAccess expectedSub = getSubregion (expected, 0u, 0u, 2u, expected.getWidth(), expected.getHeight(), 1u);
+ const tcu::ConstPixelBufferAccess resultSub = getSubregion (result, 0u, 0u, 4u, result.getWidth(), result.getHeight(), 1u);
if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
return tcu::TestStatus::fail("CopiesAndBlitting test");
}
+ else
+ {
+ for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
+ {
+ const tcu::ConstPixelBufferAccess expectedSub = getSubregion (expected, 0u, 0u, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
+ const tcu::ConstPixelBufferAccess resultSub = getSubregion (result, 0u, 0u, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
+ if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
+ return tcu::TestStatus::fail("CopiesAndBlitting test");
+ }
+ }
return tcu::TestStatus::pass("CopiesAndBlitting test");
}
auto& alloc = m_context.getDefaultAllocator();
const auto currentLayout = m_params.src.image.operationLayout;
const auto numDstLayers = getArraySize(m_params.dst.image);
- const auto numInputAttachments = numDstLayers + 1u; // For the source image.
+ const auto numInputAttachments = m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE ? 2u : numDstLayers + 1u; // For the source image.
constexpr auto numSets = 2u; // 1 for the output buffer, 1 for the input attachments.
const auto fbWidth = m_params.src.image.extent.width;
const auto fbHeight = m_params.src.image.extent.height;
std::vector<Move<VkImageView>> imageViews;
std::vector<VkImageView> imageViewsRaw;
- imageViews.push_back(makeImageView(vkd, device, m_multisampledImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.src.image.format, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)));
- for (deUint32 i = 0u; i < numDstLayers; ++i)
+
+ if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
+ {
+ imageViews.push_back(makeImageView(vkd, device, m_multisampledImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.src.image.format, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 2u, 1u)));
+ imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.src.image.format, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 4u, 1u)));
+ }
+ else
{
- const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, i, 1u);
- imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.dst.image.format, subresourceRange));
+ imageViews.push_back(makeImageView(vkd, device, m_multisampledImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.src.image.format, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)));
+ for (deUint32 i = 0u; i < numDstLayers; ++i)
+ {
+ const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, i, 1u);
+ imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.dst.image.format, subresourceRange));
+ }
}
+
imageViewsRaw.reserve(imageViews.size());
std::transform(begin(imageViews), end(imageViews), std::back_inserter(imageViewsRaw), [](const Move<VkImageView>& ptr) { return ptr.get(); });
std::vector<VkImageCopy> imageCopies;
std::vector<VkImageCopy2KHR> imageCopies2KHR;
- for (deUint32 layerNdx = 0; layerNdx < copyArraySize; ++layerNdx)
+ if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
{
const VkImageSubresourceLayers sourceSubresourceLayers =
{
getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
0u, // deUint32 mipLevel;
- 0u, // deUint32 baseArrayLayer;
+ 2u, // deUint32 baseArrayLayer;
1u // deUint32 layerCount;
};
{
getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;//getAspectFlags(dstTcuFormat)
0u, // deUint32 mipLevel;
- layerNdx, // deUint32 baseArrayLayer;
+ 4u, // deUint32 baseArrayLayer;
1u // deUint32 layerCount;
};
{0, 0, 0}, // VkOffset3D srcOffset;
destinationSubresourceLayers, // VkImageSubresourceLayers dstSubresource;
{0, 0, 0}, // VkOffset3D dstOffset;
- getExtent3D(m_params.src.image), // VkExtent3D extent;
+ getExtent3D(m_params.src.image), // VkExtent3D extent;
};
if (m_params.extensionUse == EXTENSION_USE_NONE)
imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
}
}
+ else if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
+ {
+ VkExtent3D partialExtent = {getExtent3D(m_params.src.image).width / 2,
+ getExtent3D(m_params.src.image).height / 2,
+ getExtent3D(m_params.src.image).depth};
+
+ for (CopyRegion region : m_params.regions)
+ {
+ const VkImageCopy imageCopy =
+ {
+ region.imageResolve.srcSubresource, // VkImageSubresourceLayers srcSubresource;
+ region.imageResolve.srcOffset, // VkOffset3D srcOffset;
+ region.imageResolve.dstSubresource, // VkImageSubresourceLayers dstSubresource;
+ region.imageResolve.dstOffset, // VkOffset3D dstOffset;
+ partialExtent, // VkExtent3D extent;
+ };
+
+ if (m_params.extensionUse == EXTENSION_USE_NONE)
+ {
+ imageCopies.push_back(imageCopy);
+ }
+ else
+ {
+ DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
+ imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
+ }
+ }
+ }
+ else
+ {
+ for (deUint32 layerNdx = 0; layerNdx < copyArraySize; ++layerNdx)
+ {
+ const VkImageSubresourceLayers sourceSubresourceLayers =
+ {
+ getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
+ 0u, // deUint32 mipLevel;
+ 0u, // deUint32 baseArrayLayer;
+ 1u // deUint32 layerCount;
+ };
+
+ const VkImageSubresourceLayers destinationSubresourceLayers =
+ {
+ getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;//getAspectFlags(dstTcuFormat)
+ 0u, // deUint32 mipLevel;
+ layerNdx, // deUint32 baseArrayLayer;
+ 1u // deUint32 layerCount;
+ };
+
+ const VkImageCopy imageCopy =
+ {
+ sourceSubresourceLayers, // VkImageSubresourceLayers srcSubresource;
+ {0, 0, 0}, // VkOffset3D srcOffset;
+ destinationSubresourceLayers, // VkImageSubresourceLayers dstSubresource;
+ {0, 0, 0}, // VkOffset3D dstOffset;
+ getExtent3D(m_params.src.image), // VkExtent3D extent;
+ };
+
+ if (m_params.extensionUse == EXTENSION_USE_NONE)
+ {
+ imageCopies.push_back(imageCopy);
+ }
+ else
+ {
+ DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
+ imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
+ }
+ }
+ }
const VkImageMemoryBarrier imageBarriers[] =
{
DE_NULL, // const void* pNext;
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask;
VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
- VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout;
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
m_params.src.image.operationLayout, // VkImageLayout newLayout;
VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
DE_NULL, // const void* pNext;
0, // VkAccessFlags srcAccessMask;
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
- VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
m_params.dst.image.operationLayout, // VkImageLayout newLayout;
VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
" o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
"}\n");
- if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE)
+ if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE || m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
{
// The shader verifies all layers in the copied image are the same as the source image.
// This needs an image view per layer in the copied image.
;
const auto dstLayers = getArraySize(m_params.dst.image);
- for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
+
+ if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
{
- const auto i = layerNdx + 1u;
- verificationShader << "layout (input_attachment_index=" << i << ", set=1, binding=" << i << ") uniform subpassInputMS attachment" << i << ";\n";
+ verificationShader << "layout (input_attachment_index=1, set=1, binding=1) uniform subpassInputMS attachment1;\n";
+ }
+ else
+ {
+ for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
+ {
+ const auto i = layerNdx + 1u;
+ verificationShader << "layout (input_attachment_index=" << i << ", set=1, binding=" << i << ") uniform subpassInputMS attachment" << i << ";\n";
+ }
}
// Using a loop to iterate over each sample avoids the need for the sampleRateShading feature. The pipeline needs to be
<< " vec4 orig = subpassLoad(attachment0, sampleID);\n"
;
- for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
+ std::ostringstream testCondition;
+ if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
{
- const auto i = layerNdx + 1u;
- verificationShader << " vec4 copy" << i << " = subpassLoad(attachment" << i << ", sampleID);\n";
+ verificationShader << " vec4 copy = subpassLoad(attachment1, sampleID);\n";
+ testCondition << "orig == copy";
}
-
- std::ostringstream testCondition;
- for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
+ else
{
- const auto i = layerNdx + 1u;
- testCondition << (layerNdx == 0u ? "" : " && ") << "orig == copy" << i;
+ for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
+ {
+ const auto i = layerNdx + 1u;
+ verificationShader << " vec4 copy" << i << " = subpassLoad(attachment" << i << ", sampleID);\n";
+ }
+
+ for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
+ {
+ const auto i = layerNdx + 1u;
+ testCondition << (layerNdx == 0u ? "" : " && ") << "orig == copy" << i;
+ }
}
verificationShader
}
}
+void addResolveImageLayerCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
+{
+ 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.extent.depth = 5u;
+ params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
+ 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.tiling = VK_IMAGE_TILING_OPTIMAL;
+ params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ params.allocationKind = allocationKind;
+ params.extensionUse = extensionUse;
+
+ for (deUint32 layerNdx=0; layerNdx < params.src.image.extent.depth; ++layerNdx)
+ {
+ const VkImageSubresourceLayers sourceLayer =
+ {
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
+ 0u, // deUint32 mipLevel;
+ layerNdx, // deUint32 baseArrayLayer;
+ 1u // deUint32 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)
+ {
+ 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_LAYER_TO_MS_IMAGE));
+ }
+}
+
+void addResolveCopyImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
+{
+ 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.tiling = VK_IMAGE_TILING_OPTIMAL;
+ 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.tiling = VK_IMAGE_TILING_OPTIMAL;
+ params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ params.allocationKind = allocationKind;
+ params.extensionUse = extensionUse;
+
+ int32_t imageHalfWidth = getExtent3D(params.src.image).width / 2;
+ int32_t imageHalfHeight = getExtent3D(params.src.image).height / 2;
+ VkExtent3D halfImageExtent = {resolveExtent.width / 2, resolveExtent.height / 2, 1u};
+
+ // Lower right corner to lower left corner.
+ {
+ const VkImageSubresourceLayers sourceLayer =
+ {
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
+ 0u, // deUint32 mipLevel;
+ 0u, // deUint32 baseArrayLayer;
+ 1u // deUint32 layerCount;
+ };
+
+ const VkImageResolve testResolve =
+ {
+ sourceLayer, // VkImageSubresourceLayers srcSubresource;
+ {imageHalfWidth, imageHalfHeight, 0}, // VkOffset3D srcOffset;
+ sourceLayer, // VkImageSubresourceLayers dstSubresource;
+ {0, imageHalfHeight, 0}, // VkOffset3D dstOffset;
+ halfImageExtent, // VkExtent3D extent;
+ };
+
+ CopyRegion imageResolve;
+ imageResolve.imageResolve = testResolve;
+ params.regions.push_back(imageResolve);
+ }
+
+ // Upper right corner to lower right corner.
+ {
+ const VkImageSubresourceLayers sourceLayer =
+ {
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
+ 0u, // deUint32 mipLevel;
+ 0u, // deUint32 baseArrayLayer;
+ 1u // deUint32 layerCount;
+ };
+
+ const VkImageResolve testResolve =
+ {
+ sourceLayer, // VkImageSubresourceLayers srcSubresource;
+ {imageHalfWidth, 0, 0}, // VkOffset3D srcOffset;
+ sourceLayer, // VkImageSubresourceLayers dstSubresource;
+ {imageHalfWidth, imageHalfHeight, 0}, // VkOffset3D dstOffset;
+ halfImageExtent, // 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];
+ 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_MULTIREGION));
+ }
+}
+
void addResolveImageWholeArrayImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
{
TestParams params;
addTestGroup(group, "with_regions", "Resolve from image to image (with regions)", addResolveImageWithRegionsTests, allocationKind, extensionUse);
addTestGroup(group, "whole_copy_before_resolving", "Resolve from image to image (whole copy before resolving)", addResolveImageWholeCopyBeforeResolvingTests, allocationKind, extensionUse);
addTestGroup(group, "diff_layout_copy_before_resolving", "Resolve from image to image (whole copy before resolving with different layouts)", addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests, allocationKind, extensionUse);
+ addTestGroup(group, "layer_copy_before_resolving", "Resolve from image to image (layer copy before resolving)", addResolveImageLayerCopyBeforeResolvingTests, allocationKind, extensionUse);
+ addTestGroup(group, "copy_with_regions_before_resolving", "Resolve from image to image (region copy before resolving)", addResolveCopyImageWithRegionsTests, allocationKind, extensionUse);
addTestGroup(group, "whole_array_image", "Resolve from image to image (whole array image)", addResolveImageWholeArrayImageTests, allocationKind, extensionUse);
addTestGroup(group, "whole_array_image_one_region", "Resolve from image to image (whole array image with single region)", addResolveImageWholeArrayImageSingleRegionTests, allocationKind, extensionUse);
addTestGroup(group, "diff_image_size", "Resolve from image to image of different size", addResolveImageDiffImageSizeTests, allocationKind, extensionUse);