[Mesa-dev] [PATCH 05/23] mesa: glGetProgramResourceName

Tapani Pälli tapani.palli at intel.com
Fri Mar 13 01:37:51 PDT 2015


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

Signed-off-by: Tapani Pälli <tapani.palli at intel.com>
---
 src/mesa/main/program_resource.c | 22 +++++++++
 src/mesa/main/shader_query.cpp   | 96 ++++++++++++++++++++++++++++++++++++++++
 src/mesa/main/shaderapi.h        | 10 +++++
 3 files changed, 128 insertions(+)

diff --git a/src/mesa/main/program_resource.c b/src/mesa/main/program_resource.c
index 4190f98..4fa6ac6 100644
--- a/src/mesa/main/program_resource.c
+++ b/src/mesa/main/program_resource.c
@@ -211,6 +211,28 @@ _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,
+                                      "glGetProgramResourceIndex");
+   if (!shProg)
+      return;
+
+   /* Set user friendly return values in case of errors. */
+   *name = '\0';
+   if (length)
+      *length = 0;
+
+   if (programInterface == GL_ATOMIC_COUNTER_BUFFER) {
+      _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 d1974a4..77a4af0 100644
--- a/src/mesa/main/shader_query.cpp
+++ b/src/mesa/main/shader_query.cpp
@@ -647,3 +647,99 @@ _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;
+   }
+
+   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]'.
+    */
+   if (_mesa_program_resource_array_size(res) != 0 &&
+       (!(res->StageReferences & (1 << MESA_SHADER_GEOMETRY)))) {
+      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 d80252b..7a7e3e9 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
-- 
2.1.0



More information about the mesa-dev mailing list