diff --git a/tests/unit/host_image_copy.cpp b/tests/unit/host_image_copy.cpp index 37b2dd16ce9..00a0d45cd8d 100644 --- a/tests/unit/host_image_copy.cpp +++ b/tests/unit/host_image_copy.cpp @@ -291,7 +291,7 @@ TEST_F(NegativeHostImageCopy, HostCopyImageToFromMemory) { image_3d.Init(image_ci); image_3d.SetLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - // Image must have offset.z of 0 and extent.depth of 1 + // imageOffset.z and (imageExtent.depth + imageOffset.z) both >= 0 and <= imageSubresource height copy_to_image.dstImage = image_3d; region_to_image.imageOffset.z = 1; m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyMemoryToImageInfoEXT-imageOffset-09104"); @@ -719,3 +719,553 @@ TEST_F(NegativeHostImageCopy, HostCopyImageToFromMemory) { region_to_image.imageExtent.height = height; region_from_image.imageExtent.height = height; } + +TEST_F(NegativeHostImageCopy, HostCopyImageToImage) { + TEST_DESCRIPTION("Use VK_EXT_host_image_copy to copy from an image to another image"); + + VkFormat compressed_format = VK_FORMAT_UNDEFINED; + InitHostImageCopyTest(compressed_format); + if (::testing::Test::IsSkipped()) return; + + uint32_t width = 32; + uint32_t height = 32; + VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; + VkImageLayout layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + auto image_ci = VkImageObj::ImageCreateInfo2D( + width, height, 1, 1, format, + VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, + VK_IMAGE_TILING_OPTIMAL); + VkImageFormatProperties img_prop = {}; + if (VK_SUCCESS != vk::GetPhysicalDeviceImageFormatProperties(m_device->phy().handle(), image_ci.format, image_ci.imageType, + image_ci.tiling, image_ci.usage, image_ci.flags, &img_prop)) { + GTEST_SKIP() << "Required formats/features not supported"; + } + + auto host_image_copy_props = LvlInitStruct(); + GetPhysicalDeviceProperties2(host_image_copy_props); + std::vector copy_src_layouts; + std::vector copy_dst_layouts; + copy_src_layouts.resize(host_image_copy_props.copySrcLayoutCount); + copy_dst_layouts.resize(host_image_copy_props.copyDstLayoutCount); + host_image_copy_props.pCopySrcLayouts = copy_src_layouts.data(); + host_image_copy_props.pCopyDstLayouts = copy_dst_layouts.data(); + GetPhysicalDeviceProperties2(host_image_copy_props); + if (!copy_layout_supported(copy_src_layouts, copy_dst_layouts, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) || + !copy_layout_supported(copy_src_layouts, copy_dst_layouts, VK_IMAGE_LAYOUT_GENERAL)) { + GTEST_SKIP() << "Required formats/features not supported"; + } + + auto image_copy_2 = LvlInitStruct(); + image_copy_2.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; + image_copy_2.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; + image_copy_2.extent = {width, height, 1}; + auto copy_image_to_image = LvlInitStruct(); + copy_image_to_image.regionCount = 1; + copy_image_to_image.pRegions = &image_copy_2; + copy_image_to_image.srcImageLayout = layout; + copy_image_to_image.dstImageLayout = layout; + + VkFormat no_hic_feature_format = + FindFormatWithoutFeatures2(gpu(), image_ci.tiling, VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT); + if (no_hic_feature_format != VK_FORMAT_UNDEFINED) { + // If VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT, then format features must have VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT + image_ci.format = no_hic_feature_format; + // Can't use VkImageObj because it does error checking + VkImage image_no_feature; + // Any invalid usage will get 02251 + m_errorMonitor->SetUnexpectedError("VUID-VkImageCreateInfo-imageCreateMaxMipLevels-02251"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCreateInfo-imageCreateFormatFeatures-09048"); + vk::CreateImage(m_device->device(), &image_ci, NULL, &image_no_feature); + m_errorMonitor->VerifyFound(); + image_ci.format = format; + } + + VkImageObj image1(m_device); + VkImageObj image2(m_device); + image1.Init(image_ci); + image2.Init(image_ci); + + // srcImage and dstImage must have been created with identical image creation parameters + image_ci.extent.width = image_ci.extent.width / 2; + VkImageObj skinny_image(m_device); + skinny_image.Init(image_ci); + copy_image_to_image.dstImage = image1; + copy_image_to_image.srcImage = skinny_image; + image_copy_2.extent.width = image_ci.extent.width; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcImage-09069"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + image_ci.extent.width = width; + image_copy_2.extent.width = width; + + // Note that because the images need to be identical to avoid 09069, we'll go ahead and test for src and dst errors in one call + + if (copy_layout_supported(copy_src_layouts, copy_dst_layouts, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL)) { + auto stencil_format = FindSupportedDepthStencilFormat(gpu()); + VkImageObj image_stencil1(m_device); + VkImageObj image_stencil2(m_device); + image_ci.format = stencil_format; + image_ci.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + image_stencil1.Init(image_ci); + image_stencil1.SetLayout((VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT), + VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL); + image_stencil2.Init(image_ci); + image_stencil2.SetLayout((VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT), + VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL); + + // Stencil, no VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT + image_copy_2.srcSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; + copy_image_to_image.dstImage = image_stencil1; + copy_image_to_image.dstImageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; + image_copy_2.dstSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; + copy_image_to_image.srcImage = image_stencil2; + copy_image_to_image.srcImageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-dstImage-09111"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcImage-09111"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + + // Seperate stencil, no VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT + auto stencil_usage_ci = LvlInitStruct(); + stencil_usage_ci.stencilUsage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + image_ci.pNext = &stencil_usage_ci; + VkImageObj image_separate_stencil1(m_device); + VkImageObj image_separate_stencil2(m_device); + image_separate_stencil1.Init(image_ci); + image_separate_stencil1.SetLayout((VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT), + VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL); + image_separate_stencil2.Init(image_ci); + image_separate_stencil2.SetLayout((VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT), + VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL); + + image_copy_2.dstSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; + copy_image_to_image.dstImage = image_separate_stencil1; + image_copy_2.srcSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; + copy_image_to_image.srcImage = image_separate_stencil2; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-dstImage-09112"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcImage-09112"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + + // Reset to baseline test configuration + image_copy_2.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + image_copy_2.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + copy_image_to_image.dstImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + copy_image_to_image.srcImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + image_ci.format = format; + image_ci.usage = VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + image_ci.pNext = nullptr; + } + + { + auto image_ci_no_transfer = VkImageObj::ImageCreateInfo2D(width, height, 1, 1, format, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + VK_IMAGE_TILING_OPTIMAL); + // Missing transfer usage + VkImageObj image_no_transfer1(m_device); + VkImageObj image_no_transfer2(m_device); + image_no_transfer1.Init(image_ci_no_transfer); + image_no_transfer2.Init(image_ci_no_transfer); + image_no_transfer1.SetLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + image_no_transfer2.SetLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + copy_image_to_image.dstImage = image_no_transfer1; + copy_image_to_image.srcImage = image_no_transfer2; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-dstImage-09113"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcImage-09113"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + } + + copy_image_to_image.dstImage = image1; + copy_image_to_image.srcImage = image2; + // Memcpy with imageOffset x, y, or z == 0 + copy_image_to_image.flags = VK_HOST_IMAGE_COPY_MEMCPY_EXT; + image_copy_2.dstOffset.x = 1; + image_copy_2.srcOffset.x = 1; + // If ImageExtent.width is left at width, offset will exceed width of image (07971). Setting it to width-1 will not match + // image dimensions (09115). Pick the one with MEMCPY flag set (09115) and test for both here. + image_copy_2.extent.width = width - 1; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-dstOffset-09114"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcOffset-09114"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-extent-09115"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-extent-09115"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + + // Reset to baseline test configuration + copy_image_to_image.flags = 0; + image_copy_2.dstOffset.x = 0; + image_copy_2.srcOffset.x = 0; + image_copy_2.extent.width = width; + + { + // No image memory + VkImageObj image_no_mem1(m_device); + VkImageObj image_no_mem2(m_device); + image_no_mem1.init_no_mem(*m_device, image_ci); + image_no_mem2.init_no_mem(*m_device, image_ci); + copy_image_to_image.dstImage = image_no_mem1; + copy_image_to_image.srcImage = image_no_mem2; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-dstImage-07966"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcImage-07966"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + } + + // Bad mipLevel - also throws off multiple size calculations, causing other errors + // Also get 07970 - pRegions must be contained within the specified dstSubresource of dstImage + // Also get 07971 - imageOffset.x and (imageExtent.width + imageOffset.x) both >= 0 and <= imageSubresource width + // Also get 07972 - imageOffset.y and (imageExtent.height + imageOffset.y) both >= 0 and <= imageSubresource height + // Also get 09104 - imageOffset.z and (imageExtent.depth + imageOffset.z) both >= 0 and <= imageSubresource depth + image_copy_2.dstSubresource.mipLevel = image_ci.mipLevels + 1; + image_copy_2.srcSubresource.mipLevel = image_ci.mipLevels + 1; + copy_image_to_image.dstImage = image1; + copy_image_to_image.srcImage = image2; + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-srcSubresource-07970"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-srcSubresource-07971"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-srcSubresource-07972"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-srcOffset-09104"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-dstSubresource-07970"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-dstSubresource-07971"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-dstSubresource-07972"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-dstOffset-09104"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcSubresource-07967"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-dstSubresource-07967"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + image_copy_2.dstSubresource.mipLevel = 0; + image_copy_2.srcSubresource.mipLevel = 0; + + // baseArrayLayer + layerCount > arrayLayers + image_copy_2.srcSubresource.baseArrayLayer = image_ci.arrayLayers; + image_copy_2.dstSubresource.baseArrayLayer = image_ci.arrayLayers; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcSubresource-08790"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-dstSubresource-08790"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + image_copy_2.srcSubresource.baseArrayLayer = 0; + image_copy_2.dstSubresource.baseArrayLayer = 0; + + { + // Can't use subsampled image + VkImageObj image_subsampled1(m_device); + VkImageObj image_subsampled2(m_device); + image_ci.flags = VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT; + image_subsampled1.Init(image_ci); + image_subsampled2.Init(image_ci); + image_subsampled1.SetLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + image_subsampled2.SetLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + copy_image_to_image.dstImage = image_subsampled1; + copy_image_to_image.srcImage = image_subsampled2; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcImage-07969"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-dstImage-07969"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + image_ci.flags = 0; + } + + // Extent bigger than image - Can't get 07970 without getting 07971, 07972 or 09104, so test both 07971 and 07970 here + image_copy_2.extent.width = width + 1; + copy_image_to_image.dstImage = image1; + copy_image_to_image.srcImage = image2; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcSubresource-07970"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcSubresource-07971"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-dstSubresource-07970"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-dstSubresource-07971"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + image_copy_2.extent.width = width; + + // imageOffset.y and (imageExtent.height + imageOffset.y) both >= 0 and <= imageSubresource height + // Also get 07970 - pRegions must be contained within the specified dstSubresource of dstImage + image_copy_2.srcOffset.y = -1; + image_copy_2.dstOffset.y = -1; + copy_image_to_image.dstImage = image1; + copy_image_to_image.srcImage = image2; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcSubresource-07972"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-dstSubresource-07972"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-srcSubresource-07970"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-dstSubresource-07970"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + image_copy_2.srcOffset.y = 0; + image_copy_2.dstOffset.y = 0; + + { + // Use 3D image to avoid 07980 + VkImageObj image_3d1(m_device); + VkImageObj image_3d2(m_device); + image_ci.imageType = VK_IMAGE_TYPE_3D; + image_3d1.Init(image_ci); + image_3d2.Init(image_ci); + image_3d1.SetLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + image_3d2.SetLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + image_ci.imageType = VK_IMAGE_TYPE_2D; + + // imageOffset.z and (imageExtent.depth + imageOffset.z) both >= 0 and <= imageSubresource height + // Also get 07970 - pRegions must be contained within the specified dstSubresource of dstImage + copy_image_to_image.dstImage = image_3d1; + copy_image_to_image.srcImage = image_3d2; + image_copy_2.srcOffset.z = 1; + image_copy_2.dstOffset.z = 1; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-dstOffset-09104"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcOffset-09104"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-srcSubresource-07970"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-dstSubresource-07970"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + image_copy_2.srcOffset.z = 0; + image_copy_2.dstOffset.z = 0; + + // 3D image, Subresource.baseArrayLayer must be 0 and Subresource.layerCount must be 1 + // Also get Subresource.baseArrayLayer + Subresource.layerCount <= CreateInfo.arrayLayers + image_copy_2.srcSubresource.baseArrayLayer = 1; + image_copy_2.dstSubresource.baseArrayLayer = 1; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcImage-07983"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-dstImage-07983"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-srcSubresource-08790"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-dstSubresource-08790"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + image_copy_2.srcSubresource.baseArrayLayer = 0; + image_copy_2.dstSubresource.baseArrayLayer = 0; + + // extent.depth must not be 0 + image_copy_2.extent.depth = 0; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy2-extent-06670"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + image_copy_2.extent.depth = 1; + } + + { + // Image type 1D + // Offset.y must be 0 and extent.height must be 1 + // Also get 07970 - pRegions must be contained within the specified subresource of image + // Also get 07972 - offset.y and (extent.height + offset.y) both >= 0 and <= image subresource height + VkImageObj image_1d1(m_device); + VkImageObj image_1d2(m_device); + image_ci.imageType = VK_IMAGE_TYPE_1D; + image_ci.extent.height = 1; + image_1d1.Init(image_ci); + image_1d2.Init(image_ci); + image_1d1.SetLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + image_1d2.SetLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + image_ci.imageType = VK_IMAGE_TYPE_2D; + image_ci.extent.height = height; + + copy_image_to_image.dstImage = image_1d1; + copy_image_to_image.srcImage = image_1d2; + image_copy_2.srcOffset.y = 1; + image_copy_2.dstOffset.y = 1; + image_copy_2.extent.height = 1; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcImage-07979"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-dstImage-07979"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-srcSubresource-07970"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-dstSubresource-07970"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-srcSubresource-07972"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-dstSubresource-07972"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + image_copy_2.srcOffset.y = 0; + image_copy_2.dstOffset.y = 0; + + // imageOffset.z must be 0 and imageExtent.depth must be 1 + // Also get 07970 - pRegions must be contained within the specified subresource of image + // Also get 09104 - imageOffset.z and (imageExtent.depth + imageOffset.z) both >= 0 and <= imageSubresource depth + image_copy_2.srcOffset.z = 1; + image_copy_2.dstOffset.z = 1; + image_copy_2.extent.depth = 1; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-dstImage-07980"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcImage-07980"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-srcSubresource-07970"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-dstSubresource-07970"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-srcOffset-09104"); + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-dstOffset-09104"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + image_copy_2.srcOffset.z = 0; + image_copy_2.dstOffset.z = 0; + } + + if (compressed_format != VK_FORMAT_UNDEFINED) { + if (VK_SUCCESS == vk::GetPhysicalDeviceImageFormatProperties(m_device->phy().handle(), compressed_format, + image_ci.imageType, image_ci.tiling, image_ci.usage, + image_ci.flags, &img_prop)) { + VkImageObj image_compressed1(m_device); + VkImageObj image_compressed2(m_device); + image_ci.format = compressed_format; + image_ci.mipLevels = 6; + image_compressed1.Init(image_ci); + image_compressed2.Init(image_ci); + image_compressed1.SetLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + image_compressed2.SetLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + + // imageOffset not a multiple of block size + image_copy_2.dstOffset = {1, 1, 0}; + image_copy_2.srcOffset = {1, 1, 0}; + image_copy_2.extent = {1, 1, 1}; + image_copy_2.srcSubresource.mipLevel = 4; + image_copy_2.dstSubresource.mipLevel = 4; + copy_image_to_image.dstImage = image_compressed1; + copy_image_to_image.srcImage = image_compressed2; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-pRegions-07274"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-pRegions-07274"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-pRegions-07275"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-pRegions-07275"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + image_copy_2.dstOffset = {0, 0, 0}; + image_copy_2.srcOffset = {0, 0, 0}; + + // width not a multiple of compressed block width + image_copy_2.extent = {1, 2, 1}; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-imageExtent-00207"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-imageExtent-00207"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + + // Copy height < compressed block size but not the full mip height + image_copy_2.extent = {2, 1, 1}; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-imageExtent-00208"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-imageExtent-00208"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + image_copy_2.extent = {width, height, 1}; + image_copy_2.srcSubresource.mipLevel = 0; + image_copy_2.dstSubresource.mipLevel = 0; + } + } + + // Bad aspectMask + image_copy_2.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + image_copy_2.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + copy_image_to_image.dstImage = image1; + copy_image_to_image.srcImage = image2; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcSubresource-09105"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-dstSubresource-09105"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + image_copy_2.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + image_copy_2.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + + if (VK_SUCCESS == vk::GetPhysicalDeviceImageFormatProperties( + m_device->phy().handle(), VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0, &img_prop)) { + // imageSubresource.aspectMask must be VK_IMAGE_ASPECT_PLANE_0_BIT or VK_IMAGE_ASPECT_PLANE_1_BIT + VkImageObj image_multi_twoplane1(m_device); + VkImageObj image_multi_twoplane2(m_device); + image_multi_twoplane1.Init(128, 128, 1, VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, + VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + VK_IMAGE_TILING_OPTIMAL, 0); + image_multi_twoplane2.Init(128, 128, 1, VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, + VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + VK_IMAGE_TILING_OPTIMAL, 0); + image_multi_twoplane1.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, layout); + image_multi_twoplane2.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, layout); + image_copy_2.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT; + image_copy_2.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT; + copy_image_to_image.dstImage = image_multi_twoplane1; + copy_image_to_image.srcImage = image_multi_twoplane2; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcImage-07981"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-dstImage-07981"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + image_copy_2.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + image_copy_2.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + } + + if (VK_SUCCESS == vk::GetPhysicalDeviceImageFormatProperties( + m_device->phy().handle(), VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0, &img_prop)) { + // imageSubresource.aspectMask must be VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT, or + // VK_IMAGE_ASPECT_PLANE_2_BIT + VkImageObj image_multi_threeplane1(m_device); + VkImageObj image_multi_threeplane2(m_device); + image_multi_threeplane1.Init(128, 128, 1, VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, + VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + VK_IMAGE_TILING_OPTIMAL, 0); + image_multi_threeplane2.Init(128, 128, 1, VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, + VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + VK_IMAGE_TILING_OPTIMAL, 0); + image_multi_threeplane1.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, layout); + image_multi_threeplane2.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, layout); + image_copy_2.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + image_copy_2.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + copy_image_to_image.dstImage = image_multi_threeplane1; + copy_image_to_image.srcImage = image_multi_threeplane2; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcImage-07982"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-dstImage-07982"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + } + + // Bad image layout + copy_image_to_image.srcImageLayout = VK_IMAGE_LAYOUT_GENERAL; + copy_image_to_image.dstImageLayout = VK_IMAGE_LAYOUT_GENERAL; + copy_image_to_image.dstImage = image1; + copy_image_to_image.srcImage = image2; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcImageLayout-09070"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-dstImageLayout-09071"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + copy_image_to_image.srcImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + copy_image_to_image.dstImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + if (!copy_layout_supported(copy_src_layouts, copy_dst_layouts, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)) { + // layout must be one of the image layouts returned in VkPhysicalDeviceHostImageCopyPropertiesEXT::pCopySrcLayouts + image1.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + image2.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + copy_image_to_image.srcImageLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + copy_image_to_image.dstImageLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-srcImageLayout-09072"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkCopyImageToImageInfoEXT-dstImageLayout-09073"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + copy_image_to_image.srcImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + copy_image_to_image.dstImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + image1.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + image2.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + } + + // Neither width not height can be zero + image_copy_2.extent = {0, 0, 1}; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy2-extent-06668"); + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageCopy2-extent-06669"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + image_copy_2.extent = {width, height, 1}; + + // Multiple aspect mask bits + image_copy_2.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT; + image_copy_2.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-aspectMask-00167"); + // Also get aspect not present in image + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-srcSubresource-09105"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + image_copy_2.extent = {width, height, 1}; + + // Can't include METADATA + image_copy_2.srcSubresource.aspectMask = VK_IMAGE_ASPECT_METADATA_BIT; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-aspectMask-00168"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + + // No aspect plane bits + image_copy_2.srcSubresource.aspectMask = VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-aspectMask-02247"); + // Also get aspect not present in image + m_errorMonitor->SetUnexpectedError("VUID-VkCopyImageToImageInfoEXT-srcSubresource-09105"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + image_copy_2.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + + // layerCount must be > 0 + image_copy_2.srcSubresource.layerCount = 0; + m_errorMonitor->SetDesiredFailureMsg(kErrorBit, "VUID-VkImageSubresourceLayers-layerCount-01700"); + vk::CopyImageToImageEXT(*m_device, ©_image_to_image); + m_errorMonitor->VerifyFound(); + image_copy_2.srcSubresource.layerCount = 1; +}