aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/main')
-rw-r--r--mesalib/src/mesa/main/api_exec.c12
-rw-r--r--mesalib/src/mesa/main/bufferobj.c240
-rw-r--r--mesalib/src/mesa/main/bufferobj.h10
-rw-r--r--mesalib/src/mesa/main/context.c9
-rw-r--r--mesalib/src/mesa/main/extensions.c2
-rw-r--r--mesalib/src/mesa/main/get.c60
-rw-r--r--mesalib/src/mesa/main/mtypes.h41
-rw-r--r--mesalib/src/mesa/main/transformfeedback.c66
-rw-r--r--mesalib/src/mesa/main/transformfeedback.h15
9 files changed, 384 insertions, 71 deletions
diff --git a/mesalib/src/mesa/main/api_exec.c b/mesalib/src/mesa/main/api_exec.c
index 15b9f6974..19e7f9807 100644
--- a/mesalib/src/mesa/main/api_exec.c
+++ b/mesalib/src/mesa/main/api_exec.c
@@ -579,17 +579,7 @@ _mesa_create_exec_table(void)
#endif
/* ARB 28. GL_ARB_vertex_buffer_object */
- SET_BindBufferARB(exec, _mesa_BindBufferARB);
- SET_BufferDataARB(exec, _mesa_BufferDataARB);
- SET_BufferSubDataARB(exec, _mesa_BufferSubDataARB);
- SET_DeleteBuffersARB(exec, _mesa_DeleteBuffersARB);
- SET_GenBuffersARB(exec, _mesa_GenBuffersARB);
- SET_GetBufferParameterivARB(exec, _mesa_GetBufferParameterivARB);
- SET_GetBufferPointervARB(exec, _mesa_GetBufferPointervARB);
- SET_GetBufferSubDataARB(exec, _mesa_GetBufferSubDataARB);
- SET_IsBufferARB(exec, _mesa_IsBufferARB);
- SET_MapBufferARB(exec, _mesa_MapBufferARB);
- SET_UnmapBufferARB(exec, _mesa_UnmapBufferARB);
+ _mesa_init_bufferobj_dispatch(exec);
/* ARB 29. GL_ARB_occlusion_query */
_mesa_init_queryobj_dispatch(exec);
diff --git a/mesalib/src/mesa/main/bufferobj.c b/mesalib/src/mesa/main/bufferobj.c
index 332af3d36..5f724ace3 100644
--- a/mesalib/src/mesa/main/bufferobj.c
+++ b/mesalib/src/mesa/main/bufferobj.c
@@ -43,6 +43,7 @@
#include "mtypes.h"
#include "texobj.h"
#include "transformfeedback.h"
+#include "dispatch.h"
/* Debug flags */
@@ -92,6 +93,11 @@ get_buffer_target(struct gl_context *ctx, GLenum target)
return &ctx->Texture.BufferObject;
}
break;
+ case GL_UNIFORM_BUFFER:
+ if (ctx->Extensions.ARB_uniform_buffer_object) {
+ return &ctx->UniformBuffer;
+ }
+ break;
default:
return NULL;
}
@@ -598,6 +604,8 @@ _mesa_copy_buffer_subdata(struct gl_context *ctx,
void
_mesa_init_buffer_objects( struct gl_context *ctx )
{
+ GLuint i;
+
memset(&DummyBufferObject, 0, sizeof(DummyBufferObject));
_glthread_INIT_MUTEX(DummyBufferObject.Mutex);
DummyBufferObject.RefCount = 1000*1000*1000; /* never delete */
@@ -609,16 +617,43 @@ _mesa_init_buffer_objects( struct gl_context *ctx )
ctx->Shared->NullBufferObj);
_mesa_reference_buffer_object(ctx, &ctx->CopyWriteBuffer,
ctx->Shared->NullBufferObj);
+
+ ctx->UniformBufferBindings = calloc(ctx->Const.MaxUniformBufferBindings,
+ sizeof(*ctx->UniformBufferBindings));
+
+ _mesa_reference_buffer_object(ctx, &ctx->UniformBuffer,
+ ctx->Shared->NullBufferObj);
+
+ for (i = 0; i < ctx->Const.MaxUniformBufferBindings; i++) {
+ _mesa_reference_buffer_object(ctx,
+ &ctx->UniformBufferBindings[i].BufferObject,
+ ctx->Shared->NullBufferObj);
+ ctx->UniformBufferBindings[i].Offset = -1;
+ ctx->UniformBufferBindings[i].Size = -1;
+ }
}
void
_mesa_free_buffer_objects( struct gl_context *ctx )
{
+ GLuint i;
+
_mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj, NULL);
_mesa_reference_buffer_object(ctx, &ctx->CopyReadBuffer, NULL);
_mesa_reference_buffer_object(ctx, &ctx->CopyWriteBuffer, NULL);
+
+ _mesa_reference_buffer_object(ctx, &ctx->UniformBuffer, NULL);
+
+ for (i = 0; i < ctx->Const.MaxUniformBufferBindings; i++) {
+ _mesa_reference_buffer_object(ctx,
+ &ctx->UniformBufferBindings[i].BufferObject,
+ NULL);
+ }
+
+ free(ctx->UniformBufferBindings);
+ ctx->UniformBufferBindings = NULL;
}
@@ -840,6 +875,10 @@ _mesa_DeleteBuffersARB(GLsizei n, const GLuint *ids)
}
}
+ if (ctx->UniformBuffer == bufObj) {
+ _mesa_BindBufferARB( GL_UNIFORM_BUFFER, 0 );
+ }
+
/* unbind any pixel pack/unpack pointers bound to this buffer */
if (ctx->Pack.BufferObj == bufObj) {
_mesa_BindBufferARB( GL_PIXEL_PACK_BUFFER_EXT, 0 );
@@ -1954,3 +1993,204 @@ _mesa_GetObjectParameterivAPPLE(GLenum objectType, GLuint name, GLenum pname,
}
#endif /* FEATURE_APPLE_object_purgeable */
+
+static void
+set_ubo_binding(struct gl_context *ctx,
+ int index,
+ struct gl_buffer_object *bufObj,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLboolean autoSize)
+{
+ struct gl_uniform_buffer_binding *binding;
+
+ binding = &ctx->UniformBufferBindings[index];
+ if (binding->BufferObject == bufObj &&
+ binding->Offset == offset &&
+ binding->Size == size &&
+ binding->AutomaticSize == autoSize) {
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_BUFFER_OBJECT);
+
+ _mesa_reference_buffer_object(ctx, &binding->BufferObject, bufObj);
+ binding->Offset = offset;
+ binding->Size = size;
+ binding->AutomaticSize = autoSize;
+}
+
+/**
+ * Specify a buffer object to receive vertex shader results. Plus,
+ * specify the starting offset to place the results, and max size.
+ */
+static void
+bind_buffer_range_uniform_buffer(struct gl_context *ctx,
+ GLuint index,
+ struct gl_buffer_object *bufObj,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ if (index >= ctx->Const.MaxUniformBufferBindings) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(index=%d)", index);
+ return;
+ }
+
+ if (offset & (ctx->Const.UniformBufferOffsetAlignment - 1)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glBindBufferRange(offset misalgned %d/%d)", (int) offset,
+ ctx->Const.UniformBufferOffsetAlignment);
+ return;
+ }
+
+ if (bufObj == ctx->Shared->NullBufferObj) {
+ offset = -1;
+ size = -1;
+ }
+
+ _mesa_reference_buffer_object(ctx, &ctx->UniformBuffer, bufObj);
+ set_ubo_binding(ctx, index, bufObj, offset, size, GL_FALSE);
+}
+
+
+/**
+ * Specify a buffer object to receive vertex shader results.
+ * As above, but start at offset = 0.
+ */
+static void
+bind_buffer_base_uniform_buffer(struct gl_context *ctx,
+ GLuint index,
+ struct gl_buffer_object *bufObj)
+{
+ if (index >= ctx->Const.MaxUniformBufferBindings) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferBase(index=%d)", index);
+ return;
+ }
+
+ _mesa_reference_buffer_object(ctx, &ctx->UniformBuffer, bufObj);
+ if (bufObj == ctx->Shared->NullBufferObj)
+ set_ubo_binding(ctx, index, bufObj, -1, -1, GL_TRUE);
+ else
+ set_ubo_binding(ctx, index, bufObj, 0, 0, GL_TRUE);
+}
+
+void GLAPIENTRY
+_mesa_BindBufferRange(GLenum target, GLuint index,
+ GLuint buffer, GLintptr offset, GLsizeiptr size)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_buffer_object *bufObj;
+
+ if (buffer == 0) {
+ bufObj = ctx->Shared->NullBufferObj;
+ } else {
+ bufObj = _mesa_lookup_bufferobj(ctx, buffer);
+ }
+
+ if (!bufObj) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBindBufferRange(invalid buffer=%u)", buffer);
+ return;
+ }
+
+ if (size <= 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(size=%d)",
+ (int) size);
+ return;
+ }
+
+ if (offset + size > bufObj->Size) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glBindBufferRange(offset + size %d > buffer size %d)",
+ (int) (offset + size), (int) (bufObj->Size));
+ return;
+ }
+
+ switch (target) {
+ case GL_TRANSFORM_FEEDBACK_BUFFER:
+ _mesa_bind_buffer_range_transform_feedback(ctx, index, bufObj,
+ offset, size);
+ return;
+ case GL_UNIFORM_BUFFER:
+ bind_buffer_range_uniform_buffer(ctx, index, bufObj, offset, size);
+ return;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferRange(target)");
+ return;
+ }
+}
+
+void GLAPIENTRY
+_mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_buffer_object *bufObj;
+
+ if (buffer == 0) {
+ bufObj = ctx->Shared->NullBufferObj;
+ } else {
+ bufObj = _mesa_lookup_bufferobj(ctx, buffer);
+ }
+
+ if (!bufObj) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBindBufferBase(invalid buffer=%u)", buffer);
+ return;
+ }
+
+ /* Note that there's some oddness in the GL 3.1-GL 3.3 specifications with
+ * regards to BindBufferBase. It says (GL 3.1 core spec, page 63):
+ *
+ * "BindBufferBase is equivalent to calling BindBufferRange with offset
+ * zero and size equal to the size of buffer."
+ *
+ * but it says for glGetIntegeri_v (GL 3.1 core spec, page 230):
+ *
+ * "If the parameter (starting offset or size) was not specified when the
+ * buffer object was bound, zero is returned."
+ *
+ * What happens if the size of the buffer changes? Does the size of the
+ * buffer at the moment glBindBufferBase was called still play a role, like
+ * the first quote would imply, or is the size meaningless in the
+ * glBindBufferBase case like the second quote would suggest? The GL 4.1
+ * core spec page 45 says:
+ *
+ * "It is equivalent to calling BindBufferRange with offset zero, while
+ * size is determined by the size of the bound buffer at the time the
+ * binding is used."
+ *
+ * My interpretation is that the GL 4.1 spec was a clarification of the
+ * behavior, not a change. In particular, this choice will only make
+ * rendering work in cases where it would have had undefined results.
+ */
+
+ switch (target) {
+ case GL_TRANSFORM_FEEDBACK_BUFFER:
+ _mesa_bind_buffer_base_transform_feedback(ctx, index, bufObj);
+ return;
+ case GL_UNIFORM_BUFFER:
+ bind_buffer_base_uniform_buffer(ctx, index, bufObj);
+ return;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferBase(target)");
+ return;
+ }
+}
+
+void
+_mesa_init_bufferobj_dispatch(struct _glapi_table *disp)
+{
+ SET_BindBufferARB(disp, _mesa_BindBufferARB);
+ SET_BufferDataARB(disp, _mesa_BufferDataARB);
+ SET_BufferSubDataARB(disp, _mesa_BufferSubDataARB);
+ SET_DeleteBuffersARB(disp, _mesa_DeleteBuffersARB);
+ SET_GenBuffersARB(disp, _mesa_GenBuffersARB);
+ SET_GetBufferParameterivARB(disp, _mesa_GetBufferParameterivARB);
+ SET_GetBufferPointervARB(disp, _mesa_GetBufferPointervARB);
+ SET_GetBufferSubDataARB(disp, _mesa_GetBufferSubDataARB);
+ SET_IsBufferARB(disp, _mesa_IsBufferARB);
+ SET_MapBufferARB(disp, _mesa_MapBufferARB);
+ SET_UnmapBufferARB(disp, _mesa_UnmapBufferARB);
+ SET_BindBufferRangeEXT(disp, _mesa_BindBufferRange);
+ SET_BindBufferBaseEXT(disp, _mesa_BindBufferBase);
+}
diff --git a/mesalib/src/mesa/main/bufferobj.h b/mesalib/src/mesa/main/bufferobj.h
index 66343c3cd..e1d0f7a97 100644
--- a/mesalib/src/mesa/main/bufferobj.h
+++ b/mesalib/src/mesa/main/bufferobj.h
@@ -159,4 +159,14 @@ extern void GLAPIENTRY
_mesa_GetObjectParameterivAPPLE(GLenum objectType, GLuint name, GLenum pname, GLint* params);
#endif
+void GLAPIENTRY
+_mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer);
+
+void GLAPIENTRY
+_mesa_BindBufferRange(GLenum target, GLuint index,
+ GLuint buffer, GLintptr offset, GLsizeiptr size);
+
+extern void
+_mesa_init_bufferobj_dispatch(struct _glapi_table *disp);
+
#endif
diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c
index 3bcedecd9..643476b94 100644
--- a/mesalib/src/mesa/main/context.c
+++ b/mesalib/src/mesa/main/context.c
@@ -542,6 +542,9 @@ init_program_limits(GLenum type, struct gl_program_constants *prog)
prog->MediumInt.RangeMax = 24;
prog->MediumInt.Precision = 0;
prog->LowInt = prog->HighInt = prog->MediumInt;
+
+ prog->MaxUniformBlocks = 12;
+ prog->MaxCombinedUniformComponents = prog->MaxUniformComponents;
}
@@ -653,6 +656,12 @@ _mesa_init_constants(struct gl_context *ctx)
ctx->Const.MaxTransformFeedbackSeparateComponents = 4 * MAX_FEEDBACK_ATTRIBS;
ctx->Const.MaxTransformFeedbackInterleavedComponents = 4 * MAX_FEEDBACK_ATTRIBS;
+ /** GL_ARB_uniform_buffer_object */
+ ctx->Const.MaxCombinedUniformBlocks = 36;
+ ctx->Const.MaxUniformBufferBindings = 36;
+ ctx->Const.MaxUniformBlockSize = 16384;
+ ctx->Const.UniformBufferOffsetAlignment = 1;
+
/* GL 3.2: hard-coded for now: */
ctx->Const.ProfileMask = GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c
index 079316145..e4fe73307 100644
--- a/mesalib/src/mesa/main/extensions.c
+++ b/mesalib/src/mesa/main/extensions.c
@@ -141,7 +141,7 @@ static const struct extension extension_table[] = {
{ "GL_ARB_texture_swizzle", o(EXT_texture_swizzle), GL, 2008 },
{ "GL_ARB_transform_feedback2", o(ARB_transform_feedback2), GL, 2010 },
{ "GL_ARB_transpose_matrix", o(ARB_transpose_matrix), GL, 1999 },
- { "GL_ARB_uniform_buffer_object", o(ARB_uniform_buffer_object), GL, 2002 },
+ { "GL_ARB_uniform_buffer_object", o(ARB_uniform_buffer_object), GL, 2009 },
{ "GL_ARB_vertex_array_bgra", o(EXT_vertex_array_bgra), GL, 2008 },
{ "GL_ARB_vertex_array_object", o(ARB_vertex_array_object), GL, 2006 },
{ "GL_ARB_vertex_buffer_object", o(dummy_true), GL, 2003 },
diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c
index 8dc47306f..67732521c 100644
--- a/mesalib/src/mesa/main/get.c
+++ b/mesalib/src/mesa/main/get.c
@@ -289,6 +289,12 @@ static const int extra_ARB_sampler_objects[] = {
EXTRA_END
};
+static const int extra_ARB_uniform_buffer_object_and_geometry_shader[] = {
+ EXT(ARB_uniform_buffer_object),
+ EXT(ARB_geometry_shader4),
+ EXTRA_END
+};
+
EXTRA_EXT(ARB_ES2_compatibility);
EXTRA_EXT(ARB_texture_cube_map);
@@ -335,6 +341,7 @@ EXTRA_EXT(EXT_framebuffer_sRGB);
EXTRA_EXT(ARB_texture_buffer_object);
EXTRA_EXT(OES_EGL_image_external);
EXTRA_EXT(ARB_blend_func_extended);
+EXTRA_EXT(ARB_uniform_buffer_object);
static const int
extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program[] = {
@@ -1321,6 +1328,31 @@ static const struct value_desc values[] = {
{ GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, CONTEXT_INT(Const.MaxDualSourceDrawBuffers), extra_ARB_blend_func_extended },
+ /* GL_ARB_uniform_buffer_object */
+ { GL_MAX_VERTEX_UNIFORM_BLOCKS, CONTEXT_INT(Const.VertexProgram.MaxUniformBlocks),
+ extra_ARB_uniform_buffer_object },
+ { GL_MAX_FRAGMENT_UNIFORM_BLOCKS, CONTEXT_INT(Const.FragmentProgram.MaxUniformBlocks),
+ extra_ARB_uniform_buffer_object },
+ { GL_MAX_GEOMETRY_UNIFORM_BLOCKS, CONTEXT_INT(Const.GeometryProgram.MaxUniformBlocks),
+ extra_ARB_uniform_buffer_object_and_geometry_shader },
+ { GL_MAX_COMBINED_UNIFORM_BLOCKS, CONTEXT_INT(Const.MaxCombinedUniformBlocks),
+ extra_ARB_uniform_buffer_object },
+ { GL_MAX_UNIFORM_BLOCK_SIZE, CONTEXT_INT(Const.MaxUniformBlockSize),
+ extra_ARB_uniform_buffer_object },
+ { GL_MAX_UNIFORM_BUFFER_BINDINGS, CONTEXT_INT(Const.MaxUniformBufferBindings),
+ extra_ARB_uniform_buffer_object },
+
+ { GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, CONTEXT_INT(Const.VertexProgram.MaxCombinedUniformComponents),
+ extra_ARB_uniform_buffer_object },
+ { GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, CONTEXT_INT(Const.FragmentProgram.MaxCombinedUniformComponents),
+ extra_ARB_uniform_buffer_object },
+ { GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS, CONTEXT_INT(Const.GeometryProgram.MaxCombinedUniformComponents),
+ extra_ARB_uniform_buffer_object_and_geometry_shader },
+ { GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, CONTEXT_INT(Const.UniformBufferOffsetAlignment),
+ extra_ARB_uniform_buffer_object },
+
+ { GL_UNIFORM_BUFFER_BINDING, LOC_CUSTOM, TYPE_INT, 0, extra_ARB_uniform_buffer_object },
+
#endif /* FEATURE_GL */
};
@@ -1771,6 +1803,10 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
v->value_int = samp ? samp->Name : 0;
}
break;
+ /* GL_ARB_uniform_buffer_object */
+ case GL_UNIFORM_BUFFER_BINDING:
+ v->value_int = ctx->UniformBuffer->Name;
+ break;
}
}
@@ -2530,6 +2566,30 @@ find_value_indexed(const char *func, GLenum pname, int index, union value *v)
goto invalid_enum;
v->value_int = ctx->TransformFeedback.CurrentObject->BufferNames[index];
return TYPE_INT;
+
+ case GL_UNIFORM_BUFFER_BINDING:
+ if (index >= ctx->Const.MaxUniformBufferBindings)
+ goto invalid_value;
+ if (!ctx->Extensions.ARB_uniform_buffer_object)
+ goto invalid_enum;
+ v->value_int = ctx->UniformBufferBindings[index].BufferObject->Name;
+ return TYPE_INT;
+
+ case GL_UNIFORM_BUFFER_START:
+ if (index >= ctx->Const.MaxUniformBufferBindings)
+ goto invalid_value;
+ if (!ctx->Extensions.ARB_uniform_buffer_object)
+ goto invalid_enum;
+ v->value_int = ctx->UniformBufferBindings[index].Offset;
+ return TYPE_INT;
+
+ case GL_UNIFORM_BUFFER_SIZE:
+ if (index >= ctx->Const.MaxUniformBufferBindings)
+ goto invalid_value;
+ if (!ctx->Extensions.ARB_uniform_buffer_object)
+ goto invalid_enum;
+ v->value_int = ctx->UniformBufferBindings[index].Size;
+ return TYPE_INT;
}
invalid_enum:
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index d52ab151a..def0db1aa 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -2709,6 +2709,9 @@ struct gl_program_constants
/* ES 2.0 and GL_ARB_ES2_compatibility */
struct gl_precision LowFloat, MediumFloat, HighFloat;
struct gl_precision LowInt, MediumInt, HighInt;
+ /* GL_ARB_uniform_buffer_object */
+ GLuint MaxUniformBlocks;
+ GLuint MaxCombinedUniformComponents;
};
@@ -2774,6 +2777,15 @@ struct gl_constants
GLuint MaxVertexVaryingComponents; /**< Between vert and geom shader */
GLuint MaxGeometryVaryingComponents; /**< Between geom and frag shader */
+ /** @{
+ * GL_ARB_uniform_buffer_object
+ */
+ GLuint MaxCombinedUniformBlocks;
+ GLuint MaxUniformBufferBindings;
+ GLuint MaxUniformBlockSize;
+ GLuint UniformBufferOffsetAlignment;
+ /** @} */
+
/** GL_ARB_geometry_shader4 */
GLuint MaxGeometryOutputVertices;
GLuint MaxGeometryTotalOutputComponents;
@@ -3283,6 +3295,20 @@ struct gl_driver_flags
GLbitfield NewArray; /**< Vertex array state */
};
+struct gl_uniform_buffer_binding
+{
+ struct gl_buffer_object *BufferObject;
+ /** Start of uniform block data in the buffer */
+ GLintptr Offset;
+ /** Size of data allowed to be referenced from the buffer (in bytes) */
+ GLsizeiptr Size;
+ /**
+ * glBindBufferBase() indicates that the Size should be ignored and only
+ * limited by the current size of the BufferObject.
+ */
+ GLboolean AutomaticSize;
+};
+
/**
* Mesa rendering context.
*
@@ -3418,6 +3444,21 @@ struct gl_context
struct gl_buffer_object *CopyReadBuffer; /**< GL_ARB_copy_buffer */
struct gl_buffer_object *CopyWriteBuffer; /**< GL_ARB_copy_buffer */
+
+ /**
+ * Current GL_ARB_uniform_buffer_object binding referenced by
+ * GL_UNIFORM_BUFFER target for glBufferData, glMapBuffer, etc.
+ */
+ struct gl_buffer_object *UniformBuffer;
+
+ /**
+ * Array of uniform buffers for GL_ARB_uniform_buffer_object and GL 3.1.
+ * This is set up using glBindBufferRange() or glBindBufferBase(). They are
+ * associated with uniform blocks by glUniformBlockBinding()'s state in the
+ * shader program.
+ */
+ struct gl_uniform_buffer_binding *UniformBufferBindings;
+
/*@}*/
struct gl_meta_state *Meta; /**< for "meta" operations */
diff --git a/mesalib/src/mesa/main/transformfeedback.c b/mesalib/src/mesa/main/transformfeedback.c
index 1bd76d130..84c409185 100644
--- a/mesalib/src/mesa/main/transformfeedback.c
+++ b/mesalib/src/mesa/main/transformfeedback.c
@@ -291,8 +291,6 @@ _mesa_init_transform_feedback_dispatch(struct _glapi_table *disp)
/* EXT_transform_feedback */
SET_BeginTransformFeedbackEXT(disp, _mesa_BeginTransformFeedback);
SET_EndTransformFeedbackEXT(disp, _mesa_EndTransformFeedback);
- SET_BindBufferRangeEXT(disp, _mesa_BindBufferRange);
- SET_BindBufferBaseEXT(disp, _mesa_BindBufferBase);
SET_BindBufferOffsetEXT(disp, _mesa_BindBufferOffsetEXT);
SET_TransformFeedbackVaryingsEXT(disp, _mesa_TransformFeedbackVaryings);
SET_GetTransformFeedbackVaryingEXT(disp, _mesa_GetTransformFeedbackVarying);
@@ -431,18 +429,14 @@ bind_buffer_range(struct gl_context *ctx, GLuint index,
* Specify a buffer object to receive vertex shader results. Plus,
* specify the starting offset to place the results, and max size.
*/
-void GLAPIENTRY
-_mesa_BindBufferRange(GLenum target, GLuint index,
- GLuint buffer, GLintptr offset, GLsizeiptr size)
+void
+_mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,
+ GLuint index,
+ struct gl_buffer_object *bufObj,
+ GLintptr offset,
+ GLsizeiptr size)
{
struct gl_transform_feedback_object *obj;
- struct gl_buffer_object *bufObj;
- GET_CURRENT_CONTEXT(ctx);
-
- if (target != GL_TRANSFORM_FEEDBACK_BUFFER) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferRange(target)");
- return;
- }
obj = ctx->TransformFeedback.CurrentObject;
@@ -457,8 +451,8 @@ _mesa_BindBufferRange(GLenum target, GLuint index,
return;
}
- if ((size <= 0) || (size & 0x3)) {
- /* must be positive and multiple of four */
+ if (size & 0x3) {
+ /* must a multiple of four */
_mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(size=%d)", (int) size);
return;
}
@@ -470,25 +464,6 @@ _mesa_BindBufferRange(GLenum target, GLuint index,
return;
}
- if (buffer == 0) {
- bufObj = ctx->Shared->NullBufferObj;
- } else {
- bufObj = _mesa_lookup_bufferobj(ctx, buffer);
- }
-
- if (!bufObj) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBindBufferRange(invalid buffer=%u)", buffer);
- return;
- }
-
- if (offset + size > bufObj->Size) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glBindBufferRange(offset + size %d > buffer size %d)",
- (int) (offset + size), (int) (bufObj->Size));
- return;
- }
-
bind_buffer_range(ctx, index, bufObj, offset, size);
}
@@ -497,18 +472,13 @@ _mesa_BindBufferRange(GLenum target, GLuint index,
* Specify a buffer object to receive vertex shader results.
* As above, but start at offset = 0.
*/
-void GLAPIENTRY
-_mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer)
+void
+_mesa_bind_buffer_base_transform_feedback(struct gl_context *ctx,
+ GLuint index,
+ struct gl_buffer_object *bufObj)
{
struct gl_transform_feedback_object *obj;
- struct gl_buffer_object *bufObj;
GLsizeiptr size;
- GET_CURRENT_CONTEXT(ctx);
-
- if (target != GL_TRANSFORM_FEEDBACK_BUFFER) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferBase(target)");
- return;
- }
obj = ctx->TransformFeedback.CurrentObject;
@@ -523,18 +493,6 @@ _mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer)
return;
}
- if (buffer == 0) {
- bufObj = ctx->Shared->NullBufferObj;
- } else {
- bufObj = _mesa_lookup_bufferobj(ctx, buffer);
- }
-
- if (!bufObj) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBindBufferBase(invalid buffer=%u)", buffer);
- return;
- }
-
/* default size is the buffer size rounded down to nearest
* multiple of four.
*/
diff --git a/mesalib/src/mesa/main/transformfeedback.h b/mesalib/src/mesa/main/transformfeedback.h
index 7d63de017..85f4cbc77 100644
--- a/mesalib/src/mesa/main/transformfeedback.h
+++ b/mesalib/src/mesa/main/transformfeedback.h
@@ -60,12 +60,17 @@ _mesa_BeginTransformFeedback(GLenum mode);
extern void GLAPIENTRY
_mesa_EndTransformFeedback(void);
-extern void GLAPIENTRY
-_mesa_BindBufferRange(GLenum target, GLuint index,
- GLuint buffer, GLintptr offset, GLsizeiptr size);
+extern void
+_mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx,
+ GLuint index,
+ struct gl_buffer_object *bufObj,
+ GLintptr offset,
+ GLsizeiptr size);
-extern void GLAPIENTRY
-_mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer);
+extern void
+_mesa_bind_buffer_base_transform_feedback(struct gl_context *ctx,
+ GLuint index,
+ struct gl_buffer_object *bufObj);
extern void GLAPIENTRY
_mesa_BindBufferOffsetEXT(GLenum target, GLuint index, GLuint buffer,