From 67e48bee1e642f83e751d1517c75e1dea0a56755 Mon Sep 17 00:00:00 2001 From: Michael Tang Date: Mon, 21 Dec 2020 14:58:47 -0800 Subject: [PATCH] microsoft/compiler: Add dedicated spirv_to_dxil libraries Reviewed-by: Jesse Natalie Reviewed-by: Erik Faye-Lund Part-of: --- meson.build | 2 + meson_options.txt | 6 ++ src/meson.build | 2 +- src/microsoft/meson.build | 3 + src/microsoft/spirv_to_dxil/meson.build | 31 ++++++ src/microsoft/spirv_to_dxil/spirv_to_dxil.c | 86 +++++++++++++++ src/microsoft/spirv_to_dxil/spirv_to_dxil.def | 3 + src/microsoft/spirv_to_dxil/spirv_to_dxil.h | 102 ++++++++++++++++++ 8 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 src/microsoft/spirv_to_dxil/meson.build create mode 100644 src/microsoft/spirv_to_dxil/spirv_to_dxil.c create mode 100644 src/microsoft/spirv_to_dxil/spirv_to_dxil.def create mode 100644 src/microsoft/spirv_to_dxil/spirv_to_dxil.h diff --git a/meson.build b/meson.build index a3ea925ddd5..a82a54e4a96 100644 --- a/meson.build +++ b/meson.build @@ -312,6 +312,8 @@ dep_clang = dependency( with_microsoft_clc = dep_clang.found() with_clc = dep_clang.found() +with_spirv_to_dxil = get_option('spirv-to-dxil') + if host_machine.system() == 'darwin' with_dri_platform = 'apple' pre_args += '-DBUILDING_MESA' diff --git a/meson_options.txt b/meson_options.txt index 6810602ead9..22a0ed9c2b1 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -289,6 +289,12 @@ option( value : 'auto', description : 'Build support for the Microsoft CLC to DXIL compiler' ) +option( + 'spirv-to-dxil', + type : 'boolean', + value : false, + description : 'Build support for the SPIR-V to DXIL library' +) option( 'glvnd-vendor-name', type : 'string', diff --git a/src/meson.build b/src/meson.build index 8547d16dac5..38101edace6 100644 --- a/src/meson.build +++ b/src/meson.build @@ -92,7 +92,7 @@ endif if with_any_intel subdir('intel') endif -if with_microsoft_clc or with_gallium_d3d12 +if with_microsoft_clc or with_gallium_d3d12 or with_spirv_to_dxil subdir('microsoft') endif subdir('mesa') diff --git a/src/microsoft/meson.build b/src/microsoft/meson.build index 05d86832a13..a27c343ab54 100644 --- a/src/microsoft/meson.build +++ b/src/microsoft/meson.build @@ -24,3 +24,6 @@ if with_microsoft_clc subdir('clc') endif subdir('resource_state_manager') +if with_spirv_to_dxil + subdir('spirv_to_dxil') +endif diff --git a/src/microsoft/spirv_to_dxil/meson.build b/src/microsoft/spirv_to_dxil/meson.build new file mode 100644 index 00000000000..deafe91b1d3 --- /dev/null +++ b/src/microsoft/spirv_to_dxil/meson.build @@ -0,0 +1,31 @@ +# Copyright © Microsoft 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. + +libspirv_to_dxil = both_libraries( + 'spirv_to_dxil', + files( + 'spirv_to_dxil.c', + 'spirv_to_dxil.h', + ), + vs_module_defs : 'spirv_to_dxil.def', + dependencies : [idep_nir, idep_libdxil_compiler], + include_directories : [inc_include, inc_src, inc_compiler, inc_gallium], +) diff --git a/src/microsoft/spirv_to_dxil/spirv_to_dxil.c b/src/microsoft/spirv_to_dxil/spirv_to_dxil.c new file mode 100644 index 00000000000..79ea74730a1 --- /dev/null +++ b/src/microsoft/spirv_to_dxil/spirv_to_dxil.c @@ -0,0 +1,86 @@ +/* + * Copyright © Microsoft 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. + */ + +#include "spirv_to_dxil.h" +#include "nir_to_dxil.h" +#include "shader_enums.h" +#include "spirv/nir_spirv.h" +#include "util/blob.h" + +bool +spirv_to_dxil(const uint32_t *words, size_t word_count, + struct dxil_spirv_specialization *specializations, + unsigned int num_specializations, dxil_spirv_shader_stage stage, + const char *entry_point_name, void **buffer, size_t *size) +{ + struct spirv_to_nir_options spirv_opts = {0}; + if (stage == MESA_SHADER_KERNEL) { + spirv_opts.environment = NIR_SPIRV_OPENCL; + spirv_opts.caps.address = true; + spirv_opts.caps.float64 = true; + spirv_opts.caps.int8 = true; + spirv_opts.caps.int16 = true; + spirv_opts.caps.int64 = true; + spirv_opts.caps.kernel = true; + } else { + spirv_opts.environment = NIR_SPIRV_VULKAN; + } + + glsl_type_singleton_init_or_ref(); + + nir_shader *nir = spirv_to_nir( + words, word_count, (struct nir_spirv_specialization *)specializations, + num_specializations, (gl_shader_stage)stage, entry_point_name, + &spirv_opts, dxil_get_nir_compiler_options()); + if (!nir) { + glsl_type_singleton_decref(); + return false; + } + + nir_validate_shader(nir, + "Validate before feeding NIR to the DXIL compiler"); + + NIR_PASS_V(nir, nir_lower_returns); + NIR_PASS_V(nir, nir_inline_functions); + + struct nir_to_dxil_options opts = {0}; + + struct blob dxil_blob; + if (!nir_to_dxil(nir, &opts, &dxil_blob)) { + if (dxil_blob.allocated) + blob_finish(&dxil_blob); + glsl_type_singleton_decref(); + return false; + } + + blob_finish_get_buffer(&dxil_blob, buffer, size); + + glsl_type_singleton_decref(); + return true; +} + +void +spirv_to_dxil_free(void* buffer) +{ + free(buffer); +} diff --git a/src/microsoft/spirv_to_dxil/spirv_to_dxil.def b/src/microsoft/spirv_to_dxil/spirv_to_dxil.def new file mode 100644 index 00000000000..5243f56e6c7 --- /dev/null +++ b/src/microsoft/spirv_to_dxil/spirv_to_dxil.def @@ -0,0 +1,3 @@ +EXPORTS + spirv_to_dxil + spirv_to_dxil_free diff --git a/src/microsoft/spirv_to_dxil/spirv_to_dxil.h b/src/microsoft/spirv_to_dxil/spirv_to_dxil.h new file mode 100644 index 00000000000..655d6389bac --- /dev/null +++ b/src/microsoft/spirv_to_dxil/spirv_to_dxil.h @@ -0,0 +1,102 @@ +/* + * Copyright © Microsoft 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. + */ + +#ifndef SPIRV_TO_DXIL_H +#define SPIRV_TO_DXIL_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// NB: I've copy and pasted some types into this header so we don't have to +// include other headers. This will surely break if any of these types change. + +// Copy of gl_shader_stage +typedef enum { + DXIL_SPIRV_SHADER_NONE = -1, + DXIL_SPIRV_SHADER_VERTEX = 0, + DXIL_SPIRV_SHADER_TESS_CTRL = 1, + DXIL_SPIRV_SHADER_TESS_EVAL = 2, + DXIL_SPIRV_SHADER_GEOMETRY = 3, + DXIL_SPIRV_SHADER_FRAGMENT = 4, + DXIL_SPIRV_SHADER_COMPUTE = 5, + DXIL_SPIRV_SHADER_KERNEL = 6, +} dxil_spirv_shader_stage; + +// Copy of nir_spirv_const_value +typedef union { + bool b; + float f32; + double f64; + int8_t i8; + uint8_t u8; + int16_t i16; + uint16_t u16; + int32_t i32; + uint32_t u32; + int64_t i64; + uint64_t u64; +} dxil_spirv_const_value; + +// Copy of nir_spirv_specialization +struct dxil_spirv_specialization { + uint32_t id; + dxil_spirv_const_value value; + bool defined_on_module; +}; + +/** + * Compile a SPIR-V module into DXIL. + * \param words SPIR-V module to compile + * \param word_count number of words in the SPIR-V module + * \param specializations specialization constants to compile with the shader + * \param num_specializations number of specialization constants + * \param buffer will contain the DXIL bytes on success. Needs to be freed() + * \param size length of returned buffer + * \return true if compilation succeeded + */ +bool +spirv_to_dxil(const uint32_t* words, + size_t word_count, + struct dxil_spirv_specialization* specializations, + unsigned int num_specializations, + dxil_spirv_shader_stage stage, + const char* entry_point_name, + void** buffer, + size_t* size); + +/** + * Free the buffer allocated by spirv_to_dxil. + */ +void +spirv_to_dxil_free(void* buffer); + +#ifdef __cplusplus +} +#endif + +#endif