mesa: Add support for glUniformBlockBinding() and the API to get it back.
Fixes piglit ARB_uniform_buffer_object/uniformbufferbinding. Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
@@ -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 */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user