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