[Mesa-dev] [PATCH v3 2/9] mesa: add KHR_no_error support for glUseProgram

Timothy Arceri tarceri at itsqueeze.com
Thu May 11 12:29:51 UTC 2017


V3: use always_inline attribute (Suggested by Nicolai)

Cc: Nicolai Hähnle <nhaehnle at gmail.com>
---
 src/mapi/glapi/gen/gl_API.xml |  2 +-
 src/mesa/main/shaderapi.c     | 65 ++++++++++++++++++++++++++++++-------------
 src/mesa/main/shaderapi.h     |  2 ++
 3 files changed, 48 insertions(+), 21 deletions(-)

diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index a304ac0..50d60f5 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -5493,21 +5493,21 @@
     </function>
 
     <function name="ShaderSource" es2="2.0" marshal="custom">
         <param name="shader" type="GLuint"/>
         <param name="count" type="GLsizei"/>
         <param name="string" type="const GLchar * const *"/>
         <param name="length" type="const GLint *"/>
         <glx ignore="true"/>
     </function>
 
-    <function name="UseProgram" es2="2.0">
+    <function name="UseProgram" es2="2.0" no_error="true">
         <param name="program" type="GLuint"/>
         <glx ignore="true"/>
     </function>
 
     <function name="Uniform1f" es2="2.0">
         <param name="location" type="GLint"/>
         <param name="v0" type="GLfloat"/>
         <glx ignore="true"/>
     </function>
     <function name="Uniform2f" es2="2.0">
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index f63215a..68fb3fa 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -1796,80 +1796,105 @@ _mesa_ShaderSource(GLuint shaderObj, GLsizei count,
       source = replacement;
    }
 #endif /* ENABLE_SHADER_CACHE */
 
    shader_source(sh, source);
 
    free(offsets);
 }
 
 
-void GLAPIENTRY
-_mesa_UseProgram(GLuint program)
+static ALWAYS_INLINE void
+use_program(GLuint program, bool no_error)
 {
    GET_CURRENT_CONTEXT(ctx);
    struct gl_shader_program *shProg = NULL;
 
    if (MESA_VERBOSE & VERBOSE_API)
       _mesa_debug(ctx, "glUseProgram %u\n", program);
 
-   if (_mesa_is_xfb_active_and_unpaused(ctx)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glUseProgram(transform feedback active)");
-      return;
-   }
-
-   if (program) {
-      shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
-      if (!shProg) {
-         return;
+   if (no_error) {
+      if (program) {
+         shProg = _mesa_lookup_shader_program(ctx, program);
       }
-      if (!shProg->data->LinkStatus) {
+   } else {
+      if (_mesa_is_xfb_active_and_unpaused(ctx)) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glUseProgram(program %u not linked)", program);
+                     "glUseProgram(transform feedback active)");
          return;
       }
 
-      /* debug code */
-      if (ctx->_Shader->Flags & GLSL_USE_PROG) {
-         print_shader_info(shProg);
+      if (program) {
+         shProg =
+            _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
+         if (!shProg)
+            return;
+
+         if (!shProg->data->LinkStatus) {
+            _mesa_error(ctx, GL_INVALID_OPERATION,
+                        "glUseProgram(program %u not linked)", program);
+            return;
+         }
+
+         /* debug code */
+         if (ctx->_Shader->Flags & GLSL_USE_PROG) {
+            print_shader_info(shProg);
+         }
       }
    }
 
    /* The ARB_separate_shader_object spec says:
     *
     *     "The executable code for an individual shader stage is taken from
     *     the current program for that stage.  If there is a current program
     *     object established by UseProgram, that program is considered current
     *     for all stages.  Otherwise, if there is a bound program pipeline
     *     object (section 2.14.PPO), the program bound to the appropriate
     *     stage of the pipeline object is considered current."
     */
-   if (program) {
+   if (shProg) {
       /* Attach shader state to the binding point */
       _mesa_reference_pipeline_object(ctx, &ctx->_Shader, &ctx->Shader);
       /* Update the program */
       _mesa_use_shader_program(ctx, shProg);
    } else {
       /* Must be done first: detach the progam */
       _mesa_use_shader_program(ctx, shProg);
       /* Unattach shader_state binding point */
-      _mesa_reference_pipeline_object(ctx, &ctx->_Shader, ctx->Pipeline.Default);
+      _mesa_reference_pipeline_object(ctx, &ctx->_Shader,
+                                      ctx->Pipeline.Default);
       /* If a pipeline was bound, rebind it */
       if (ctx->Pipeline.Current) {
-         _mesa_BindProgramPipeline(ctx->Pipeline.Current->Name);
+         if (no_error)
+            _mesa_BindProgramPipeline_no_error(ctx->Pipeline.Current->Name);
+         else
+            _mesa_BindProgramPipeline(ctx->Pipeline.Current->Name);
       }
    }
 }
 
 
 void GLAPIENTRY
+_mesa_UseProgram_no_error(GLuint program)
+{
+   use_program(program, true);
+}
+
+
+void GLAPIENTRY
+_mesa_UseProgram(GLuint program)
+{
+   use_program(program, false);
+}
+
+
+void GLAPIENTRY
 _mesa_ValidateProgram(GLuint program)
 {
    GET_CURRENT_CONTEXT(ctx);
    validate_program(ctx, program);
 }
 
 
 /**
  * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
  */
diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h
index 99b4fe8..0a28185 100644
--- a/src/mesa/main/shaderapi.h
+++ b/src/mesa/main/shaderapi.h
@@ -120,20 +120,22 @@ _mesa_IsProgram(GLuint name);
 
 extern GLboolean GLAPIENTRY
 _mesa_IsShader(GLuint name);
 
 extern void GLAPIENTRY
 _mesa_LinkProgram(GLuint programObj);
 
 extern void GLAPIENTRY
 _mesa_ShaderSource(GLuint, GLsizei, const GLchar* const *, const GLint *);
 
+void GLAPIENTRY
+_mesa_UseProgram_no_error(GLuint);
 extern void GLAPIENTRY
 _mesa_UseProgram(GLuint);
 
 extern void GLAPIENTRY
 _mesa_ValidateProgram(GLuint);
 
 
 extern void GLAPIENTRY
 _mesa_BindAttribLocation(GLuint program, GLuint, const GLchar *);
 
-- 
2.9.3



More information about the mesa-dev mailing list