diff options
-rw-r--r-- | src/compiler/nir/nir.c | 7 | ||||
-rw-r--r-- | src/compiler/nir/nir.h | 31 | ||||
-rw-r--r-- | src/compiler/nir/nir_clone.c | 7 | ||||
-rw-r--r-- | src/compiler/nir/nir_instr_set.c | 15 | ||||
-rw-r--r-- | src/compiler/nir/nir_lower_samplers.c | 13 | ||||
-rw-r--r-- | src/compiler/nir/nir_lower_tex.c | 6 | ||||
-rw-r--r-- | src/compiler/nir/nir_opt_constant_folding.c | 11 | ||||
-rw-r--r-- | src/compiler/nir/nir_print.c | 14 | ||||
-rw-r--r-- | src/compiler/nir/nir_remove_dead_variables.c | 5 | ||||
-rw-r--r-- | src/compiler/nir/nir_validate.c | 3 | ||||
-rw-r--r-- | src/gallium/auxiliary/nir/tgsi_to_nir.c | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4_nir.cpp | 3 | ||||
-rw-r--r-- | src/mesa/program/prog_to_nir.c | 1 |
14 files changed, 102 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); } diff --git a/src/gallium/auxiliary/nir/tgsi_to_nir.c b/src/gallium/auxiliary/nir/tgsi_to_nir.c index 8cd8ea4cb66..b71917618c1 100644 --- a/src/gallium/auxiliary/nir/tgsi_to_nir.c +++ b/src/gallium/auxiliary/nir/tgsi_to_nir.c @@ -1310,6 +1310,7 @@ ttn_tex(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src) assert(tgsi_inst->Src[samp].Register.File == TGSI_FILE_SAMPLER); instr->texture_index = tgsi_inst->Src[samp].Register.Index; + instr->sampler_index = tgsi_inst->Src[samp].Register.Index; /* TODO if we supported any opc's which take an explicit SVIEW * src, we would use that here instead. But for the "legacy" diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp index ecca3ef7183..1a2c39f4b35 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp @@ -3024,6 +3024,9 @@ fs_visitor::nir_emit_texture(const fs_builder &bld, nir_tex_instr *instr) break; } + case nir_tex_src_sampler_offset: + break; /* Ignored for now */ + default: unreachable("unknown texture source"); } diff --git a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp index 40a7530d940..41d20ff0d13 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp @@ -1738,6 +1738,9 @@ vec4_visitor::nir_emit_texture(nir_tex_instr *instr) break; } + case nir_tex_src_sampler_offset: + break; /* Ignored for now */ + case nir_tex_src_projector: unreachable("Should be lowered by do_lower_texture_projection"); diff --git a/src/mesa/program/prog_to_nir.c b/src/mesa/program/prog_to_nir.c index 93a167e0aa1..74cbbfb1cc6 100644 --- a/src/mesa/program/prog_to_nir.c +++ b/src/mesa/program/prog_to_nir.c @@ -610,6 +610,7 @@ ptn_tex(nir_builder *b, nir_alu_dest dest, nir_ssa_def **src, instr->dest_type = nir_type_float; instr->is_shadow = prog_inst->TexShadow; instr->texture_index = prog_inst->TexSrcUnit; + instr->sampler_index = prog_inst->TexSrcUnit; switch (prog_inst->TexSrcTarget) { case TEXTURE_1D_INDEX: |