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