From: Eric Anholt Date: Tue, 19 Jun 2012 20:43:00 +0000 (-0700) Subject: mesa: Add support for glUniformBlockBinding() and the API to get it back. X-Git-Tag: accepted/2.0alpha-wayland/20121114.171706~887 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=467304dfe56bb4e3a66f500db5754500cc18955a;p=profile%2Fivi%2Fmesa.git 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 --- diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c index ccbd753..940cb07 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 */ }