| 23 | constexpr VkFormatFeatureFlags kSrcDstFeature = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT; |
| 24 | |
| 25 | TEST_F(NegativeCopyBufferImage, ImageBufferCopy) { |
| 26 | TEST_DESCRIPTION("Image to buffer and buffer to image tests"); |
| 27 | AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); |
| 28 | RETURN_IF_SKIP(Init()); |
| 29 | |
| 30 | // Verify R8G8B8A8_UINT format is supported for transfer |
| 31 | bool missing_rgba_support = false; |
| 32 | VkFormatProperties props = {0, 0, 0}; |
| 33 | vk::GetPhysicalDeviceFormatProperties(m_device->Physical(), VK_FORMAT_R8G8B8A8_UINT, &props); |
| 34 | missing_rgba_support |= (props.bufferFeatures == 0 && props.linearTilingFeatures == 0 && props.optimalTilingFeatures == 0); |
| 35 | missing_rgba_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0; |
| 36 | missing_rgba_support |= (props.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0; |
| 37 | |
| 38 | if (missing_rgba_support) { |
| 39 | GTEST_SKIP() << "R8G8B8A8_UINT transfer unsupported"; |
| 40 | } |
| 41 | |
| 42 | // 128^2 texels, 64k |
| 43 | vkt::Image image_64k(*m_device, 128, 128, VK_FORMAT_R8G8B8A8_UINT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | kSrcDstUsage); |
| 44 | // 64^2 texels, 16k |
| 45 | vkt::Image image_16k(*m_device, 64, 64, VK_FORMAT_R8G8B8A8_UINT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | kSrcDstUsage); |
| 46 | |
| 47 | VkBufferUsageFlags transfer_usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; |
| 48 | vkt::Buffer buffer_64k(*m_device, 65536, transfer_usage); // 64k |
| 49 | vkt::Buffer buffer_16k(*m_device, 16384, transfer_usage); // 16k |
| 50 | |
| 51 | VkBufferImageCopy region = {}; |
| 52 | region.bufferRowLength = 0; |
| 53 | region.bufferImageHeight = 0; |
| 54 | region.imageSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}; |
| 55 | region.imageOffset = {0, 0, 0}; |
| 56 | region.imageExtent = {64, 64, 1}; |
| 57 | region.bufferOffset = 0; |
| 58 | |
| 59 | m_command_buffer.Begin(); |
| 60 | |
| 61 | // successful copies |
| 62 | vk::CmdCopyImageToBuffer(m_command_buffer, image_16k, VK_IMAGE_LAYOUT_GENERAL, buffer_16k, 1, ®ion); |
| 63 | m_command_buffer.FullMemoryBarrier(); |
| 64 | vk::CmdCopyBufferToImage(m_command_buffer, buffer_16k, image_16k, VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); |
| 65 | region.imageOffset.x = 16; // 16k copy, offset requires larger imagem_command_buffer.FullMemoryBarrier(); |
| 66 | vk::CmdCopyImageToBuffer(m_command_buffer, image_64k, VK_IMAGE_LAYOUT_GENERAL, buffer_16k, 1, ®ion); |
| 67 | region.imageExtent.height = 78; // > 16k copy requires larger buffer & image |
| 68 | m_command_buffer.FullMemoryBarrier(); |
| 69 | vk::CmdCopyBufferToImage(m_command_buffer, buffer_64k, image_64k, VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); |
| 70 | region.imageOffset.x = 0; |
| 71 | region.imageExtent.height = 64; |
| 72 | region.bufferOffset = 256; // 16k copy with buffer offset, requires larger buffer |
| 73 | m_command_buffer.FullMemoryBarrier(); |
| 74 | vk::CmdCopyImageToBuffer(m_command_buffer, image_16k, VK_IMAGE_LAYOUT_GENERAL, buffer_64k, 1, ®ion); |
| 75 | |
| 76 | // image/buffer too small (extent too large) on copy to image |
| 77 | region.imageExtent = {65, 64, 1}; |
| 78 | m_errorMonitor->SetDesiredError("VUID-vkCmdCopyBufferToImage-pRegions-00171"); // buffer too small |
| 79 | vk::CmdCopyBufferToImage(m_command_buffer, buffer_16k, image_64k, VK_IMAGE_LAYOUT_GENERAL, 1, ®ion); |
| 80 | m_errorMonitor->VerifyFound(); |
| 81 | |
| 82 | m_errorMonitor->SetUnexpectedError("VUID-vkCmdCopyBufferToImage-imageSubresource-07971"); |
nothing calls this directly
no test coverage detected