Mesa (master): zink: implement txf

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jan 3 14:47:35 UTC 2020


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

Author: Erik Faye-Lund <erik.faye-lund at collabora.com>
Date:   Fri Dec 20 15:56:08 2019 +0100

zink: implement txf

texelFetch is a requirement for OpenGL 3.0, so this gets us a step
closer to GL 3.0 support.

Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>

---

 .../drivers/zink/nir_to_spirv/nir_to_spirv.c       | 40 ++++++++++++++++-----
 .../drivers/zink/nir_to_spirv/spirv_builder.c      | 42 ++++++++++++++++++++++
 .../drivers/zink/nir_to_spirv/spirv_builder.h      | 11 ++++++
 3 files changed, 85 insertions(+), 8 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 e11882348cb..e027058628e 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
@@ -1319,13 +1319,23 @@ get_src_float(struct ntv_context *ctx, nir_src *src)
    return bitcast_to_fvec(ctx, def, bit_size, num_components);
 }
 
+static SpvId
+get_src_int(struct ntv_context *ctx, nir_src *src)
+{
+   SpvId def = get_src_uint(ctx, src);
+   unsigned num_components = nir_src_num_components(*src);
+   unsigned bit_size = nir_src_bit_size(*src);
+   return bitcast_to_ivec(ctx, def, bit_size, num_components);
+}
+
 static void
 emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
 {
    assert(tex->op == nir_texop_tex ||
           tex->op == nir_texop_txb ||
           tex->op == nir_texop_txl ||
-          tex->op == nir_texop_txd);
+          tex->op == nir_texop_txd ||
+          tex->op == nir_texop_txf);
    assert(nir_alu_type_get_base_type(tex->dest_type) == nir_type_float);
    assert(tex->texture_index == tex->sampler_index);
 
@@ -1334,7 +1344,10 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
    for (unsigned i = 0; i < tex->num_srcs; i++) {
       switch (tex->src[i].src_type) {
       case nir_tex_src_coord:
-         coord = get_src_float(ctx, &tex->src[i].src);
+         if (tex->op == nir_texop_txf)
+            coord = get_src_int(ctx, &tex->src[i].src);
+         else
+            coord = get_src_float(ctx, &tex->src[i].src);
          coord_components = nir_src_num_components(tex->src[i].src);
          break;
 
@@ -1352,7 +1365,10 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
 
       case nir_tex_src_lod:
          assert(nir_src_num_components(tex->src[i].src) == 1);
-         lod = get_src_float(ctx, &tex->src[i].src);
+         if (tex->op == nir_texop_txf)
+            lod = get_src_int(ctx, &tex->src[i].src);
+         else
+            lod = get_src_float(ctx, &tex->src[i].src);
          assert(lod != 0);
          break;
 
@@ -1425,11 +1441,19 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
    if (dref)
       actual_dest_type = float_type;
 
-   SpvId result = spirv_builder_emit_image_sample(&ctx->builder,
-                                                  actual_dest_type, load,
-                                                  coord,
-                                                  proj != 0,
-                                                  lod, bias, dref, dx, dy);
+   SpvId result;
+   if (tex->op == nir_texop_txf) {
+      SpvId image = spirv_builder_emit_image(&ctx->builder, image_type, load);
+      result = spirv_builder_emit_image_fetch(&ctx->builder, dest_type,
+                                              image, coord, lod);
+   } else {
+      result = spirv_builder_emit_image_sample(&ctx->builder,
+                                               actual_dest_type, load,
+                                               coord,
+                                               proj != 0,
+                                               lod, bias, dref, dx, dy);
+   }
+
    spirv_builder_emit_decoration(&ctx->builder, result,
                                  SpvDecorationRelaxedPrecision);
 
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 275f81eb4fb..43a4a556653 100644
--- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c
+++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c
@@ -565,6 +565,48 @@ spirv_builder_emit_image_sample(struct spirv_builder *b,
    return result;
 }
 
+SpvId
+spirv_builder_emit_image(struct spirv_builder *b, SpvId result_type,
+                         SpvId sampled_image)
+{
+   SpvId result = spirv_builder_new_id(b);
+   spirv_buffer_prepare(&b->instructions, 4);
+   spirv_buffer_emit_word(&b->instructions, SpvOpImage | (4 << 16));
+   spirv_buffer_emit_word(&b->instructions, result_type);
+   spirv_buffer_emit_word(&b->instructions, result);
+   spirv_buffer_emit_word(&b->instructions, sampled_image);
+   return result;
+}
+
+SpvId
+spirv_builder_emit_image_fetch(struct spirv_builder *b,
+                               SpvId result_type,
+                               SpvId image,
+                               SpvId coordinate,
+                               SpvId lod)
+{
+   SpvId result = spirv_builder_new_id(b);
+
+   SpvId extra_operands[2];
+   int num_extra_operands = 0;
+   if (lod) {
+      extra_operands[0] = SpvImageOperandsLodMask;
+      extra_operands[1] = lod;
+      num_extra_operands = 2;
+   }
+
+   spirv_buffer_prepare(&b->instructions, 5 + num_extra_operands);
+   spirv_buffer_emit_word(&b->instructions, SpvOpImageFetch |
+                          ((5 + 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);
+   for (int i = 0; i < num_extra_operands; ++i)
+      spirv_buffer_emit_word(&b->instructions, extra_operands[i]);
+   return result;
+}
+
 SpvId
 spirv_builder_emit_ext_inst(struct spirv_builder *b, SpvId result_type,
                             SpvId set, uint32_t instruction,
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 736eb211fc7..d7213d85f65 100644
--- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h
+++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.h
@@ -217,6 +217,17 @@ spirv_builder_emit_image_sample(struct spirv_builder *b,
                                 SpvId dx,
                                 SpvId dy);
 
+SpvId
+spirv_builder_emit_image(struct spirv_builder *b, SpvId result_type,
+                         SpvId sampled_image);
+
+SpvId
+spirv_builder_emit_image_fetch(struct spirv_builder *b,
+                               SpvId result_type,
+                               SpvId image,
+                               SpvId coordinate,
+                               SpvId lod);
+
 SpvId
 spirv_builder_emit_ext_inst(struct spirv_builder *b, SpvId result_type,
                             SpvId set, uint32_t instruction,




More information about the mesa-commit mailing list