Mesa (glsl2): glsl2: Move ir_to_mesa handling to driver CompileShader and LinkShader hooks.

Eric Anholt anholt at kemper.freedesktop.org
Sat Aug 14 00:55:43 UTC 2010


Module: Mesa
Branch: glsl2
Commit: d19eecef54384c163af27a470496ed885a5a271b
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=d19eecef54384c163af27a470496ed885a5a271b

Author: Eric Anholt <eric at anholt.net>
Date:   Tue Aug 10 20:11:44 2010 -0700

glsl2: Move ir_to_mesa handling to driver CompileShader and LinkShader hooks.

This lets drivers override ir_to_mesa with their own codegen, or at
least have a native alternative.

---

 src/mesa/main/dd.h              |   21 +++++++
 src/mesa/main/shaderobj.c       |    2 +
 src/mesa/program/ir_to_mesa.cpp |  126 +++++++++++++++++++++++----------------
 src/mesa/program/ir_to_mesa.h   |    2 +
 4 files changed, 99 insertions(+), 52 deletions(-)

diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 825073c..71d0f57 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -595,6 +595,27 @@ struct dd_function_table {
    
    /*@}*/
 
+   /**
+    * \name GLSL shader/program functions.
+    */
+   /*@{*/
+   /**
+    * Called when a shader is compiled.
+    *
+    * Note that not all shader objects get ShaderCompile called on
+    * them.  Notably, the shaders containing builtin functions do not
+    * have CompileShader() called, so if lowering passes are done they
+    * need to also be performed in LinkShader().
+    */
+   GLboolean (*CompileShader)(GLcontext *ctx, struct gl_shader *shader);
+   /**
+    * Called when a shader program is linked.
+    *
+    * This gives drivers an opportunity to clone the IR and make their
+    * own transformations on it for the purposes of code generation.
+    */
+   GLboolean (*LinkShader)(GLcontext *ctx, struct gl_shader_program *shader);
+   /*@}*/
 
    /**
     * \name State-changing functions.
diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c
index 129d974..863d50f 100644
--- a/src/mesa/main/shaderobj.c
+++ b/src/mesa/main/shaderobj.c
@@ -387,4 +387,6 @@ _mesa_init_shader_object_functions(struct dd_function_table *driver)
    driver->DeleteShader = __mesa_delete_shader;
    driver->NewShaderProgram = _mesa_new_shader_program;
    driver->DeleteShaderProgram = __mesa_delete_shader_program;
+   driver->CompileShader = _mesa_ir_compile_shader;
+   driver->LinkShader = _mesa_ir_link_shader;
 }
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index c8c655b..7490ffa 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -2543,6 +2543,72 @@ get_mesa_program(GLcontext *ctx, struct gl_shader_program *shader_program,
 }
 
 extern "C" {
+GLboolean
+_mesa_ir_compile_shader(GLcontext *ctx, struct gl_shader *shader)
+{
+   assert(shader->CompileStatus);
+
+   return GL_TRUE;
+}
+
+GLboolean
+_mesa_ir_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
+{
+   assert(prog->LinkStatus);
+
+   for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
+      bool progress;
+      exec_list *ir = prog->_LinkedShaders[i]->ir;
+
+      do {
+	 progress = false;
+
+	 /* Lowering */
+	 do_mat_op_to_vec(ir);
+	 do_mod_to_fract(ir);
+	 do_div_to_mul_rcp(ir);
+	 do_explog_to_explog2(ir);
+
+	 progress = do_common_optimization(ir, true) || progress;
+
+	 if (ctx->Shader.EmitNoIfs)
+	    progress = do_if_to_cond_assign(ir) || progress;
+
+	 progress = do_vec_index_to_cond_assign(ir) || progress;
+      } while (progress);
+
+      validate_ir_tree(ir);
+   }
+
+   for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
+      struct gl_program *linked_prog;
+      bool ok = true;
+
+      linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]);
+
+      link_uniforms_to_shared_uniform_list(prog->Uniforms, linked_prog);
+
+      switch (prog->_LinkedShaders[i]->Type) {
+      case GL_VERTEX_SHADER:
+	 _mesa_reference_vertprog(ctx, &prog->VertexProgram,
+				  (struct gl_vertex_program *)linked_prog);
+	 ok = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
+					      linked_prog);
+	 break;
+      case GL_FRAGMENT_SHADER:
+	 _mesa_reference_fragprog(ctx, &prog->FragmentProgram,
+				  (struct gl_fragment_program *)linked_prog);
+	 ok = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
+					      linked_prog);
+	 break;
+      }
+      if (!ok) {
+	 return GL_FALSE;
+      }
+   }
+
+   return GL_TRUE;
+}
 
 void
 _mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader)
@@ -2604,7 +2670,12 @@ _mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader)
    reparent_ir(shader->ir, shader);
 
    talloc_free(state);
- }
+
+   if (shader->CompileStatus) {
+      if (!ctx->Driver.CompileShader(ctx, shader))
+	 shader->CompileStatus = GL_FALSE;
+   }
+}
 
 void
 _mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
@@ -2639,57 +2710,8 @@ _mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
    }
 
    if (prog->LinkStatus) {
-      for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
-	 bool progress;
-	 exec_list *ir = prog->_LinkedShaders[i]->ir;
-
-	 do {
-	    progress = false;
-
-	    /* Lowering */
-	    do_mat_op_to_vec(ir);
-	    do_mod_to_fract(ir);
-	    do_div_to_mul_rcp(ir);
-	    do_explog_to_explog2(ir);
-
-	    progress = do_common_optimization(ir, true) || progress;
-
-	    if (ctx->Shader.EmitNoIfs)
-	       progress = do_if_to_cond_assign(ir) || progress;
-
-	    progress = do_vec_index_to_cond_assign(ir) || progress;
-	 } while (progress);
-      }
-   }
-
-   if (prog->LinkStatus) {
-      for (i = 0; i < prog->_NumLinkedShaders; i++) {
-	 struct gl_program *linked_prog;
-	 bool ok = true;
-
-	 linked_prog = get_mesa_program(ctx, prog,
-					prog->_LinkedShaders[i]);
-
-	 link_uniforms_to_shared_uniform_list(prog->Uniforms, linked_prog);
-
-	 switch (prog->_LinkedShaders[i]->Type) {
-	 case GL_VERTEX_SHADER:
-	    _mesa_reference_vertprog(ctx, &prog->VertexProgram,
-				     (struct gl_vertex_program *)linked_prog);
-	    ok = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
-						 linked_prog);
-	    break;
-	 case GL_FRAGMENT_SHADER:
-	    _mesa_reference_fragprog(ctx, &prog->FragmentProgram,
-				     (struct gl_fragment_program *)linked_prog);
-	    ok = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
-						 linked_prog);
-	    break;
-	 }
-	 if (!ok) {
-	    prog->LinkStatus = GL_FALSE;
-	 }
-      }
+      if (!ctx->Driver.LinkShader(ctx, prog))
+	 prog->LinkStatus = GL_FALSE;
    }
 }
 
diff --git a/src/mesa/program/ir_to_mesa.h b/src/mesa/program/ir_to_mesa.h
index e832f84..ecaacde 100644
--- a/src/mesa/program/ir_to_mesa.h
+++ b/src/mesa/program/ir_to_mesa.h
@@ -30,6 +30,8 @@ extern "C" {
 
 void _mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *sh);
 void _mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog);
+GLboolean _mesa_ir_compile_shader(GLcontext *ctx, struct gl_shader *shader);
+GLboolean _mesa_ir_link_shader(GLcontext *ctx, struct gl_shader_program *prog);
 
 #ifdef __cplusplus
 }




More information about the mesa-commit mailing list