From 0de0440b7cecddb23a66364db516a15380f6ac8a Mon Sep 17 00:00:00 2001 From: Antonio Caggiano Date: Thu, 4 Nov 2021 14:50:38 +0100 Subject: [PATCH] gallium: add a link shader hook Allow drivers to register a callback for when a shader program is linked. Signed-off-by: Antonio Caggiano Reviewed-by: Gert Wollny Reviewed-by: Emma Anholt Part-of: --- src/gallium/include/pipe/p_context.h | 16 +++++++++++++ src/mesa/state_tracker/st_glsl_to_ir.cpp | 30 +++++++++++++++++++++--- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index bedc9261bc7..af040fb2b11 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -323,6 +323,22 @@ struct pipe_context { /*@}*/ + /** + * \name GLSL shader/program functions. + */ + /*@{*/ + /** + * Called when a shader program is linked. + * \param handles Array of shader handles attached to this program. + * The size of the array is \c PIPE_SHADER_TYPES, and each + * position contains the corresponding \c pipe_shader_state* + * or \c pipe_compute_state*, or \c NULL. + * E.g. You can retrieve the fragment shader handle with + * \c handles[PIPE_SHADER_FRAGMENT] + */ + void (*link_shader)(struct pipe_context *, void** handles); + /*@}*/ + /** * State functions (create/bind/destroy state objects) */ diff --git a/src/mesa/state_tracker/st_glsl_to_ir.cpp b/src/mesa/state_tracker/st_glsl_to_ir.cpp index a13bb573aa4..664808eb2e1 100644 --- a/src/mesa/state_tracker/st_glsl_to_ir.cpp +++ b/src/mesa/state_tracker/st_glsl_to_ir.cpp @@ -31,6 +31,7 @@ #include "st_nir.h" #include "st_shader_cache.h" #include "st_glsl_to_tgsi.h" +#include "st_program.h" #include "tgsi/tgsi_from_mesa.h" @@ -45,7 +46,10 @@ extern "C" { GLboolean st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) { - struct pipe_screen *pscreen = st_context(ctx)->screen; + GLboolean ret; + struct st_context *sctx = st_context(ctx); + struct pipe_context *pctx = sctx->pipe; + struct pipe_screen *pscreen = sctx->screen; enum pipe_shader_ir preferred_ir = (enum pipe_shader_ir) pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX, @@ -169,9 +173,29 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) build_program_resource_list(ctx, prog, use_nir); if (use_nir) - return st_link_nir(ctx, prog); + ret = st_link_nir(ctx, prog); else - return st_link_tgsi(ctx, prog); + ret = st_link_tgsi(ctx, prog); + + if (pctx->link_shader) { + void *driver_handles[PIPE_SHADER_TYPES]; + memset(driver_handles, 0, sizeof(driver_handles)); + + for (uint32_t i = 0; i < MESA_SHADER_STAGES; ++i) { + struct gl_linked_shader *shader = prog->_LinkedShaders[i]; + if (shader) { + struct st_program *stp = st_program(shader->Program); + if (stp && stp->variants) { + enum pipe_shader_type type = pipe_shader_type_from_mesa(shader->Stage); + driver_handles[type] = stp->variants->driver_shader; + } + } + } + + pctx->link_shader(pctx, driver_handles); + } + + return ret; } } /* extern "C" */