microsoft/compiler: Change vulkan_environment bool to an enum
authorJesse Natalie <jenatali@microsoft.com>
Tue, 28 Dec 2021 21:13:03 +0000 (13:13 -0800)
committerMarge Bot <emma+marge@anholt.net>
Fri, 7 Jan 2022 03:31:16 +0000 (03:31 +0000)
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 <sivileri@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14342>

src/gallium/drivers/d3d12/d3d12_compiler.cpp
src/microsoft/clc/clc_compiler.c
src/microsoft/compiler/nir_to_dxil.c
src/microsoft/compiler/nir_to_dxil.h
src/microsoft/spirv_to_dxil/spirv_to_dxil.c

index d8c702f..9b79f13 100644 (file)
@@ -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)) {
index d1400b9..46ae127 100644 (file)
@@ -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++) {
index 7649e8e..9b460d9 100644 (file)
@@ -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(&params, 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) {
index f661582..e38af4e 100644 (file)
@@ -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
index e45ca71..1b6fc42 100644 (file)
@@ -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)) {