summaryrefslogtreecommitdiff
path: root/src/mesa/main/program_resource.c
diff options
context:
space:
mode:
authorTapani Pälli <tapani.palli@intel.com>2015-03-12 13:45:22 +0200
committerTapani Pälli <tapani.palli@intel.com>2015-04-16 07:55:56 +0300
commite0e4d77f0120865b3ca0a4055358fc87d38d1cfe (patch)
tree38e663dd90d25ef851687b3b2920d5061d976953 /src/mesa/main/program_resource.c
parent2a5a0d19d67b2ccd7eee33a6f3bead66cc2d78ff (diff)
mesa: glGetProgramResourceLocation
Patch adds required helper functions to shaderapi.h and the actual implementation. corresponding Piglit test: arb_program_interface_query-resource-location The added functionality can be tested by tests for following functions that are refactored by later patches: GetAttribLocation GetUniformLocation GetFragDataLocation v2: code cleanup, changes to array element syntax checking (Ilia Mirkin) Signed-off-by: Tapani Pälli <tapani.palli@intel.com> Reviewed-by: Martin Peres <martin.peres@linux.intel.com>
Diffstat (limited to 'src/mesa/main/program_resource.c')
-rw-r--r--src/mesa/main/program_resource.c81
1 files changed, 80 insertions, 1 deletions
diff --git a/src/mesa/main/program_resource.c b/src/mesa/main/program_resource.c
index a60b2e4e658..ee39f3125cf 100644
--- a/src/mesa/main/program_resource.c
+++ b/src/mesa/main/program_resource.c
@@ -278,11 +278,90 @@ _mesa_GetProgramResourceiv(GLuint program, GLenum programInterface,
{
}
+/**
+ * Function verifies syntax of given name for GetProgramResourceLocation
+ * and GetProgramResourceLocationIndex for the following cases:
+ *
+ * "array element portion of a string passed to GetProgramResourceLocation
+ * or GetProgramResourceLocationIndex must not have, a "+" sign, extra
+ * leading zeroes, or whitespace".
+ *
+ * Check is written to be compatible with GL_ARB_array_of_arrays.
+ */
+static bool
+invalid_array_element_syntax(const GLchar *name)
+{
+ char *first = strchr(name, '[');
+ char *last = strrchr(name, '[');
+
+ if (!first)
+ return false;
+
+ /* No '+' or ' ' allowed anywhere. */
+ if (strchr(first, '+') || strchr(first, ' '))
+ return true;
+
+ /* Check that last array index is 0. */
+ if (last[1] == '0' && last[2] != ']')
+ return true;
+
+ return false;
+}
+
+static struct gl_shader_program *
+lookup_linked_program(GLuint program, const char *caller)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *prog =
+ _mesa_lookup_shader_program_err(ctx, program, caller);
+
+ if (!prog)
+ return NULL;
+
+ if (prog->LinkStatus == GL_FALSE) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)",
+ caller);
+ return NULL;
+ }
+ return prog;
+}
+
GLint GLAPIENTRY
_mesa_GetProgramResourceLocation(GLuint program, GLenum programInterface,
const GLchar *name)
{
- return -1;
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg =
+ lookup_linked_program(program, "glGetProgramResourceLocation");
+
+ if (!shProg || !name || invalid_array_element_syntax(name))
+ return -1;
+
+ /* Validate programInterface. */
+ switch (programInterface) {
+ case GL_UNIFORM:
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ break;
+
+ /* For reference valid cases requiring additional extension support:
+ * GL_ARB_shader_subroutine
+ * GL_ARB_tessellation_shader
+ * GL_ARB_compute_shader
+ */
+ 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:
+
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceLocation(%s %s)",
+ _mesa_lookup_enum_by_nr(programInterface), name);
+ }
+
+ return _mesa_program_resource_location(shProg, programInterface, name);
}
GLint GLAPIENTRY