mesa: Include compiler.h in hash_table.h.
[mesa.git] / src / mesa / main / uniform_query.cpp
index f5d998ffb221ead122c1cd040e2c347315fec3d1..c71577c6ed165f688dba16d818b026fb199b2409 100644 (file)
@@ -38,7 +38,7 @@
 
 
 extern "C" void GLAPIENTRY
-_mesa_GetActiveUniformARB(GLhandleARB program, GLuint index,
+_mesa_GetActiveUniform(GLhandleARB program, GLuint index,
                           GLsizei maxLength, GLsizei *length, GLint *size,
                           GLenum *type, GLcharARB *nameOut)
 {
@@ -74,6 +74,79 @@ _mesa_GetActiveUniformARB(GLhandleARB program, GLuint index,
    }
 }
 
+extern "C" void GLAPIENTRY
+_mesa_GetActiveUniformsiv(GLuint program,
+                         GLsizei uniformCount,
+                         const GLuint *uniformIndices,
+                         GLenum pname,
+                         GLint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_shader_program *shProg;
+   GLsizei i;
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
+   if (!shProg)
+      return;
+
+   if (uniformCount < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                 "glGetUniformIndices(uniformCount < 0)");
+      return;
+   }
+
+   for (i = 0; i < uniformCount; i++) {
+      GLuint index = uniformIndices[i];
+      const struct gl_uniform_storage *uni = &shProg->UniformStorage[index];
+
+      if (index >= shProg->NumUserUniformStorage) {
+        _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(index)");
+        return;
+      }
+
+      switch (pname) {
+      case GL_UNIFORM_TYPE:
+        params[i] = uni->type->gl_type;
+        break;
+
+      case GL_UNIFORM_SIZE:
+        /* array_elements is zero for non-arrays, but the API requires that 1 be
+         * returned.
+         */
+        params[i] = MAX2(1, uni->array_elements);
+        break;
+
+      case GL_UNIFORM_NAME_LENGTH:
+        params[i] = strlen(uni->name) + 1;
+        break;
+
+      case GL_UNIFORM_BLOCK_INDEX:
+        params[i] = uni->block_index;
+        break;
+
+      case GL_UNIFORM_OFFSET:
+        params[i] = uni->offset;
+        break;
+
+      case GL_UNIFORM_ARRAY_STRIDE:
+        params[i] = uni->array_stride;
+        break;
+
+      case GL_UNIFORM_MATRIX_STRIDE:
+        params[i] = uni->matrix_stride;
+        break;
+
+      case GL_UNIFORM_IS_ROW_MAJOR:
+        params[i] = uni->row_major;
+        break;
+
+      default:
+        _mesa_error(ctx, GL_INVALID_ENUM, "glGetActiveUniformsiv(pname)");
+        return;
+      }
+   }
+}
+
 static bool
 validate_uniform_parameters(struct gl_context *ctx,
                            struct gl_shader_program *shProg,
@@ -736,7 +809,8 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
                   sizeof(shProg->SamplerUnits));
 
            _mesa_update_shader_textures_used(shProg, prog);
-           (void) ctx->Driver.ProgramStringNotify(ctx, prog->Target, prog);
+            if (ctx->Driver.SamplerUniformChange)
+              ctx->Driver.SamplerUniformChange(ctx, prog->Target, prog);
         }
       }
    }
@@ -852,13 +926,17 @@ _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg,
 /**
  * Called via glGetUniformLocation().
  *
- * The return value will encode two values, the uniform location and an
- * offset (used for arrays, structs).
+ * Returns the uniform index into UniformStorage (also the
+ * glGetActiveUniformsiv uniform index), and stores the referenced
+ * array offset in *offset, or GL_INVALID_INDEX (-1).  Those two
+ * return values can be encoded into a uniform location for
+ * glUniform* using _mesa_uniform_merge_location_offset(index, offset).
  */
-extern "C" GLint
+extern "C" unsigned
 _mesa_get_uniform_location(struct gl_context *ctx,
                            struct gl_shader_program *shProg,
-                          const GLchar *name)
+                           const GLchar *name,
+                           unsigned *out_offset)
 {
    const size_t len = strlen(name);
    long offset;
@@ -901,13 +979,13 @@ _mesa_get_uniform_location(struct gl_context *ctx,
        * (or other non-digit characters) before the opening '['.
        */
       if ((i == 0) || name[i-1] != '[')
-        return -1;
+        return GL_INVALID_INDEX;
 
       /* Return an error if there are no digits between the opening '[' to
        * match the closing ']'.
        */
       if (i == (len - 1))
-        return -1;
+        return GL_INVALID_INDEX;
 
       /* Make a new string that is a copy of the old string up to (but not
        * including) the '[' character.
@@ -919,7 +997,7 @@ _mesa_get_uniform_location(struct gl_context *ctx,
       offset = strtol(&name[i], NULL, 10);
       if (offset < 0) {
         free(name_copy);
-        return -1;
+        return GL_INVALID_INDEX;
       }
 
       array_lookup = true;
@@ -941,16 +1019,17 @@ _mesa_get_uniform_location(struct gl_context *ctx,
       free(name_copy);
 
    if (!found)
-      return -1;
+      return GL_INVALID_INDEX;
 
    /* Since array_elements is 0 for non-arrays, this causes look-ups of 'a[0]'
     * to (correctly) fail if 'a' is not an array.
     */
    if (array_lookup && shProg->UniformStorage[location].array_elements == 0) {
-      return -1;
+      return GL_INVALID_INDEX;
    }
 
-   return _mesa_uniform_merge_location_offset(location, offset);
+   *out_offset = offset;
+   return location;
 }
 
 extern "C" bool