Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vulkan dump resources convert with blit #1799

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions USAGE_android.md
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,7 @@ usage: gfxrecon.py replay [-h] [--push-file LOCAL_FILE] [--version] [--pause-fra
[--dump-resources-dump-vertex-index-buffers]
[--dump-resources-json-output-per-command]
[--dump-resources-dump-immutable-resources]
[--dump-resources-dump-raw-images]
[--dump-resources-dump-all-image-subresources]
[--pbi-all] [--pbis <index1,index2>]
[file]
Expand Down Expand Up @@ -902,6 +903,8 @@ optional arguments:
Enables dumping of resources that are used as inputs in the commands requested for dumping
--dump-resources-dump-all-image-subresources
Enables dumping of all image sub resources (mip map levels and array layers)
--dump-resources-dump-raw-images
When enabled all image resources will be dumped verbatim as raw bin files.
--pbi-all
Print all block information.
--pbis <index1,index2>
Expand Down
7 changes: 5 additions & 2 deletions USAGE_desktop_Vulkan.md
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,7 @@ gfxrecon-replay [-h | --help] [--version] [--gpu <index>]
[--dump-resources-dump-vertex-index-buffers]
[--dump-resources-json-output-per-command]
[--dump-resources-dump-immutable-resources]
[--dump-resources-dump-raw-images]
[--dump-resources-dump-all-image-subresources] <file>
[--pbi-all] [--pbis <index1,index2>]
[--pipeline-creation-jobs | --pcj <num_jobs>]
Expand Down Expand Up @@ -758,15 +759,17 @@ Optional arguments:
Enables dumping of resources that are used as inputs in the commands requested for dumping.
--dump-resources-dump-all-image-subresources
Enables dumping of all image sub resources (mip map levels and array layers).
--pbi-all
--dump-resources-dump-raw-images
When enabled all image resources will be dumped verbatim as raw bin files.
--pbi-all
Print all block information.
--pbis <index1,index2>
Print block information between block index1 and block index2.
--pipeline-creation-jobs | --pcj <num_jobs>
Specify the number of asynchronous pipeline-creation jobs as integer.
If <num_jobs> is negative it will be added to the number of cpu-cores, e.g. -1 -> num_cores - 1.
Default: 0 (do not use asynchronous operations)
```

### Key Controls
Expand Down
4 changes: 4 additions & 0 deletions android/scripts/gfxrecon.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ def CreateReplayParser():
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.')
parser.add_argument('--dump-resources-dump-immutable-resources', action='store_true', default=False, help= 'Dump immutable immutable shader resources.')
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.')
parser.add_argument('--dump-resources-dump-raw-images', action='store_true', default=False, help= 'Dump images verbatim as raw binary files.')
parser.add_argument('--pbi-all', action='store_true', default=False, help='Print all block information.')
parser.add_argument('--pbis', metavar='RANGES', default=False, help='Print block information between block index1 and block index2')
parser.add_argument('--pcj', '--pipeline-creation-jobs', action='store_true', default=False, help='Specify the number of pipeline-creation-jobs or background-threads.')
Expand Down Expand Up @@ -271,6 +272,9 @@ def MakeExtrasString(args):
if args.dump_resources_dump_all_image_subresources:
arg_list.append('--dump-resources-dump-all-image-subresources')

if args.dump_resources_dump_raw_images:
arg_list.append('--dump-resources-dump-raw-images')

if args.pbi_all:
arg_list.append('--pbi-all')

Expand Down
174 changes: 125 additions & 49 deletions framework/decode/vulkan_replay_dump_resources_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ bool IsFormatAstcCompressed(VkFormat format)
return vkuFormatIsCompressed_ASTC_HDR(format) || vkuFormatIsCompressed_ASTC_LDR(format);
}

util::imagewriter::DataFormats VkFormatToImageWriterDataFormat(VkFormat format)
static util::imagewriter::DataFormats VkFormatToImageWriterDataFormat(VkFormat format)
{
if (IsFormatAstcCompressed(format))
{
Expand All @@ -68,9 +68,6 @@ util::imagewriter::DataFormats VkFormatToImageWriterDataFormat(VkFormat format)

switch (format)
{
case VK_FORMAT_R8_UNORM:
return util::imagewriter::DataFormats::kFormat_R8;

case VK_FORMAT_R8G8B8_UNORM:
return util::imagewriter::DataFormats::kFormat_RGB;

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

case VK_FORMAT_R16G16B16A16_SFLOAT:
return util::imagewriter::DataFormats::kFormat_R16G16B16A16_SFLOAT;

case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
return util::imagewriter::DataFormats::kFormat_B10G11R11_UFLOAT;

case VK_FORMAT_B8G8R8A8_SRGB:
case VK_FORMAT_B8G8R8A8_UNORM:
return util::imagewriter::DataFormats::kFormat_BGRA;

case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
return util::imagewriter::DataFormats::kFormat_A2B10G10R10;

case VK_FORMAT_D32_SFLOAT:
case VK_FORMAT_D32_SFLOAT_S8_UINT:
return util::imagewriter::DataFormats::kFormat_D32_FLOAT;
Expand All @@ -109,36 +97,45 @@ util::imagewriter::DataFormats VkFormatToImageWriterDataFormat(VkFormat format)
}
}

const char* ImageFileExtension(VkFormat format, util::ScreenshotFormat image_file_format)
const char* ImageFileExtension(DumpedImageFormat image_format)
{
const util::imagewriter::DataFormats output_image_format = VkFormatToImageWriterDataFormat(format);

if (output_image_format != util::imagewriter::DataFormats::kFormat_UNSPECIFIED)
switch (image_format)
{
if (output_image_format == util::imagewriter::DataFormats::kFormat_ASTC)
{
case kFormatBMP:
return ".bmp";

case KFormatPNG:
return ".png";

case KFormatAstc:
return ".astc";
}
else
{
switch (image_file_format)
{
case util::ScreenshotFormat::kBmp:
return ".bmp";

case util::ScreenshotFormat::kPng:
return ".png";
case KFormatRaw:
default:
return ".bin";
}
}

default:
assert(0);
return ".bmp";
}
}
static VkFormat ChooseDestinationImageFormat(VkFormat format)
{
VkFormat dst_format;

if (vkuFormatIsSRGB(format))
{
dst_format = vkuFormatHasAlpha(format) ? VK_FORMAT_B8G8R8A8_SRGB : VK_FORMAT_B8G8R8_SRGB;
}
else if (vkuFormatIsDepthOrStencil(format))
{
// Converting depth format with vkCmdBlit is not allowed.
// We will do the conversion on the cpu.
dst_format = format;
}
else
{
return ".bin";
dst_format = vkuFormatHasAlpha(format) ? VK_FORMAT_B8G8R8A8_UNORM : VK_FORMAT_B8G8R8_UNORM;
}

return dst_format;
}

uint32_t GetMemoryTypeIndex(const VkPhysicalDeviceMemoryProperties& memory_properties,
Expand Down Expand Up @@ -448,6 +445,7 @@ VkResult DumpImageToFile(const ImageInfo* image_info,
std::vector<bool>& scaling_supported,
util::ScreenshotFormat image_file_format,
bool dump_all_subresources,
bool dump_image_raw,
VkImageLayout layout,
const VkExtent3D* extent_p)
{
Expand Down Expand Up @@ -477,6 +475,8 @@ VkResult DumpImageToFile(const ImageInfo* image_info,
(extent_p != nullptr) ? extent_p->height : image_info->extent.height,
(extent_p != nullptr) ? extent_p->depth : image_info->extent.depth };

const VkFormat dst_format = ChooseDestinationImageFormat(image_info->format);

uint32_t f = 0;
for (size_t i = 0; i < aspects.size(); ++i)
{
Expand Down Expand Up @@ -504,7 +504,8 @@ VkResult DumpImageToFile(const ImageInfo* image_info,
subresource_sizes,
scaled,
false,
scale);
scale,
dst_format);

assert(!subresource_offsets.empty());
assert(!subresource_sizes.empty());
Expand All @@ -519,7 +520,18 @@ VkResult DumpImageToFile(const ImageInfo* image_info,
return res;
}

const util::imagewriter::DataFormats output_image_format = VkFormatToImageWriterDataFormat(image_info->format);
const DumpedImageFormat output_image_format = GetDumpedImageFormat(device_info,
device_table,
instance_table,
object_info_table,
image_info->format,
image_info->tiling,
image_info->type,
image_file_format,
dump_image_raw);

const util::imagewriter::DataFormats image_writer_format = VkFormatToImageWriterDataFormat(dst_format);
assert(image_writer_format != util::imagewriter::DataFormats::kFormat_UNSPECIFIED);

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

if (output_image_format != util::imagewriter::DataFormats::kFormat_UNSPECIFIED)
if (output_image_format != KFormatRaw)
{
VkExtent3D scaled_extent;
if (scale != 1.0f && scaled)
Expand All @@ -543,10 +555,10 @@ VkResult DumpImageToFile(const ImageInfo* image_info,
scaled_extent = image_info->extent;
}

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

if (output_image_format == util::imagewriter::DataFormats::kFormat_ASTC)
if (output_image_format == KFormatAstc)
{
VKU_FORMAT_INFO format_info = vkuGetFormatInfo(image_info->format);

Expand All @@ -560,26 +572,26 @@ VkResult DumpImageToFile(const ImageInfo* image_info,
data.data(),
subresource_sizes[0]);
}
else if (image_file_format == util::ScreenshotFormat::kBmp)
else if (output_image_format == kFormatBMP)
{
util::imagewriter::WriteBmpImage(filename,
scaled_extent.width,
scaled_extent.height,
subresource_sizes[0],
data.data(),
stride,
output_image_format,
image_writer_format,
vkuFormatHasAlpha(image_info->format));
}
else if (image_file_format == util::ScreenshotFormat::kPng)
else if (output_image_format == KFormatPNG)
{
util::imagewriter::WritePngImage(filename,
scaled_extent.width,
scaled_extent.height,
subresource_sizes[0],
data.data(),
stride,
output_image_format,
image_writer_format,
vkuFormatHasAlpha(image_info->format));
}
}
Expand Down Expand Up @@ -607,7 +619,7 @@ VkResult DumpImageToFile(const ImageInfo* image_info,
const void* data_offset = reinterpret_cast<const void*>(
reinterpret_cast<const uint8_t*>(data.data()) + subresource_offsets[sub_res_idx]);

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

if (output_image_format == util::imagewriter::DataFormats::kFormat_ASTC)
if (output_image_format == KFormatAstc)
{
VKU_FORMAT_INFO format_info = vkuGetFormatInfo(image_info->format);

Expand All @@ -642,25 +654,25 @@ VkResult DumpImageToFile(const ImageInfo* image_info,
data.data(),
subresource_sizes[sub_res_idx]);
}
else if (image_file_format == util::ScreenshotFormat::kBmp)
else if (output_image_format == kFormatBMP)
{
util::imagewriter::WriteBmpImage(filename,
scaled_extent.width,
scaled_extent.height,
subresource_sizes[sub_res_idx],
data_offset,
stride,
output_image_format);
image_writer_format);
}
else if (image_file_format == util::ScreenshotFormat::kPng)
else if (output_image_format == KFormatPNG)
{
util::imagewriter::WritePngImage(filename,
scaled_extent.width,
scaled_extent.height,
subresource_sizes[sub_res_idx],
data_offset,
stride,
output_image_format);
image_writer_format);
}
}
else
Expand Down Expand Up @@ -854,5 +866,69 @@ void GetFormatAspects(VkFormat format, std::vector<VkImageAspectFlagBits>& aspec
}
}

DumpedImageFormat GetDumpedImageFormat(const DeviceInfo* device_info,
const encode::VulkanDeviceTable* device_table,
const encode::VulkanInstanceTable* instance_table,
VulkanObjectInfoTable& object_info_table,
VkFormat src_format,
VkImageTiling src_image_tiling,
VkImageType type,
util::ScreenshotFormat image_file_format,
bool dump_raw)
{
const PhysicalDeviceInfo* phys_dev_info = object_info_table.GetPhysicalDeviceInfo(device_info->parent_id);
assert(phys_dev_info);

// If there's a request for images to be dumped as raw bin files
if (dump_raw)
{
// We consider astc as a raw bin format
if (IsFormatAstcCompressed(src_format))
{
return KFormatAstc;
}
else
{
return KFormatRaw;
}
}

// Astc images will be dumped as .astc files
if (IsFormatAstcCompressed(src_format))
{
return KFormatAstc;
}

graphics::VulkanResourcesUtil resource_util(device_info->handle,
device_info->parent,
*device_table,
*instance_table,
*phys_dev_info->replay_device_info->memory_properties);

// Image cannot be converted into a format compatible for dumping in an image file
const VkFormat dst_format = ChooseDestinationImageFormat(src_format);
bool is_blit_supported = resource_util.IsBlitSupported(src_format, src_image_tiling, dst_format);
if (!vkuFormatIsDepthOrStencil(src_format) && src_format != dst_format && !is_blit_supported)
{
return KFormatRaw;
}

// Choose the requested preference for image file extension
switch (image_file_format)
{
case util::ScreenshotFormat::kBmp:
return kFormatBMP;

case util::ScreenshotFormat::kPng:
return KFormatPNG;

default:
assert(0);
return KFormatRaw;
}

return KFormatRaw;
}

GFXRECON_END_NAMESPACE(gfxrecon)
GFXRECON_END_NAMESPACE(decode)
Loading
Loading