vtn: introduce vtn_bindgen tool

This is a small command line utility to generate NIR bindings for a SPIR-V
library, using vtn's infrastructure for this. This is split out from asahi_clc
in an effort to make clc more modular. Notably, this tool does not depend on:

* LLVM, SPIRV-LLVM, CLC, etc (important for Android, and gets us closer to the
  clang spir-v future)
* Driver details other than addressing modes (which are already largely
  hardcoded, setting them to anything else doesn't make a ton of sense for CL C)
* The driver itself, or its backend compiler. That means that the backend
  compiler can depend on the generated bindings header, even if the compiler is
  also used for internal shader precompiling. This breaks the dep loop.

So in short term, this solves the dependency problem for asahi, and in the long
term helps more drivers use clc infrastructure without re-rolling things
themselves.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Konstantin Seurer <konstantin.seurer@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32226>
This commit is contained in:
Alyssa Rosenzweig 2024-11-17 13:14:39 -04:00 committed by Marge Bot
parent 6874c4f516
commit 0b588506ff
2 changed files with 92 additions and 0 deletions

View file

@ -77,6 +77,25 @@ spirv2nir = executable(
install : with_tools.contains('nir'),
)
# Due to the cross build issues in current meson, we only build vtn_bindgen when
# building drivers that need it.
#
# XXX: Build by default once https://github.com/mesonbuild/meson/pull/12022
# ships.
if with_gallium_asahi or with_asahi_vk
prog_vtn_bindgen = executable(
'vtn_bindgen',
['vtn_bindgen.c'],
include_directories : [inc_include, inc_src],
c_args : [c_msvc_compat_args, no_override_init_args],
dependencies : [idep_vtn, idep_mesautil],
# If we can run host binaries directly, just build vtn_bindgen for the host.
# Most commonly this happens when doing a cross compile from an x86_64 build
# machine to an x86 host
native : not meson.can_run_host_binaries(),
)
endif
if with_tests
test(
'spirv_tests',

View file

@ -0,0 +1,73 @@
/*
* Copyright 2024 Valve Corporation
* Copyright 2023 Alyssa Rosenzweig
* SPDX-License-Identifier: MIT
*/
#include "compiler/spirv/nir_spirv.h"
static const struct spirv_to_nir_options spirv_options = {
.environment = NIR_SPIRV_OPENCL,
.shared_addr_format = nir_address_format_62bit_generic,
.global_addr_format = nir_address_format_62bit_generic,
.temp_addr_format = nir_address_format_62bit_generic,
.constant_addr_format = nir_address_format_64bit_global,
.create_library = true,
};
int
main(int argc, char **argv)
{
if (argc != 3) {
fprintf(stderr, "Usage: %s [input spir-v] [output header]\n", argv[0]);
return 1;
}
const char *infile = argv[1];
const char *outfile = argv[2];
FILE *fin = fopen(infile, "rb");
if (!fin) {
fprintf(stderr, "Failed to open %s\n", infile);
return 1;
}
fseek(fin, 0L, SEEK_END);
size_t len = ftell(fin);
rewind(fin);
uint32_t *map = malloc(ALIGN_POT(len, 4));
if (!map) {
fprintf(stderr, "Failed to allocate");
fclose(fin);
return 1;
}
fread(map, 1, len, fin);
fclose(fin);
FILE *fout = fopen(outfile, "w");
if (!fout) {
fprintf(stderr, "Failed to open %s\n", outfile);
free(map);
return 1;
}
glsl_type_singleton_init_or_ref();
fprintf(fout, "/*\n");
fprintf(fout, " * Copyright Mesa3D Contributors\n");
fprintf(fout, " * SPDX-License-Identifier: MIT\n");
fprintf(fout, " *\n");
fprintf(fout, " * Autogenerated file, do not edit\n");
fprintf(fout, " */\n");
fprintf(fout, "#pragma once\n");
fprintf(fout, "#include <stdint.h>\n");
spirv_library_to_nir_builder(fout, map, len / 4, &spirv_options);
glsl_type_singleton_decref();
fclose(fout);
free(map);
return 0;
}