microsoft/compiler: Add a max validator version

Reviewed-by: Enrico Galli <enrico.galli@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17603>
This commit is contained in:
Jesse Natalie 2022-02-13 13:05:12 -08:00 committed by Marge Bot
parent c8f63e07da
commit 6af22121cf
9 changed files with 62 additions and 2 deletions

View 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)) {

View 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++) {

View 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;

View 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);

View 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);

View 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

View 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)) {

View 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);

View 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;