summaryrefslogtreecommitdiffstats
path: root/src/mesa/main/uniforms.c
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2012-06-19 13:43:00 -0700
committerEric Anholt <[email protected]>2012-07-31 12:06:19 -0700
commit467304dfe56bb4e3a66f500db5754500cc18955a (patch)
tree2526f19d5d9a8253926e54b836cf2e9e950aa893 /src/mesa/main/uniforms.c
parentfafa394c15d7d4ca87fc220196dd5a57bd9cf601 (diff)
mesa: Add support for glUniformBlockBinding() and the API to get it back.
Fixes piglit ARB_uniform_buffer_object/uniformbufferbinding. Reviewed-by: Kenneth Graunke <[email protected]> Reviewed-by: Ian Romanick <[email protected]>
Diffstat (limited to 'src/mesa/main/uniforms.c')
-rw-r--r--src/mesa/main/uniforms.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c
index ccbd753dbec..940cb07c247 100644
--- a/src/mesa/main/uniforms.c
+++ b/src/mesa/main/uniforms.c
@@ -41,6 +41,7 @@
#include "main/shaderapi.h"
#include "main/shaderobj.h"
#include "main/uniforms.h"
+#include "main/enums.h"
#include "ir_uniform.h"
#include "glsl_types.h"
@@ -583,6 +584,98 @@ _mesa_GetUniformIndices(GLuint program,
}
}
+static void GLAPIENTRY
+_mesa_UniformBlockBinding(GLuint program,
+ GLuint uniformBlockIndex,
+ GLuint uniformBlockBinding)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg;
+
+ if (!ctx->Extensions.ARB_uniform_buffer_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformBlockBinding");
+ return;
+ }
+
+ shProg = _mesa_lookup_shader_program_err(ctx, program,
+ "glUniformBlockBinding");
+ if (!shProg)
+ return;
+
+ if (uniformBlockIndex >= shProg->NumUniformBlocks) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glUniformBlockBinding(block index %d >= %d)",
+ uniformBlockIndex, shProg->NumUniformBlocks);
+ return;
+ }
+
+ if (uniformBlockBinding >= ctx->Const.MaxUniformBufferBindings) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glUniformBlockBinding(block binding %d >= %d)",
+ uniformBlockBinding, ctx->Const.MaxUniformBufferBindings);
+ return;
+ }
+
+ if (shProg->UniformBlocks[uniformBlockIndex].Binding !=
+ uniformBlockBinding) {
+ int i;
+
+ FLUSH_VERTICES(ctx, _NEW_BUFFER_OBJECT);
+ shProg->UniformBlocks[uniformBlockIndex].Binding = uniformBlockBinding;
+
+ for (i = 0; i < MESA_SHADER_TYPES; i++) {
+ int stage_index = shProg->UniformBlockStageIndex[i][uniformBlockIndex];
+
+ if (stage_index != -1) {
+ struct gl_shader *sh = shProg->_LinkedShaders[i];
+ sh->UniformBlocks[stage_index].Binding = uniformBlockBinding;
+ }
+ }
+ }
+}
+
+static void GLAPIENTRY
+_mesa_GetActiveUniformBlockiv(GLuint program,
+ GLuint uniformBlockIndex,
+ GLenum pname,
+ GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg;
+ struct gl_uniform_block *block;
+
+ if (!ctx->Extensions.ARB_uniform_buffer_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv");
+ return;
+ }
+
+ shProg = _mesa_lookup_shader_program_err(ctx, program,
+ "glGetActiveUniformBlockiv");
+ if (!shProg)
+ return;
+
+ if (uniformBlockIndex >= shProg->NumUniformBlocks) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glGetActiveUniformBlockiv(block index %d >= %d)",
+ uniformBlockIndex, shProg->NumUniformBlocks);
+ return;
+ }
+
+ block = &shProg->UniformBlocks[uniformBlockIndex];
+
+ switch (pname) {
+ case GL_UNIFORM_BLOCK_BINDING:
+ params[0] = block->Binding;
+ return;
+
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetActiveUniformBlockiv(pname 0x%x (%s))",
+ pname, _mesa_lookup_enum_by_nr(pname));
+ return;
+ }
+}
+
/**
* Plug in shader uniform-related functions into API dispatch table.
*/
@@ -644,6 +737,8 @@ _mesa_init_shader_uniform_dispatch(struct _glapi_table *exec)
SET_GetUniformBlockIndex(exec, _mesa_GetUniformBlockIndex);
SET_GetUniformIndices(exec, _mesa_GetUniformIndices);
SET_GetActiveUniformsiv(exec, _mesa_GetActiveUniformsiv);
+ SET_GetActiveUniformBlockiv(exec, _mesa_GetActiveUniformBlockiv);
+ SET_UniformBlockBinding(exec, _mesa_UniformBlockBinding);
#endif /* FEATURE_GL */
}