zink: handle struct derefs in ntv
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Thu, 23 Jul 2020 11:47:14 +0000 (07:47 -0400)
committerMarge Bot <eric+marge@anholt.net>
Thu, 17 Dec 2020 19:10:41 +0000 (19:10 +0000)
Erik Faye-Lund <erik.faye-lund@collabora.com>

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8142>

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

index 4c57e906a8c8d067b8139fb11959aedc04b95d97..e063c9495ce4258ce919f97e15fd043d5f38fc49 100644 (file)
@@ -2177,6 +2177,28 @@ emit_deref_array(struct ntv_context *ctx, nir_deref_instr *deref)
    store_dest(ctx, &deref->dest, result, nir_type_uint);
 }
 
+static void
+emit_deref_struct(struct ntv_context *ctx, nir_deref_instr *deref)
+{
+   assert(deref->deref_type == nir_deref_type_struct);
+   nir_variable *var = nir_deref_instr_get_variable(deref);
+
+   SpvStorageClass storage_class = get_storage_class(var);
+
+   SpvId index = emit_uint_const(ctx, 32, deref->strct.index);
+
+   SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
+                                               storage_class,
+                                               get_glsl_type(ctx, deref->type));
+
+   SpvId result = spirv_builder_emit_access_chain(&ctx->builder,
+                                                  ptr_type,
+                                                  get_src(ctx, &deref->parent),
+                                                  &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);
+}
+
 static void
 emit_deref(struct ntv_context *ctx, nir_deref_instr *deref)
 {
@@ -2189,6 +2211,10 @@ emit_deref(struct ntv_context *ctx, nir_deref_instr *deref)
       emit_deref_array(ctx, deref);
       break;
 
+   case nir_deref_type_struct:
+      emit_deref_struct(ctx, deref);
+      break;
+
    default:
       unreachable("unexpected deref_type");
    }