diff options
Diffstat (limited to 'src/mesa/main')
-rw-r--r-- | src/mesa/main/program_resource.c | 23 | ||||
-rw-r--r-- | src/mesa/main/shader_query.cpp | 106 | ||||
-rw-r--r-- | src/mesa/main/shaderapi.h | 10 |
3 files changed, 139 insertions, 0 deletions
diff --git a/src/mesa/main/program_resource.c b/src/mesa/main/program_resource.c index 7a2732503a9..a60b2e4e658 100644 --- a/src/mesa/main/program_resource.c +++ b/src/mesa/main/program_resource.c @@ -245,6 +245,29 @@ _mesa_GetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, 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 diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp index 61eec68683f..ab61be97a09 100644 --- a/src/mesa/main/shader_query.cpp +++ b/src/mesa/main/shader_query.cpp @@ -648,3 +648,109 @@ _mesa_program_resource_index(struct gl_shader_program *shProg, 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; +} diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h index d80252b460a..7a7e3e9e731 100644 --- a/src/mesa/main/shaderapi.h +++ b/src/mesa/main/shaderapi.h @@ -234,6 +234,16 @@ extern struct gl_program_resource * _mesa_program_resource_find_name(struct gl_shader_program *shProg, 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 } #endif |