[Mesa-dev] [PATCH 03/12] sso: add support of GL_PROGRAM_SEPARABLE and CreateShaderProgramv

Gregory Hainaut gregory.hainaut at gmail.com
Fri May 3 10:44:07 PDT 2013


V1:
CreateShaderProgramv is similar as CreateShaderProgramEXT. The 2 differences are
1/ it an array of strings
2/ it support the GL_PROGRAM_SEPARABLE (aka SeparateShader) flag

V2: Formatting improvement
---
 src/mesa/main/mtypes.h    |    5 +++
 src/mesa/main/shaderapi.c |   94 +++++++++++++++++++++++++++++++--------------
 src/mesa/main/shaderapi.h |    3 +-
 3 files changed, 72 insertions(+), 30 deletions(-)

diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 4487068..f979cd0 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2255,6 +2255,11 @@ struct gl_shader_program
     * glClear()).
     */
    GLboolean InternalSeparateShader;
+   /* ARB_separate_shader_objects
+    * indicates whether program can be bound for individual pipeline stages using
+    * UseProgramStages after it is next linked.
+    */
+   GLboolean SeparateShader;
 
    GLuint NumShaders;          /**< number of attached shaders */
    struct gl_shader **Shaders; /**< List of attached the shaders */
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 774163d..46072ba 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -622,6 +622,11 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param
    case GL_PROGRAM_BINARY_LENGTH:
       *params = 0;
       return;
+   case GL_PROGRAM_SEPARABLE:
+      if (!ctx->Extensions.ARB_separate_shader_objects)
+         break;
+      *params = shProg->SeparateShader;
+      return;
    default:
       break;
    }
@@ -1702,6 +1707,25 @@ _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value)
        */
       shProg->BinaryRetreivableHint = value;
       return;
+
+   case GL_PROGRAM_SEPARABLE:
+      if (!ctx->Extensions.ARB_separate_shader_objects)
+         break;
+
+      /* Spec imply that the behavior is the same as ARB_get_program_binary
+       * Chapter 7.3 Program Objects
+       */
+      if (value != GL_TRUE && value != GL_FALSE) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glProgramParameteri(pname=%s, value=%d): "
+                     "value must be 0 or 1.",
+                     _mesa_lookup_enum_by_nr(pname),
+                     value);
+         return;
+      }
+      shProg->SeparateShader = value;
+      return;
+
    default:
       break;
    }
@@ -1773,59 +1797,71 @@ _mesa_ActiveProgramEXT(GLuint program)
    return;
 }
 
-
-/**
- * For GL_EXT_separate_shader_objects
- */
-GLuint GLAPIENTRY
-_mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string)
+static GLuint
+_mesa_create_shader_program(struct gl_context* ctx, GLboolean separate,
+                            GLenum type, GLsizei count, const GLchar* const *strings)
 {
-   GET_CURRENT_CONTEXT(ctx);
    const GLuint shader = create_shader(ctx, type);
    GLuint program = 0;
 
    if (shader) {
-      shader_source(ctx, shader, _mesa_strdup(string));
+      _mesa_ShaderSource(shader, count, strings, NULL);
+
       compile_shader(ctx, shader);
 
       program = create_shader_program(ctx);
       if (program) {
-	 struct gl_shader_program *shProg;
-	 struct gl_shader *sh;
-	 GLint compiled = GL_FALSE;
+         struct gl_shader_program *shProg;
+         struct gl_shader *sh;
+         GLint compiled = GL_FALSE;
 
-	 shProg = _mesa_lookup_shader_program(ctx, program);
-	 sh = _mesa_lookup_shader(ctx, shader);
+         shProg = _mesa_lookup_shader_program(ctx, program);
+         sh = _mesa_lookup_shader(ctx, shader);
 
-	 get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
-	 if (compiled) {
-	    attach_shader(ctx, program, shader);
-	    link_program(ctx, program);
-	    detach_shader(ctx, program, shader);
+         shProg->SeparateShader = separate;
 
+         get_shaderiv(ctx, shader, GL_COMPILE_STATUS, &compiled);
+         if (compiled) {
+            attach_shader(ctx, program, shader);
+            link_program(ctx, program);
+            detach_shader(ctx, program, shader);
 #if 0
-	    /* Possibly... */
-	    if (active-user-defined-varyings-in-linked-program) {
-	       append-error-to-info-log;
-	       shProg->LinkStatus = GL_FALSE;
-	    }
+            /* Possibly... */
+            if (active-user-defined-varyings-in-linked-program) {
+               append-error-to-info-log;
+               shProg->LinkStatus = GL_FALSE;
+            }
 #endif
-	 }
+         }
 
-	 ralloc_strcat(&shProg->InfoLog, sh->InfoLog);
+         ralloc_strcat(&shProg->InfoLog, sh->InfoLog);
       }
-
       delete_shader(ctx, shader);
    }
-
    return program;
 }
 
 /**
+ * For GL_EXT_separate_shader_objects
+ */
+GLuint GLAPIENTRY
+_mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   return _mesa_create_shader_program(ctx, GL_FALSE, type, 1, &string);
+}
+
+/**
  * ARB_separate_shader_objects: Compile & Link Program
+ * Basically the same as _mesa_CreateShaderProgramEXT but
+ * with support of multiple strings and SeparateShader flag.
  */
 GLuint GLAPIENTRY
-_mesa_CreateShaderProgramv(GLenum type, GLsizei count, const GLchar* const *strings)
+_mesa_CreateShaderProgramv(GLenum type, GLsizei count,
+                           const GLchar* const *strings)
 {
-   return 0;
+   GET_CURRENT_CONTEXT(ctx);
+
+   return _mesa_create_shader_program(ctx, GL_TRUE, type, count, strings);
 }
diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h
index 4381703..d9b3809 100644
--- a/src/mesa/main/shaderapi.h
+++ b/src/mesa/main/shaderapi.h
@@ -214,7 +214,8 @@ _mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string);
 
 /* GL_ARB_separate_shader_objects */
 extern GLuint GLAPIENTRY
-_mesa_CreateShaderProgramv(GLenum type, GLsizei count, const GLchar* const *strings);
+_mesa_CreateShaderProgramv(GLenum type, GLsizei count,
+                           const GLchar* const *strings);
 
 #ifdef __cplusplus
 }
-- 
1.7.10.4



More information about the mesa-dev mailing list