[Mesa-dev] [RFC 6/6] nir: Rework the way texture instructions reference samplers
Jason Ekstrand
jason at jlekstrand.net
Sat Feb 6 05:10:55 UTC 2016
Originally, NIR texture instructions had a pointer to a deref chain that
represented the sampler. This commit changes that. Instead, we now use a
load_var to get the sampler index and then pass that directly into the
sampler_offset source of the instruction. This mechanism has a couple of
advantages: First, it gets rid of a bunch of special-casing around handling
variable derefs. Second, it means that we can now pass samplers into
functions because the load of a sampler is just an integer. This will make
things a bit easier for SPIR-V.
---
src/compiler/nir/glsl_to_nir.cpp | 35 ++++++++-------
src/compiler/nir/nir.c | 5 ---
src/compiler/nir/nir.h | 2 -
src/compiler/nir/nir_clone.c | 2 -
src/compiler/nir/nir_instr_set.c | 15 +------
src/compiler/nir/nir_lower_samplers.c | 59 +++++++++++++-------------
src/compiler/nir/nir_opt_constant_folding.c | 5 +--
src/compiler/nir/nir_print.c | 6 +--
src/compiler/nir/nir_remove_dead_variables.c | 13 ------
src/compiler/nir/nir_validate.c | 7 +--
src/gallium/drivers/vc4/vc4_nir_lower_txf_ms.c | 1 -
11 files changed, 53 insertions(+), 97 deletions(-)
diff --git a/src/compiler/nir/glsl_to_nir.cpp b/src/compiler/nir/glsl_to_nir.cpp
index 365fd4d..7ddf8d2 100644
--- a/src/compiler/nir/glsl_to_nir.cpp
+++ b/src/compiler/nir/glsl_to_nir.cpp
@@ -1753,69 +1753,69 @@ nir_visitor::visit(ir_swizzle *ir)
void
nir_visitor::visit(ir_texture *ir)
{
- unsigned num_srcs;
+ unsigned num_srcs = 1 /* Texture index */;
nir_texop op;
switch (ir->op) {
case ir_tex:
op = nir_texop_tex;
- num_srcs = 1; /* coordinate */
+ num_srcs += 1; /* coordinate */
break;
case ir_txb:
case ir_txl:
op = (ir->op == ir_txb) ? nir_texop_txb : nir_texop_txl;
- num_srcs = 2; /* coordinate, bias/lod */
+ num_srcs += 2; /* coordinate, bias/lod */
break;
case ir_txd:
op = nir_texop_txd; /* coordinate, dPdx, dPdy */
- num_srcs = 3;
+ num_srcs += 3;
break;
case ir_txf:
op = nir_texop_txf;
if (ir->lod_info.lod != NULL)
- num_srcs = 2; /* coordinate, lod */
+ num_srcs += 2; /* coordinate, lod */
else
- num_srcs = 1; /* coordinate */
+ num_srcs += 1; /* coordinate */
break;
case ir_txf_ms:
op = nir_texop_txf_ms;
- num_srcs = 2; /* coordinate, sample_index */
+ num_srcs += 2; /* coordinate, sample_index */
break;
case ir_txs:
op = nir_texop_txs;
if (ir->lod_info.lod != NULL)
- num_srcs = 1; /* lod */
+ num_srcs += 1; /* lod */
else
- num_srcs = 0;
+ num_srcs += 0;
break;
case ir_lod:
op = nir_texop_lod;
- num_srcs = 1; /* coordinate */
+ num_srcs += 1; /* coordinate */
break;
case ir_tg4:
op = nir_texop_tg4;
- num_srcs = 1; /* coordinate */
+ num_srcs += 1; /* coordinate */
break;
case ir_query_levels:
op = nir_texop_query_levels;
- num_srcs = 0;
+ num_srcs += 0;
break;
case ir_texture_samples:
op = nir_texop_texture_samples;
- num_srcs = 0;
+ num_srcs += 0;
break;
case ir_samples_identical:
op = nir_texop_samples_identical;
- num_srcs = 1; /* coordinate */
+ num_srcs += 1; /* coordinate */
break;
default:
@@ -1853,9 +1853,12 @@ nir_visitor::visit(ir_texture *ir)
unreachable("not reached");
}
- instr->sampler = evaluate_deref(&instr->instr, ir->sampler);
+ nir_deref_var *sampler_deref = evaluate_deref(&instr->instr, ir->sampler);
+ instr->src[0].src = nir_src_for_ssa(nir_load_deref_var(&b, sampler_deref));
+ instr->src[0].src_type = nir_tex_src_sampler_offset;
+ instr->sampler_index = 0;
- unsigned src_number = 0;
+ unsigned src_number = 1;
if (ir->coordinate != NULL) {
instr->coord_components = ir->coordinate->type->vector_elements;
diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c
index 805c72d..f10fe6a 100644
--- a/src/compiler/nir/nir.c
+++ b/src/compiler/nir/nir.c
@@ -488,7 +488,6 @@ nir_tex_instr_create(nir_shader *shader, unsigned num_srcs)
instr->sampler_index = 0;
instr->max_sampler_index = 0;
- instr->sampler = NULL;
return instr;
}
@@ -1005,10 +1004,6 @@ visit_tex_src(nir_tex_instr *instr, nir_foreach_src_cb cb, void *state)
if (!visit_src(&instr->src[i].src, cb, 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 b077f5a..645f71d 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -982,8 +982,6 @@ typedef struct {
/** The maximum total sampler index including base and indirect*/
unsigned max_sampler_index;
-
- nir_deref_var *sampler; /* if this is NULL, use sampler_index instead */
} nir_tex_instr;
static inline unsigned
diff --git a/src/compiler/nir/nir_clone.c b/src/compiler/nir/nir_clone.c
index fc2e2d1..3f2d65f 100644
--- a/src/compiler/nir/nir_clone.c
+++ b/src/compiler/nir/nir_clone.c
@@ -359,8 +359,6 @@ clone_tex(clone_state *state, const nir_tex_instr *tex)
ntex->component = tex->component;
ntex->sampler_index = tex->sampler_index;
ntex->max_sampler_index = tex->max_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 32c7318..66f7bbc 100644
--- a/src/compiler/nir/nir_instr_set.c
+++ b/src/compiler/nir/nir_instr_set.c
@@ -158,8 +158,6 @@ hash_tex(uint32_t hash, const nir_tex_instr *instr)
hash = HASH(hash, instr->sampler_index);
hash = HASH(hash, instr->max_sampler_index);
- assert(!instr->sampler);
-
return hash;
}
@@ -310,9 +308,6 @@ nir_instrs_equal(const nir_instr *instr1, const nir_instr *instr2)
return false;
}
- /* Don't support un-lowered sampler derefs currently. */
- assert(!tex1->sampler && !tex2->sampler);
-
return true;
}
case nir_instr_type_load_const: {
@@ -417,16 +412,8 @@ instr_can_rewrite(nir_instr *instr)
case nir_instr_type_alu:
case nir_instr_type_load_const:
case nir_instr_type_phi:
+ case nir_instr_type_tex:
return true;
- case nir_instr_type_tex: {
- nir_tex_instr *tex = nir_instr_as_tex(instr);
-
- /* Don't support un-lowered sampler derefs currently. */
- if (tex->sampler)
- return false;
-
- return true;
- }
case nir_instr_type_intrinsic: {
const nir_intrinsic_info *info =
&nir_intrinsic_infos[nir_instr_as_intrinsic(instr)->intrinsic];
diff --git a/src/compiler/nir/nir_lower_samplers.c b/src/compiler/nir/nir_lower_samplers.c
index c889df0..d51932d 100644
--- a/src/compiler/nir/nir_lower_samplers.c
+++ b/src/compiler/nir/nir_lower_samplers.c
@@ -59,9 +59,6 @@ calc_sampler_offsets(nir_deref *tail, nir_tex_instr *instr,
nir_imul(b, nir_imm_int(b, *array_elements),
nir_ssa_for_src(b, deref_array->indirect, 1));
- nir_instr_rewrite_src(&instr->instr, &deref_array->indirect,
- NIR_SRC_INIT);
-
if (*indirect) {
*indirect = nir_iadd(b, *indirect, mul);
} else {
@@ -91,40 +88,46 @@ static void
lower_sampler(nir_tex_instr *instr, const struct gl_shader_program *shader_program,
gl_shader_stage stage, nir_builder *builder)
{
- if (instr->sampler == NULL)
+ unsigned src_idx;
+ for (src_idx = 0; src_idx < instr->num_srcs; src_idx++) {
+ if (instr->src[src_idx].src_type == nir_tex_src_sampler_offset)
+ break;
+ }
+ if (src_idx >= instr->num_srcs)
return;
+ assert(instr->src[src_idx].src_type == nir_tex_src_sampler_offset);
+ assert(instr->src[src_idx].src.is_ssa);
+ assert(instr->src[src_idx].src.ssa->parent_instr->type ==
+ nir_instr_type_intrinsic);
+
+ nir_intrinsic_instr *offset_load =
+ nir_instr_as_intrinsic(instr->src[src_idx].src.ssa->parent_instr);
+
+ assert(offset_load->intrinsic == nir_intrinsic_load_var);
+ assert(glsl_get_base_type(nir_deref_tail(&offset_load->variables[0]->deref)->type) == GLSL_TYPE_SAMPLER);
+
instr->sampler_index = 0;
- unsigned location = instr->sampler->var->data.location;
+ unsigned location = offset_load->variables[0]->var->data.location;
unsigned array_elements = 1;
nir_ssa_def *indirect = NULL;
builder->cursor = nir_before_instr(&instr->instr);
- calc_sampler_offsets(&instr->sampler->deref, instr, &array_elements,
- &indirect, builder, &location);
+ calc_sampler_offsets(&offset_load->variables[0]->deref, instr,
+ &array_elements, &indirect, builder, &location);
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);
-
- for (unsigned i = 0; i < instr->num_srcs; i++) {
- new_srcs[i].src_type = instr->src[i].src_type;
- nir_instr_move_src(&instr->instr, &new_srcs[i].src,
- &instr->src[i].src);
- }
-
- ralloc_free(instr->src);
- instr->src = new_srcs;
-
- /* Now we can go ahead and move the source over to being a
- * first-class texture source.
- */
- 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_instr_rewrite_src(&instr->instr, &instr->src[src_idx].src,
nir_src_for_ssa(indirect));
+ } else {
+ nir_instr_rewrite_src(&instr->instr, &instr->src[src_idx].src,
+ NIR_SRC_INIT);
+ for (unsigned i = src_idx + 1; i < instr->num_srcs; i++) {
+ instr->src[i-1].src_type = instr->src[i].src_type;
+ nir_instr_move_src(&instr->instr,
+ &instr->src[i-1].src, &instr->src[i].src);
+ }
+ instr->num_srcs--;
}
if (location > shader_program->NumUniformStorage - 1 ||
@@ -137,8 +140,6 @@ lower_sampler(nir_tex_instr *instr, const struct gl_shader_program *shader_progr
shader_program->UniformStorage[location].opaque[stage].index;
instr->max_sampler_index = instr->sampler_index + array_elements - 1;
-
- instr->sampler = NULL;
}
typedef struct {
diff --git a/src/compiler/nir/nir_opt_constant_folding.c b/src/compiler/nir/nir_opt_constant_folding.c
index 28a73f8..fc9f0c3 100644
--- a/src/compiler/nir/nir_opt_constant_folding.c
+++ b/src/compiler/nir/nir_opt_constant_folding.c
@@ -136,10 +136,7 @@ constant_fold_intrinsic_instr(nir_intrinsic_instr *instr)
static bool
constant_fold_tex_instr(nir_tex_instr *instr)
{
- if (instr->sampler)
- return constant_fold_deref(&instr->instr, instr->sampler);
- else
- return false;
+ return false;
}
static bool
diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c
index 48ecb48..cb1a90d 100644
--- a/src/compiler/nir/nir_print.c
+++ b/src/compiler/nir/nir_print.c
@@ -630,11 +630,7 @@ print_tex_instr(nir_tex_instr *instr, print_state *state)
fprintf(fp, "%u (gather_component), ", instr->component);
}
- if (instr->sampler) {
- print_deref(instr->sampler, state);
- } else {
- fprintf(fp, "%u", instr->sampler_index);
- }
+ fprintf(fp, "%u", instr->sampler_index);
fprintf(fp, " (sampler)");
}
diff --git a/src/compiler/nir/nir_remove_dead_variables.c b/src/compiler/nir/nir_remove_dead_variables.c
index db754e5..5c8b3a1 100644
--- a/src/compiler/nir/nir_remove_dead_variables.c
+++ b/src/compiler/nir/nir_remove_dead_variables.c
@@ -51,15 +51,6 @@ add_var_use_call(nir_call_instr *instr, struct set *live)
}
}
-static void
-add_var_use_tex(nir_tex_instr *instr, struct set *live)
-{
- if (instr->sampler != NULL) {
- nir_variable *var = instr->sampler->var;
- _mesa_set_add(live, var);
- }
-}
-
static bool
add_var_use_block(nir_block *block, void *state)
{
@@ -75,10 +66,6 @@ add_var_use_block(nir_block *block, void *state)
add_var_use_call(nir_instr_as_call(instr), live);
break;
- case nir_instr_type_tex:
- add_var_use_tex(nir_instr_as_tex(instr), live);
- break;
-
default:
break;
}
diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c
index e4db68d..6092813 100644
--- a/src/compiler/nir/nir_validate.c
+++ b/src/compiler/nir/nir_validate.c
@@ -401,9 +401,7 @@ validate_intrinsic_instr(nir_intrinsic_instr *instr, validate_state *state)
case nir_intrinsic_load_var: {
const struct glsl_type *type =
nir_deref_tail(&instr->variables[0]->deref)->type;
- assert(glsl_type_is_vector_or_scalar(type) ||
- (instr->variables[0]->var->data.mode == nir_var_uniform &&
- glsl_get_base_type(type) == GLSL_TYPE_SUBROUTINE));
+ assert(!glsl_type_is_matrix(type));
assert(instr->num_components == glsl_get_vector_elements(type));
break;
}
@@ -445,9 +443,6 @@ validate_tex_instr(nir_tex_instr *instr, validate_state *state)
validate_src(&instr->src[i].src, state);
}
- if (instr->sampler != NULL)
- validate_deref_var(instr, instr->sampler, state);
-
validate_dest(&instr->dest, state);
}
diff --git a/src/gallium/drivers/vc4/vc4_nir_lower_txf_ms.c b/src/gallium/drivers/vc4/vc4_nir_lower_txf_ms.c
index 6a952c6..d662f8f 100644
--- a/src/gallium/drivers/vc4/vc4_nir_lower_txf_ms.c
+++ b/src/gallium/drivers/vc4/vc4_nir_lower_txf_ms.c
@@ -47,7 +47,6 @@ vc4_nir_lower_txf_ms_instr(struct vc4_compile *c, nir_builder *b,
nir_tex_instr *txf = nir_tex_instr_create(c->s, 1);
txf->op = nir_texop_txf;
- txf->sampler = txf_ms->sampler;
txf->sampler_index = txf_ms->sampler_index;
txf->coord_components = txf_ms->coord_components;
txf->is_shadow = txf_ms->is_shadow;
--
2.5.0.400.gff86faf
More information about the mesa-dev
mailing list