From df059c67813154d2adbb4fcd734558596111bfed Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Mon, 21 Feb 2022 10:59:54 +0200 Subject: [PATCH] intel/clc: deal with SPIRV-Tools linker new behavior We're now required to provide all modules to link at the same SPIRV version. Signed-off-by: Lionel Landwerlin Acked-by: Jason Ekstrand Part-of: --- src/intel/compiler/intel_clc.c | 45 ++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/intel/compiler/intel_clc.c b/src/intel/compiler/intel_clc.c index 7531cd1fbc8..33798474639 100644 --- a/src/intel/compiler/intel_clc.c +++ b/src/intel/compiler/intel_clc.c @@ -29,6 +29,7 @@ #include "dev/intel_debug.h" #include "util/build_id.h" #include "util/disk_cache.h" +#include "util/macros.h" #include "util/mesa-sha1.h" #include "util/u_dynarray.h" @@ -40,6 +41,9 @@ #include #include +/* Shader functions */ +#define SPIR_V_MAGIC_NUMBER 0x07230203 + static struct disk_cache * get_disk_cache(struct brw_compiler *compiler) { @@ -267,6 +271,22 @@ print_usage(char *exec_name, FILE *f) #define OPT_PREFIX 1000 +static uint32_t +get_module_spirv_version(const uint32_t *spirv, size_t size) +{ + assert(size >= 8); + assert(spirv[0] == SPIR_V_MAGIC_NUMBER); + return spirv[1]; +} + +static void +set_module_spirv_version(uint32_t *spirv, size_t size, uint32_t version) +{ + assert(size >= 8); + assert(spirv[0] == SPIR_V_MAGIC_NUMBER); + spirv[1] = version; +} + int main(int argc, char **argv) { brw_process_intel_debug_variable(); @@ -424,6 +444,31 @@ int main(int argc, char **argv) util_dynarray_append(&spirv_ptr_objs, struct clc_binary *, spirv_out); } + /* The SPIRV-Tools linker started checking that all modules have the same + * version. But SPIRV-LLVM-Translator picks the lower required version for + * each module it compiles. So we have to iterate over all of them and set + * the max found to make SPIRV-Tools link our modules. + * + * TODO: This is not the correct thing to do. We need SPIRV-LLVM-Translator + * to pick a given SPIRV version given to it and have all the modules + * at that version. We should remove this hack when this issue is + * fixed : + * https://github.com/KhronosGroup/SPIRV-LLVM-Translator/issues/1445 + */ + uint32_t max_spirv_version = 0; + util_dynarray_foreach(&spirv_ptr_objs, struct clc_binary *, module) { + max_spirv_version = MAX2(max_spirv_version, + get_module_spirv_version((*module)->data, + (*module)->size)); + } + + assert(max_spirv_version > 0); + util_dynarray_foreach(&spirv_ptr_objs, struct clc_binary *, module) { + set_module_spirv_version((*module)->data, (*module)->size, + max_spirv_version); + } + + struct clc_linker_args link_args = { .in_objs = util_dynarray_begin(&spirv_ptr_objs), .num_in_objs = util_dynarray_num_elements(&spirv_ptr_objs,