[Mesa-dev] [PATCH 03/23] mesa: glGetProgramInterfaceiv

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


Patch adds required helper functions to shaderapi.h and
the actual implementation.

corresponding Piglit test:
   arb_program_interface_query-getprograminterfaceiv

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

diff --git a/src/mesa/main/program_resource.c b/src/mesa/main/program_resource.c
index b3b93aa..a9194d1 100644
--- a/src/mesa/main/program_resource.c
+++ b/src/mesa/main/program_resource.c
@@ -23,12 +23,91 @@
  *
  */
 
+#include "main/enums.h"
+#include "main/macros.h"
+#include "main/mtypes.h"
+#include "main/shaderapi.h"
+#include "main/shaderobj.h"
 #include "program_resource.h"
 
 void GLAPIENTRY
 _mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface,
                             GLenum pname, GLint *params)
 {
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_program_resource *res;
+   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;
+   }
+
+   res = shProg->ProgramResourceList;
+   *params = 0;
+
+   /* Validate pname against interface. */
+   switch(pname) {
+   case GL_ACTIVE_RESOURCES:
+      for (i = 0; i < shProg->NumProgramResourceList; i++, res++)
+         if (res->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; i < shProg->NumProgramResourceList; i++, res++)
+         if (res->Type == programInterface) {
+            const char *name = _mesa_program_resource_name(res);
+            unsigned array_size = _mesa_program_resource_array_size(res);
+            *params = MAX2(*params, strlen(name) +
+                            (array_size > 0 ? 3 : 0) + 1);
+         }
+      break;
+   case GL_MAX_NUM_ACTIVE_VARIABLES:
+      switch (programInterface) {
+      case GL_UNIFORM_BLOCK:
+      case GL_ATOMIC_COUNTER_BUFFER:
+         for (i = 0; i < shProg->NumProgramResourceList; i++, res++) {
+            if (res->Type == programInterface) {
+               if (res->Type == GL_UNIFORM_BLOCK) {
+                  struct gl_uniform_block *block =
+                     (struct gl_uniform_block *) res->Data;
+                  *params = MAX2(*params, block->NumUniforms);
+               } else {
+                  struct gl_active_atomic_buffer *buffer =
+                     (struct gl_active_atomic_buffer *) res->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;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glGetProgramInterfaceiv(pname %s)",
+                  _mesa_lookup_enum_by_nr(pname));
+   }
 }
 
 GLuint GLAPIENTRY
diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp
index df9081b..9df793e 100644
--- a/src/mesa/main/shader_query.cpp
+++ b/src/mesa/main/shader_query.cpp
@@ -34,11 +34,29 @@
 #include "shaderobj.h"
 #include "program/hash_table.h"
 #include "../glsl/program.h"
+#include "uniforms.h"
+#include "main/enums.h"
 
 extern "C" {
 #include "shaderapi.h"
 }
 
+/**
+ * Declare convenience functions to return resource data in a given type.
+ * Warning! this is not type safe so be *very* careful when using these.
+ */
+#define DECL_RESOURCE_FUNC(name, type)\
+   const type * RESOURCE_ ##name (gl_program_resource *res) {\
+   assert(res->Data);\
+   return (type *) res->Data;\
+}
+
+DECL_RESOURCE_FUNC(VAR, ir_variable);
+DECL_RESOURCE_FUNC(UBO, gl_uniform_block);
+DECL_RESOURCE_FUNC(UNI, gl_uniform_storage);
+DECL_RESOURCE_FUNC(ATC, gl_active_atomic_buffer);
+DECL_RESOURCE_FUNC(XFB, gl_transform_feedback_varying_info);
+
 void GLAPIENTRY
 _mesa_BindAttribLocation(GLhandleARB program, GLuint index,
                             const GLcharARB *name)
@@ -498,3 +516,43 @@ _mesa_GetFragDataLocation(GLuint program, const GLchar *name)
 
    return -1;
 }
+
+const char*
+_mesa_program_resource_name(struct gl_program_resource *res)
+{
+   switch (res->Type) {
+   case GL_UNIFORM_BLOCK:
+      return RESOURCE_UBO(res)->Name;
+   case GL_TRANSFORM_FEEDBACK_VARYING:
+      return RESOURCE_XFB(res)->Name;
+   case GL_PROGRAM_INPUT:
+   case GL_PROGRAM_OUTPUT:
+      return RESOURCE_VAR(res)->name;
+   case GL_UNIFORM:
+      return RESOURCE_UNI(res)->name;
+   default:
+      assert(!"support for resource type not implemented");
+   }
+   return NULL;
+}
+
+
+unsigned
+_mesa_program_resource_array_size(struct gl_program_resource *res)
+{
+   switch (res->Type) {
+   case GL_TRANSFORM_FEEDBACK_VARYING:
+      return RESOURCE_XFB(res)->Size;
+   case GL_PROGRAM_INPUT:
+   case GL_PROGRAM_OUTPUT:
+      return RESOURCE_VAR(res)->data.max_array_access;
+   case GL_UNIFORM:
+      return RESOURCE_UNI(res)->array_elements;
+   case GL_ATOMIC_COUNTER_BUFFER:
+   case GL_UNIFORM_BLOCK:
+      return 0;
+   default:
+      assert(!"support for resource type not implemented");
+   }
+   return 0;
+}
diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h
index 047d256..6db52f7 100644
--- a/src/mesa/main/shaderapi.h
+++ b/src/mesa/main/shaderapi.h
@@ -219,6 +219,13 @@ extern GLuint GLAPIENTRY
 _mesa_CreateShaderProgramv(GLenum type, GLsizei count,
                            const GLchar* const *strings);
 
+/* GL_ARB_program_resource_query */
+extern const char*
+_mesa_program_resource_name(struct gl_program_resource *res);
+
+extern unsigned
+_mesa_program_resource_array_size(struct gl_program_resource *res);
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.1.0



More information about the mesa-dev mailing list