From 467304dfe56bb4e3a66f500db5754500cc18955a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 19 Jun 2012 13:43:00 -0700 Subject: [PATCH] mesa: Add support for glUniformBlockBinding() and the API to get it back. Fixes piglit ARB_uniform_buffer_object/uniformbufferbinding. Reviewed-by: Kenneth Graunke Reviewed-by: Ian Romanick --- src/mesa/main/uniforms.c | 95 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) 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 */ } -- 2.30.2