diff --git a/meson.build b/meson.build index 9e740779165..e14f69e7d09 100644 --- a/meson.build +++ b/meson.build @@ -1916,14 +1916,21 @@ if with_clover_spirv or with_clc '>= @0@.@1@'.format(chosen_llvm_version_major, chosen_llvm_version_minor), '< @0@.@1@'.format(chosen_llvm_version_major, chosen_llvm_version_minor + 1) ] - dep_spirv_tools = dependency('SPIRV-Tools', required : true, version : '>= 2018.0') # LLVMSPIRVLib is available at https://github.com/KhronosGroup/SPIRV-LLVM-Translator dep_llvmspirvlib = dependency('LLVMSPIRVLib', required : true, version : _llvmspirvlib_version) else - dep_spirv_tools = null_dep dep_llvmspirvlib = null_dep endif +dep_spirv_tools = dependency( + 'SPIRV-Tools', + required : with_clover_spirv or with_clc, + version : '>= 2018.0' +) +if dep_spirv_tools.found() + pre_args += '-DHAVE_SPIRV_TOOLS' +endif + dep_clang = null_dep if with_clc llvm_libdir = dep_llvm.get_variable(cmake : 'LLVM_LIBRARY_DIR', configtool: 'libdir') diff --git a/src/compiler/spirv/meson.build b/src/compiler/spirv/meson.build index 80c832700f9..1c643b694e2 100644 --- a/src/compiler/spirv/meson.build +++ b/src/compiler/spirv/meson.build @@ -36,6 +36,7 @@ files_libvtn = files( 'vtn_amd.c', 'vtn_cfg.c', 'vtn_cmat.c', + 'vtn_debug.c', 'vtn_glsl450.c', 'vtn_opencl.c', 'vtn_private.h', @@ -54,12 +55,12 @@ libvtn = static_library( include_directories : [inc_include, inc_src, inc_mapi, inc_mesa], c_args : [c_msvc_compat_args, no_override_init_args], gnu_symbol_visibility : 'hidden', - dependencies : [idep_nir, dep_valgrind], + dependencies : [dep_spirv_tools, idep_nir, dep_valgrind], build_by_default : false, ) idep_vtn = declare_dependency( - dependencies : [idep_nir, idep_mesautil], + dependencies : [dep_spirv_tools, idep_nir, idep_mesautil], link_with : libvtn, ) diff --git a/src/compiler/spirv/nir_spirv.h b/src/compiler/spirv/nir_spirv.h index 2d85194efae..6cb677634a3 100644 --- a/src/compiler/spirv/nir_spirv.h +++ b/src/compiler/spirv/nir_spirv.h @@ -166,6 +166,8 @@ bool spirv_library_to_nir_builder(FILE *fp, const uint32_t *words, size_t word_count, const struct spirv_to_nir_options *options); +void spirv_print_asm(FILE *fp, const uint32_t *words, size_t word_count); + #ifdef __cplusplus } #endif diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index 0b75940fed8..62406018ab3 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -206,6 +206,8 @@ static const struct debug_named_value mesa_spirv_debug_control[] = { "Print information of the SPIR-V structured control flow parsing" }, { "values", MESA_SPIRV_DEBUG_VALUES, "Print information of the SPIR-V values" }, + { "asm", MESA_SPIRV_DEBUG_ASM, "Print the SPIR-V assembly" }, + { "color", MESA_SPIRV_DEBUG_COLOR, "Debug in color, if available" }, DEBUG_NAMED_VALUE_END, }; @@ -6847,6 +6849,9 @@ spirv_to_nir(const uint32_t *words, size_t word_count, { mesa_spirv_debug_init(); + if (MESA_SPIRV_DEBUG(ASM)) + spirv_print_asm(stderr, words, word_count); + const uint32_t *word_end = words + word_count; struct vtn_builder *b = vtn_create_builder(words, word_count, diff --git a/src/compiler/spirv/vtn_debug.c b/src/compiler/spirv/vtn_debug.c new file mode 100644 index 00000000000..9cafc2f9315 --- /dev/null +++ b/src/compiler/spirv/vtn_debug.c @@ -0,0 +1,65 @@ +/* + * Copyright © 2024 Collabora, Ltd. + * + * 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. + * + * Authors: + * Faith Ekstrand (faith@gfxstrand.net) + * + */ + +#include "vtn_private.h" + +#ifdef HAVE_SPIRV_TOOLS +#include +#endif /* HAVE_SPIRV_TOOLS */ + +void +spirv_print_asm(FILE *fp, const uint32_t *words, size_t word_count) +{ +#ifdef HAVE_SPIRV_TOOLS + spv_context ctx = spvContextCreate(SPV_ENV_UNIVERSAL_1_6); + + spv_binary_to_text_options_t options = + SPV_BINARY_TO_TEXT_OPTION_INDENT | + SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES; + + if (MESA_SPIRV_DEBUG(COLOR)) + options |= SPV_BINARY_TO_TEXT_OPTION_COLOR; + + spv_text text = NULL; + spv_diagnostic diagnostic = NULL; + spv_result_t res = spvBinaryToText(ctx, words, word_count, options, + &text, &diagnostic); + if (res == SPV_SUCCESS) { + fprintf(fp, "SPIR-V assembly:\n"); + fwrite(text->str, 1, text->length, fp); + } else { + fprintf(fp, "Failed to disassemble SPIR-V:\n"); + spvDiagnosticPrint(diagnostic); + spvDiagnosticDestroy(diagnostic); + } + + spvTextDestroy(text); +#else + fprintf(fp, "Cannot dump SPIR-V assembly. " + "You need to build against SPIR-V tools.\n"); +#endif /* HAVE_SPIRV_TOOLS */ +} diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h index 80d87761e78..404ef3e47c3 100644 --- a/src/compiler/spirv/vtn_private.h +++ b/src/compiler/spirv/vtn_private.h @@ -40,6 +40,8 @@ extern uint32_t mesa_spirv_debug; #define MESA_SPIRV_DEBUG_STRUCTURED (1u << 0) #define MESA_SPIRV_DEBUG_VALUES (1u << 1) +#define MESA_SPIRV_DEBUG_ASM (1u << 2) +#define MESA_SPIRV_DEBUG_COLOR (1u << 3) struct vtn_builder; struct vtn_decoration;