[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