From 8a4b443c5bcac93579567d7093088a622316e677 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Tue, 28 Dec 2021 13:13:03 -0800 Subject: [PATCH] microsoft/compiler: Change vulkan_environment bool to an enum There are currently 3 different "environments" supported by this backend, and they have slightly different semantics for how resources are accessed, which is only going to get a little weirder when GL images start getting supported. To try to make things less confusing, use an explicit enum with heavy documentation on what's different between them. Reviewed-by: Sil Vilerino Part-of: --- src/gallium/drivers/d3d12/d3d12_compiler.cpp | 1 + src/microsoft/clc/clc_compiler.c | 1 + src/microsoft/compiler/nir_to_dxil.c | 40 ++++++++++++++-------------- src/microsoft/compiler/nir_to_dxil.h | 38 +++++++++++++++++++++++++- src/microsoft/spirv_to_dxil/spirv_to_dxil.c | 2 +- 5 files changed, 60 insertions(+), 22 deletions(-) diff --git a/src/gallium/drivers/d3d12/d3d12_compiler.cpp b/src/gallium/drivers/d3d12/d3d12_compiler.cpp index d8c702f..9b79f13 100644 --- a/src/gallium/drivers/d3d12/d3d12_compiler.cpp +++ b/src/gallium/drivers/d3d12/d3d12_compiler.cpp @@ -180,6 +180,7 @@ compile_nir(struct d3d12_context *ctx, struct d3d12_shader_selector *sel, opts.lower_int16 = !screen->opts4.Native16BitShaderOpsSupported; opts.ubo_binding_offset = shader->has_default_ubo0 ? 0 : 1; opts.provoking_vertex = key->fs.provoking_vertex; + opts.environment = DXIL_ENVIRONMENT_GL; 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 d1400b9..46ae127 100644 --- a/src/microsoft/clc/clc_compiler.c +++ b/src/microsoft/clc/clc_compiler.c @@ -1166,6 +1166,7 @@ clc_spirv_to_dxil(struct clc_libclc *lib, .ubo_binding_offset = 0, .disable_math_refactoring = true, .num_kernel_globals = num_global_inputs, + .environment = DXIL_ENVIRONMENT_CL, }; for (unsigned i = 0; i < out_dxil->kernel->num_args; i++) { diff --git a/src/microsoft/compiler/nir_to_dxil.c b/src/microsoft/compiler/nir_to_dxil.c index 7649e8e..9b460d9 100644 --- a/src/microsoft/compiler/nir_to_dxil.c +++ b/src/microsoft/compiler/nir_to_dxil.c @@ -877,7 +877,7 @@ emit_srv(struct ntd_context *ctx, nir_variable *var, unsigned count) if (res_type == DXIL_RES_SRV_RAW) ctx->mod.raw_and_structured_buffers = true; - if (!ctx->opts->vulkan_environment) { + if (ctx->opts->environment != DXIL_ENVIRONMENT_VULKAN) { for (unsigned i = 0; i < count; ++i) { const struct dxil_value *handle = emit_createhandle_call_const_index(ctx, DXIL_RESOURCE_CLASS_SRV, @@ -885,7 +885,7 @@ emit_srv(struct ntd_context *ctx, nir_variable *var, unsigned count) if (!handle) return false; - int idx = var->data.binding + i; + int idx = binding + i; ctx->srv_handles[idx] = handle; } } @@ -955,7 +955,7 @@ emit_uav(struct ntd_context *ctx, unsigned binding, unsigned space, unsigned cou ctx->mod.shader_kind != DXIL_COMPUTE_SHADER) ctx->mod.feats.uavs_at_every_stage = true; - if (!ctx->opts->vulkan_environment) { + if (ctx->opts->environment != DXIL_ENVIRONMENT_VULKAN) { for (unsigned i = 0; i < count; ++i) { const struct dxil_value *handle = emit_createhandle_call_const_index(ctx, DXIL_RESOURCE_CLASS_UAV, id, binding + i, false); @@ -1124,7 +1124,7 @@ emit_cbv(struct ntd_context *ctx, unsigned binding, unsigned space, util_dynarray_append(&ctx->cbv_metadata_nodes, const struct dxil_mdnode *, cbv_meta); add_resource(ctx, DXIL_RES_CBV, &layout); - if (!ctx->opts->vulkan_environment) { + if (ctx->opts->environment != DXIL_ENVIRONMENT_VULKAN) { for (unsigned i = 0; i < count; ++i) { const struct dxil_value *handle = emit_createhandle_call_const_index(ctx, DXIL_RESOURCE_CLASS_CBV, idx, binding + i, false); @@ -1164,7 +1164,7 @@ emit_sampler(struct ntd_context *ctx, nir_variable *var, unsigned count) util_dynarray_append(&ctx->sampler_metadata_nodes, const struct dxil_mdnode *, sampler_meta); add_resource(ctx, DXIL_RES_SAMPLER, &layout); - if (!ctx->opts->vulkan_environment) { + if (ctx->opts->environment != DXIL_ENVIRONMENT_VULKAN) { for (unsigned i = 0; i < count; ++i) { const struct dxil_value *handle = emit_createhandle_call_const_index(ctx, DXIL_RESOURCE_CLASS_SAMPLER, @@ -1385,7 +1385,7 @@ emit_metadata(struct ntd_context *ctx) } const struct dxil_mdnode *signatures = get_signatures(&ctx->mod, ctx->shader, - ctx->opts->vulkan_environment); + ctx->opts->environment == DXIL_ENVIRONMENT_VULKAN); const struct dxil_mdnode *dx_entry_point = emit_entrypoint(ctx, main_func, "main", signatures, resources_node, shader_properties); @@ -2424,7 +2424,7 @@ get_ubo_ssbo_handle(struct ntd_context *ctx, nir_src *src, enum dxil_resource_cl nir_const_value *const_block_index = nir_src_as_const_value(*src); const struct dxil_value **handle_entry = NULL; if (const_block_index) { - assert(!ctx->opts->vulkan_environment); + assert(ctx->opts->environment != DXIL_ENVIRONMENT_VULKAN); switch (class) { case DXIL_RESOURCE_CLASS_CBV: handle_entry = &ctx->cbv_handles[const_block_index->u32]; @@ -2444,7 +2444,7 @@ get_ubo_ssbo_handle(struct ntd_context *ctx, nir_src *src, enum dxil_resource_cl return *handle_entry; const struct dxil_value *value = get_src_ssa(ctx, src->ssa, 0); - if (ctx->opts->vulkan_environment) { + if (ctx->opts->environment == DXIL_ENVIRONMENT_VULKAN) { return value; } @@ -2462,7 +2462,7 @@ emit_load_ssbo(struct ntd_context *ctx, nir_intrinsic_instr *intr) const struct dxil_value *int32_undef = get_int32_undef(&ctx->mod); enum dxil_resource_class class = DXIL_RESOURCE_CLASS_UAV; - if (ctx->opts->vulkan_environment) { + if (ctx->opts->environment == DXIL_ENVIRONMENT_VULKAN) { nir_variable *var = nir_get_binding_variable(ctx->shader, nir_chase_binding(intr->src[0])); if (var && var->data.access & ACCESS_NON_WRITEABLE) class = DXIL_RESOURCE_CLASS_SRV; @@ -2971,7 +2971,7 @@ emit_image_store(struct ntd_context *ctx, nir_intrinsic_instr *intr) { const struct dxil_value *handle; bool is_array = false; - if (ctx->opts->vulkan_environment) { + if (ctx->opts->environment == DXIL_ENVIRONMENT_VULKAN) { assert(intr->intrinsic == nir_intrinsic_image_deref_store); handle = get_src_ssa(ctx, intr->src[0].ssa, 0); is_array = glsl_sampler_type_is_array(nir_src_as_deref(intr->src[0])->type); @@ -3036,7 +3036,7 @@ emit_image_load(struct ntd_context *ctx, nir_intrinsic_instr *intr) { const struct dxil_value *handle; bool is_array = false; - if (ctx->opts->vulkan_environment) { + if (ctx->opts->environment == DXIL_ENVIRONMENT_VULKAN) { assert(intr->intrinsic == nir_intrinsic_image_deref_load); handle = get_src_ssa(ctx, intr->src[0].ssa, 0); is_array = glsl_sampler_type_is_array(nir_src_as_deref(intr->src[0])->type); @@ -3126,7 +3126,7 @@ static bool emit_image_size(struct ntd_context *ctx, nir_intrinsic_instr *intr) { const struct dxil_value *handle; - if (ctx->opts->vulkan_environment) { + if (ctx->opts->environment == DXIL_ENVIRONMENT_VULKAN) { assert(intr->intrinsic == nir_intrinsic_image_deref_size); handle = get_src_ssa(ctx, intr->src[0].ssa, 0); } @@ -3162,7 +3162,7 @@ static bool emit_get_ssbo_size(struct ntd_context *ctx, nir_intrinsic_instr *intr) { const struct dxil_value* handle = NULL; - if (ctx->opts->vulkan_environment) { + if (ctx->opts->environment == DXIL_ENVIRONMENT_VULKAN) { handle = get_src_ssa(ctx, intr->src[0].ssa, 0); } else { int binding = nir_src_as_int(intr->src[0]); @@ -3567,7 +3567,7 @@ emit_deref(struct ntd_context* ctx, nir_deref_instr* instr) /* In the non-Vulkan environment, there's nothing to emit. Any references to * derefs will emit the necessary logic to handle scratch/shared GEP addressing */ - if (!ctx->opts->vulkan_environment) + if (ctx->opts->environment != DXIL_ENVIRONMENT_VULKAN) return true; /* In the Vulkan environment, we don't have cached handles for textures or @@ -3901,7 +3901,7 @@ emit_tex(struct ntd_context *ctx, nir_tex_instr *instr) { struct texop_parameters params; memset(¶ms, 0, sizeof(struct texop_parameters)); - if (!ctx->opts->vulkan_environment) { + if (ctx->opts->environment != DXIL_ENVIRONMENT_VULKAN) { params.tex = ctx->srv_handles[instr->texture_index]; params.sampler = ctx->sampler_handles[instr->sampler_index]; } @@ -3986,12 +3986,12 @@ emit_tex(struct ntd_context *ctx, nir_tex_instr *instr) break; case nir_tex_src_texture_deref: - assert(ctx->opts->vulkan_environment); + assert(ctx->opts->environment == DXIL_ENVIRONMENT_VULKAN); params.tex = get_src_ssa(ctx, instr->src[i].src.ssa, 0); break; case nir_tex_src_sampler_deref: - assert(ctx->opts->vulkan_environment); + assert(ctx->opts->environment == DXIL_ENVIRONMENT_VULKAN); params.sampler = get_src_ssa(ctx, instr->src[i].src.ssa, 0); break; @@ -4296,7 +4296,7 @@ prepare_phi_values(struct ntd_context *ctx) static bool emit_cbvs(struct ntd_context *ctx) { - if (ctx->shader->info.stage == MESA_SHADER_KERNEL || ctx->opts->vulkan_environment) { + if (ctx->opts->environment != DXIL_ENVIRONMENT_GL) { nir_foreach_variable_with_modes(var, ctx->shader, nir_var_mem_ubo) { if (!emit_ubo_var(ctx, var)) return false; @@ -4405,7 +4405,7 @@ emit_module(struct ntd_context *ctx, const struct nir_to_dxil_options *opts) } /* Handle read-only SSBOs as SRVs */ - if (ctx->opts->vulkan_environment) { + if (ctx->opts->environment == DXIL_ENVIRONMENT_VULKAN) { nir_foreach_variable_with_modes(var, ctx->shader, nir_var_mem_ssbo) { if ((var->data.access & ACCESS_NON_WRITEABLE) != 0) { unsigned count = 1; @@ -4454,7 +4454,7 @@ emit_module(struct ntd_context *ctx, const struct nir_to_dxil_options *opts) return false; if (!emit_global_consts(ctx)) return false; - } else if (ctx->opts->vulkan_environment) { + } else if (ctx->opts->environment == DXIL_ENVIRONMENT_VULKAN) { /* Handle read/write SSBOs as UAVs */ nir_foreach_variable_with_modes(var, ctx->shader, nir_var_mem_ssbo) { if ((var->data.access & ACCESS_NON_WRITEABLE) == 0) { diff --git a/src/microsoft/compiler/nir_to_dxil.h b/src/microsoft/compiler/nir_to_dxil.h index f661582..e38af4e 100644 --- a/src/microsoft/compiler/nir_to_dxil.h +++ b/src/microsoft/compiler/nir_to_dxil.h @@ -43,6 +43,42 @@ enum dxil_sysvalue_type { enum dxil_sysvalue_type nir_var_to_dxil_sysvalue_type(nir_variable *var, uint64_t other_stage_mask); +/* Controls how resource decls/accesses are handled. Common to all: + * Images, textures, and samplers map to D3D UAV, SRV, and sampler types + * Shared is lowered to explicit I/O and then to a DXIL-specific intrinsic for 4-byte indices instead of byte addressing + * Input/output are lowered to dedicated intrinsics + */ +enum dxil_environment { + /* In the GL environment: + * Samplers/textures are lowered, vars/intrinsics use binding to refer to them; dynamic array indexing not yet supported + * The lowering done by mesa/st assigns bindings from 0 -> N + * All other resource variables have driver_location set instead, assigned from 0 -> N + * UBOs may or may not have interface variables, and are declared from ubo_binding_offset -> num_ubos; no dynamic indexing yet + * SSBOs may or may not have interface variables, and are declared from from 0 -> num_ssbos; no dynamic indexing yet + * No images, immediate constant buffer, or scratch + */ + DXIL_ENVIRONMENT_GL, + /* In the CL environment: + * Shader kind is always KERNEL + * All resources use binding for identification + * Samplers/textures/images are lowered; dynamic indexing not supported by spec + * UBOs are arrays of uints in the NIR + * SSBOs are implicitly declared via num_kernel_globals + * Variables of shader_temp are used to declare an immediate constant buffer, with load_ptr_dxil intrinsics to access it + * Scratch is supported and lowered to DXIL-specific intrinsics for scalar 32-bit access + */ + DXIL_ENVIRONMENT_CL, + /* In the Vulkan environment: + * All resources use binding / descriptor_set for identification + * Samplers/textures/images are not lowered + * Deref chains are walked to emit the DXIL handle to the resource; dynamic indexing supported + * UBOs/SSBOs are struct variables in the NIR, accessed via vulkan_resource_index/load_vulkan_descriptor; dynamic indexing supported + * Read-only SSBOs, as declared in the SPIR-V, are bound as raw buffer SRVs instead of UAVs + * No immediate constant buffer or scratch + */ + DXIL_ENVIRONMENT_VULKAN, +}; + struct nir_to_dxil_options { bool interpolate_at_vertex; bool lower_int16; @@ -50,7 +86,7 @@ struct nir_to_dxil_options { unsigned ubo_binding_offset; unsigned provoking_vertex; unsigned num_kernel_globals; - bool vulkan_environment; + enum dxil_environment environment; }; bool diff --git a/src/microsoft/spirv_to_dxil/spirv_to_dxil.c b/src/microsoft/spirv_to_dxil/spirv_to_dxil.c index e45ca71..1b6fc42 100644 --- a/src/microsoft/spirv_to_dxil/spirv_to_dxil.c +++ b/src/microsoft/spirv_to_dxil/spirv_to_dxil.c @@ -312,7 +312,7 @@ spirv_to_dxil(const uint32_t *words, size_t word_count, dxil_sort_ps_outputs(nir); } - struct nir_to_dxil_options opts = {.vulkan_environment = true}; + struct nir_to_dxil_options opts = {.environment = DXIL_ENVIRONMENT_VULKAN}; struct blob dxil_blob; if (!nir_to_dxil(nir, &opts, &dxil_blob)) { -- 2.7.4