Skip to content

Commit a3e57a8

Browse files
authored
Vulkan dump resources: Convert images with blit (#1799)
1 parent ae2a3cf commit a3e57a8

17 files changed

+381
-469
lines changed

USAGE_android.md

+3
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,7 @@ usage: gfxrecon.py replay [-h] [--push-file LOCAL_FILE] [--version] [--pause-fra
709709
[--dump-resources-dump-vertex-index-buffers]
710710
[--dump-resources-json-output-per-command]
711711
[--dump-resources-dump-immutable-resources]
712+
[--dump-resources-dump-raw-images]
712713
[--dump-resources-dump-all-image-subresources]
713714
[--pbi-all] [--pbis <index1,index2>]
714715
[file]
@@ -902,6 +903,8 @@ optional arguments:
902903
Enables dumping of resources that are used as inputs in the commands requested for dumping
903904
--dump-resources-dump-all-image-subresources
904905
Enables dumping of all image sub resources (mip map levels and array layers)
906+
--dump-resources-dump-raw-images
907+
When enabled all image resources will be dumped verbatim as raw bin files.
905908
--pbi-all
906909
Print all block information.
907910
--pbis <index1,index2>

USAGE_desktop_Vulkan.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,7 @@ gfxrecon-replay [-h | --help] [--version] [--gpu <index>]
542542
[--dump-resources-dump-vertex-index-buffers]
543543
[--dump-resources-json-output-per-command]
544544
[--dump-resources-dump-immutable-resources]
545+
[--dump-resources-dump-raw-images]
545546
[--dump-resources-dump-all-image-subresources] <file>
546547
[--pbi-all] [--pbis <index1,index2>]
547548
[--pipeline-creation-jobs | --pcj <num_jobs>]
@@ -758,15 +759,17 @@ Optional arguments:
758759
Enables dumping of resources that are used as inputs in the commands requested for dumping.
759760
--dump-resources-dump-all-image-subresources
760761
Enables dumping of all image sub resources (mip map levels and array layers).
761-
--pbi-all
762+
--dump-resources-dump-raw-images
763+
When enabled all image resources will be dumped verbatim as raw bin files.
764+
--pbi-all
762765
Print all block information.
763766
--pbis <index1,index2>
764767
Print block information between block index1 and block index2.
765768
--pipeline-creation-jobs | --pcj <num_jobs>
766769
Specify the number of asynchronous pipeline-creation jobs as integer.
767770
If <num_jobs> is negative it will be added to the number of cpu-cores, e.g. -1 -> num_cores - 1.
768771
Default: 0 (do not use asynchronous operations)
769-
772+
770773
```
771774

772775
### Key Controls

android/scripts/gfxrecon.py

+4
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ def CreateReplayParser():
111111
parser.add_argument('--dump-resources-json-output-per-command', action='store_true', default=False, help= 'Enables storing a json output file for each dumped command. Default is disabled.')
112112
parser.add_argument('--dump-resources-dump-immutable-resources', action='store_true', default=False, help= 'Dump immutable immutable shader resources.')
113113
parser.add_argument('--dump-resources-dump-all-image-subresources', action='store_true', default=False, help= 'Dump all available mip levels and layers when dumping images.')
114+
parser.add_argument('--dump-resources-dump-raw-images', action='store_true', default=False, help= 'Dump images verbatim as raw binary files.')
114115
parser.add_argument('--pbi-all', action='store_true', default=False, help='Print all block information.')
115116
parser.add_argument('--pbis', metavar='RANGES', default=False, help='Print block information between block index1 and block index2')
116117
parser.add_argument('--pcj', '--pipeline-creation-jobs', action='store_true', default=False, help='Specify the number of pipeline-creation-jobs or background-threads.')
@@ -271,6 +272,9 @@ def MakeExtrasString(args):
271272
if args.dump_resources_dump_all_image_subresources:
272273
arg_list.append('--dump-resources-dump-all-image-subresources')
273274

275+
if args.dump_resources_dump_raw_images:
276+
arg_list.append('--dump-resources-dump-raw-images')
277+
274278
if args.pbi_all:
275279
arg_list.append('--pbi-all')
276280

framework/decode/vulkan_replay_dump_resources_common.cpp

+125-49
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ bool IsFormatAstcCompressed(VkFormat format)
5959
return vkuFormatIsCompressed_ASTC_HDR(format) || vkuFormatIsCompressed_ASTC_LDR(format);
6060
}
6161

62-
util::imagewriter::DataFormats VkFormatToImageWriterDataFormat(VkFormat format)
62+
static util::imagewriter::DataFormats VkFormatToImageWriterDataFormat(VkFormat format)
6363
{
6464
if (IsFormatAstcCompressed(format))
6565
{
@@ -68,9 +68,6 @@ util::imagewriter::DataFormats VkFormatToImageWriterDataFormat(VkFormat format)
6868

6969
switch (format)
7070
{
71-
case VK_FORMAT_R8_UNORM:
72-
return util::imagewriter::DataFormats::kFormat_R8;
73-
7471
case VK_FORMAT_R8G8B8_UNORM:
7572
return util::imagewriter::DataFormats::kFormat_RGB;
7673

@@ -81,19 +78,10 @@ util::imagewriter::DataFormats VkFormatToImageWriterDataFormat(VkFormat format)
8178
case VK_FORMAT_B8G8R8_UNORM:
8279
return util::imagewriter::DataFormats::kFormat_BGR;
8380

84-
case VK_FORMAT_R16G16B16A16_SFLOAT:
85-
return util::imagewriter::DataFormats::kFormat_R16G16B16A16_SFLOAT;
86-
87-
case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
88-
return util::imagewriter::DataFormats::kFormat_B10G11R11_UFLOAT;
89-
9081
case VK_FORMAT_B8G8R8A8_SRGB:
9182
case VK_FORMAT_B8G8R8A8_UNORM:
9283
return util::imagewriter::DataFormats::kFormat_BGRA;
9384

94-
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
95-
return util::imagewriter::DataFormats::kFormat_A2B10G10R10;
96-
9785
case VK_FORMAT_D32_SFLOAT:
9886
case VK_FORMAT_D32_SFLOAT_S8_UINT:
9987
return util::imagewriter::DataFormats::kFormat_D32_FLOAT;
@@ -109,36 +97,45 @@ util::imagewriter::DataFormats VkFormatToImageWriterDataFormat(VkFormat format)
10997
}
11098
}
11199

112-
const char* ImageFileExtension(VkFormat format, util::ScreenshotFormat image_file_format)
100+
const char* ImageFileExtension(DumpedImageFormat image_format)
113101
{
114-
const util::imagewriter::DataFormats output_image_format = VkFormatToImageWriterDataFormat(format);
115-
116-
if (output_image_format != util::imagewriter::DataFormats::kFormat_UNSPECIFIED)
102+
switch (image_format)
117103
{
118-
if (output_image_format == util::imagewriter::DataFormats::kFormat_ASTC)
119-
{
104+
case kFormatBMP:
105+
return ".bmp";
106+
107+
case KFormatPNG:
108+
return ".png";
109+
110+
case KFormatAstc:
120111
return ".astc";
121-
}
122-
else
123-
{
124-
switch (image_file_format)
125-
{
126-
case util::ScreenshotFormat::kBmp:
127-
return ".bmp";
128112

129-
case util::ScreenshotFormat::kPng:
130-
return ".png";
113+
case KFormatRaw:
114+
default:
115+
return ".bin";
116+
}
117+
}
131118

132-
default:
133-
assert(0);
134-
return ".bmp";
135-
}
136-
}
119+
static VkFormat ChooseDestinationImageFormat(VkFormat format)
120+
{
121+
VkFormat dst_format;
122+
123+
if (vkuFormatIsSRGB(format))
124+
{
125+
dst_format = vkuFormatHasAlpha(format) ? VK_FORMAT_B8G8R8A8_SRGB : VK_FORMAT_B8G8R8_SRGB;
126+
}
127+
else if (vkuFormatIsDepthOrStencil(format))
128+
{
129+
// Converting depth format with vkCmdBlit is not allowed.
130+
// We will do the conversion on the cpu.
131+
dst_format = format;
137132
}
138133
else
139134
{
140-
return ".bin";
135+
dst_format = vkuFormatHasAlpha(format) ? VK_FORMAT_B8G8R8A8_UNORM : VK_FORMAT_B8G8R8_UNORM;
141136
}
137+
138+
return dst_format;
142139
}
143140

144141
uint32_t GetMemoryTypeIndex(const VkPhysicalDeviceMemoryProperties& memory_properties,
@@ -448,6 +445,7 @@ VkResult DumpImageToFile(const ImageInfo* image_info,
448445
std::vector<bool>& scaling_supported,
449446
util::ScreenshotFormat image_file_format,
450447
bool dump_all_subresources,
448+
bool dump_image_raw,
451449
VkImageLayout layout,
452450
const VkExtent3D* extent_p)
453451
{
@@ -477,6 +475,8 @@ VkResult DumpImageToFile(const ImageInfo* image_info,
477475
(extent_p != nullptr) ? extent_p->height : image_info->extent.height,
478476
(extent_p != nullptr) ? extent_p->depth : image_info->extent.depth };
479477

478+
const VkFormat dst_format = ChooseDestinationImageFormat(image_info->format);
479+
480480
uint32_t f = 0;
481481
for (size_t i = 0; i < aspects.size(); ++i)
482482
{
@@ -504,7 +504,8 @@ VkResult DumpImageToFile(const ImageInfo* image_info,
504504
subresource_sizes,
505505
scaled,
506506
false,
507-
scale);
507+
scale,
508+
dst_format);
508509

509510
assert(!subresource_offsets.empty());
510511
assert(!subresource_sizes.empty());
@@ -519,7 +520,18 @@ VkResult DumpImageToFile(const ImageInfo* image_info,
519520
return res;
520521
}
521522

522-
const util::imagewriter::DataFormats output_image_format = VkFormatToImageWriterDataFormat(image_info->format);
523+
const DumpedImageFormat output_image_format = GetDumpedImageFormat(device_info,
524+
device_table,
525+
instance_table,
526+
object_info_table,
527+
image_info->format,
528+
image_info->tiling,
529+
image_info->type,
530+
image_file_format,
531+
dump_image_raw);
532+
533+
const util::imagewriter::DataFormats image_writer_format = VkFormatToImageWriterDataFormat(dst_format);
534+
assert(image_writer_format != util::imagewriter::DataFormats::kFormat_UNSPECIFIED);
523535

524536
if ((image_info->level_count == 1 && image_info->layer_count == 1) || !dump_all_subresources)
525537
{
@@ -529,7 +541,7 @@ VkResult DumpImageToFile(const ImageInfo* image_info,
529541
if (aspects[i] == VK_IMAGE_ASPECT_STENCIL_BIT)
530542
continue;
531543

532-
if (output_image_format != util::imagewriter::DataFormats::kFormat_UNSPECIFIED)
544+
if (output_image_format != KFormatRaw)
533545
{
534546
VkExtent3D scaled_extent;
535547
if (scale != 1.0f && scaled)
@@ -543,10 +555,10 @@ VkResult DumpImageToFile(const ImageInfo* image_info,
543555
scaled_extent = image_info->extent;
544556
}
545557

546-
const uint32_t texel_size = vkuFormatElementSizeWithAspect(image_info->format, aspects[i]);
558+
const uint32_t texel_size = vkuFormatElementSizeWithAspect(dst_format, aspects[i]);
547559
const uint32_t stride = texel_size * scaled_extent.width;
548560

549-
if (output_image_format == util::imagewriter::DataFormats::kFormat_ASTC)
561+
if (output_image_format == KFormatAstc)
550562
{
551563
VKU_FORMAT_INFO format_info = vkuGetFormatInfo(image_info->format);
552564

@@ -560,26 +572,26 @@ VkResult DumpImageToFile(const ImageInfo* image_info,
560572
data.data(),
561573
subresource_sizes[0]);
562574
}
563-
else if (image_file_format == util::ScreenshotFormat::kBmp)
575+
else if (output_image_format == kFormatBMP)
564576
{
565577
util::imagewriter::WriteBmpImage(filename,
566578
scaled_extent.width,
567579
scaled_extent.height,
568580
subresource_sizes[0],
569581
data.data(),
570582
stride,
571-
output_image_format,
583+
image_writer_format,
572584
vkuFormatHasAlpha(image_info->format));
573585
}
574-
else if (image_file_format == util::ScreenshotFormat::kPng)
586+
else if (output_image_format == KFormatPNG)
575587
{
576588
util::imagewriter::WritePngImage(filename,
577589
scaled_extent.width,
578590
scaled_extent.height,
579591
subresource_sizes[0],
580592
data.data(),
581593
stride,
582-
output_image_format,
594+
image_writer_format,
583595
vkuFormatHasAlpha(image_info->format));
584596
}
585597
}
@@ -607,7 +619,7 @@ VkResult DumpImageToFile(const ImageInfo* image_info,
607619
const void* data_offset = reinterpret_cast<const void*>(
608620
reinterpret_cast<const uint8_t*>(data.data()) + subresource_offsets[sub_res_idx]);
609621

610-
if (output_image_format != util::imagewriter::DataFormats::kFormat_UNSPECIFIED)
622+
if (output_image_format != KFormatRaw)
611623
{
612624
VkExtent3D scaled_extent;
613625
if (scale != 1.0f && scaled)
@@ -628,7 +640,7 @@ VkResult DumpImageToFile(const ImageInfo* image_info,
628640
const uint32_t texel_size = vkuFormatElementSizeWithAspect(image_info->format, aspect);
629641
const uint32_t stride = texel_size * scaled_extent.width;
630642

631-
if (output_image_format == util::imagewriter::DataFormats::kFormat_ASTC)
643+
if (output_image_format == KFormatAstc)
632644
{
633645
VKU_FORMAT_INFO format_info = vkuGetFormatInfo(image_info->format);
634646

@@ -642,25 +654,25 @@ VkResult DumpImageToFile(const ImageInfo* image_info,
642654
data.data(),
643655
subresource_sizes[sub_res_idx]);
644656
}
645-
else if (image_file_format == util::ScreenshotFormat::kBmp)
657+
else if (output_image_format == kFormatBMP)
646658
{
647659
util::imagewriter::WriteBmpImage(filename,
648660
scaled_extent.width,
649661
scaled_extent.height,
650662
subresource_sizes[sub_res_idx],
651663
data_offset,
652664
stride,
653-
output_image_format);
665+
image_writer_format);
654666
}
655-
else if (image_file_format == util::ScreenshotFormat::kPng)
667+
else if (output_image_format == KFormatPNG)
656668
{
657669
util::imagewriter::WritePngImage(filename,
658670
scaled_extent.width,
659671
scaled_extent.height,
660672
subresource_sizes[sub_res_idx],
661673
data_offset,
662674
stride,
663-
output_image_format);
675+
image_writer_format);
664676
}
665677
}
666678
else
@@ -854,5 +866,69 @@ void GetFormatAspects(VkFormat format, std::vector<VkImageAspectFlagBits>& aspec
854866
}
855867
}
856868

869+
DumpedImageFormat GetDumpedImageFormat(const DeviceInfo* device_info,
870+
const encode::VulkanDeviceTable* device_table,
871+
const encode::VulkanInstanceTable* instance_table,
872+
VulkanObjectInfoTable& object_info_table,
873+
VkFormat src_format,
874+
VkImageTiling src_image_tiling,
875+
VkImageType type,
876+
util::ScreenshotFormat image_file_format,
877+
bool dump_raw)
878+
{
879+
const PhysicalDeviceInfo* phys_dev_info = object_info_table.GetPhysicalDeviceInfo(device_info->parent_id);
880+
assert(phys_dev_info);
881+
882+
// If there's a request for images to be dumped as raw bin files
883+
if (dump_raw)
884+
{
885+
// We consider astc as a raw bin format
886+
if (IsFormatAstcCompressed(src_format))
887+
{
888+
return KFormatAstc;
889+
}
890+
else
891+
{
892+
return KFormatRaw;
893+
}
894+
}
895+
896+
// Astc images will be dumped as .astc files
897+
if (IsFormatAstcCompressed(src_format))
898+
{
899+
return KFormatAstc;
900+
}
901+
902+
graphics::VulkanResourcesUtil resource_util(device_info->handle,
903+
device_info->parent,
904+
*device_table,
905+
*instance_table,
906+
*phys_dev_info->replay_device_info->memory_properties);
907+
908+
// Image cannot be converted into a format compatible for dumping in an image file
909+
const VkFormat dst_format = ChooseDestinationImageFormat(src_format);
910+
bool is_blit_supported = resource_util.IsBlitSupported(src_format, src_image_tiling, dst_format);
911+
if (!vkuFormatIsDepthOrStencil(src_format) && src_format != dst_format && !is_blit_supported)
912+
{
913+
return KFormatRaw;
914+
}
915+
916+
// Choose the requested preference for image file extension
917+
switch (image_file_format)
918+
{
919+
case util::ScreenshotFormat::kBmp:
920+
return kFormatBMP;
921+
922+
case util::ScreenshotFormat::kPng:
923+
return KFormatPNG;
924+
925+
default:
926+
assert(0);
927+
return KFormatRaw;
928+
}
929+
930+
return KFormatRaw;
931+
}
932+
857933
GFXRECON_END_NAMESPACE(gfxrecon)
858934
GFXRECON_END_NAMESPACE(decode)

0 commit comments

Comments
 (0)