diff options
author | Tapani Pälli <[email protected]> | 2015-03-06 15:05:51 +0200 |
---|---|---|
committer | Tapani Pälli <[email protected]> | 2015-04-16 07:55:56 +0300 |
commit | 4d3b98bc5801df27a7f9f2e3df28d66d83f883d9 (patch) | |
tree | e9df880029d5591f591157978e8d5e9f78082753 /src/mesa/main/program_resource.c | |
parent | c796ce4108ccc4987c24df43606d04a0f3658d44 (diff) |
mesa: glGetProgramInterfaceiv
Patch adds required helper functions to shaderapi.h and
the actual implementation.
v2: code cleanup (Ilia Mirkin)
fix array size fo xfb varyings
validate programInterface and throw error
v3: put GL_MAX_NUM_COMPATIBLE_SUBROUTINES where
it belongs
corresponding Piglit test:
arb_program_interface_query-getprograminterfaceiv
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 | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/src/mesa/main/program_resource.c b/src/mesa/main/program_resource.c index b3b93aa6cc8..ae28a26d3e4 100644 --- a/src/mesa/main/program_resource.c +++ b/src/mesa/main/program_resource.c @@ -23,12 +23,131 @@ * */ +#include "main/enums.h" +#include "main/macros.h" +#include "main/mtypes.h" +#include "main/shaderapi.h" +#include "main/shaderobj.h" #include "program_resource.h" +static bool +supported_interface_enum(GLenum iface) +{ + switch (iface) { + case GL_UNIFORM: + case GL_UNIFORM_BLOCK: + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + case GL_TRANSFORM_FEEDBACK_VARYING: + case GL_ATOMIC_COUNTER_BUFFER: + return true; + case GL_VERTEX_SUBROUTINE: + case GL_TESS_CONTROL_SUBROUTINE: + case GL_TESS_EVALUATION_SUBROUTINE: + case GL_GEOMETRY_SUBROUTINE: + case GL_FRAGMENT_SUBROUTINE: + case GL_COMPUTE_SUBROUTINE: + case GL_VERTEX_SUBROUTINE_UNIFORM: + case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: + case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: + case GL_GEOMETRY_SUBROUTINE_UNIFORM: + case GL_FRAGMENT_SUBROUTINE_UNIFORM: + case GL_COMPUTE_SUBROUTINE_UNIFORM: + case GL_BUFFER_VARIABLE: + case GL_SHADER_STORAGE_BLOCK: + default: + return false; + } +} + void GLAPIENTRY _mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint *params) { + GET_CURRENT_CONTEXT(ctx); + unsigned i; + struct gl_shader_program *shProg = + _mesa_lookup_shader_program_err(ctx, program, + "glGetProgramInterfaceiv"); + if (!shProg) + return; + + if (!params) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramInterfaceiv(params NULL)"); + return; + } + + /* Validate interface. */ + if (!supported_interface_enum(programInterface)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramInterfaceiv(%s)", + _mesa_lookup_enum_by_nr(programInterface)); + return; + } + + /* Validate pname against interface. */ + switch(pname) { + case GL_ACTIVE_RESOURCES: + for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++) + if (shProg->ProgramResourceList[i].Type == programInterface) + (*params)++; + break; + case GL_MAX_NAME_LENGTH: + if (programInterface == GL_ATOMIC_COUNTER_BUFFER) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramInterfaceiv(%s pname %s)", + _mesa_lookup_enum_by_nr(programInterface), + _mesa_lookup_enum_by_nr(pname)); + return; + } + /* Name length consists of base name, 3 additional chars '[0]' if + * resource is an array and finally 1 char for string terminator. + */ + for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++) { + if (shProg->ProgramResourceList[i].Type != programInterface) + continue; + const char *name = + _mesa_program_resource_name(&shProg->ProgramResourceList[i]); + unsigned array_size = + _mesa_program_resource_array_size(&shProg->ProgramResourceList[i]); + *params = MAX2(*params, strlen(name) + (array_size ? 3 : 0) + 1); + } + break; + case GL_MAX_NUM_ACTIVE_VARIABLES: + switch (programInterface) { + case GL_UNIFORM_BLOCK: + for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++) { + if (shProg->ProgramResourceList[i].Type == programInterface) { + struct gl_uniform_block *block = + (struct gl_uniform_block *) + shProg->ProgramResourceList[i].Data; + *params = MAX2(*params, block->NumUniforms); + } + } + break; + case GL_ATOMIC_COUNTER_BUFFER: + for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++) { + if (shProg->ProgramResourceList[i].Type == programInterface) { + struct gl_active_atomic_buffer *buffer = + (struct gl_active_atomic_buffer *) + shProg->ProgramResourceList[i].Data; + *params = MAX2(*params, buffer->NumUniforms); + } + } + break; + default: + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramInterfaceiv(%s pname %s)", + _mesa_lookup_enum_by_nr(programInterface), + _mesa_lookup_enum_by_nr(pname)); + }; + break; + case GL_MAX_NUM_COMPATIBLE_SUBROUTINES: + default: + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramInterfaceiv(pname %s)", + _mesa_lookup_enum_by_nr(pname)); + } } GLuint GLAPIENTRY |