glsl,gallium: add pipe_caps::glsl_bindless_handles_are_32bit

to lower bindless handles to 32 bits before nir_opt_varyings, so that
the high 32 bits of (input) loads of bindless handles are eliminated early.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41170>
This commit is contained in:
Marek Olšák 2026-04-21 14:52:45 -04:00 committed by Marge Bot
parent 1b409ff681
commit 5db0493a04
9 changed files with 38 additions and 17 deletions

View file

@ -34,12 +34,14 @@ struct nir_shader;
struct gl_constants;
struct gl_linked_shader;
struct gl_shader_program;
struct pipe_caps;
bool gl_nir_lower_atomics(nir_shader *shader,
const struct gl_shader_program *shader_program,
bool use_binding_as_idx);
bool gl_nir_lower_images(nir_shader *shader, bool bindless_only);
bool gl_nir_lower_images(nir_shader *shader, const struct pipe_caps *caps,
bool bindless_only);
bool gl_nir_lower_samplers(nir_shader *shader,
const struct gl_shader_program *shader_program);
bool gl_nir_lower_samplers_as_deref(nir_shader *shader,
@ -64,8 +66,6 @@ void gl_nir_lower_packed_varyings(const struct gl_constants *consts,
bool disable_varying_packing,
bool disable_xfb_packing, bool xfb_enabled);
void gl_nir_inline_functions(nir_shader *shader);
#ifdef __cplusplus
}
#endif

View file

@ -138,8 +138,8 @@ replace_tex_src(nir_tex_src *dst, nir_tex_src_type src_type, nir_def *src_def,
list_addtail(&dst->src.use_link, &dst->src.ssa->uses);
}
void
gl_nir_inline_functions(nir_shader *shader)
static void
gl_nir_inline_functions(const struct pipe_caps *caps, nir_shader *shader)
{
/* We have to lower away local constant initializers right before we
* inline functions. That way they get properly initialized at the top
@ -181,6 +181,10 @@ gl_nir_inline_functions(nir_shader *shader)
if (!nir_deref_mode_is(deref, nir_var_uniform) ||
nir_deref_instr_get_variable(deref)->data.bindless) {
nir_def *load = nir_load_deref(&b, deref);
if (caps->glsl_bindless_handles_are_32bit)
load = nir_u2u32(&b, load);
replace_tex_src(&intr->src[0], nir_tex_src_texture_handle,
load, instr);
replace_tex_src(&intr->src[1], nir_tex_src_sampler_handle,
@ -1371,7 +1375,7 @@ preprocess_shader(const struct pipe_screen *screen,
NIR_PASS(_, nir, nir_opt_barrier_modes);
/* before buffers and vars_to_ssa */
NIR_PASS(_, nir, gl_nir_lower_images, true);
NIR_PASS(_, nir, gl_nir_lower_images, &screen->caps, true);
if (prog->nir->info.stage == MESA_SHADER_COMPUTE ||
prog->nir->info.stage == MESA_SHADER_TASK ||
@ -3951,7 +3955,8 @@ gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog)
if (!prog->data->LinkStatus)
goto done;
gl_nir_inline_functions(prog->_LinkedShaders[i]->Program->nir);
gl_nir_inline_functions(&ctx->screen->caps,
prog->_LinkedShaders[i]->Program->nir);
}
resize_tes_inputs(consts, prog);

View file

@ -35,6 +35,12 @@
#include "compiler/nir/nir_deref.h"
#include "compiler/glsl/gl_nir.h"
#include "pipe/p_defines.h"
typedef struct {
const struct pipe_caps *caps;
bool bindless_only;
} lower_images_options;
static void
type_size_align_1(const struct glsl_type *type, unsigned *size, unsigned *align)
@ -56,8 +62,7 @@ lower_instr(nir_builder *b, nir_instr *instr, void *cb_data)
if (instr->type != nir_instr_type_intrinsic)
return false;
bool bindless_only = *(bool *)cb_data;
const lower_images_options *options = (const lower_images_options *)cb_data;
nir_intrinsic_instr *intrinsic = nir_instr_as_intrinsic(instr);
nir_deref_instr *deref;
@ -81,7 +86,7 @@ lower_instr(nir_builder *b, nir_instr *instr, void *cb_data)
}
bool bindless = var->data.mode != nir_var_image || var->data.bindless;
if (bindless_only && !bindless)
if (options->bindless_only && !bindless)
return false;
b->cursor = nir_before_instr(instr);
@ -98,6 +103,10 @@ lower_instr(nir_builder *b, nir_instr *instr, void *cb_data)
nir_build_deref_offset(b, deref, type_size_align_1),
var->data.driver_location);
}
if (bindless && options->caps->glsl_bindless_handles_are_32bit)
src = nir_u2u32(b, src);
nir_rewrite_image_intrinsic(intrinsic, src,
bindless ? nir_image_intrinsic_type_bindless : nir_image_intrinsic_type_default);
if (!bindless)
@ -107,9 +116,15 @@ lower_instr(nir_builder *b, nir_instr *instr, void *cb_data)
}
bool
gl_nir_lower_images(nir_shader *shader, bool bindless_only)
gl_nir_lower_images(nir_shader *shader, const struct pipe_caps *caps,
bool bindless_only)
{
lower_images_options options = {
.caps = caps,
.bindless_only = bindless_only,
};
return nir_shader_instructions_pass(shader, lower_instr,
nir_metadata_control_flow,
&bindless_only);
&options);
}

View file

@ -41,7 +41,7 @@ svga_create_compute_state(struct pipe_context *pipe,
assert(templ->ir_type == PIPE_SHADER_IR_NIR);
/* nir_to_tgsi requires lowered images */
NIR_PASS(_, nir, gl_nir_lower_images, false);
NIR_PASS(_, nir, gl_nir_lower_images, NULL, false);
cs->base.tokens = nir_to_tgsi((void *)nir, pipe->screen);

View file

@ -932,7 +932,7 @@ svga_create_shader(struct pipe_context *pipe,
.keep_double_immediates = true,
};
/* nir_to_tgsi requires lowered images */
NIR_PASS(_, nir, gl_nir_lower_images, false);
NIR_PASS(_, nir, gl_nir_lower_images, NULL, false);
shader->tokens = nir_to_tgsi_options(nir, pipe->screen, &ntt_options);
} else {
shader->tokens = pipe_shader_state_to_tgsi_tokens(pipe->screen, templ);

View file

@ -1062,6 +1062,7 @@ struct pipe_caps {
bool representative_fragment_test;
bool prefer_persp;
bool blit_3d;
bool glsl_bindless_handles_are_32bit;
int accelerated;
int min_texel_offset;

View file

@ -755,7 +755,7 @@ st_finalize_nir(struct st_context *st, struct gl_program *prog,
st_nir_lower_samplers(screen, nir, shader_program, prog);
if (!is_draw_shader && !screen->caps.nir_images_as_deref)
NIR_PASS(_, nir, gl_nir_lower_images, false);
NIR_PASS(_, nir, gl_nir_lower_images, NULL, false);
}
/**

View file

@ -58,7 +58,7 @@ st_nir_finish_builtin_nir(struct st_context *st, nir_shader *nir)
st_nir_lower_samplers(screen, nir, NULL, NULL);
st_nir_lower_uniforms(st, nir);
if (!screen->caps.nir_images_as_deref)
NIR_PASS(_, nir, gl_nir_lower_images, false);
NIR_PASS(_, nir, gl_nir_lower_images, NULL, false);
assert(nir->info.stage == MESA_SHADER_COMPUTE || nir->info.io_lowered);

View file

@ -899,7 +899,7 @@ st_create_common_variant(struct st_context *st,
}
if (key->is_draw_shader) {
NIR_PASS(_, state.ir.nir, gl_nir_lower_images, false);
NIR_PASS(_, state.ir.nir, gl_nir_lower_images, NULL, false);
v->base.driver_shader = draw_create_vertex_shader(st->draw, &state);
}
else