summaryrefslogtreecommitdiffstats
path: root/src/compiler
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2015-11-02 17:58:29 -0800
committerJason Ekstrand <[email protected]>2016-02-09 15:00:17 -0800
commit5ec456375e4fdd0b6c7d797f99191044e19ead74 (patch)
treec34b2d2e4560f516ef3ab10bd798a6a3b7c469c1 /src/compiler
parentee85014b90af1d94d637ec763a803479e9bac5dc (diff)
nir: Separate texture from sampler in nir_tex_instr
This commit adds the capability to NIR to support separate textures and samplers. As it currently stands, glsl_to_nir only sets the texture deref and leaves the sampler deref alone as it did before and nir_lower_samplers assumes this. Backends can still assume that they are combined and only look at only at the texture index. Or, if they wish, they can assume that they are separate because nir_lower_samplers, tgsi_to_nir, and prog_to_nir all set both texture and sampler index whenever a sampler is required (the two indices are the same in this case). Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/compiler')
-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);
}