diff options
author | Eric Anholt <[email protected]> | 2017-11-21 13:42:08 -0800 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2017-12-14 14:36:17 -0800 |
commit | b08b6289943b225b6451e6c8ce331a8c11bd0c7f (patch) | |
tree | 50590887b30bb02c9f8aebc099a2ff8f79560043 | |
parent | 52f024b0523763799e71de0a327d5143df72a792 (diff) |
nir: Fix interaction of GL_CLAMP lowering with texture offsets.
We want the clamping of the coordinate to apply after the offset, so we
need to do math to lower the offset out of the instruction. Fixes texwrap
offset cases for GL_CLAMP with GL_NEAREST on vc5.
Note: I moved the get_texture_size() verbatim, so that it was defined
before use.
Reviewed-by: Ian Romanick <[email protected]>
-rw-r--r-- | src/compiler/nir/nir_lower_tex.c | 75 |
1 files changed, 42 insertions, 33 deletions
diff --git a/src/compiler/nir/nir_lower_tex.c b/src/compiler/nir/nir_lower_tex.c index a50cb52d549..bd603cc2288 100644 --- a/src/compiler/nir/nir_lower_tex.c +++ b/src/compiler/nir/nir_lower_tex.c @@ -101,6 +101,36 @@ project_src(nir_builder *b, nir_tex_instr *tex) nir_tex_instr_remove_src(tex, proj_index); } +static nir_ssa_def * +get_texture_size(nir_builder *b, nir_tex_instr *tex) +{ + b->cursor = nir_before_instr(&tex->instr); + + nir_tex_instr *txs; + + txs = nir_tex_instr_create(b->shader, 1); + txs->op = nir_texop_txs; + txs->sampler_dim = tex->sampler_dim; + txs->is_array = tex->is_array; + txs->is_shadow = tex->is_shadow; + txs->is_new_style_shadow = tex->is_new_style_shadow; + txs->texture_index = tex->texture_index; + txs->texture = nir_deref_var_clone(tex->texture, txs); + txs->sampler_index = tex->sampler_index; + txs->sampler = nir_deref_var_clone(tex->sampler, txs); + txs->dest_type = nir_type_int; + + /* 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, + nir_tex_instr_dest_size(txs), 32, NULL); + nir_builder_instr_insert(b, &txs->instr); + + return nir_i2f32(b, &txs->dest.ssa); +} + static bool lower_offset(nir_builder *b, nir_tex_instr *tex) { @@ -120,8 +150,17 @@ lower_offset(nir_builder *b, nir_tex_instr *tex) nir_ssa_def *offset_coord; if (nir_tex_instr_src_type(tex, coord_index) == nir_type_float) { - assert(tex->sampler_dim == GLSL_SAMPLER_DIM_RECT); - offset_coord = nir_fadd(b, coord, nir_i2f32(b, offset)); + if (tex->sampler_dim == GLSL_SAMPLER_DIM_RECT) { + offset_coord = nir_fadd(b, coord, nir_i2f32(b, offset)); + } else { + nir_ssa_def *txs = get_texture_size(b, tex); + nir_ssa_def *scale = nir_frcp(b, txs); + + offset_coord = nir_fadd(b, coord, + nir_fmul(b, + nir_i2f32(b, offset), + scale)); + } } else { offset_coord = nir_iadd(b, coord, offset); } @@ -148,37 +187,6 @@ lower_offset(nir_builder *b, nir_tex_instr *tex) return true; } - -static nir_ssa_def * -get_texture_size(nir_builder *b, nir_tex_instr *tex) -{ - b->cursor = nir_before_instr(&tex->instr); - - nir_tex_instr *txs; - - txs = nir_tex_instr_create(b->shader, 1); - txs->op = nir_texop_txs; - txs->sampler_dim = tex->sampler_dim; - txs->is_array = tex->is_array; - txs->is_shadow = tex->is_shadow; - txs->is_new_style_shadow = tex->is_new_style_shadow; - txs->texture_index = tex->texture_index; - txs->texture = nir_deref_var_clone(tex->texture, txs); - txs->sampler_index = tex->sampler_index; - txs->sampler = nir_deref_var_clone(tex->sampler, txs); - txs->dest_type = nir_type_int; - - /* 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, - nir_tex_instr_dest_size(txs), 32, NULL); - nir_builder_instr_insert(b, &txs->instr); - - return nir_i2f32(b, &txs->dest.ssa); -} - static void lower_rect(nir_builder *b, nir_tex_instr *tex) { @@ -749,6 +757,7 @@ nir_lower_tex_block(nir_block *block, nir_builder *b, } if ((tex->op == nir_texop_txf && options->lower_txf_offset) || + (sat_mask && nir_tex_instr_src_index(tex, nir_tex_src_coord) >= 0) || (tex->sampler_dim == GLSL_SAMPLER_DIM_RECT && options->lower_rect_offset)) { progress = lower_offset(b, tex) || progress; |