From: Rob Clark Date: Wed, 16 Sep 2015 20:49:14 +0000 (-0400) Subject: nir/lower_tex: support for lowering RECT textures X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1ce8060c25c7f2c7a54159fab6a6974c0ba182a8;p=mesa.git 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 Reviewed-by: Kenneth Graunke --- 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;