[Mesa-dev] [PATCH 18/27] main: Add _mesa_build_fallback_shader_program

Jordan Justen jordan.l.justen at intel.com
Sat Aug 19 07:44:34 UTC 2017


This routine will handle fallback shader compilation. Based on Tim's
"i965: add cache fallback support" patch.

Tim's commit message was:

  "This is fairly simple, if we have no IR we compile the fallback
   shaders then copy the other fallback data such as attibute bindings
   to a temp shader program struct, then we link the program and clean
   up the mess. The IR will be attached to the existing gl_program."

I also made some changes to fix issues with atomic counters.

Signed-off-by: Jordan Justen <jordan.l.justen at intel.com>
Cc: Timothy Arceri <tarceri at itsqueeze.com>
---
 src/mesa/main/shaderobj.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++
 src/mesa/main/shaderobj.h |  5 +++
 2 files changed, 91 insertions(+)

diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c
index 5b342f865b..0bd0791107 100644
--- a/src/mesa/main/shaderobj.c
+++ b/src/mesa/main/shaderobj.c
@@ -42,6 +42,7 @@
 #include "util/ralloc.h"
 #include "util/string_to_uint_map.h"
 #include "util/u_atomic.h"
+#include "compiler/glsl/program.h"
 
 /**********************************************************************/
 /*** Shader object functions                                        ***/
@@ -313,6 +314,91 @@ _mesa_new_shader_program(GLuint name)
    return shProg;
 }
 
+void
+_mesa_build_fallback_shader_program(struct gl_context *ctx, GLuint name,
+                                    struct gl_shader_program_data *data,
+                                    struct shader_info *info)
+{
+   data->cache_fallback = true;
+
+   for (unsigned i = 0; i < data->NumFallbackShaders; i++) {
+      _mesa_glsl_compile_shader(ctx, data->FallbackShaders[i], false, false,
+                                true);
+   }
+
+   /* Create a temp shader program to be used for linking */
+   struct gl_shader_program *shProg = _mesa_new_shader_program(name);
+   // FIXME: recheck if this is needed
+   struct gl_shader_program_data *tmp_prog_data = shProg->data;
+
+   shProg->data = data;
+
+   shProg->NumShaders = data->NumFallbackShaders;
+   shProg->Shaders = data->FallbackShaders;
+
+   string_to_uint_map_dtor(shProg->AttributeBindings);
+   shProg->AttributeBindings = data->FallbackAttributeBindings;
+   string_to_uint_map_dtor(shProg->FragDataBindings);
+   shProg->FragDataBindings = data->FallbackFragDataBindings;
+   string_to_uint_map_dtor(shProg->FragDataIndexBindings);
+   shProg->FragDataIndexBindings = data->FallbackFragDataIndexBindings;
+   shProg->SeparateShader = info->separate_shader;
+
+   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+      struct gl_program *curr_prog = ctx->_Shader->CurrentProgram[i];
+      if (!curr_prog)
+         continue;
+
+      shProg->cache_progs[i] = curr_prog;
+   }
+
+   void *mem_ctx = ralloc_parent(data->AtomicBuffers);
+   assert(mem_ctx);
+
+   _mesa_glsl_link_shader(ctx, shProg);
+
+   /* We should never get here again so free the fallback data */
+   data->NumFallbackShaders = 0;
+   ralloc_free(data->FallbackShaders);
+   data->FallbackShaders = NULL;
+
+   string_to_uint_map_dtor(shProg->AttributeBindings);
+   data->FallbackAttributeBindings = NULL;
+   shProg->AttributeBindings = NULL;
+
+   string_to_uint_map_dtor(shProg->FragDataBindings);
+   data->FallbackFragDataBindings = NULL;
+   shProg->FragDataBindings = NULL;
+
+   string_to_uint_map_dtor(shProg->FragDataIndexBindings);
+   data->FallbackFragDataIndexBindings = NULL;
+   shProg->FragDataIndexBindings = NULL;
+
+   ralloc_adopt(mem_ctx, ralloc_context(data->AtomicBuffers));
+   ralloc_steal(mem_ctx, data->AtomicBuffers);
+   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+      struct gl_program *curr_prog =
+         shProg->_LinkedShaders[i] ?
+         shProg->_LinkedShaders[i]->Program : NULL;
+      if (!curr_prog)
+         continue;
+
+      if (curr_prog->sh.AtomicBuffers)
+         ralloc_steal(mem_ctx, curr_prog->sh.AtomicBuffers);
+   }
+
+   /* Since we don't bother referencing these we need to reset them so the
+    * delete shader program call doesn't try to remove a reference that
+    * doesn't exist.
+    */
+   shProg->NumShaders = 0;
+   shProg->Shaders = NULL;
+
+   shProg->data = tmp_prog_data; // FIXME: recheck if this is needed
+   _mesa_delete_shader_program(ctx, shProg);
+
+   data->cache_fallback = false;
+}
 
 /**
  * Clear (free) the shader program state that gets produced by linking.
diff --git a/src/mesa/main/shaderobj.h b/src/mesa/main/shaderobj.h
index 97b8ce7ac2..85f49b1130 100644
--- a/src/mesa/main/shaderobj.h
+++ b/src/mesa/main/shaderobj.h
@@ -100,6 +100,11 @@ _mesa_lookup_shader_program_err(struct gl_context *ctx, GLuint name,
 extern struct gl_shader_program *
 _mesa_new_shader_program(GLuint name);
 
+extern void
+_mesa_build_fallback_shader_program(struct gl_context *ctx, GLuint name,
+                                    struct gl_shader_program_data *data,
+                                    struct shader_info *info);
+
 extern void
 _mesa_clear_shader_program_data(struct gl_context *ctx,
                                 struct gl_shader_program *shProg);
-- 
2.14.0



More information about the mesa-dev mailing list