Repository: LunarG/gfxreconstruct
Pull request #2192: Get aspect mask by its format
Author: login: locke-lunarg
Created: 2025-05-05T22:28:40Z | Merged: 2025-05-08T15:47:10Z

Use GetFormatAspectMask, instead of VK_IMAGE_ASPECT_COLOR_BIT

closed: https://github.com/LunarG/gfxreconstruct/issues/2166


Diff:
diff --git a/framework/decode/screenshot_handler.cpp b/framework/decode/screenshot_handler.cpp
index a6029e577a..705724e7f7 100644
--- a/framework/decode/screenshot_handler.cpp
+++ b/framework/decode/screenshot_handler.cpp
@@ -24,6 +24,7 @@
 #include "util/image_writer.h"
 #include "util/logging.h"
 #include "util/platform.h"
+#include "graphics/vulkan_resources_util.h"
 #include "decode/decoder_util.h"
 #include "generated/generated_vulkan_enum_to_string.h"
 
@@ -194,6 +195,8 @@ void ScreenshotHandler::WriteImage(const std::string&                      filen
 
             if (result == VK_SUCCESS)
             {
+                auto image_aspect_mask = graphics::GetFormatAspectMask(format);
+
                 // Transition source image from image_layout to the TRANSFER_DST layout.
                 VkImageMemoryBarrier image_barrier            = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
                 image_barrier.pNext                           = nullptr;
@@ -204,7 +207,7 @@ void ScreenshotHandler::WriteImage(const std::string&                      filen
                 image_barrier.srcQueueFamilyIndex             = VK_QUEUE_FAMILY_IGNORED;
                 image_barrier.dstQueueFamilyIndex             = VK_QUEUE_FAMILY_IGNORED;
                 image_barrier.image                           = image;
-                image_barrier.subresourceRange.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
+                image_barrier.subresourceRange.aspectMask     = image_aspect_mask;
                 image_barrier.subresourceRange.baseArrayLayer = 0;
                 image_barrier.subresourceRange.layerCount     = 1;
                 image_barrier.subresourceRange.baseMipLevel   = 0;
@@ -222,7 +225,9 @@ void ScreenshotHandler::WriteImage(const std::string&                      filen
                                                  &image_barrier);
 
                 // The 'copy_image' is the image to be used with the image to buffer copy.
-                VkImage copy_image = image;
+                VkImage copy_image             = image;
+                auto    copy_image_aspect_mask = graphics::GetFormatAspectMask(copy_format);
+
                 if (copy_resource.convert_image != VK_NULL_HANDLE)
                 {
                     // Need to perform a blit to covert the Vulkan image format to the image file format.
@@ -238,7 +243,7 @@ void ScreenshotHandler::WriteImage(const std::string&                      filen
                     convert_image_barrier.srcQueueFamilyIndex             = VK_QUEUE_FAMILY_IGNORED;
                     convert_image_barrier.dstQueueFamilyIndex             = VK_QUEUE_FAMILY_IGNORED;
                     convert_image_barrier.image                           = copy_image;
-                    convert_image_barrier.subresourceRange.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
+                    convert_image_barrier.subresourceRange.aspectMask     = copy_image_aspect_mask;
                     convert_image_barrier.subresourceRange.baseArrayLayer = 0;
                     convert_image_barrier.subresourceRange.layerCount     = 1;
                     convert_image_barrier.subresourceRange.baseMipLevel   = 0;
@@ -256,7 +261,7 @@ void ScreenshotHandler::WriteImage(const std::string&                      filen
                                                      &convert_image_barrier);
 
                     VkImageBlit blit_region;
-                    blit_region.srcSubresource.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
+                    blit_region.srcSubresource.aspectMask     = image_aspect_mask;
                     blit_region.srcSubresource.mipLevel       = 0;
                     blit_region.srcSubresource.baseArrayLayer = 0;
                     blit_region.srcSubresource.layerCount     = 1;
@@ -266,7 +271,7 @@ void ScreenshotHandler::WriteImage(const std::string&                      filen
                     blit_region.srcOffsets[1].x               = width;
                     blit_region.srcOffsets[1].y               = height;
                     blit_region.srcOffsets[1].z               = 1;
-                    blit_region.dstSubresource.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
+                    blit_region.dstSubresource.aspectMask     = copy_image_aspect_mask;
                     blit_region.dstSubresource.mipLevel       = 0;
                     blit_region.dstSubresource.baseArrayLayer = 0;
                     blit_region.dstSubresource.layerCount     = 1;
@@ -309,7 +314,7 @@ void ScreenshotHandler::WriteImage(const std::string&                      filen
                 copy_region.bufferOffset                    = 0;
                 copy_region.bufferRowLength                 = 0;
                 copy_region.bufferImageHeight               = 0;
-                copy_region.imageSubresource.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
+                copy_region.imageSubresource.aspectMask     = copy_image_aspect_mask;
                 copy_region.imageSubresource.mipLevel       = 0;
                 copy_region.imageSubresource.baseArrayLayer = 0;
                 copy_region.imageSubresource.layerCount     = 1;
diff --git a/framework/decode/vulkan_captured_swapchain.cpp b/framework/decode/vulkan_captured_swapchain.cpp
index 3c03a9b37a..bb1552089a 100644
--- a/framework/decode/vulkan_captured_swapchain.cpp
+++ b/framework/decode/vulkan_captured_swapchain.cpp
@@ -24,6 +24,7 @@
 #include "decode/decoder_util.h"
 
 #include "util/logging.h"
+#include "graphics/vulkan_resources_util.h"
 
 GFXRECON_BEGIN_NAMESPACE(gfxrecon)
 GFXRECON_BEGIN_NAMESPACE(decode)
@@ -398,7 +399,6 @@ void VulkanCapturedSwapchain::ProcessSetSwapchainImageStatePreAcquire(
         image_barrier.oldLayout                       = VK_IMAGE_LAYOUT_UNDEFINED;
         image_barrier.srcQueueFamilyIndex             = VK_QUEUE_FAMILY_IGNORED;
         image_barrier.dstQueueFamilyIndex             = VK_QUEUE_FAMILY_IGNORED;
-        image_barrier.subresourceRange.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
         image_barrier.subresourceRange.baseMipLevel   = 0;
         image_barrier.subresourceRange.levelCount     = 1;
         image_barrier.subresourceRange.baseArrayLayer = 0;
@@ -457,6 +457,8 @@ void VulkanCapturedSwapchain::ProcessSetSwapchainImageStatePreAcquire(
                         {
                             image_barrier.newLayout = image_layout;
                             image_barrier.image     = image;
+                            image_barrier.subresourceRange.aspectMask =
+                                graphics::GetFormatAspectMask(image_entry->format);
 
                             result = device_table_->BeginCommandBuffer(transition_command, &begin_info);
 
@@ -607,7 +609,6 @@ void VulkanCapturedSwapchain::ProcessSetSwapchainImageStateQueueSubmit(
         image_barrier.newLayout                       = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
         image_barrier.srcQueueFamilyIndex             = VK_QUEUE_FAMILY_IGNORED;
         image_barrier.dstQueueFamilyIndex             = VK_QUEUE_FAMILY_IGNORED;
-        image_barrier.subresourceRange.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
         image_barrier.subresourceRange.baseMipLevel   = 0;
         image_barrier.subresourceRange.levelCount     = 1;
         image_barrier.subresourceRange.baseArrayLayer = 0;
@@ -655,8 +656,9 @@ void VulkanCapturedSwapchain::ProcessSetSwapchainImageStateQueueSubmit(
 
                     if (result == VK_SUCCESS)
                     {
-                        image_barrier.image        = image;
-                        present_info.pImageIndices = &image_index;
+                        image_barrier.image                       = image;
+                        image_barrier.subresourceRange.aspectMask = graphics::GetFormatAspectMask(image_entry->format);
+                        present_info.pImageIndices                = &image_index;
 
                         result = device_table_->BeginCommandBuffer(command, &begin_info);
                     }
diff --git a/framework/decode/vulkan_rebind_allocator.cpp b/framework/decode/vulkan_rebind_allocator.cpp
index e507ca1c4e..e78bdb2c4b 100644
--- a/framework/decode/vulkan_rebind_allocator.cpp
+++ b/framework/decode/vulkan_rebind_allocator.cpp
@@ -59,6 +59,7 @@
 #include "util/alignment_utils.h"
 #include "util/platform.h"
 #include "graphics/vulkan_util.h"
+#include "graphics/vulkan_resources_util.h"
 #include "graphics/vulkan_struct_get_pnext.h"
 
 #include "generated/generated_vulkan_enum_to_string.h"
@@ -1678,37 +1679,23 @@ void VulkanRebindAllocator::WriteBoundResourceStaging(
                     "Ignoring potential mip maps/array layers in staging buffer to image copy: support "
                     "not yet implemented");
 
-                VkImageAspectFlags aspect{};
-                switch (resource_alloc_info->format)
+                std::vector<VkImageAspectFlagBits> aspects;
+                graphics::GetFormatAspects(resource_alloc_info->format, &aspects);
+
+                for (auto aspect : aspects)
                 {
-                    case VK_FORMAT_D16_UNORM:
-                    case VK_FORMAT_X8_D24_UNORM_PACK32:
-                    case VK_FORMAT_D32_SFLOAT:
-                        aspect = VK_IMAGE_ASPECT_DEPTH_BIT;
-                        break;
-                    case VK_FORMAT_S8_UINT:
-                        aspect = VK_IMAGE_ASPECT_STENCIL_BIT;
-                        break;
-                    case VK_FORMAT_D16_UNORM_S8_UINT:
-                    case VK_FORMAT_D24_UNORM_S8_UINT:
-                    case VK_FORMAT_D32_SFLOAT_S8_UINT:
-                        aspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
-                        break;
-                    default:
-                        aspect = VK_IMAGE_ASPECT_COLOR_BIT;
-                        break;
+                    VkImageAspectFlags aspect_flags = aspect;
+
+                    VkBufferImageCopy region{};
+                    region.bufferOffset      = 0;
+                    region.bufferRowLength   = 0;
+                    region.bufferImageHeight = 0;
+                    region.imageSubresource  = { aspect_flags, 0, 0, 1 };
+                    region.imageOffset       = { 0, 0, 0 };
+                    region.imageExtent       = { 1, 1, 1 };
+                    functions_.cmd_copy_buffer_to_image(
+                        cmd_buffer_, staging_buf, original_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
                 }
-
-                VkBufferImageCopy region{};
-                region.bufferOffset      = 0;
-                region.bufferRowLength   = 0;
-                region.bufferImageHeight = 0;
-                region.imageSubresource  = { aspect, 0, 0, 1 };
-                region.imageOffset       = { 0, 0, 0 };
-                region.imageExtent       = { 1, 1, 1 };
-
-                functions_.cmd_copy_buffer_to_image(
-                    cmd_buffer_, staging_buf, original_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
                 result = functions_.end_command_buffer(cmd_buffer_);
             }
         }
diff --git a/framework/decode/vulkan_replay_consumer_base.cpp b/framework/decode/vulkan_replay_consumer_base.cpp
index 513b5eb295..207f83c09c 100644
--- a/framework/decode/vulkan_replay_consumer_base.cpp
+++ b/framework/decode/vulkan_replay_consumer_base.cpp
@@ -42,6 +42,7 @@
 #include "graphics/vulkan_check_buffer_references.h"
 #include "graphics/vulkan_device_util.h"
 #include "graphics/vulkan_util.h"
+#include "graphics/vulkan_resources_util.h"
 #include "graphics/vulkan_struct_get_pnext.h"
 #include "graphics/vulkan_struct_deep_copy.h"
 #include "graphics/vulkan_struct_extract_handles.h"
@@ -560,28 +561,37 @@ void VulkanReplayConsumerBase::ProcessFillMemoryCommand(uint64_t       memory_id
                 if (vk_result == VK_SUCCESS)
                     vk_result = device_table->BindImageMemory(device, ahb_image, image_memory, 0);
 
-                VkBufferImageCopy copy_region = {};
-                copy_region.imageSubresource  = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
-                copy_region.imageExtent       = { desc.width, desc.height, 1 };
-
                 ProcessBeginResourceInitCommand(buffer_info.device_id, size, size);
 
                 VulkanResourceInitializer* initializer = device_info->resource_initializer.get();
-                initializer->InitializeImage(size,
-                                             data,
-                                             0,
-                                             ahb_image,
-                                             image_info.imageType,
-                                             VK_FORMAT_R8G8B8A8_UNORM,
-                                             image_info.extent,
-                                             VK_IMAGE_ASPECT_COLOR_BIT,
-                                             image_info.samples,
-                                             image_info.usage,
-                                             image_info.initialLayout,
-                                             final_layout,
-                                             image_info.arrayLayers,
-                                             1,
-                                             &copy_region);
+
+                std::vector<VkImageAspectFlagBits> aspects;
+                graphics::GetFormatAspects(image_info.format, &aspects);
+
+                for (auto aspect : aspects)
+                {
+                    VkImageAspectFlags aspect_flags = aspect;
+
+                    VkBufferImageCopy copy_region = {};
+                    copy_region.imageSubresource  = { aspect_flags, 0, 0, 1 };
+                    copy_region.imageExtent       = { desc.width, desc.height, 1 };
+
+                    initializer->InitializeImage(size,
+                                                 data,
+                                                 0,
+                                                 ahb_image,
+                                                 image_info.imageType,
+                                                 image_info.format,
+                                                 image_info.extent,
+                                                 aspect,
+                                                 image_info.samples,
+                                                 image_info.usage,
+                                                 image_info.initialLayout,
+                                                 final_layout,
+                                                 image_info.arrayLayers,
+                                                 1,
+                                                 &copy_region);
+                }
 
                 ProcessEndResourceInitCommand(buffer_info.device_id);
 
diff --git a/framework/decode/vulkan_replay_dump_resources_draw_calls.cpp b/framework/decode/vulkan_replay_dump_resources_draw_calls.cpp
index ca8dec3a86..ad64088efd 100644
--- a/framework/decode/vulkan_replay_dump_resources_draw_calls.cpp
+++ b/framework/decode/vulkan_replay_dump_resources_draw_calls.cpp
@@ -735,9 +735,11 @@ void DrawCallsDumpingContext::FinalizeCommandBuffer()
                         barrier.oldLayout           = cat->intermediate_layout;
                         barrier.newLayout           = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
                         barrier.image               = cat->handle;
-                        barrier.subresourceRange    = {
-                               VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS
-                        };
+                        barrier.subresourceRange    = { graphics::GetFormatAspectMask(cat->format),
+                                                        0,
+                                                        VK_REMAINING_MIP_LEVELS,
+                                                        0,
+                                                        VK_REMAINING_ARRAY_LAYERS };
 
                         device_table_->CmdPipelineBarrier(current_command_buffer,
                                                           VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
@@ -1015,6 +1017,8 @@ VkResult DrawCallsDumpingContext::RevertRenderTargetImageLayouts(VkQueue queue,
     {
         VulkanImageInfo* image_info = render_targets_[rp][sp].depth_att_img;
 
+        img_barrier.subresourceRange.aspectMask = graphics::GetFormatAspectMask(image_info->format);
+
         img_barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
         img_barrier.newLayout     = entry->second.depth_attachment_layout;
         img_barrier.image         = image_info->handle;
diff --git a/framework/decode/vulkan_virtual_swapchain.cpp b/framework/decode/vulkan_virtual_swapchain.cpp
index 39c1173d6a..c95ad66207 100644
--- a/framework/decode/vulkan_virtual_swapchain.cpp
+++ b/framework/decode/vulkan_virtual_swapchain.cpp
@@ -25,6 +25,7 @@
 #include "decode/vulkan_resource_allocator.h"
 #include "decode/decoder_util.h"
 #include "decode/mark_injected_commands.h"
+#include "graphics/vulkan_resources_util.h"
 #include "vulkan/vulkan_core.h"
 #include <array>
 
@@ -520,7 +521,7 @@ VkResult VulkanVirtualSwapchain::CreateSwapchainResourceData(const VulkanDeviceI
                 VK_QUEUE_FAMILY_IGNORED,                // dstQueueFamilyIndex
                 VK_NULL_HANDLE,                         // image
                 VkImageSubresourceRange{
-                    VK_IMAGE_ASPECT_COLOR_BIT,
+                    graphics::GetFormatAspectMask(swapchain_info->format),
                     0,
                     image_create_info.mipLevels,
                     0,
@@ -808,6 +809,13 @@ VkResult VulkanVirtualSwapchain::QueuePresentKHR(VkResult
         uint32_t    capture_image_index = capture_image_indices[i];
         uint32_t    replay_image_index  = present_info->pImageIndices[i];
 
+        auto aspect_mask       = graphics::GetFormatAspectMask(swapchain_info->format);
+        subresource.aspectMask = aspect_mask;
+        initial_barrier_virtual_image.subresourceRange.aspectMask   = aspect_mask;
+        final_barrier_virtual_image.subresourceRange.aspectMask     = aspect_mask;
+        initial_barrier_swapchain_image.subresourceRange.aspectMask = aspect_mask;
+        final_barrier_swapchain_image.subresourceRange.aspectMask   = aspect_mask;
+
         // Get the per swapchain resource data so we have access to the virtual swapchain-specific information.
         if (swapchain_resources_.find(swapchain_info->handle) == swapchain_resources_.end())
         {
diff --git a/framework/encode/vulkan_capture_common.cpp b/framework/encode/vulkan_capture_common.cpp
index a4c43d968f..436c5a96a2 100644
--- a/framework/encode/vulkan_capture_common.cpp
+++ b/framework/encode/vulkan_capture_common.cpp
@@ -402,6 +402,8 @@ void CommonProcessHardwareBuffer(format::ThreadId                      thread_id
         sampler_ycbcr_conversion_info.pNext                        = nullptr;
         sampler_ycbcr_conversion_info.conversion                   = ycbcr_conversion;
 
+        auto ahb_image_aspect_mask = graphics::GetFormatAspectMask(format_properties.format);
+
         VkImageViewCreateInfo image_view_create_info;
         image_view_create_info.sType                           = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
         image_view_create_info.pNext                           = &sampler_ycbcr_conversion_info;
@@ -413,7 +415,7 @@ void CommonProcessHardwareBuffer(format::ThreadId                      thread_id
         image_view_create_info.components.g                    = VK_COMPONENT_SWIZZLE_IDENTITY;
         image_view_create_info.components.b                    = VK_COMPONENT_SWIZZLE_IDENTITY;
         image_view_create_info.components.a                    = VK_COMPONENT_SWIZZLE_IDENTITY;
-        image_view_create_info.subresourceRange.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
+        image_view_create_info.subresourceRange.aspectMask     = ahb_image_aspect_mask;
         image_view_create_info.subresourceRange.baseMipLevel   = 0u;
         image_view_create_info.subresourceRange.levelCount     = 1u;
         image_view_create_info.subresourceRange.baseArrayLayer = 0u;
@@ -506,6 +508,8 @@ void CommonProcessHardwareBuffer(format::ThreadId                      thread_id
         if (vk_result == VK_SUCCESS)
             vk_result = device_table->BindImageMemory(device, host_image, host_image_memory, 0);
 
+        auto host_image_aspect_mask = graphics::GetFormatAspectMask(host_image_format);
+
         VkImageViewCreateInfo host_image_view_create_info{ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, nullptr };
         host_image_view_create_info.flags                           = 0u;
         host_image_view_create_info.image                           = host_image;
@@ -515,7 +519,7 @@ void CommonProcessHardwareBuffer(format::ThreadId                      thread_id
         host_image_view_create_info.components.g                    = VK_COMPONENT_SWIZZLE_IDENTITY;
         host_image_view_create_info.components.b                    = VK_COMPONENT_SWIZZLE_IDENTITY;
         host_image_view_create_info.components.a                    = VK_COMPONENT_SWIZZLE_IDENTITY;
-        host_image_view_create_info.subresourceRange.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
+        host_image_view_create_info.subresourceRange.aspectMask     = host_image_aspect_mask;
         host_image_view_create_info.subresourceRange.baseMipLevel   = 0u;
         host_image_view_create_info.subresourceRange.levelCount     = 1u;
         host_image_view_create_info.subresourceRange.baseArrayLayer = 0u;
@@ -573,7 +577,7 @@ void CommonProcessHardwareBuffer(format::ThreadId                      thread_id
             barriers[0].srcQueueFamilyIndex             = VK_QUEUE_FAMILY_IGNORED;
             barriers[0].dstQueueFamilyIndex             = VK_QUEUE_FAMILY_IGNORED;
             barriers[0].image                           = ahb_image;
-            barriers[0].subresourceRange.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
+            barriers[0].subresourceRange.aspectMask     = ahb_image_aspect_mask;
             barriers[0].subresourceRange.baseMipLevel   = 0u;
             barriers[0].subresourceRange.levelCount     = 1u;
             barriers[0].subresourceRange.baseArrayLayer = 0u;
@@ -587,7 +591,7 @@ void CommonProcessHardwareBuffer(format::ThreadId                      thread_id
             barriers[1].srcQueueFamilyIndex             = VK_QUEUE_FAMILY_IGNORED;
             barriers[1].dstQueueFamilyIndex             = VK_QUEUE_FAMILY_IGNORED;
             barriers[1].image                           = host_image;
-            barriers[1].subresourceRange.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
+            barriers[1].subresourceRange.aspectMask     = host_image_aspect_mask;
             barriers[1].subresourceRange.baseMipLevel   = 0u;
             barriers[1].subresourceRange.levelCount     = 1u;
             barriers[1].subresourceRange.baseArrayLayer = 0u;
@@ -606,10 +610,10 @@ void CommonProcessHardwareBuffer(format::ThreadId                      thread_id
 
             VkImageCopy copy_region               = {};
             copy_region.dstSubresource.layerCount = 1;
-            copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+            copy_region.dstSubresource.aspectMask = host_image_aspect_mask;
             copy_region.extent                    = { desc.width, desc.height, 1 };
             copy_region.srcSubresource.layerCount = 1;
-            copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+            copy_region.srcSubresource.aspectMask = ahb_image_aspect_mask;
 
             device_table->CmdCopyImage(command_buffer,
                                        ahb_image,
@@ -844,7 +848,7 @@ void CommonProcessHardwareBuffer(format::ThreadId                      thread_id
                 barriers[0].srcQueueFamilyIndex             = VK_QUEUE_FAMILY_IGNORED;
                 barriers[0].dstQueueFamilyIndex             = VK_QUEUE_FAMILY_IGNORED;
                 barriers[0].image                           = ahb_image;
-                barriers[0].subresourceRange.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
+                barriers[0].subresourceRange.aspectMask     = ahb_image_aspect_mask;
                 barriers[0].subresourceRange.baseMipLevel   = 0u;
                 barriers[0].subresourceRange.levelCount     = 1u;
                 barriers[0].subresourceRange.baseArrayLayer = 0u;
@@ -857,7 +861,7 @@ void CommonProcessHardwareBuffer(format::ThreadId                      thread_id
                 barriers[1].srcQueueFamilyIndex             = VK_QUEUE_FAMILY_IGNORED;
                 barriers[1].dstQueueFamilyIndex             = VK_QUEUE_FAMILY_IGNORED;
                 barriers[1].image                           = host_image;
-                barriers[1].subresourceRange.aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT;
+                barriers[1].subresourceRange.aspectMask     = host_image_aspect_mask;
                 barriers[1].subresourceRange.baseMipLevel   = 0u;
                 barriers[1].subresourceRange.levelCount     = 1u;
                 barriers[1].subresourceRange.baseArrayLayer = 0u;
diff --git a/framework/graphics/vulkan_resources_util.h b/framework/graphics/vulkan_resources_util.h
index d024239cc6..0fe1ded81b 100644
--- a/framework/graphics/vulkan_resources_util.h
+++ b/framework/graphics/vulkan_resources_util.h
@@ -31,6 +31,7 @@
 #include "vulkan/vulkan_core.h"
 
 #include <vector>
+#include <functional>
 
 GFXRECON_BEGIN_NAMESPACE(gfxrecon)
 GFXRECON_BEGIN_NAMESPACE(graphics)


Reviews:
user: login: locke-lunarg
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T03:59:37Z
user: login: fabian-lunarg
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T10:48:10Z
user: login: fabian-lunarg
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T13:12:23Z
user: login: fabian-lunarg
body: the changes look good to me, overall cleaner, all CI tests pass.
I checked several cases on Desktop and Android and did not spot any differences
in terms of correctness or validation-warnings.
just curious when/where this caused problems -
is there a testcase for this or could we create a simple one?
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T13:24:39Z
user: login: fabian-lunarg
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T07:02:28Z
user: login: bradgrantham-lunarg
body: LGTM, just need to resolve those merge conflicts.
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T16:08:13Z
user: login: locke-lunarg
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T23:08:06Z
user: login: locke-lunarg
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-08T15:39:05Z

Review comments:
diff_hunk: @@ -556,28 +557,35 @@ void VulkanReplayConsumerBase::ProcessFillMemoryCommand(uint64_t       memory_id
                 if (vk_result == VK_SUCCESS)
                     vk_result = device_table->BindImageMemory(device, ahb_image, image_memory, 0);
 
-                VkBufferImageCopy copy_region = {};
-                copy_region.imageSubresource  = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
-                copy_region.imageExtent       = { desc.width, desc.height, 1 };
-
                 ProcessBeginResourceInitCommand(buffer_info.device_id, size, size);
 
                 VulkanResourceInitializer* initializer = device_info->resource_initializer.get();
-                initializer->InitializeImage(size,
-                                             data,
-                                             0,
-                                             ahb_image,
-                                             image_info.imageType,
-                                             VK_FORMAT_R8G8B8A8_UNORM,
-                                             image_info.extent,
-                                             VK_IMAGE_ASPECT_COLOR_BIT,
-                                             image_info.samples,
-                                             image_info.usage,
-                                             image_info.initialLayout,
-                                             final_layout,
-                                             image_info.arrayLayers,
-                                             1,
-                                             &copy_region);
+
+                std::vector<VkImageAspectFlagBits> aspects;
+                graphics::GetFormatAspects(image_info.format, &aspects);
+
+                for (auto aspect : aspects)
+                {
+                    VkBufferImageCopy copy_region = {};
+                    copy_region.imageSubresource  = { aspect, 0, 0, 1 };
+                    copy_region.imageExtent       = { desc.width, desc.height, 1 };
+
+                    initializer->InitializeImage(size,
+                                                 data,
+                                                 0,
+                                                 ahb_image,
+                                                 image_info.imageType,
+                                                 image_info.format,
+                                                 image_info.extent,
+                                                 aspect,
+                                                 image_info.samples,
+                                                 image_info.usage,
+                                                 image_info.initialLayout,
+                                                 final_layout,
+                                                 image_info.arrayLayers,
+                                                 1,
+                                                 &copy_region);
+                }
path: framework/decode/vulkan_replay_consumer_base.cpp
user: login: locke-lunarg
body: Could someone please helps me to verify whether this change is correct?
created_at: 2025-05-06T03:59:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -556,28 +557,35 @@ void VulkanReplayConsumerBase::ProcessFillMemoryCommand(uint64_t       memory_id
                 if (vk_result == VK_SUCCESS)
                     vk_result = device_table->BindImageMemory(device, ahb_image, image_memory, 0);
 
-                VkBufferImageCopy copy_region = {};
-                copy_region.imageSubresource  = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
-                copy_region.imageExtent       = { desc.width, desc.height, 1 };
-
                 ProcessBeginResourceInitCommand(buffer_info.device_id, size, size);
 
                 VulkanResourceInitializer* initializer = device_info->resource_initializer.get();
-                initializer->InitializeImage(size,
-                                             data,
-                                             0,
-                                             ahb_image,
-                                             image_info.imageType,
-                                             VK_FORMAT_R8G8B8A8_UNORM,
-                                             image_info.extent,
-                                             VK_IMAGE_ASPECT_COLOR_BIT,
-                                             image_info.samples,
-                                             image_info.usage,
-                                             image_info.initialLayout,
-                                             final_layout,
-                                             image_info.arrayLayers,
-                                             1,
-                                             &copy_region);
+
+                std::vector<VkImageAspectFlagBits> aspects;
+                graphics::GetFormatAspects(image_info.format, &aspects);
+
+                for (auto aspect : aspects)
+                {
+                    VkBufferImageCopy copy_region = {};
+                    copy_region.imageSubresource  = { aspect, 0, 0, 1 };
+                    copy_region.imageExtent       = { desc.width, desc.height, 1 };
+
+                    initializer->InitializeImage(size,
+                                                 data,
+                                                 0,
+                                                 ahb_image,
+                                                 image_info.imageType,
+                                                 image_info.format,
+                                                 image_info.extent,
+                                                 aspect,
+                                                 image_info.samples,
+                                                 image_info.usage,
+                                                 image_info.initialLayout,
+                                                 final_layout,
+                                                 image_info.arrayLayers,
+                                                 1,
+                                                 &copy_region);
+                }
path: framework/decode/vulkan_replay_consumer_base.cpp
user: login: fabian-lunarg
body: ok, this is guarded by `VK_USE_PLATFORM_ANDROID_KHR`, took me a while to realize :)
created_at: 2025-05-06T10:48:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -556,28 +557,35 @@ void VulkanReplayConsumerBase::ProcessFillMemoryCommand(uint64_t       memory_id
                 if (vk_result == VK_SUCCESS)
                     vk_result = device_table->BindImageMemory(device, ahb_image, image_memory, 0);
 
-                VkBufferImageCopy copy_region = {};
-                copy_region.imageSubresource  = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
-                copy_region.imageExtent       = { desc.width, desc.height, 1 };
-
                 ProcessBeginResourceInitCommand(buffer_info.device_id, size, size);
 
                 VulkanResourceInitializer* initializer = device_info->resource_initializer.get();
-                initializer->InitializeImage(size,
-                                             data,
-                                             0,
-                                             ahb_image,
-                                             image_info.imageType,
-                                             VK_FORMAT_R8G8B8A8_UNORM,
-                                             image_info.extent,
-                                             VK_IMAGE_ASPECT_COLOR_BIT,
-                                             image_info.samples,
-                                             image_info.usage,
-                                             image_info.initialLayout,
-                                             final_layout,
-                                             image_info.arrayLayers,
-                                             1,
-                                             &copy_region);
+
+                std::vector<VkImageAspectFlagBits> aspects;
+                graphics::GetFormatAspects(image_info.format, &aspects);
+
+                for (auto aspect : aspects)
+                {
+                    VkBufferImageCopy copy_region = {};
+                    copy_region.imageSubresource  = { aspect, 0, 0, 1 };
+                    copy_region.imageExtent       = { desc.width, desc.height, 1 };
+
+                    initializer->InitializeImage(size,
+                                                 data,
+                                                 0,
+                                                 ahb_image,
+                                                 image_info.imageType,
+                                                 image_info.format,
+                                                 image_info.extent,
+                                                 aspect,
+                                                 image_info.samples,
+                                                 image_info.usage,
+                                                 image_info.initialLayout,
+                                                 final_layout,
+                                                 image_info.arrayLayers,
+                                                 1,
+                                                 &copy_region);
+                }
path: framework/decode/vulkan_replay_consumer_base.cpp
user: login: fabian-lunarg
body: I tried several android captures I had but none is exercising this code-path.
it seems this handling an AndroidHardwareBuffer case?
created_at: 2025-05-06T13:12:23Z
author_association: CONTRIBUTOR
diff_hunk: @@ -556,28 +557,35 @@ void VulkanReplayConsumerBase::ProcessFillMemoryCommand(uint64_t       memory_id
                 if (vk_result == VK_SUCCESS)
                     vk_result = device_table->BindImageMemory(device, ahb_image, image_memory, 0);
 
-                VkBufferImageCopy copy_region = {};
-                copy_region.imageSubresource  = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
-                copy_region.imageExtent       = { desc.width, desc.height, 1 };
-
                 ProcessBeginResourceInitCommand(buffer_info.device_id, size, size);
 
                 VulkanResourceInitializer* initializer = device_info->resource_initializer.get();
-                initializer->InitializeImage(size,
-                                             data,
-                                             0,
-                                             ahb_image,
-                                             image_info.imageType,
-                                             VK_FORMAT_R8G8B8A8_UNORM,
-                                             image_info.extent,
-                                             VK_IMAGE_ASPECT_COLOR_BIT,
-                                             image_info.samples,
-                                             image_info.usage,
-                                             image_info.initialLayout,
-                                             final_layout,
-                                             image_info.arrayLayers,
-                                             1,
-                                             &copy_region);
+
+                std::vector<VkImageAspectFlagBits> aspects;
+                graphics::GetFormatAspects(image_info.format, &aspects);
+
+                for (auto aspect : aspects)
+                {
+                    VkBufferImageCopy copy_region = {};
+                    copy_region.imageSubresource  = { aspect, 0, 0, 1 };
+                    copy_region.imageExtent       = { desc.width, desc.height, 1 };
+
+                    initializer->InitializeImage(size,
+                                                 data,
+                                                 0,
+                                                 ahb_image,
+                                                 image_info.imageType,
+                                                 image_info.format,
+                                                 image_info.extent,
+                                                 aspect,
+                                                 image_info.samples,
+                                                 image_info.usage,
+                                                 image_info.initialLayout,
+                                                 final_layout,
+                                                 image_info.arrayLayers,
+                                                 1,
+                                                 &copy_region);
+                }
path: framework/decode/vulkan_replay_consumer_base.cpp
user: login: fabian-lunarg
body: found an android capture that exercises that code-path.
there were no apparent issues here, both with and w/o `-m rebind`
created_at: 2025-05-07T07:02:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1678,37 +1679,23 @@ void VulkanRebindAllocator::WriteBoundResourceStaging(
                     "Ignoring potential mip maps/array layers in staging buffer to image copy: support "
                     "not yet implemented");
 
-                VkImageAspectFlags aspect{};
-                switch (resource_alloc_info->format)
+                std::vector<VkImageAspectFlagBits> aspects;
+                graphics::GetFormatAspects(resource_alloc_info->format, &aspects);
+
+                for (auto aspect : aspects)
                 {
-                    case VK_FORMAT_D16_UNORM:
-                    case VK_FORMAT_X8_D24_UNORM_PACK32:
-                    case VK_FORMAT_D32_SFLOAT:
-                        aspect = VK_IMAGE_ASPECT_DEPTH_BIT;
-                        break;
-                    case VK_FORMAT_S8_UINT:
-                        aspect = VK_IMAGE_ASPECT_STENCIL_BIT;
-                        break;
-                    case VK_FORMAT_D16_UNORM_S8_UINT:
-                    case VK_FORMAT_D24_UNORM_S8_UINT:
-                    case VK_FORMAT_D32_SFLOAT_S8_UINT:
-                        aspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
-                        break;
-                    default:
-                        aspect = VK_IMAGE_ASPECT_COLOR_BIT;
-                        break;
+                    VkImageAspectFlags aspect_flags = aspect;
+
+                    VkBufferImageCopy region{};
+                    region.bufferOffset      = 0;
+                    region.bufferRowLength   = 0;
+                    region.bufferImageHeight = 0;
+                    region.imageSubresource  = { aspect_flags, 0, 0, 1 };
path: framework/decode/vulkan_rebind_allocator.cpp
user: login: locke-lunarg
body: Added this change. `VkBufferImageCopy-aspectMask-09103: The aspectMask member of imageSubresource must only have a single bit set.`
created_at: 2025-05-07T23:08:01Z
author_association: CONTRIBUTOR
diff_hunk: @@ -556,28 +557,35 @@ void VulkanReplayConsumerBase::ProcessFillMemoryCommand(uint64_t       memory_id
                 if (vk_result == VK_SUCCESS)
                     vk_result = device_table->BindImageMemory(device, ahb_image, image_memory, 0);
 
-                VkBufferImageCopy copy_region = {};
-                copy_region.imageSubresource  = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
-                copy_region.imageExtent       = { desc.width, desc.height, 1 };
-
                 ProcessBeginResourceInitCommand(buffer_info.device_id, size, size);
 
                 VulkanResourceInitializer* initializer = device_info->resource_initializer.get();
-                initializer->InitializeImage(size,
-                                             data,
-                                             0,
-                                             ahb_image,
-                                             image_info.imageType,
-                                             VK_FORMAT_R8G8B8A8_UNORM,
-                                             image_info.extent,
-                                             VK_IMAGE_ASPECT_COLOR_BIT,
-                                             image_info.samples,
-                                             image_info.usage,
-                                             image_info.initialLayout,
-                                             final_layout,
-                                             image_info.arrayLayers,
-                                             1,
-                                             &copy_region);
+
+                std::vector<VkImageAspectFlagBits> aspects;
+                graphics::GetFormatAspects(image_info.format, &aspects);
+
+                for (auto aspect : aspects)
+                {
+                    VkBufferImageCopy copy_region = {};
+                    copy_region.imageSubresource  = { aspect, 0, 0, 1 };
+                    copy_region.imageExtent       = { desc.width, desc.height, 1 };
+
+                    initializer->InitializeImage(size,
+                                                 data,
+                                                 0,
+                                                 ahb_image,
+                                                 image_info.imageType,
+                                                 image_info.format,
+                                                 image_info.extent,
+                                                 aspect,
+                                                 image_info.samples,
+                                                 image_info.usage,
+                                                 image_info.initialLayout,
+                                                 final_layout,
+                                                 image_info.arrayLayers,
+                                                 1,
+                                                 &copy_region);
+                }
path: framework/decode/vulkan_replay_consumer_base.cpp
user: login: locke-lunarg
body: Thank you for testing.
created_at: 2025-05-08T15:39:05Z
author_association: CONTRIBUTOR

PR comments:
user: login: ci-tester-lunarg
created_at: 2025-05-05T22:28:42Z
body: CI gfxreconstruct build queued with queue ID 437784.
author_association: COLLABORATOR
user: login: ci-tester-lunarg
created_at: 2025-05-05T22:38:13Z
body: CI gfxreconstruct build queued with queue ID 437787.
author_association: COLLABORATOR
user: login: ci-tester-lunarg
created_at: 2025-05-05T23:20:49Z
body: CI gfxreconstruct build # 6804 running.
author_association: COLLABORATOR
user: login: ci-tester-lunarg
created_at: 2025-05-05T23:49:19Z
body: CI gfxreconstruct build # 6804 failed.
author_association: COLLABORATOR
user: login: ci-tester-lunarg
created_at: 2025-05-06T03:23:48Z
body: CI gfxreconstruct build queued with queue ID 437895.
author_association: COLLABORATOR
user: login: ci-tester-lunarg
created_at: 2025-05-06T03:25:01Z
body: CI gfxreconstruct build # 6806 running.
author_association: COLLABORATOR
user: login: ci-tester-lunarg
created_at: 2025-05-06T03:41:41Z
body: CI gfxreconstruct build queued with queue ID 437913.
author_association: COLLABORATOR
user: login: ci-tester-lunarg
created_at: 2025-05-06T03:54:20Z
body: CI gfxreconstruct build # 6807 running.
author_association: COLLABORATOR
user: login: ci-tester-lunarg
created_at: 2025-05-06T04:30:25Z
body: CI gfxreconstruct build # 6807 passed.
author_association: COLLABORATOR
user: login: bradgrantham-lunarg
created_at: 2025-05-07T00:47:55Z
body: > just curious when/where this caused problems - is there a testcase for this or could we create a simple one?

Just reported in #2166.  We don't have a test case.  Locke, can you think for a minute whether there may be a capture file already in CI that exercises one of these code paths?  Or are there a few lines we could add to vkcube to make the code path run?  I don't think you have to go as far as making a sample program.
author_association: CONTRIBUTOR
user: login: locke-lunarg
created_at: 2025-05-07T06:30:57Z
body: @fabian-lunarg @bradgrantham-lunarg  I don't know how to make this bug happen. For issue https://github.com/LunarG/gfxreconstruct/issues/2166, the bug could happen with `-m rebind` in two cases. 

1. `VulkanReplayConsumerBase::ProcessFillMemoryCommand (for image)`, and the memory type is not `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT (!resource_alloc_info->is_host_visible)`. 

2. `VulkanRebindAllocator::BindImageMemory`, and the memory type is not `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT (!resource_alloc_info->is_host_visible)`, and the memory had been written by `ProcessFillMemoryCommand (memory_alloc_info->original_content != nullptr)`.

Although a depth image memory isn't host visible, but gfxr doesn't write depth image memory. `ProcessFillMemoryCommand` isn't for depth images. I couldn't write a testcase for it.
author_association: CONTRIBUTOR
user: login: locke-lunarg
created_at: 2025-05-07T06:57:22Z
body: https://github.com/LunarG/gfxreconstruct/pull/2190
This PR did something that I did. Only for rebind. In this case, `dev` should already solve issue https://github.com/LunarG/gfxreconstruct/issues/2166. I will override some this PR.
author_association: CONTRIBUTOR
user: login: ci-tester-lunarg
created_at: 2025-05-07T16:54:14Z
body: CI gfxreconstruct build queued with queue ID 439090.
author_association: COLLABORATOR
user: login: ci-tester-lunarg
created_at: 2025-05-07T16:55:01Z
body: CI gfxreconstruct build # 6827 running.
author_association: COLLABORATOR
user: login: ci-tester-lunarg
created_at: 2025-05-07T17:31:32Z
body: CI gfxreconstruct build # 6827 passed.
author_association: COLLABORATOR
user: login: ci-tester-lunarg
created_at: 2025-05-07T21:04:09Z
body: CI gfxreconstruct build queued with queue ID 439202.
author_association: COLLABORATOR
user: login: ci-tester-lunarg
created_at: 2025-05-07T21:05:01Z
body: CI gfxreconstruct build # 6829 running.
author_association: COLLABORATOR
user: login: ci-tester-lunarg
created_at: 2025-05-07T21:11:57Z
body: CI gfxreconstruct build queued with queue ID 439218.
author_association: COLLABORATOR
user: login: ci-tester-lunarg
created_at: 2025-05-07T21:16:46Z
body: CI gfxreconstruct build queued with queue ID 439220.
author_association: COLLABORATOR
user: login: ci-tester-lunarg
created_at: 2025-05-07T21:44:17Z
body: CI gfxreconstruct build queued with queue ID 439255.
author_association: COLLABORATOR
user: login: ci-tester-lunarg
created_at: 2025-05-07T22:55:01Z
body: CI gfxreconstruct build # 6832 running.
author_association: COLLABORATOR
user: login: ci-tester-lunarg
created_at: 2025-05-07T23:31:19Z
body: CI gfxreconstruct build # 6832 passed.
author_association: COLLABORATOR