Mesa (master): zink: implement ARB_texture_gather

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jan 4 16:00:01 UTC 2021


Module: Mesa
Branch: master
Commit: 03a9a063e5361dcd127457ae2a0051037c5eee5f
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=03a9a063e5361dcd127457ae2a0051037c5eee5f

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Wed Jul 15 15:25:45 2020 -0400

zink: implement ARB_texture_gather

again pretty straightforward, just hooking up tg4 tex op in ntv

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

---

 .../drivers/zink/nir_to_spirv/nir_to_spirv.c       | 15 +++++--
 .../drivers/zink/nir_to_spirv/spirv_builder.c      | 46 ++++++++++++++++++++++
 .../drivers/zink/nir_to_spirv/spirv_builder.h      | 10 +++++
 3 files changed, 67 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
index 232c3c074b6..3cd68252cbf 100644
--- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
+++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
@@ -2105,7 +2105,8 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
           tex->op == nir_texop_txf ||
           tex->op == nir_texop_txf_ms ||
           tex->op == nir_texop_txs ||
-          tex->op == nir_texop_lod);
+          tex->op == nir_texop_lod ||
+          tex->op == nir_texop_tg4);
    assert(tex->texture_index == tex->sampler_index);
 
    SpvId coord = 0, proj = 0, bias = 0, lod = 0, dref = 0, dx = 0, dy = 0,
@@ -2267,12 +2268,18 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
 
    SpvId result;
    if (tex->op == nir_texop_txf ||
-       tex->op == nir_texop_txf_ms) {
+       tex->op == nir_texop_txf_ms ||
+       tex->op == nir_texop_tg4) {
       SpvId image = spirv_builder_emit_image(&ctx->builder, image_type, load);
       if (offset)
          spirv_builder_emit_cap(&ctx->builder, SpvCapabilityImageGatherExtended);
-      result = spirv_builder_emit_image_fetch(&ctx->builder, dest_type,
-                                              image, coord, lod, sample, offset);
+      if (tex->op == nir_texop_tg4)
+         result = spirv_builder_emit_image_gather(&ctx->builder, dest_type,
+                                                 load, coord, emit_uint_const(ctx, 32, tex->component),
+                                                 lod, sample, offset);
+      else
+         result = spirv_builder_emit_image_fetch(&ctx->builder, dest_type,
+                                                 image, coord, lod, sample, offset);
    } else {
       result = spirv_builder_emit_image_sample(&ctx->builder,
                                                actual_dest_type, load,
diff --git a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c
index 6d0e6384924..5d09b0d7dc0 100644
--- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c
+++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c
@@ -710,6 +710,52 @@ spirv_builder_emit_image(struct spirv_builder *b, SpvId result_type,
    return result;
 }
 
+SpvId
+spirv_builder_emit_image_gather(struct spirv_builder *b,
+                               SpvId result_type,
+                               SpvId image,
+                               SpvId coordinate,
+                               SpvId component,
+                               SpvId lod,
+                               SpvId sample,
+                               SpvId offset)
+{
+   SpvId result = spirv_builder_new_id(b);
+
+   SpvImageOperandsMask operand_mask = SpvImageOperandsMaskNone;
+   SpvId extra_operands[4];
+   int num_extra_operands = 0;
+   if (lod) {
+      extra_operands[++num_extra_operands] = lod;
+      operand_mask |= SpvImageOperandsLodMask;
+   }
+   if (sample) {
+      extra_operands[++num_extra_operands] = sample;
+      operand_mask |= SpvImageOperandsSampleMask;
+   }
+   if (offset) {
+      extra_operands[++num_extra_operands] = offset;
+      operand_mask |= SpvImageOperandsOffsetMask;
+   }
+   /* finalize num_extra_operands / extra_operands */
+   if (num_extra_operands > 0) {
+      extra_operands[0] = operand_mask;
+      num_extra_operands++;
+   }
+
+   spirv_buffer_prepare(&b->instructions, b->mem_ctx, 6 + num_extra_operands);
+   spirv_buffer_emit_word(&b->instructions, SpvOpImageGather |
+                          ((6 + num_extra_operands) << 16));
+   spirv_buffer_emit_word(&b->instructions, result_type);
+   spirv_buffer_emit_word(&b->instructions, result);
+   spirv_buffer_emit_word(&b->instructions, image);
+   spirv_buffer_emit_word(&b->instructions, coordinate);
+   spirv_buffer_emit_word(&b->instructions, component);
+   for (int i = 0; i < num_extra_operands; ++i)
+      spirv_buffer_emit_word(&b->instructions, extra_operands[i]);
+   return result;
+}
+
 SpvId
 spirv_builder_emit_image_fetch(struct spirv_builder *b,
                                SpvId result_type,
diff --git a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h
index 6fd38f151c9..622adb61463 100644
--- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h
+++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h
@@ -266,6 +266,16 @@ spirv_builder_emit_image_fetch(struct spirv_builder *b,
                                SpvId sample,
                                SpvId offset);
 SpvId
+spirv_builder_emit_image_gather(struct spirv_builder *b,
+                               SpvId result_type,
+                               SpvId image,
+                               SpvId coordinate,
+                               SpvId component,
+                               SpvId lod,
+                               SpvId sample,
+                               SpvId offset);
+
+SpvId
 spirv_builder_emit_image_query_size(struct spirv_builder *b,
                                     SpvId result_type,
                                     SpvId image,



More information about the mesa-commit mailing list