zink: handle textureGather with Shadow-type samplers
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Fri, 24 Jul 2020 13:48:36 +0000 (09:48 -0400)
committerMarge Bot <eric+marge@anholt.net>
Mon, 4 Jan 2021 15:55:17 +0000 (15:55 +0000)
these have to go through OpImageDrefGather without composite construction
on the result

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

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

index 3cd6825..1912128 100644 (file)
@@ -2276,7 +2276,7 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
       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);
+                                                 lod, sample, offset, dref);
       else
          result = spirv_builder_emit_image_fetch(&ctx->builder, dest_type,
                                                  image, coord, lod, sample, offset);
@@ -2292,7 +2292,7 @@ emit_tex(struct ntv_context *ctx, nir_tex_instr *tex)
    spirv_builder_emit_decoration(&ctx->builder, result,
                                  SpvDecorationRelaxedPrecision);
 
-   if (dref && nir_dest_num_components(tex->dest) > 1) {
+   if (dref && nir_dest_num_components(tex->dest) > 1 && tex->op != nir_texop_tg4) {
       SpvId components[4] = { result, result, result, result };
       result = spirv_builder_emit_composite_construct(&ctx->builder,
                                                       dest_type,
index 5d09b0d..5aee0b6 100644 (file)
@@ -718,9 +718,11 @@ spirv_builder_emit_image_gather(struct spirv_builder *b,
                                SpvId component,
                                SpvId lod,
                                SpvId sample,
-                               SpvId offset)
+                               SpvId offset,
+                               SpvId dref)
 {
    SpvId result = spirv_builder_new_id(b);
+   SpvId op = SpvOpImageGather;
 
    SpvImageOperandsMask operand_mask = SpvImageOperandsMaskNone;
    SpvId extra_operands[4];
@@ -737,6 +739,8 @@ spirv_builder_emit_image_gather(struct spirv_builder *b,
       extra_operands[++num_extra_operands] = offset;
       operand_mask |= SpvImageOperandsOffsetMask;
    }
+   if (dref)
+      op = SpvOpImageDrefGather;
    /* finalize num_extra_operands / extra_operands */
    if (num_extra_operands > 0) {
       extra_operands[0] = operand_mask;
@@ -744,13 +748,16 @@ spirv_builder_emit_image_gather(struct spirv_builder *b,
    }
 
    spirv_buffer_prepare(&b->instructions, b->mem_ctx, 6 + num_extra_operands);
-   spirv_buffer_emit_word(&b->instructions, SpvOpImageGather |
+   spirv_buffer_emit_word(&b->instructions, op |
                           ((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);
+   if (dref)
+      spirv_buffer_emit_word(&b->instructions, dref);
+   else
+      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;
index 622adb6..d819a6d 100644 (file)
@@ -273,7 +273,8 @@ spirv_builder_emit_image_gather(struct spirv_builder *b,
                                SpvId component,
                                SpvId lod,
                                SpvId sample,
-                               SpvId offset);
+                               SpvId offset,
+                               SpvId dref);
 
 SpvId
 spirv_builder_emit_image_query_size(struct spirv_builder *b,