summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/compiler/nir/nir.h10
-rw-r--r--src/compiler/nir/nir_lower_tex.c54
2 files changed, 64 insertions, 0 deletions
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 5a69e7858d4..f23d0b256a8 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -2409,6 +2409,16 @@ typedef struct nir_lower_tex_options {
unsigned lower_txp;
/**
+ * If true, lower away nir_tex_src_offset for all texelfetch instructions.
+ */
+ bool lower_txf_offset;
+
+ /**
+ * If true, lower away nir_tex_src_offset for all rect textures.
+ */
+ bool lower_rect_offset;
+
+ /**
* 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.
diff --git a/src/compiler/nir/nir_lower_tex.c b/src/compiler/nir/nir_lower_tex.c
index e70a9aa7693..93637a33844 100644
--- a/src/compiler/nir/nir_lower_tex.c
+++ b/src/compiler/nir/nir_lower_tex.c
@@ -128,6 +128,54 @@ project_src(nir_builder *b, nir_tex_instr *tex)
tex_instr_remove_src(tex, proj_index);
}
+static bool
+lower_offset(nir_builder *b, nir_tex_instr *tex)
+{
+ int offset_index = tex_instr_find_src(tex, nir_tex_src_offset);
+ if (offset_index < 0)
+ return false;
+
+ int coord_index = tex_instr_find_src(tex, nir_tex_src_coord);
+ assert(coord_index >= 0);
+
+ assert(tex->src[offset_index].src.is_ssa);
+ assert(tex->src[coord_index].src.is_ssa);
+ nir_ssa_def *offset = tex->src[offset_index].src.ssa;
+ nir_ssa_def *coord = tex->src[coord_index].src.ssa;
+
+ b->cursor = nir_before_instr(&tex->instr);
+
+ 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_i2f(b, offset));
+ } else {
+ offset_coord = nir_iadd(b, coord, offset);
+ }
+
+ if (tex->is_array) {
+ /* The offset is not applied to the array index */
+ if (tex->coord_components == 2) {
+ offset_coord = nir_vec2(b, nir_channel(b, offset_coord, 0),
+ nir_channel(b, coord, 1));
+ } else if (tex->coord_components == 3) {
+ offset_coord = nir_vec3(b, nir_channel(b, offset_coord, 0),
+ nir_channel(b, offset_coord, 1),
+ nir_channel(b, coord, 2));
+ } else {
+ unreachable("Invalid number of components");
+ }
+ }
+
+ nir_instr_rewrite_src(&tex->instr, &tex->src[coord_index].src,
+ nir_src_for_ssa(offset_coord));
+
+ tex_instr_remove_src(tex, offset_index);
+
+ return true;
+}
+
+
static nir_ssa_def *
get_texture_size(nir_builder *b, nir_tex_instr *tex)
{
@@ -458,6 +506,12 @@ nir_lower_tex_block(nir_block *block, nir_builder *b,
progress = true;
}
+ if ((tex->op == nir_texop_txf && options->lower_txf_offset) ||
+ (tex->sampler_dim == GLSL_SAMPLER_DIM_RECT &&
+ options->lower_rect_offset)) {
+ progress = lower_offset(b, tex) || progress;
+ }
+
if ((tex->sampler_dim == GLSL_SAMPLER_DIM_RECT) && options->lower_rect) {
lower_rect(b, tex);
progress = true;