diff options
author | Tapani Pälli <[email protected]> | 2015-03-10 09:30:30 +0200 |
---|---|---|
committer | Tapani Pälli <[email protected]> | 2015-04-16 07:55:56 +0300 |
commit | 161f57f6103802de55d792bcc6a4370afa5c5173 (patch) | |
tree | 99acd1008bb300817352af3d050366f7b5fe1f0f /src/mesa/main/program_resource.c | |
parent | 4d3b98bc5801df27a7f9f2e3df28d66d83f883d9 (diff) |
mesa: glGetProgramResourceIndex
Patch adds required helper functions to shaderapi.h and
the actual implementation.
v2: code cleanup (Ilia Mirkin)
corresponding Piglit test:
arb_program_interface_query-getprogramresourceindex
Signed-off-by: Tapani Pälli <[email protected]>
Reviewed-by: Martin Peres <[email protected]>
Diffstat (limited to 'src/mesa/main/program_resource.c')
-rw-r--r-- | src/mesa/main/program_resource.c | 85 |
1 files changed, 84 insertions, 1 deletions
diff --git a/src/mesa/main/program_resource.c b/src/mesa/main/program_resource.c index ae28a26d3e4..7a2732503a9 100644 --- a/src/mesa/main/program_resource.c +++ b/src/mesa/main/program_resource.c @@ -150,11 +150,94 @@ _mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface, } } +static bool +is_xfb_marker(const char *str) +{ + static const char *markers[] = { + "gl_NextBuffer", + "gl_SkipComponents1", + "gl_SkipComponents2", + "gl_SkipComponents3", + "gl_SkipComponents4", + NULL + }; + const char **m = markers; + + if (strncmp(str, "gl_", 3) != 0) + return false; + + for (; *m; m++) + if (strcmp(*m, str) == 0) + return true; + + return false; +} + +/** + * Checks if given name index is legal for GetProgramResourceIndex, + * check is written to be compatible with GL_ARB_array_of_arrays. + */ +static bool +valid_program_resource_index_name(const GLchar *name) +{ + const char *array = strstr(name, "["); + const char *close = strrchr(name, ']'); + + /* Not array, no need for the check. */ + if (!array) + return true; + + /* Last array index has to be zero. */ + if (!close || *--close != '0') + return false; + + return true; +} + GLuint GLAPIENTRY _mesa_GetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name) { - return 0; + GET_CURRENT_CONTEXT(ctx); + struct gl_program_resource *res; + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glGetProgramResourceIndex"); + if (!shProg || !name) + return GL_INVALID_INDEX; + + /* + * For the interface TRANSFORM_FEEDBACK_VARYING, the value INVALID_INDEX + * should be returned when querying the index assigned to the special names + * "gl_NextBuffer", "gl_SkipComponents1", "gl_SkipComponents2", + * "gl_SkipComponents3", and "gl_SkipComponents4". + */ + if (programInterface == GL_TRANSFORM_FEEDBACK_VARYING && + is_xfb_marker(name)) + return GL_INVALID_INDEX; + + switch (programInterface) { + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + case GL_UNIFORM: + case GL_UNIFORM_BLOCK: + case GL_TRANSFORM_FEEDBACK_VARYING: + /* Validate name syntax for arrays. */ + if (!valid_program_resource_index_name(name)) + return GL_INVALID_INDEX; + + res = _mesa_program_resource_find_name(shProg, programInterface, name); + if (!res) + return GL_INVALID_INDEX; + + return _mesa_program_resource_index(shProg, res); + case GL_ATOMIC_COUNTER_BUFFER: + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceIndex(%s)", + _mesa_lookup_enum_by_nr(programInterface)); + } + + return GL_INVALID_INDEX; } void GLAPIENTRY |