[Mesa-dev] [PATCH 17/19] mesa: fill out the ARB_shader_subroutine APIs
From: Dave Airlie airl...@redhat.com This fleshes out the APIs, using the program resource APIs where they should match. It also sets the default values to valid subroutines. Signed-off-by: Dave Airlie airl...@redhat.com --- src/mesa/main/shaderapi.c | 457 +- src/mesa/main/shaderapi.h | 3 + 2 files changed, 457 insertions(+), 3 deletions(-) diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index 48ab217..1a46749 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -1071,6 +1071,7 @@ _mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg) use_shader_program(ctx, i, shProg, ctx-Shader); _mesa_active_program(ctx, shProg, glUseProgram); + _mesa_shader_program_init_subroutine_defaults(shProg); if (ctx-Driver.UseProgram) ctx-Driver.UseProgram(ctx, shProg); } @@ -1993,15 +1994,75 @@ GLint GLAPIENTRY _mesa_GetSubroutineUniformLocation(GLuint program, GLenum shadertype, const GLchar *name) { - return -1; -} + GET_CURRENT_CONTEXT(ctx); + const char *api_name = glGetSubroutineUniformLocation; + struct gl_shader_program *shProg; + GLenum resource_type; + gl_shader_stage stage; + + if (!ctx-Extensions.ARB_shader_subroutine) { + _mesa_error(ctx, GL_INVALID_OPERATION, api_name); + return -1; + } + + if (!_mesa_validate_shader_target(ctx, shadertype)) { + _mesa_error(ctx, GL_INVALID_OPERATION, api_name); + return -1; + } + shProg = _mesa_lookup_shader_program_err(ctx, program, api_name); + if (!shProg) + return -1; + + stage = _mesa_shader_enum_to_shader_stage(shadertype); + if (!shProg-_LinkedShaders[stage]) { + _mesa_error(ctx, GL_INVALID_OPERATION, api_name); + return -1; + } + + resource_type = _mesa_shader_stage_to_subroutine_uniform(stage); + return _mesa_program_resource_location(shProg, resource_type, name); +} GLuint GLAPIENTRY _mesa_GetSubroutineIndex(GLuint program, GLenum shadertype, const GLchar *name) { - return GL_INVALID_INDEX; + GET_CURRENT_CONTEXT(ctx); + const char *api_name = glGetSubroutineIndex; + struct gl_shader_program *shProg; + struct gl_program_resource *res; + GLenum resource_type; + gl_shader_stage stage; + + if (!ctx-Extensions.ARB_shader_subroutine) { + _mesa_error(ctx, GL_INVALID_OPERATION, api_name); + return -1; + } + + if (!_mesa_validate_shader_target(ctx, shadertype)) { + _mesa_error(ctx, GL_INVALID_OPERATION, api_name); + return -1; + } + + shProg = _mesa_lookup_shader_program_err(ctx, program, api_name); + if (!shProg) + return -1; + + stage = _mesa_shader_enum_to_shader_stage(shadertype); + if (!shProg-_LinkedShaders[stage]) { + _mesa_error(ctx, GL_INVALID_OPERATION, api_name); + return -1; + } + + resource_type = _mesa_shader_stage_to_subroutine(stage); + res = _mesa_program_resource_find_name(shProg, resource_type, name); + if (!res) { + _mesa_error(ctx, GL_INVALID_OPERATION, api_name); + return -1; + } + + return _mesa_program_resource_index(shProg, res); } @@ -2009,6 +2070,91 @@ GLvoid GLAPIENTRY _mesa_GetActiveSubroutineUniformiv(GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values) { + GET_CURRENT_CONTEXT(ctx); + const char *api_name = glGetActiveSubroutineUniformiv; + struct gl_shader_program *shProg; + struct gl_shader *sh; + gl_shader_stage stage; + struct gl_program_resource *res; + const struct gl_uniform_storage *uni; + GLenum resource_type; + int count, i, j; + if (!ctx-Extensions.ARB_shader_subroutine) { + _mesa_error(ctx, GL_INVALID_OPERATION, api_name); + return; + } + + if (!_mesa_validate_shader_target(ctx, shadertype)) { + _mesa_error(ctx, GL_INVALID_OPERATION, api_name); + return; + } + + shProg = _mesa_lookup_shader_program_err(ctx, program, api_name); + if (!shProg) + return; + + stage = _mesa_shader_enum_to_shader_stage(shadertype); + resource_type = _mesa_shader_stage_to_subroutine_uniform(stage); + + sh = shProg-_LinkedShaders[stage]; + if (!sh) { + _mesa_error(ctx, GL_INVALID_OPERATION, api_name); + return; + } + + switch (pname) { + case GL_NUM_COMPATIBLE_SUBROUTINES: { + res = _mesa_program_resource_find_index(shProg, resource_type, index); + if (res) { + uni = res-Data; + count = 0; + for (i = 0; i sh-NumSubroutineFunctions; i++) { +struct gl_subroutine_function *fn = sh-SubroutineFunctions[i]; +for (j = 0; j fn-num_compat_types; j++) { + if (fn-types[j] == uni-type) { + count++; + break; + } +} + } + values[0] = count; + } + break; + } + case GL_COMPATIBLE_SUBROUTINES: { + res =
[Mesa-dev] [PATCH 17/19] mesa: fill out the ARB_shader_subroutine APIs
From: Dave Airlie airl...@redhat.com This fleshes out the APIs, using the program resource APIs where they should match. It also sets the default values to valid subroutines. Signed-off-by: Dave Airlie airl...@redhat.com --- src/mesa/main/shaderapi.c | 457 +- src/mesa/main/shaderapi.h | 3 + 2 files changed, 457 insertions(+), 3 deletions(-) diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index 1165776..69c080c 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -1071,6 +1071,7 @@ _mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg) use_shader_program(ctx, i, shProg, ctx-Shader); _mesa_active_program(ctx, shProg, glUseProgram); + _mesa_shader_program_init_subroutine_defaults(shProg); if (ctx-Driver.UseProgram) ctx-Driver.UseProgram(ctx, shProg); } @@ -1993,15 +1994,75 @@ GLint GLAPIENTRY _mesa_GetSubroutineUniformLocation(GLuint program, GLenum shadertype, const GLchar *name) { - return -1; -} + GET_CURRENT_CONTEXT(ctx); + const char *api_name = glGetSubroutineUniformLocation; + struct gl_shader_program *shProg; + GLenum resource_type; + gl_shader_stage stage; + + if (!ctx-Extensions.ARB_shader_subroutine) { + _mesa_error(ctx, GL_INVALID_OPERATION, api_name); + return -1; + } + + if (!_mesa_validate_shader_target(ctx, shadertype)) { + _mesa_error(ctx, GL_INVALID_OPERATION, api_name); + return -1; + } + shProg = _mesa_lookup_shader_program_err(ctx, program, api_name); + if (!shProg) + return -1; + + stage = _mesa_shader_enum_to_shader_stage(shadertype); + if (!shProg-_LinkedShaders[stage]) { + _mesa_error(ctx, GL_INVALID_OPERATION, api_name); + return -1; + } + + resource_type = _mesa_shader_stage_to_subroutine_uniform(stage); + return _mesa_program_resource_location(shProg, resource_type, name); +} GLuint GLAPIENTRY _mesa_GetSubroutineIndex(GLuint program, GLenum shadertype, const GLchar *name) { - return GL_INVALID_INDEX; + GET_CURRENT_CONTEXT(ctx); + const char *api_name = glGetSubroutineIndex; + struct gl_shader_program *shProg; + struct gl_program_resource *res; + GLenum resource_type; + gl_shader_stage stage; + + if (!ctx-Extensions.ARB_shader_subroutine) { + _mesa_error(ctx, GL_INVALID_OPERATION, api_name); + return -1; + } + + if (!_mesa_validate_shader_target(ctx, shadertype)) { + _mesa_error(ctx, GL_INVALID_OPERATION, api_name); + return -1; + } + + shProg = _mesa_lookup_shader_program_err(ctx, program, api_name); + if (!shProg) + return -1; + + stage = _mesa_shader_enum_to_shader_stage(shadertype); + if (!shProg-_LinkedShaders[stage]) { + _mesa_error(ctx, GL_INVALID_OPERATION, api_name); + return -1; + } + + resource_type = _mesa_shader_stage_to_subroutine(stage); + res = _mesa_program_resource_find_name(shProg, resource_type, name); + if (!res) { + _mesa_error(ctx, GL_INVALID_OPERATION, api_name); + return -1; + } + + return _mesa_program_resource_index(shProg, res); } @@ -2009,6 +2070,91 @@ GLvoid GLAPIENTRY _mesa_GetActiveSubroutineUniformiv(GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values) { + GET_CURRENT_CONTEXT(ctx); + const char *api_name = glGetActiveSubroutineUniformiv; + struct gl_shader_program *shProg; + struct gl_shader *sh; + gl_shader_stage stage; + struct gl_program_resource *res; + const struct gl_uniform_storage *uni; + GLenum resource_type; + int count, i, j; + if (!ctx-Extensions.ARB_shader_subroutine) { + _mesa_error(ctx, GL_INVALID_OPERATION, api_name); + return; + } + + if (!_mesa_validate_shader_target(ctx, shadertype)) { + _mesa_error(ctx, GL_INVALID_OPERATION, api_name); + return; + } + + shProg = _mesa_lookup_shader_program_err(ctx, program, api_name); + if (!shProg) + return; + + stage = _mesa_shader_enum_to_shader_stage(shadertype); + resource_type = _mesa_shader_stage_to_subroutine_uniform(stage); + + sh = shProg-_LinkedShaders[stage]; + if (!sh) { + _mesa_error(ctx, GL_INVALID_OPERATION, api_name); + return; + } + + switch (pname) { + case GL_NUM_COMPATIBLE_SUBROUTINES: { + res = _mesa_program_resource_find_index(shProg, resource_type, index); + if (res) { + uni = res-Data; + count = 0; + for (i = 0; i sh-NumSubroutineFunctions; i++) { +struct gl_subroutine_function *fn = sh-SubroutineFunctions[i]; +for (j = 0; j fn-num_compat_types; j++) { + if (fn-types[j] == uni-type) { + count++; + break; + } +} + } + values[0] = count; + } + break; + } + case GL_COMPATIBLE_SUBROUTINES: { + res =