diff options
Diffstat (limited to 'src/compiler/nir')
-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 |
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); } |