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/shader_query.cpp | |
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/shader_query.cpp')
-rw-r--r-- | src/mesa/main/shader_query.cpp | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp index 4e0247ea817..61eec68683f 100644 --- a/src/mesa/main/shader_query.cpp +++ b/src/mesa/main/shader_query.cpp @@ -557,3 +557,94 @@ _mesa_program_resource_array_size(struct gl_program_resource *res) } return 0; } + +static int +array_index_of_resource(struct gl_program_resource *res, + const char *name) +{ + assert(res->Data); + + switch (res->Type) { + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + return get_matching_index(RESOURCE_VAR(res), name); + default: + assert(!"support for resource type not implemented"); + } +} + +/* Find a program resource with specific name in given interface. + */ +struct gl_program_resource * +_mesa_program_resource_find_name(struct gl_shader_program *shProg, + GLenum interface, const char *name) +{ + struct gl_program_resource *res = shProg->ProgramResourceList; + for (unsigned i = 0; i < shProg->NumProgramResourceList; i++, res++) { + if (res->Type != interface) + continue; + + /* Resource basename. */ + const char *rname = _mesa_program_resource_name(res); + unsigned baselen = strlen(rname); + + switch (interface) { + case GL_TRANSFORM_FEEDBACK_VARYING: + case GL_UNIFORM_BLOCK: + case GL_UNIFORM: + if (strncmp(rname, name, baselen) == 0) { + /* Basename match, check if array or struct. */ + if (name[baselen] == '\0' || + name[baselen] == '[' || + name[baselen] == '.') { + return res; + } + } + break; + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + if (array_index_of_resource(res, name) >= 0) + return res; + break; + default: + assert(!"not implemented for given interface"); + } + } + return NULL; +} + +static GLuint +calc_resource_index(struct gl_shader_program *shProg, + struct gl_program_resource *res) +{ + unsigned i; + GLuint index = 0; + for (i = 0; i < shProg->NumProgramResourceList; i++) { + if (&shProg->ProgramResourceList[i] == res) + return index; + if (shProg->ProgramResourceList[i].Type == res->Type) + index++; + } + return GL_INVALID_INDEX; +} + +/** + * Calculate index for the given resource. + */ +GLuint +_mesa_program_resource_index(struct gl_shader_program *shProg, + struct gl_program_resource *res) +{ + if (!res) + return GL_INVALID_INDEX; + + switch (res->Type) { + case GL_UNIFORM_BLOCK: + return RESOURCE_UBO(res)- shProg->UniformBlocks; + case GL_ATOMIC_COUNTER_BUFFER: + return RESOURCE_ATC(res) - shProg->AtomicBuffers; + case GL_TRANSFORM_FEEDBACK_VARYING: + default: + return calc_resource_index(shProg, res); + } +} |