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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev