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)
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);
}
}
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);
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;
}
/* 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;
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);
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
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" */
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,
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,