zink: expand ntv array derefs to track image derefs
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Tue, 17 Nov 2020 23:43:54 +0000 (18:43 -0500)
committerMarge Bot <eric+marge@anholt.net>
Thu, 21 Jan 2021 19:48:45 +0000 (19:48 +0000)
this is sort of what we should be moving towards for io as well at some point,
the gist of the change here being that when images are deref'd, we need
to be able to do a lookup on the deref store later on in order to get the
image back

Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8504>

src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c

index fcc4701..8a4648f 100644 (file)
@@ -2714,19 +2714,46 @@ emit_deref_array(struct ntv_context *ctx, nir_deref_instr *deref)
    nir_variable *var = nir_deref_instr_get_variable(deref);
 
    SpvStorageClass storage_class = get_storage_class(var);
+   SpvId base, type;
+   switch (var->data.mode) {
+   case nir_var_shader_in:
+   case nir_var_shader_out:
+      base = get_src(ctx, &deref->parent);
+      type = get_glsl_type(ctx, deref->type);
+      break;
+
+   case nir_var_uniform: {
+      assert(glsl_type_is_image(glsl_without_array(var->type)));
+      struct hash_entry *he = _mesa_hash_table_search(ctx->vars, var);
+      assert(he);
+      base = (SpvId)(intptr_t)he->data;
+      type = ctx->image_types[var->data.binding];
+      break;
+   }
+
+   default:
+      unreachable("Unsupported nir_variable_mode\n");
+   }
 
    SpvId index = get_src(ctx, &deref->arr.index);
 
    SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
                                                storage_class,
-                                               get_glsl_type(ctx, deref->type));
+                                               type);
 
    SpvId result = spirv_builder_emit_access_chain(&ctx->builder,
                                                   ptr_type,
-                                                  get_src(ctx, &deref->parent),
+                                                  base,
                                                   &index, 1);
    /* uint is a bit of a lie here, it's really just an opaque type */
    store_dest(ctx, &deref->dest, result, nir_type_uint);
+
+   /* image ops always need to be able to get the variable to check out sampler types and such */
+   if (glsl_type_is_image(glsl_without_array(var->type))) {
+      uint32_t *key = ralloc_size(ctx->mem_ctx, sizeof(uint32_t));
+      *key = result;
+      _mesa_hash_table_insert(ctx->image_vars, key, var);
+   }
 }
 
 static void