From 6af22121cfd9b05c0bd7fdd835993a3442047f9d Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Sun, 13 Feb 2022 13:05:12 -0800 Subject: [PATCH] microsoft/compiler: Add a max validator version Reviewed-by: Enrico Galli Part-of: --- src/gallium/drivers/d3d12/d3d12_compiler.cpp | 1 + src/microsoft/clc/clc_compiler.c | 1 + src/microsoft/compiler/dxil_module.h | 1 + src/microsoft/compiler/dxil_validator.h | 12 ++++++ src/microsoft/compiler/nir_to_dxil.c | 44 +++++++++++++++++++- src/microsoft/compiler/nir_to_dxil.h | 2 + src/microsoft/spirv_to_dxil/spirv_to_dxil.c | 1 + src/microsoft/vulkan/dzn_meta.c | 1 + src/microsoft/vulkan/dzn_pipeline.c | 1 + 9 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/d3d12/d3d12_compiler.cpp b/src/gallium/drivers/d3d12/d3d12_compiler.cpp index 07920429007..60f6761c002 100644 --- a/src/gallium/drivers/d3d12/d3d12_compiler.cpp +++ b/src/gallium/drivers/d3d12/d3d12_compiler.cpp @@ -149,6 +149,7 @@ compile_nir(struct d3d12_context *ctx, struct d3d12_shader_selector *sel, opts.input_clip_size = key->input_clip_size; opts.environment = DXIL_ENVIRONMENT_GL; opts.shader_model_max = SHADER_MODEL_6_2; + opts.validator_version_max = DXIL_VALIDATOR_1_4; struct blob tmp; if (!nir_to_dxil(nir, &opts, &tmp)) { diff --git a/src/microsoft/clc/clc_compiler.c b/src/microsoft/clc/clc_compiler.c index b45f462af4d..dc8f31234de 100644 --- a/src/microsoft/clc/clc_compiler.c +++ b/src/microsoft/clc/clc_compiler.c @@ -1114,6 +1114,7 @@ clc_spirv_to_dxil(struct clc_libclc *lib, .num_kernel_globals = num_global_inputs, .environment = DXIL_ENVIRONMENT_CL, .shader_model_max = SHADER_MODEL_6_2, + .validator_version_max = DXIL_VALIDATOR_1_4, }; for (unsigned i = 0; i < out_dxil->kernel->num_args; i++) { diff --git a/src/microsoft/compiler/dxil_module.h b/src/microsoft/compiler/dxil_module.h index 13323280d03..db778014423 100644 --- a/src/microsoft/compiler/dxil_module.h +++ b/src/microsoft/compiler/dxil_module.h @@ -176,6 +176,7 @@ struct dxil_module { void *ralloc_ctx; enum dxil_shader_kind shader_kind; unsigned major_version, minor_version; + unsigned major_validator, minor_validator; struct dxil_features feats; unsigned raw_and_structured_buffers : 1; struct dxil_shader_info info; diff --git a/src/microsoft/compiler/dxil_validator.h b/src/microsoft/compiler/dxil_validator.h index de5c064b711..827aec7396d 100644 --- a/src/microsoft/compiler/dxil_validator.h +++ b/src/microsoft/compiler/dxil_validator.h @@ -32,6 +32,18 @@ struct dxil_validator; extern "C" { #endif +enum dxil_validator_version { + NO_DXIL_VALIDATION, + DXIL_VALIDATOR_1_0 = 0x10000, + DXIL_VALIDATOR_1_1, + DXIL_VALIDATOR_1_2, + DXIL_VALIDATOR_1_3, + DXIL_VALIDATOR_1_4, + DXIL_VALIDATOR_1_5, + DXIL_VALIDATOR_1_6, + DXIL_VALIDATOR_1_7, +}; + struct dxil_validator * dxil_create_validator(const void *ctx); diff --git a/src/microsoft/compiler/nir_to_dxil.c b/src/microsoft/compiler/nir_to_dxil.c index d60129d7319..92340325ea7 100644 --- a/src/microsoft/compiler/nir_to_dxil.c +++ b/src/microsoft/compiler/nir_to_dxil.c @@ -1536,10 +1536,15 @@ emit_tag(struct ntd_context *ctx, enum dxil_shader_tag tag, static bool emit_metadata(struct ntd_context *ctx, const struct dxil_mdnode *signatures) { + /* DXIL versions are 1.x for shader model 6.x */ + assert(ctx->mod.major_version == 6); + unsigned dxilMajor = 1; unsigned dxilMinor = ctx->mod.minor_version; + unsigned valMajor = ctx->mod.major_validator; + unsigned valMinor = ctx->mod.minor_validator; if (!emit_llvm_ident(&ctx->mod) || - !emit_named_version(&ctx->mod, "dx.version", 1, dxilMinor) || - !emit_named_version(&ctx->mod, "dx.valver", 1, 4) || + !emit_named_version(&ctx->mod, "dx.version", dxilMajor, dxilMinor) || + !emit_named_version(&ctx->mod, "dx.valver", valMajor, valMinor) || !emit_dx_shader_model(&ctx->mod)) return false; @@ -5694,6 +5699,16 @@ type_size_vec4(const struct glsl_type *type, bool bindless) return glsl_count_attribute_slots(type, false); } +static bool +dxil_validator_can_validate_shader_model(unsigned sm_minor, unsigned val_minor) +{ + /* Currently the validators are versioned such that val 1.x is needed for SM6.x */ + return sm_minor <= val_minor; +} + +static const unsigned dxil_validator_min_capable_version = DXIL_VALIDATOR_1_4; +static const unsigned dxil_validator_max_capable_version = DXIL_VALIDATOR_1_4; + bool nir_to_dxil(struct nir_shader *s, const struct nir_to_dxil_options *opts, struct blob *blob) @@ -5708,6 +5723,22 @@ nir_to_dxil(struct nir_shader *s, const struct nir_to_dxil_options *opts, return false; } + if (opts->validator_version_max != NO_DXIL_VALIDATION && + opts->validator_version_max < dxil_validator_min_capable_version) { + debug_printf("D3D12: Invalid validator version %d.%d, must be 1.4 or greater\n", + opts->validator_version_max >> 16, + opts->validator_version_max & 0xffff); + return false; + } + + /* If no validation, write a blob as if it was going to be validated by the newest understood validator. + * Same if the validator is newer than we know how to write for. + */ + uint32_t validator_version = + opts->validator_version_max == NO_DXIL_VALIDATION || + opts->validator_version_max > dxil_validator_max_capable_version ? + dxil_validator_max_capable_version : opts->validator_version_max; + struct ntd_context *ctx = calloc(1, sizeof(*ctx)); if (!ctx) return false; @@ -5730,6 +5761,8 @@ nir_to_dxil(struct nir_shader *s, const struct nir_to_dxil_options *opts, ctx->mod.shader_kind = get_dxil_shader_kind(s); ctx->mod.major_version = 6; ctx->mod.minor_version = 1; + ctx->mod.major_validator = validator_version >> 16; + ctx->mod.minor_validator = validator_version & 0xffff; if (s->info.stage <= MESA_SHADER_FRAGMENT) { uint64_t in_mask = @@ -5787,6 +5820,13 @@ nir_to_dxil(struct nir_shader *s, const struct nir_to_dxil_options *opts, goto out; } + assert(ctx->mod.major_validator == 1); + if (!dxil_validator_can_validate_shader_model(ctx->mod.minor_version, ctx->mod.minor_validator)) { + debug_printf("D3D12: shader model exceeds max that can be validated\n"); + retval = false; + goto out; + } + if (debug_dxil & DXIL_DEBUG_DUMP_MODULE) { struct dxil_dumper *dumper = dxil_dump_create(); dxil_dump_module(dumper, &ctx->mod); diff --git a/src/microsoft/compiler/nir_to_dxil.h b/src/microsoft/compiler/nir_to_dxil.h index f2f5f5123b1..cab8c4d18bf 100644 --- a/src/microsoft/compiler/nir_to_dxil.h +++ b/src/microsoft/compiler/nir_to_dxil.h @@ -27,6 +27,7 @@ #include #include "nir.h" +#include "dxil_validator.h" #ifdef __cplusplus extern "C" { @@ -97,6 +98,7 @@ struct nir_to_dxil_options { unsigned input_clip_size; enum dxil_environment environment; uint32_t shader_model_max; + uint32_t validator_version_max; }; bool diff --git a/src/microsoft/spirv_to_dxil/spirv_to_dxil.c b/src/microsoft/spirv_to_dxil/spirv_to_dxil.c index a92fa75c7ba..b62fb9832e6 100644 --- a/src/microsoft/spirv_to_dxil/spirv_to_dxil.c +++ b/src/microsoft/spirv_to_dxil/spirv_to_dxil.c @@ -146,6 +146,7 @@ spirv_to_dxil(const uint32_t *words, size_t word_count, struct nir_to_dxil_options opts = { .environment = DXIL_ENVIRONMENT_VULKAN, .shader_model_max = SHADER_MODEL_6_2, + .validator_version_max = DXIL_VALIDATOR_1_4, }; struct blob dxil_blob; if (!nir_to_dxil(nir, &opts, &dxil_blob)) { diff --git a/src/microsoft/vulkan/dzn_meta.c b/src/microsoft/vulkan/dzn_meta.c index 0f7c694bd4d..d9ff20184b1 100644 --- a/src/microsoft/vulkan/dzn_meta.c +++ b/src/microsoft/vulkan/dzn_meta.c @@ -46,6 +46,7 @@ dzn_meta_compile_shader(struct dzn_device *device, nir_shader *nir, struct nir_to_dxil_options opts = { .environment = DXIL_ENVIRONMENT_VULKAN, .shader_model_max = SHADER_MODEL_6_2, + .validator_version_max = DXIL_VALIDATOR_1_4, }; struct blob dxil_blob; ASSERTED bool ret = nir_to_dxil(nir, &opts, &dxil_blob); diff --git a/src/microsoft/vulkan/dzn_pipeline.c b/src/microsoft/vulkan/dzn_pipeline.c index 71eaaefa869..97986880980 100644 --- a/src/microsoft/vulkan/dzn_pipeline.c +++ b/src/microsoft/vulkan/dzn_pipeline.c @@ -348,6 +348,7 @@ dzn_pipeline_compile_shader(struct dzn_device *device, struct nir_to_dxil_options opts = { .environment = DXIL_ENVIRONMENT_VULKAN, .shader_model_max = SHADER_MODEL_6_2, + .validator_version_max = DXIL_VALIDATOR_1_4, }; struct blob dxil_blob; VkResult result = VK_SUCCESS;