mesa: glGetProgramResourceName
Patch adds required helper functions to shaderapi.h and the actual implementation. Name generation copied from '_mesa_get_uniform_name' which can be removed later by refactoring functions to use resource list. The added functionality can be tested by tests for following functions that are refactored by later patches: GetActiveUniformName GetActiveUniformBlockName v2: no index for geometry shader inputs (Ilia Mirkin) add bufSize < 0 check and error out validate enum corresponding Piglit test: arb_program_interface_query-getprogramresourcename Signed-off-by: Tapani Pälli <tapani.palli@intel.com> Reviewed-by: Martin Peres <martin.peres@linux.intel.org>
This commit is contained in:
@@ -245,6 +245,29 @@ _mesa_GetProgramResourceName(GLuint program, GLenum programInterface,
|
|||||||
GLuint index, GLsizei bufSize, GLsizei *length,
|
GLuint index, GLsizei bufSize, GLsizei *length,
|
||||||
GLchar *name)
|
GLchar *name)
|
||||||
{
|
{
|
||||||
|
GET_CURRENT_CONTEXT(ctx);
|
||||||
|
struct gl_shader_program *shProg =
|
||||||
|
_mesa_lookup_shader_program_err(ctx, program,
|
||||||
|
"glGetProgramResourceName");
|
||||||
|
|
||||||
|
/* Set user friendly return values in case of errors. */
|
||||||
|
if (name)
|
||||||
|
*name = '\0';
|
||||||
|
if (length)
|
||||||
|
*length = 0;
|
||||||
|
|
||||||
|
if (!shProg || !name)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (programInterface == GL_ATOMIC_COUNTER_BUFFER ||
|
||||||
|
!supported_interface_enum(programInterface)) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceName(%s)",
|
||||||
|
_mesa_lookup_enum_by_nr(programInterface));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_mesa_get_program_resource_name(shProg, programInterface, index, bufSize,
|
||||||
|
length, name, "glGetProgramResourceName");
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLAPIENTRY
|
void GLAPIENTRY
|
||||||
|
@@ -648,3 +648,109 @@ _mesa_program_resource_index(struct gl_shader_program *shProg,
|
|||||||
return calc_resource_index(shProg, res);
|
return calc_resource_index(shProg, res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find a program resource with specific index in given interface.
|
||||||
|
*/
|
||||||
|
struct gl_program_resource *
|
||||||
|
_mesa_program_resource_find_index(struct gl_shader_program *shProg,
|
||||||
|
GLenum interface, GLuint index)
|
||||||
|
{
|
||||||
|
struct gl_program_resource *res = shProg->ProgramResourceList;
|
||||||
|
int idx = -1;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < shProg->NumProgramResourceList; i++, res++) {
|
||||||
|
if (res->Type != interface)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (res->Type) {
|
||||||
|
case GL_UNIFORM_BLOCK:
|
||||||
|
case GL_ATOMIC_COUNTER_BUFFER:
|
||||||
|
if (_mesa_program_resource_index(shProg, res) == index)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
case GL_TRANSFORM_FEEDBACK_VARYING:
|
||||||
|
case GL_PROGRAM_INPUT:
|
||||||
|
case GL_PROGRAM_OUTPUT:
|
||||||
|
case GL_UNIFORM:
|
||||||
|
if (++idx == (int) index)
|
||||||
|
return res;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(!"not implemented for given interface");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get full name of a program resource.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
_mesa_get_program_resource_name(struct gl_shader_program *shProg,
|
||||||
|
GLenum interface, GLuint index,
|
||||||
|
GLsizei bufSize, GLsizei *length,
|
||||||
|
GLchar *name, const char *caller)
|
||||||
|
{
|
||||||
|
GET_CURRENT_CONTEXT(ctx);
|
||||||
|
|
||||||
|
/* Find resource with given interface and index. */
|
||||||
|
struct gl_program_resource *res =
|
||||||
|
_mesa_program_resource_find_index(shProg, interface, index);
|
||||||
|
|
||||||
|
/* The error INVALID_VALUE is generated if <index> is greater than
|
||||||
|
* or equal to the number of entries in the active resource list for
|
||||||
|
* <programInterface>.
|
||||||
|
*/
|
||||||
|
if (!res) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_VALUE, "%s(index %u)", caller, index);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bufSize < 0) {
|
||||||
|
_mesa_error(ctx, GL_INVALID_VALUE, "%s(bufSize %d)", caller, bufSize);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLsizei localLength;
|
||||||
|
|
||||||
|
if (length == NULL)
|
||||||
|
length = &localLength;
|
||||||
|
|
||||||
|
_mesa_copy_string(name, bufSize, length, _mesa_program_resource_name(res));
|
||||||
|
|
||||||
|
/* Page 61 (page 73 of the PDF) in section 2.11 of the OpenGL ES 3.0
|
||||||
|
* spec says:
|
||||||
|
*
|
||||||
|
* "If the active uniform is an array, the uniform name returned in
|
||||||
|
* name will always be the name of the uniform array appended with
|
||||||
|
* "[0]"."
|
||||||
|
*
|
||||||
|
* The same text also appears in the OpenGL 4.2 spec. It does not,
|
||||||
|
* however, appear in any previous spec. Previous specifications are
|
||||||
|
* ambiguous in this regard. However, either name can later be passed
|
||||||
|
* to glGetUniformLocation (and related APIs), so there shouldn't be any
|
||||||
|
* harm in always appending "[0]" to uniform array names.
|
||||||
|
*
|
||||||
|
* Geometry shader stage has different naming convention where the 'normal'
|
||||||
|
* condition is an array, therefore for variables referenced in geometry
|
||||||
|
* stage we do not add '[0]'.
|
||||||
|
*
|
||||||
|
* Note, that TCS outputs and TES inputs should not have index appended
|
||||||
|
* either.
|
||||||
|
*/
|
||||||
|
bool add_index = !(((interface == GL_PROGRAM_INPUT) &&
|
||||||
|
res->StageReferences & (1 << MESA_SHADER_GEOMETRY)));
|
||||||
|
|
||||||
|
if (add_index && _mesa_program_resource_array_size(res)) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* The comparison is strange because *length does *NOT* include the
|
||||||
|
* terminating NUL, but maxLength does.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < 3 && (*length + i + 1) < bufSize; i++)
|
||||||
|
name[*length + i] = "[0]"[i];
|
||||||
|
|
||||||
|
name[*length + i] = '\0';
|
||||||
|
*length += i;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@@ -234,6 +234,16 @@ extern struct gl_program_resource *
|
|||||||
_mesa_program_resource_find_name(struct gl_shader_program *shProg,
|
_mesa_program_resource_find_name(struct gl_shader_program *shProg,
|
||||||
GLenum interface, const char *name);
|
GLenum interface, const char *name);
|
||||||
|
|
||||||
|
extern struct gl_program_resource *
|
||||||
|
_mesa_program_resource_find_index(struct gl_shader_program *shProg,
|
||||||
|
GLenum interface, GLuint index);
|
||||||
|
|
||||||
|
extern bool
|
||||||
|
_mesa_get_program_resource_name(struct gl_shader_program *shProg,
|
||||||
|
GLenum interface, GLuint index,
|
||||||
|
GLsizei bufSize, GLsizei *length,
|
||||||
|
GLchar *name, const char *caller);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user