From 03a9a063e5361dcd127457ae2a0051037c5eee5f Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 15 Jul 2020 15:25:45 -0400 Subject: [PATCH] zink: implement ARB_texture_gather again pretty straightforward, just hooking up tg4 tex op in ntv Reviewed-by: Erik Faye-Lund Part-of: --- .../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 232c3c0..3cd6825 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 6d0e638..5d09b0d 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c +++ b/src/gallium/drivers/zink/nir_to_spirv/spirv_builder.c @@ -711,6 +711,52 @@ spirv_builder_emit_image(struct spirv_builder *b, SpvId result_type, } 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, SpvId image, 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 6fd38f1..622adb6 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, -- 2.7.4