summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2017-11-21 13:42:08 -0800
committerEric Anholt <[email protected]>2017-12-14 14:36:17 -0800
commitb08b6289943b225b6451e6c8ce331a8c11bd0c7f (patch)
tree50590887b30bb02c9f8aebc099a2ff8f79560043
parent52f024b0523763799e71de0a327d5143df72a792 (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.c75
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;