diff --git a/src/compiler/glsl/gl_nir_lower_samplers_as_deref.c b/src/compiler/glsl/gl_nir_lower_samplers_as_deref.c index c8f17ef9aaa..ea32195d42f 100644 --- a/src/compiler/glsl/gl_nir_lower_samplers_as_deref.c +++ b/src/compiler/glsl/gl_nir_lower_samplers_as_deref.c @@ -197,6 +197,26 @@ lower_deref(nir_builder *b, struct lower_samplers_as_deref_state *state, return new_deref; } +static void +record_textures_used(struct shader_info *info, + nir_deref_instr *deref, + nir_texop op) +{ + nir_variable *var = nir_deref_instr_get_variable(deref); + + /* Structs have been lowered already, so get_aoa_size is sufficient. */ + const unsigned size = + glsl_type_is_array(var->type) ? glsl_get_aoa_size(var->type) : 1; + unsigned mask = ((1ull << MAX2(size, 1)) - 1) << var->data.binding; + + info->textures_used |= mask; + + if (op == nir_texop_txf || + op == nir_texop_txf_ms || + op == nir_texop_txf_ms_mcs) + info->textures_used_by_txf |= mask; +} + static bool lower_sampler(nir_tex_instr *instr, struct lower_samplers_as_deref_state *state, nir_builder *b) @@ -217,6 +237,7 @@ lower_sampler(nir_tex_instr *instr, struct lower_samplers_as_deref_state *state, if (texture_deref) { nir_instr_rewrite_src(&instr->instr, &instr->src[texture_idx].src, nir_src_for_ssa(&texture_deref->dest.ssa)); + record_textures_used(&b->shader->info, texture_deref, instr->op); } } @@ -297,6 +318,9 @@ gl_nir_lower_samplers_as_deref(nir_shader *shader, state.remap_table = _mesa_hash_table_create(NULL, _mesa_key_hash_string, _mesa_key_string_equal); + shader->info.textures_used = 0; + shader->info.textures_used_by_txf = 0; + nir_foreach_function(function, shader) { if (function->impl) progress |= lower_impl(function->impl, &state); diff --git a/src/compiler/nir/nir_gather_info.c b/src/compiler/nir/nir_gather_info.c index 18a74a135d9..19438912ff0 100644 --- a/src/compiler/nir/nir_gather_info.c +++ b/src/compiler/nir/nir_gather_info.c @@ -286,13 +286,6 @@ gather_tex_info(nir_tex_instr *instr, nir_shader *shader) case nir_texop_tg4: shader->info.uses_texture_gather = true; break; - case nir_texop_txf: - case nir_texop_txf_ms: - case nir_texop_txf_ms_mcs: - shader->info.textures_used_by_txf |= - ((1 << MAX2(instr->texture_array_size, 1)) - 1) << - instr->texture_index; - break; default: break; } diff --git a/src/compiler/shader_info.h b/src/compiler/shader_info.h index 3d871938751..ea6f9a16375 100644 --- a/src/compiler/shader_info.h +++ b/src/compiler/shader_info.h @@ -115,6 +115,9 @@ typedef struct shader_info { /* Whether or not this shader ever uses textureGather() */ bool uses_texture_gather; + /** Bitfield of which textures are used */ + uint32_t textures_used; + /** Bitfield of which textures are used by texelFetch() */ uint32_t textures_used_by_txf; diff --git a/src/mesa/drivers/dri/i965/brw_link.cpp b/src/mesa/drivers/dri/i965/brw_link.cpp index 2cbb1e0b879..66581b21f61 100644 --- a/src/mesa/drivers/dri/i965/brw_link.cpp +++ b/src/mesa/drivers/dri/i965/brw_link.cpp @@ -324,6 +324,8 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *shProg) brw_shader_gather_info(prog->nir, prog); NIR_PASS_V(prog->nir, gl_nir_lower_samplers, shProg); + prog->info.textures_used = prog->nir->info.textures_used; + prog->info.textures_used_by_txf = prog->nir->info.textures_used_by_txf; NIR_PASS_V(prog->nir, gl_nir_lower_atomics, shProg, false); NIR_PASS_V(prog->nir, nir_lower_atomics_to_ssbo, prog->nir->info.num_abos); diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp b/src/mesa/state_tracker/st_glsl_to_nir.cpp index b904060528b..89f7424e4db 100644 --- a/src/mesa/state_tracker/st_glsl_to_nir.cpp +++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp @@ -848,12 +848,18 @@ st_nir_assign_varying_locations(struct st_context *st, nir_shader *nir) void st_nir_lower_samplers(struct pipe_screen *screen, nir_shader *nir, - struct gl_shader_program *shader_program) + struct gl_shader_program *shader_program, + struct gl_program *prog) { if (screen->get_param(screen, PIPE_CAP_NIR_SAMPLERS_AS_DEREF)) NIR_PASS_V(nir, gl_nir_lower_samplers_as_deref, shader_program); else NIR_PASS_V(nir, gl_nir_lower_samplers, shader_program); + + if (prog) { + prog->info.textures_used = nir->info.textures_used; + prog->info.textures_used_by_txf = nir->info.textures_used_by_txf; + } } /* Last third of preparing nir from glsl, which happens after shader @@ -891,7 +897,7 @@ st_finalize_nir(struct st_context *st, struct gl_program *prog, NIR_PASS_V(nir, st_nir_lower_uniforms_to_ubo); } - st_nir_lower_samplers(screen, nir, shader_program); + st_nir_lower_samplers(screen, nir, shader_program, prog); } } /* extern "C" */ diff --git a/src/mesa/state_tracker/st_nir.h b/src/mesa/state_tracker/st_nir.h index 42a04a4676b..d45ab3c4474 100644 --- a/src/mesa/state_tracker/st_nir.h +++ b/src/mesa/state_tracker/st_nir.h @@ -56,7 +56,8 @@ void st_nir_assign_varying_locations(struct st_context *st, struct nir_shader *nir); void st_nir_lower_samplers(struct pipe_screen *screen, struct nir_shader *nir, - struct gl_shader_program *shader_program); + struct gl_shader_program *shader_program, + struct gl_program *prog); struct pipe_shader_state * st_nir_finish_builtin_shader(struct st_context *st, diff --git a/src/mesa/state_tracker/st_nir_builtins.c b/src/mesa/state_tracker/st_nir_builtins.c index 18dc2095d6f..3826d96a888 100644 --- a/src/mesa/state_tracker/st_nir_builtins.c +++ b/src/mesa/state_tracker/st_nir_builtins.c @@ -61,7 +61,7 @@ st_nir_finish_builtin_shader(struct st_context *st, st_nir_assign_varying_locations(st, nir); - st_nir_lower_samplers(screen, nir, NULL); + st_nir_lower_samplers(screen, nir, NULL, NULL); if (st->ctx->Const.PackedDriverUniformStorage) { NIR_PASS_V(nir, nir_lower_io, nir_var_uniform, st_glsl_type_dword_size,