gallium: add a link shader hook
authorAntonio Caggiano <antonio.caggiano@collabora.com>
Thu, 4 Nov 2021 13:50:38 +0000 (14:50 +0100)
committerMarge Bot <emma+marge@anholt.net>
Tue, 23 Nov 2021 16:14:16 +0000 (16:14 +0000)
Allow drivers to register a callback for when a shader program is linked.

Signed-off-by: Antonio Caggiano <antonio.caggiano@collabora.com>
Reviewed-by: Gert Wollny <gert.wollny@collabora.com>
Reviewed-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13674>

src/gallium/include/pipe/p_context.h
src/mesa/state_tracker/st_glsl_to_ir.cpp

index bedc926..af040fb 100644 (file)
@@ -324,6 +324,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)
     */
    /*@{*/
index a13bb57..664808e 100644 (file)
@@ -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" */