From 1d747653d4203e130a76fa2886e012497582c5ae Mon Sep 17 00:00:00 2001 From: Konstantin Seurer Date: Sun, 4 Feb 2024 18:10:47 +0100 Subject: [PATCH] radv: Add an IB annotation layer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The layer annotates the command buffers with api entrypoint names. Reviewed-by: Marek Olšák Part-of: --- src/amd/vulkan/layers/meson.build | 31 +++++ .../vulkan/layers/radv_annotate_layer_gen.py | 108 ++++++++++++++++++ src/amd/vulkan/meson.build | 7 +- src/amd/vulkan/radv_device.c | 12 +- src/amd/vulkan/radv_private.h | 2 + 5 files changed, 156 insertions(+), 4 deletions(-) create mode 100644 src/amd/vulkan/layers/meson.build create mode 100644 src/amd/vulkan/layers/radv_annotate_layer_gen.py diff --git a/src/amd/vulkan/layers/meson.build b/src/amd/vulkan/layers/meson.build new file mode 100644 index 00000000000..bddefc11c33 --- /dev/null +++ b/src/amd/vulkan/layers/meson.build @@ -0,0 +1,31 @@ +# Copyright © 2022 Valve Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +radv_annotate_layer = custom_target( + 'radv_annotate', + input : [files('radv_annotate_layer_gen.py'), vk_api_xml], + output : ['radv_annotate_layer.c'], + command : [ + prog_python, '@INPUT0@', '--xml', '@INPUT1@', + '--out-c', '@OUTPUT0@', + '--beta', with_vulkan_beta.to_string(), + ], + depend_files : [files('radv_annotate_layer_gen.py'), vk_dispatch_table_gen_depend_files], +) diff --git a/src/amd/vulkan/layers/radv_annotate_layer_gen.py b/src/amd/vulkan/layers/radv_annotate_layer_gen.py new file mode 100644 index 00000000000..66ddc8e6cd9 --- /dev/null +++ b/src/amd/vulkan/layers/radv_annotate_layer_gen.py @@ -0,0 +1,108 @@ +COPYRIGHT=u""" +/* Copyright © 2021 Intel Corporation + * Copyright © 2024 Valve Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +""" + +import argparse +import os +import sys +import xml.etree.ElementTree as et + +import mako +from mako.template import Template + +sys.path.append(os.path.join(sys.path[0], '../../../vulkan/util/')) + +from vk_entrypoints import get_entrypoints_from_xml + +EXCLUDED_COMMANDS = [ + 'CmdBeginRenderPass', + 'CmdEndRenderPass', + 'CmdDispatch', +] + +TEMPLATE = Template(COPYRIGHT + """ +/* This file generated from ${filename}, don't edit directly. */ + +#include "radv_private.h" + +#define ANNOTATE(command, ...) \ + radv_cmd_buffer_annotate(radv_cmd_buffer_from_handle(commandBuffer), #command); \ + radv_cmd_buffer_from_handle(commandBuffer)->device->layer_dispatch.annotate.command(__VA_ARGS__) + +% for c in commands: +% if c.guard is not None: +#ifdef ${c.guard} +% endif +VKAPI_ATTR ${c.return_type} VKAPI_CALL +annotate_${c.name}(${c.decl_params()}) +{ + ANNOTATE(${c.name}, ${c.call_params()}); +} + +% if c.guard is not None: +#endif // ${c.guard} +% endif +% endfor +""") + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--out-c", required=True, help="Output C file.") + parser.add_argument("--beta", required=True, help="Enable beta extensions.") + parser.add_argument("--xml", + help="Vulkan API XML file.", + required=True, action="append", dest="xml_files") + args = parser.parse_args() + + commands = [] + commands_names = [] + for e in get_entrypoints_from_xml(args.xml_files, args.beta): + if not e.name.startswith('Cmd') or e.alias or e.return_type != "void": + continue + + stripped_name = e.name.removesuffix('EXT').removesuffix('KHR').removesuffix('2') + if stripped_name in commands_names or stripped_name in EXCLUDED_COMMANDS: + continue + + commands.append(e) + commands_names.append(stripped_name) + + environment = { + "filename": os.path.basename(__file__), + "commands": commands, + } + + try: + with open(args.out_c, "w", encoding='utf-8') as f: + f.write(TEMPLATE.render(**environment)) + except Exception: + # In the event there"s an error, this uses some helpers from mako + # to print a useful stack trace and prints it, then exits with + # status 1, if python is run with debug; otherwise it just raises + # the exception + print(mako.exceptions.text_error_template().render(), file=sys.stderr) + sys.exit(1) + +if __name__ == "__main__": + main() diff --git a/src/amd/vulkan/meson.build b/src/amd/vulkan/meson.build index 144fb9fbd34..40a31ae039c 100644 --- a/src/amd/vulkan/meson.build +++ b/src/amd/vulkan/meson.build @@ -38,6 +38,9 @@ radv_entrypoints_gen_command += [ '--device-prefix', 'metro_exodus', '--device-prefix', 'rage2', '--device-prefix', 'quantic_dream', + + # Command buffer annotation layer entrypoints + '--device-prefix', 'annotate', ] radv_entrypoints = custom_target( @@ -177,6 +180,8 @@ libradv_files += radix_sort_files subdir('bvh') +subdir('layers') + radv_deps = [] radv_flags = cc.get_supported_arguments(['-Wimplicit-fallthrough', '-Wshadow']) @@ -203,7 +208,7 @@ endif libvulkan_radeon = shared_library( 'vulkan_radeon', - [libradv_files, radv_entrypoints, sha1_h, radix_sort_spv, bvh_spv], + [libradv_files, radv_entrypoints, sha1_h, radix_sort_spv, bvh_spv, radv_annotate_layer], vs_module_defs : vulkan_api_def, include_directories : [ inc_include, inc_src, inc_amd, inc_amd_common, inc_amd_common_llvm, inc_util, diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index 3d79747fb7f..bb9e3a4ce83 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -594,12 +594,17 @@ init_dispatch_tables(struct radv_device *device, struct radv_physical_device *ph { struct dispatch_table_builder b = {0}; b.tables[RADV_DEVICE_DISPATCH_TABLE] = &device->vk.dispatch_table; + b.tables[RADV_ANNOTATE_DISPATCH_TABLE] = &device->layer_dispatch.annotate; b.tables[RADV_APP_DISPATCH_TABLE] = &device->layer_dispatch.app; b.tables[RADV_RGP_DISPATCH_TABLE] = &device->layer_dispatch.rgp; b.tables[RADV_RRA_DISPATCH_TABLE] = &device->layer_dispatch.rra; b.tables[RADV_RMV_DISPATCH_TABLE] = &device->layer_dispatch.rmv; b.tables[RADV_CTX_ROLL_DISPATCH_TABLE] = &device->layer_dispatch.ctx_roll; + bool gather_ctx_rolls = physical_device->instance->vk.trace_mode & RADV_TRACE_MODE_CTX_ROLLS; + if (radv_device_fault_detection_enabled(device) || gather_ctx_rolls) + add_entrypoints(&b, &annotate_device_entrypoints, RADV_ANNOTATE_DISPATCH_TABLE); + if (!strcmp(physical_device->instance->drirc.app_layer, "metroexodus")) { add_entrypoints(&b, &metro_exodus_device_entrypoints, RADV_APP_DISPATCH_TABLE); } else if (!strcmp(physical_device->instance->drirc.app_layer, "rage2")) { @@ -619,7 +624,7 @@ init_dispatch_tables(struct radv_device *device, struct radv_physical_device *ph add_entrypoints(&b, &rmv_device_entrypoints, RADV_RMV_DISPATCH_TABLE); #endif - if (physical_device->instance->vk.trace_mode & RADV_TRACE_MODE_CTX_ROLLS) + if (gather_ctx_rolls) add_entrypoints(&b, &ctx_roll_device_entrypoints, RADV_CTX_ROLL_DISPATCH_TABLE); add_entrypoints(&b, &radv_device_entrypoints, RADV_DISPATCH_TABLE_COUNT); @@ -728,14 +733,15 @@ radv_CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCr return result; } - init_dispatch_tables(device, physical_device); - device->vk.capture_trace = capture_trace; device->vk.command_buffer_ops = &radv_cmd_buffer_ops; device->instance = physical_device->instance; device->physical_device = physical_device; + + init_dispatch_tables(device, physical_device); + simple_mtx_init(&device->ctx_roll_mtx, mtx_plain); simple_mtx_init(&device->trace_mtx, mtx_plain); simple_mtx_init(&device->pstate_mtx, mtx_plain); diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 77069bda309..2d234f0d1d9 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -1026,6 +1026,7 @@ struct radv_rra_trace_data { enum radv_dispatch_table { RADV_DEVICE_DISPATCH_TABLE, + RADV_ANNOTATE_DISPATCH_TABLE, RADV_APP_DISPATCH_TABLE, RADV_RGP_DISPATCH_TABLE, RADV_RRA_DISPATCH_TABLE, @@ -1035,6 +1036,7 @@ enum radv_dispatch_table { }; struct radv_layer_dispatch_tables { + struct vk_device_dispatch_table annotate; struct vk_device_dispatch_table app; struct vk_device_dispatch_table rgp; struct vk_device_dispatch_table rra;