summaryrefslogtreecommitdiffstats
path: root/src/compiler/nir
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/nir')
-rw-r--r--src/compiler/nir/nir.c7
-rw-r--r--src/compiler/nir/nir.h31
-rw-r--r--src/compiler/nir/nir_clone.c7
-rw-r--r--src/compiler/nir/nir_instr_set.c15
-rw-r--r--src/compiler/nir/nir_lower_samplers.c13
-rw-r--r--src/compiler/nir/nir_lower_tex.c6
-rw-r--r--src/compiler/nir/nir_opt_constant_folding.c11
-rw-r--r--src/compiler/nir/nir_print.c14
-rw-r--r--src/compiler/nir/nir_remove_dead_variables.c5
-rw-r--r--src/compiler/nir/nir_validate.c3
10 files changed, 94 insertions, 18 deletions
diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c
index 6a070f530b2..df40a554714 100644
--- a/src/compiler/nir/nir.c
+++ b/src/compiler/nir/nir.c
@@ -489,6 +489,8 @@ nir_tex_instr_create(nir_shader *shader, unsigned num_srcs)
instr->texture_index = 0;
instr->texture_array_size = 0;
instr->texture = NULL;
+ instr->sampler_index = 0;
+ instr->sampler = NULL;
return instr;
}
@@ -1012,6 +1014,11 @@ visit_tex_src(nir_tex_instr *instr, nir_foreach_src_cb cb, void *state)
return false;
}
+ if (instr->sampler != NULL) {
+ if (!visit_deref_src(instr->sampler, cb, state))
+ return false;
+ }
+
return true;
}
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 48dda99a949..8085341b552 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -966,6 +966,7 @@ typedef enum {
nir_tex_src_ddx,
nir_tex_src_ddy,
nir_tex_src_texture_offset, /* < dynamically uniform indirect offset */
+ nir_tex_src_sampler_offset, /* < dynamically uniform indirect offset */
nir_num_tex_src_types
} nir_tex_src_type;
@@ -1025,7 +1026,35 @@ typedef struct {
/** The size of the texture array or 0 if it's not an array */
unsigned texture_array_size;
- nir_deref_var *texture; /* if this is NULL, use texture_index instead */
+ /** The texture deref
+ *
+ * If this is null, use texture_index instead.
+ */
+ nir_deref_var *texture;
+
+ /** The sampler index
+ *
+ * The following operations do not require a sampler and, as such, this
+ * field should be ignored:
+ * - nir_texop_txf
+ * - nir_texop_txf_ms
+ * - nir_texop_txs
+ * - nir_texop_lod
+ * - nir_texop_tg4
+ * - nir_texop_query_levels
+ * - nir_texop_texture_samples
+ * - nir_texop_samples_identical
+ *
+ * If this texture instruction has a nir_tex_src_sampler_offset source,
+ * then the sampler index is given by sampler_index + sampler_offset.
+ */
+ unsigned sampler_index;
+
+ /** The sampler deref
+ *
+ * If this is null, use sampler_index instead.
+ */
+ nir_deref_var *sampler;
} nir_tex_instr;
static inline unsigned
diff --git a/src/compiler/nir/nir_clone.c b/src/compiler/nir/nir_clone.c
index d9c190d35e9..a666d8ee451 100644
--- a/src/compiler/nir/nir_clone.c
+++ b/src/compiler/nir/nir_clone.c
@@ -357,10 +357,15 @@ clone_tex(clone_state *state, const nir_tex_instr *tex)
ntex->is_new_style_shadow = tex->is_new_style_shadow;
memcpy(ntex->const_offset, tex->const_offset, sizeof(ntex->const_offset));
ntex->component = tex->component;
+
ntex->texture_index = tex->texture_index;
- ntex->texture_array_size = tex->texture_array_size;
if (tex->texture)
ntex->texture = clone_deref_var(state, tex->texture, &ntex->instr);
+ ntex->texture_array_size = tex->texture_array_size;
+
+ ntex->sampler_index = tex->sampler_index;
+ if (tex->sampler)
+ ntex->sampler = clone_deref_var(state, tex->sampler, &ntex->instr);
return ntex;
}
diff --git a/src/compiler/nir/nir_instr_set.c b/src/compiler/nir/nir_instr_set.c
index 4489a881905..c3cf2579be7 100644
--- a/src/compiler/nir/nir_instr_set.c
+++ b/src/compiler/nir/nir_instr_set.c
@@ -157,8 +157,9 @@ hash_tex(uint32_t hash, const nir_tex_instr *instr)
hash = HASH(hash, component);
hash = HASH(hash, instr->texture_index);
hash = HASH(hash, instr->texture_array_size);
+ hash = HASH(hash, instr->sampler_index);
- assert(!instr->texture);
+ assert(!instr->texture && !instr->sampler);
return hash;
}
@@ -306,12 +307,14 @@ nir_instrs_equal(const nir_instr *instr1, const nir_instr *instr2)
sizeof(tex1->const_offset)) != 0 ||
tex1->component != tex2->component ||
tex1->texture_index != tex2->texture_index ||
- tex1->texture_array_size != tex2->texture_array_size) {
+ tex1->texture_array_size != tex2->texture_array_size ||
+ tex1->sampler_index != tex2->sampler_index) {
return false;
}
- /* Don't support un-lowered texture derefs currently. */
- assert(!tex1->texture && !tex2->texture);
+ /* Don't support un-lowered sampler derefs currently. */
+ assert(!tex1->texture && !tex1->sampler &&
+ !tex2->texture && !tex2->sampler);
return true;
}
@@ -421,8 +424,8 @@ instr_can_rewrite(nir_instr *instr)
case nir_instr_type_tex: {
nir_tex_instr *tex = nir_instr_as_tex(instr);
- /* Don't support un-lowered texture derefs currently. */
- if (tex->texture)
+ /* Don't support un-lowered sampler derefs currently. */
+ if (tex->texture || tex->sampler)
return false;
return true;
diff --git a/src/compiler/nir/nir_lower_samplers.c b/src/compiler/nir/nir_lower_samplers.c
index bccb544dc91..f5d3e596c20 100644
--- a/src/compiler/nir/nir_lower_samplers.c
+++ b/src/compiler/nir/nir_lower_samplers.c
@@ -94,6 +94,9 @@ lower_sampler(nir_tex_instr *instr, const struct gl_shader_program *shader_progr
if (instr->texture == NULL)
return;
+ /* In GLSL, we only fill out the texture field. The sampler is inferred */
+ assert(instr->sampler == NULL);
+
instr->texture_index = 0;
unsigned location = instr->texture->var->data.location;
unsigned array_elements = 1;
@@ -106,7 +109,7 @@ lower_sampler(nir_tex_instr *instr, const struct gl_shader_program *shader_progr
if (indirect) {
/* First, we have to resize the array of texture sources */
nir_tex_src *new_srcs = rzalloc_array(instr, nir_tex_src,
- instr->num_srcs + 1);
+ instr->num_srcs + 2);
for (unsigned i = 0; i < instr->num_srcs; i++) {
new_srcs[i].src_type = instr->src[i].src_type;
@@ -126,6 +129,12 @@ lower_sampler(nir_tex_instr *instr, const struct gl_shader_program *shader_progr
&instr->src[instr->num_srcs - 1].src,
nir_src_for_ssa(indirect));
+ instr->src[instr->num_srcs].src_type = nir_tex_src_sampler_offset;
+ instr->num_srcs++;
+ nir_instr_rewrite_src(&instr->instr,
+ &instr->src[instr->num_srcs - 1].src,
+ nir_src_for_ssa(indirect));
+
instr->texture_array_size = array_elements;
}
@@ -138,6 +147,8 @@ lower_sampler(nir_tex_instr *instr, const struct gl_shader_program *shader_progr
instr->texture_index +=
shader_program->UniformStorage[location].opaque[stage].index;
+ instr->sampler_index = instr->texture_index;
+
instr->texture = NULL;
}
diff --git a/src/compiler/nir/nir_lower_tex.c b/src/compiler/nir/nir_lower_tex.c
index 4c0759b8788..806acd8333c 100644
--- a/src/compiler/nir/nir_lower_tex.c
+++ b/src/compiler/nir/nir_lower_tex.c
@@ -291,11 +291,11 @@ nir_lower_tex_block(nir_block *block, void *void_state)
/* mask of src coords to saturate (clamp): */
unsigned sat_mask = 0;
- if ((1 << tex->texture_index) & state->options->saturate_r)
+ if ((1 << tex->sampler_index) & state->options->saturate_r)
sat_mask |= (1 << 2); /* .z */
- if ((1 << tex->texture_index) & state->options->saturate_t)
+ if ((1 << tex->sampler_index) & state->options->saturate_t)
sat_mask |= (1 << 1); /* .y */
- if ((1 << tex->texture_index) & state->options->saturate_s)
+ if ((1 << tex->sampler_index) & state->options->saturate_s)
sat_mask |= (1 << 0); /* .x */
/* If we are clamping any coords, we must lower projector first
diff --git a/src/compiler/nir/nir_opt_constant_folding.c b/src/compiler/nir/nir_opt_constant_folding.c
index 20b31a8110c..04876a42fd7 100644
--- a/src/compiler/nir/nir_opt_constant_folding.c
+++ b/src/compiler/nir/nir_opt_constant_folding.c
@@ -136,10 +136,15 @@ constant_fold_intrinsic_instr(nir_intrinsic_instr *instr)
static bool
constant_fold_tex_instr(nir_tex_instr *instr)
{
+ bool progress = false;
+
if (instr->texture)
- return constant_fold_deref(&instr->instr, instr->texture);
- else
- return false;
+ progress |= constant_fold_deref(&instr->instr, instr->texture);
+
+ if (instr->sampler)
+ progress |= constant_fold_deref(&instr->instr, instr->sampler);
+
+ return progress;
}
static bool
diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c
index 5e7ae820968..d9d75c2e8df 100644
--- a/src/compiler/nir/nir_print.c
+++ b/src/compiler/nir/nir_print.c
@@ -625,6 +625,9 @@ print_tex_instr(nir_tex_instr *instr, print_state *state)
case nir_tex_src_texture_offset:
fprintf(fp, "(texture_offset)");
break;
+ case nir_tex_src_sampler_offset:
+ fprintf(fp, "(sampler_offset)");
+ break;
default:
unreachable("Invalid texture source type");
@@ -654,11 +657,16 @@ print_tex_instr(nir_tex_instr *instr, print_state *state)
if (instr->texture) {
print_deref(instr->texture, state);
+ fprintf(fp, " (texture)");
+ if (instr->sampler) {
+ print_deref(instr->sampler, state);
+ fprintf(fp, " (sampler)");
+ }
} else {
- fprintf(fp, "%u", instr->texture_index);
+ assert(instr->sampler == NULL);
+ fprintf(fp, "%u (texture) %u (sampler)",
+ instr->texture_index, instr->sampler_index);
}
-
- fprintf(fp, " (texture)");
}
static void
diff --git a/src/compiler/nir/nir_remove_dead_variables.c b/src/compiler/nir/nir_remove_dead_variables.c
index 24bae46c7fc..65192682d3c 100644
--- a/src/compiler/nir/nir_remove_dead_variables.c
+++ b/src/compiler/nir/nir_remove_dead_variables.c
@@ -58,6 +58,11 @@ add_var_use_tex(nir_tex_instr *instr, struct set *live)
nir_variable *var = instr->texture->var;
_mesa_set_add(live, var);
}
+
+ if (instr->sampler != NULL) {
+ nir_variable *var = instr->sampler->var;
+ _mesa_set_add(live, var);
+ }
}
static bool
diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c
index 2fadff7869e..d1a90485e7e 100644
--- a/src/compiler/nir/nir_validate.c
+++ b/src/compiler/nir/nir_validate.c
@@ -448,6 +448,9 @@ validate_tex_instr(nir_tex_instr *instr, validate_state *state)
if (instr->texture != NULL)
validate_deref_var(instr, instr->texture, state);
+ if (instr->sampler != NULL)
+ validate_deref_var(instr, instr->sampler, state);
+
validate_dest(&instr->dest, state);
}