summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2015-09-16 16:49:14 -0400
committerRob Clark <[email protected]>2015-09-18 21:07:49 -0400
commit1ce8060c25c7f2c7a54159fab6a6974c0ba182a8 (patch)
treeb820d528e0e01a7684a2c104a4d338074b980362
parentfaf5f174ddbc7680f6947ceababb94fdb552bcdb (diff)
nir/lower_tex: support for lowering RECT textures
v2: comments/suggestions from Ilia and Eric, split out get_texture_size() helper so we can use it in the next commit for clamping RECT textures. Signed-off-by: Rob Clark <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
-rw-r--r--src/glsl/nir/nir.h7
-rw-r--r--src/glsl/nir/nir_lower_tex.c59
2 files changed, 63 insertions, 3 deletions
diff --git a/src/glsl/nir/nir.h b/src/glsl/nir/nir.h
index 4600fb0a744..3c908b9f295 100644
--- a/src/glsl/nir/nir.h
+++ b/src/glsl/nir/nir.h
@@ -1843,6 +1843,13 @@ typedef struct nir_lower_tex_options {
* sampler types a texture projector is lowered.
*/
unsigned lower_txp;
+
+ /**
+ * If true, lower rect textures to 2D, using txs to fetch the
+ * texture dimensions and dividing the texture coords by the
+ * texture dims to normalize.
+ */
+ bool lower_rect;
} nir_lower_tex_options;
void nir_lower_tex(nir_shader *shader,
diff --git a/src/glsl/nir/nir_lower_tex.c b/src/glsl/nir/nir_lower_tex.c
index 281fc9f3e8f..63f51bcbdc5 100644
--- a/src/glsl/nir/nir_lower_tex.c
+++ b/src/glsl/nir/nir_lower_tex.c
@@ -22,9 +22,13 @@
*/
/*
- * This lowering pass converts the coordinate division for texture projection
- * to be done in ALU instructions instead of asking the texture operation to
- * do so.
+ * This lowering pass supports (as configured via nir_lower_tex_options)
+ * various texture related conversions:
+ * + texture projector lowering: converts the coordinate division for
+ * texture projection to be done in ALU instructions instead of
+ * asking the texture operation to do so.
+ * + lowering RECT: converts the un-normalized RECT texture coordinates
+ * to normalized coordinates with txs plus ALU instructions
*/
#include "nir.h"
@@ -111,6 +115,52 @@ project_src(nir_builder *b, nir_tex_instr *tex)
tex->num_srcs--;
}
+static nir_ssa_def *
+get_texture_size(nir_builder *b, nir_tex_instr *tex)
+{
+ b->cursor = nir_before_instr(&tex->instr);
+
+ /* RECT textures should not be array: */
+ assert(!tex->is_array);
+
+ nir_tex_instr *txs;
+
+ txs = nir_tex_instr_create(b->shader, 1);
+ txs->op = nir_texop_txs;
+ txs->sampler_dim = GLSL_SAMPLER_DIM_RECT;
+ txs->sampler_index = tex->sampler_index;
+
+ /* only single src, the lod: */
+ txs->src[0].src = nir_src_for_ssa(nir_imm_int(b, 0));
+ txs->src[0].src_type = nir_tex_src_lod;
+
+ nir_ssa_dest_init(&txs->instr, &txs->dest, 2, NULL);
+ nir_builder_instr_insert(b, &txs->instr);
+
+ return nir_i2f(b, &txs->dest.ssa);
+}
+
+static void
+lower_rect(nir_builder *b, nir_tex_instr *tex)
+{
+ nir_ssa_def *txs = get_texture_size(b, tex);
+ nir_ssa_def *scale = nir_frcp(b, txs);
+
+ /* Walk through the sources normalizing the requested arguments. */
+ for (unsigned i = 0; i < tex->num_srcs; i++) {
+ if (tex->src[i].src_type != nir_tex_src_coord)
+ continue;
+
+ nir_ssa_def *coords =
+ nir_ssa_for_src(b, tex->src[i].src, tex->coord_components);
+ nir_instr_rewrite_src(&tex->instr,
+ &tex->src[i].src,
+ nir_src_for_ssa(nir_fmul(b, coords, scale)));
+ }
+
+ tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
+}
+
static bool
nir_lower_tex_block(nir_block *block, void *void_state)
{
@@ -127,6 +177,9 @@ nir_lower_tex_block(nir_block *block, void *void_state)
if (lower_txp)
project_src(b, tex);
+ if ((tex->sampler_dim == GLSL_SAMPLER_DIM_RECT) &&
+ state->options->lower_rect)
+ lower_rect(b, tex);
}
return true;