[Mesa-dev] [PATCH 4/6] nir/lower_tex: support for lowering RECT textures
Rob Clark
robdclark at gmail.com
Fri Sep 18 09:36:21 PDT 2015
On Fri, Sep 18, 2015 at 11:22 AM, Kenneth Graunke <kenneth at whitecape.org> wrote:
> On Friday, September 18, 2015 10:55:07 AM Rob Clark wrote:
>> From: Rob Clark <robclark at freedesktop.org>
>>
>> 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 <robclark at freedesktop.org>
>> ---
>> src/glsl/nir/nir.h | 7 +++++
>> src/glsl/nir/nir_lower_tex.c | 62 +++++++++++++++++++++++++++++++++++++++++---
>> 2 files changed, 66 insertions(+), 3 deletions(-)
>>
>> diff --git a/src/glsl/nir/nir.h b/src/glsl/nir/nir.h
>> index 4600fb0..3c908b9 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 281fc9f..a71a5c5 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,55 @@ 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, 3, NULL);
>
> Shouldn't this be 2? textureSize of 2DRect returns an ivec2...
yup
>> + 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 *scalex = nir_frcp(b, nir_channel(b, txs, 0));
>> + nir_ssa_def *scaley = nir_frcp(b, nir_channel(b, txs, 1));
>> + nir_ssa_def *scale = nir_vec2(b, scalex, scaley);
>
> Why not just do 1 / txs.xy directly?
I had assumed that frcp just operates on src.x (at least that it is
how it is in tgsi and hw that I have seen).. if it operates on each
component, then yes I could do it in one shot. And I guess since txs
is already a vec2, I could just:
nir_ssa_def *scale = nir_frcp(b, txs);
> unsigned swizzle[4] = { SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y };
> nir_ssa_def *scale = nir_frcp(b, nir_swizzle(b, txs, swizzle, 2, false);
>
>> +
>> + /* 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 +180,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) &&
>
> Please remove the bonus parens.
hmm, I'm the only one who *likes* bonus parens? (Then again, I'd
always liked lisp/scheme so maybe I have a paren fetish..)
BR,
-R
>> + state->options->lower_rect)
>> + lower_rect(b, tex);
>> }
>>
>> return true;
>>
>
> With the ivec2/ivec3 thing fixed, this would be:
> Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
More information about the mesa-dev
mailing list