diff --git a/src/compiler/glsl/gl_nir.h b/src/compiler/glsl/gl_nir.h index d8bddd43e57..a170284b777 100644 --- a/src/compiler/glsl/gl_nir.h +++ b/src/compiler/glsl/gl_nir.h @@ -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 diff --git a/src/compiler/glsl/gl_nir_linker.c b/src/compiler/glsl/gl_nir_linker.c index 7768c823609..230e0426870 100644 --- a/src/compiler/glsl/gl_nir_linker.c +++ b/src/compiler/glsl/gl_nir_linker.c @@ -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); diff --git a/src/compiler/glsl/gl_nir_lower_images.c b/src/compiler/glsl/gl_nir_lower_images.c index d3a88f590d6..27949f98355 100644 --- a/src/compiler/glsl/gl_nir_lower_images.c +++ b/src/compiler/glsl/gl_nir_lower_images.c @@ -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); } diff --git a/src/gallium/drivers/svga/svga_pipe_cs.c b/src/gallium/drivers/svga/svga_pipe_cs.c index 2e8037e7392..d4484aec40a 100644 --- a/src/gallium/drivers/svga/svga_pipe_cs.c +++ b/src/gallium/drivers/svga/svga_pipe_cs.c @@ -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); diff --git a/src/gallium/drivers/svga/svga_shader.c b/src/gallium/drivers/svga/svga_shader.c index 293d82b467d..93db5cb8f8b 100644 --- a/src/gallium/drivers/svga/svga_shader.c +++ b/src/gallium/drivers/svga/svga_shader.c @@ -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); diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 1b1f0230b13..7d8213493b0 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -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; diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp b/src/mesa/state_tracker/st_glsl_to_nir.cpp index 4ee17306829..7bab380de0c 100644 --- a/src/mesa/state_tracker/st_glsl_to_nir.cpp +++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp @@ -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); } /** diff --git a/src/mesa/state_tracker/st_nir_builtins.c b/src/mesa/state_tracker/st_nir_builtins.c index 9dfea3a8651..a3d0e7bebf8 100644 --- a/src/mesa/state_tracker/st_nir_builtins.c +++ b/src/mesa/state_tracker/st_nir_builtins.c @@ -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); diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index d4fcaf52b02..a106ee5ddf4 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -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