microsoft/compiler: Add a max validator version
authorJesse Natalie <jenatali@microsoft.com>
Sun, 13 Feb 2022 21:05:12 +0000 (13:05 -0800)
committerMarge Bot <emma+marge@anholt.net>
Sat, 23 Jul 2022 14:48:17 +0000 (14:48 +0000)
Reviewed-by: Enrico Galli <enrico.galli@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17603>

src/gallium/drivers/d3d12/d3d12_compiler.cpp
src/microsoft/clc/clc_compiler.c
src/microsoft/compiler/dxil_module.h
src/microsoft/compiler/dxil_validator.h
src/microsoft/compiler/nir_to_dxil.c
src/microsoft/compiler/nir_to_dxil.h
src/microsoft/spirv_to_dxil/spirv_to_dxil.c
src/microsoft/vulkan/dzn_meta.c
src/microsoft/vulkan/dzn_pipeline.c

index 0792042..60f6761 100644 (file)
@@ -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)) {
index b45f462..dc8f312 100644 (file)
@@ -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++) {
index 1332328..db77801 100644 (file)
@@ -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;
index de5c064..827aec7 100644 (file)
@@ -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);
 
index d60129d..9234032 100644 (file)
@@ -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);
index f2f5f51..cab8c4d 100644 (file)
@@ -27,6 +27,7 @@
 #include <stdbool.h>
 
 #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
index a92fa75..b62fb98 100644 (file)
@@ -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)) {
index 0f7c694..d9ff201 100644 (file)
@@ -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);
index 71eaaef..9798688 100644 (file)
@@ -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;