vertex arrays.
void _ac_DestroyContext( GLcontext *ctx )
{
+ struct gl_buffer_object *nullObj = ctx->Array.NullBufferObj;
ACcontext *ac = AC_CONTEXT(ctx);
GLint i;
- if (ac->Cache.Vertex.Ptr) FREE( ac->Cache.Vertex.Ptr );
- if (ac->Cache.Normal.Ptr) FREE( ac->Cache.Normal.Ptr );
- if (ac->Cache.Color.Ptr) FREE( ac->Cache.Color.Ptr );
- if (ac->Cache.SecondaryColor.Ptr) FREE( ac->Cache.SecondaryColor.Ptr );
- if (ac->Cache.EdgeFlag.Ptr) FREE( ac->Cache.EdgeFlag.Ptr );
- if (ac->Cache.Index.Ptr) FREE( ac->Cache.Index.Ptr );
- if (ac->Cache.FogCoord.Ptr) FREE( ac->Cache.FogCoord.Ptr );
+ /* only free vertex data if it's really a pointer to vertex data and
+ * not an offset into a buffer object.
+ */
+ if (ac->Cache.Vertex.Ptr && ac->Cache.Vertex.BufferObj == nullObj)
+ FREE( ac->Cache.Vertex.Ptr );
+ if (ac->Cache.Normal.Ptr && ac->Cache.Normal.BufferObj == nullObj)
+ FREE( ac->Cache.Normal.Ptr );
+ if (ac->Cache.Color.Ptr && ac->Cache.Color.BufferObj == nullObj)
+ FREE( ac->Cache.Color.Ptr );
+ if (ac->Cache.SecondaryColor.Ptr && ac->Cache.SecondaryColor.BufferObj == nullObj)
+ FREE( ac->Cache.SecondaryColor.Ptr );
+ if (ac->Cache.EdgeFlag.Ptr && ac->Cache.EdgeFlag.BufferObj == nullObj)
+ FREE( ac->Cache.EdgeFlag.Ptr );
+ if (ac->Cache.Index.Ptr && ac->Cache.Index.BufferObj == nullObj)
+ FREE( ac->Cache.Index.Ptr );
+ if (ac->Cache.FogCoord.Ptr && ac->Cache.FogCoord.BufferObj == nullObj)
+ FREE( ac->Cache.FogCoord.Ptr );
for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
- if (ac->Cache.TexCoord[i].Ptr)
+ if (ac->Cache.TexCoord[i].Ptr && ac->Cache.TexCoord[i].BufferObj == nullObj)
FREE( ac->Cache.TexCoord[i].Ptr );
}
for (i = 0; i < VERT_ATTRIB_MAX; i++) {
- if (ac->Cache.Attrib[i].Ptr)
+ if (ac->Cache.Attrib[i].Ptr && ac->Cache.Attrib[i].BufferObj == nullObj)
FREE( ac->Cache.Attrib[i].Ptr );
}
- if (ac->Elts) FREE( ac->Elts );
+ if (ac->Elts)
+ FREE( ac->Elts );
/* Free the context structure itself */
FREE(ac);
#include "array_cache/ac_context.h"
#include "math/m_translate.h"
-#define STRIDE_ARRAY( array, offset ) \
-do { \
- GLubyte *tmp = (array).Ptr; \
- tmp += (offset) * (array).StrideB; \
- (array).Ptr = tmp; \
+#define STRIDE_ARRAY( array, offset ) \
+do { \
+ GLubyte *tmp = ADD_POINTERS( (array).BufferObj->Data, (array).Ptr ) \
+ + (offset) * (array).StrideB; \
+ (array).Ptr = tmp; \
} while (0)
+
/* Set the array pointer back to its source when the cached data is
* invalidated:
*/
-
static void reset_texcoord( GLcontext *ctx, GLuint unit )
{
ACcontext *ac = AC_CONTEXT(ctx);
struct gl_client_array *to,
struct gl_client_array *from )
{
+ GLubyte *dest;
+ const GLubyte *src;
ACcontext *ac = AC_CONTEXT(ctx);
if (type == 0)
type = from->Type;
+ /* The dest and source data addresses are the sum of the buffer
+ * object's start plus the vertex array pointer/offset.
+ */
+ dest = ADD_POINTERS(to->BufferObj->Data, to->Ptr);
+ src = ADD_POINTERS(from->BufferObj->Data, from->Ptr);
+
switch (type) {
case GL_FLOAT:
- _math_trans_4fc( (GLfloat (*)[4]) to->Ptr,
- from->Ptr,
+ _math_trans_4fc( (GLfloat (*)[4]) dest,
+ src,
from->StrideB,
from->Type,
from->Size,
break;
case GL_UNSIGNED_BYTE:
- _math_trans_4ub( (GLubyte (*)[4]) to->Ptr,
- from->Ptr,
+ _math_trans_4ub( (GLubyte (*)[4]) dest,
+ src,
from->StrideB,
from->Type,
from->Size,
break;
case GL_UNSIGNED_SHORT:
- _math_trans_4us( (GLushort (*)[4]) to->Ptr,
- from->Ptr,
+ _math_trans_4us( (GLushort (*)[4]) dest,
+ src,
from->StrideB,
from->Type,
from->Size,
#include "glheader.h"
#include "GL/osmesa.h"
#include "buffers.h"
+#include "bufferobj.h"
#include "context.h"
#include "colormac.h"
#include "depth.h"
ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
+#if FEATURE_ARB_vertex_buffer_object
+ ctx->Driver.NewBufferObject = _mesa_new_buffer_object;
+ ctx->Driver.DeleteBuffer = _mesa_delete_buffer_object;
+ ctx->Driver.BindBuffer = NULL;
+ ctx->Driver.BufferData = _mesa_buffer_data;
+ ctx->Driver.BufferSubData = _mesa_buffer_subdata;
+ ctx->Driver.MapBuffer = _mesa_buffer_map;
+ ctx->Driver.UnmapBuffer = NULL;
+#endif
+
swdd->SetBuffer = set_buffer;
/* RGB(A) span/pixel functions */
#include "glxheader.h"
+#include "bufferobj.h"
#include "context.h"
#include "colormac.h"
#include "depth.h"
static void
-finish( GLcontext *ctx )
+finish_or_flush( GLcontext *ctx )
{
#ifdef XFree86Server
/* NOT_NEEDED */
}
-static void
-flush( GLcontext *ctx )
-{
-#ifdef XFree86Server
- /* NOT_NEEDED */
-#else
- const XMesaContext xmesa = XMESA_CONTEXT(ctx);
- if (xmesa) {
- _glthread_LOCK_MUTEX(_xmesa_lock);
- XFlush( xmesa->display );
- _glthread_UNLOCK_MUTEX(_xmesa_lock);
- }
-#endif
-}
-
-
/*
* This chooses the color buffer for reading and writing spans, points,
#endif
-
+/*
+ * Every driver should implement a GetString function in order to
+ * return a meaningful GL_RENDERER string.
+ */
static const GLubyte *
get_string( GLcontext *ctx, GLenum name )
{
}
+/*
+ * We implement the glEnable function only because we care about
+ * dither enable/disable.
+ */
static void
enable( GLcontext *ctx, GLenum pname, GLboolean state )
{
TNLcontext *tnl;
struct swrast_device_driver *dd = _swrast_GetDeviceDriverReference( ctx );
+ /* Plug in our driver-specific functions here */
ctx->Driver.GetString = get_string;
ctx->Driver.GetBufferSize = get_buffer_size;
- ctx->Driver.Flush = flush;
- ctx->Driver.Finish = finish;
-
+ ctx->Driver.Flush = finish_or_flush;
+ ctx->Driver.Finish = finish_or_flush;
+ ctx->Driver.ClearIndex = clear_index;
+ ctx->Driver.ClearColor = clear_color;
+ ctx->Driver.IndexMask = index_mask;
+ ctx->Driver.ColorMask = color_mask;
+ ctx->Driver.Enable = enable;
+
/* Software rasterizer pixel paths:
*/
ctx->Driver.Accum = _swrast_Accum;
ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
-
- /* Statechange callbacks:
- */
- ctx->Driver.ClearIndex = clear_index;
- ctx->Driver.ClearColor = clear_color;
- ctx->Driver.IndexMask = index_mask;
- ctx->Driver.ColorMask = color_mask;
- ctx->Driver.Enable = enable;
-
+#if FEATURE_ARB_vertex_buffer_object
+ ctx->Driver.NewBufferObject = _mesa_new_buffer_object;
+ ctx->Driver.DeleteBuffer = _mesa_delete_buffer_object;
+ ctx->Driver.BindBuffer = NULL;
+ ctx->Driver.BufferData = _mesa_buffer_data;
+ ctx->Driver.BufferSubData = _mesa_buffer_subdata;
+ ctx->Driver.MapBuffer = _mesa_buffer_map;
+ ctx->Driver.UnmapBuffer = NULL;
+#endif
/* Initialize the TNL driver interface:
*/
-
/*
* Mesa 3-D graphics library
* Version: 5.1
_ae_update_state( ctx );
for (ta = actx->texarrays ; ta->func ; ta++) {
- ta->func( ta->unit + GL_TEXTURE0_ARB, (char *)ta->array->Ptr + elt * ta->array->StrideB );
+ GLubyte *src = ta->array->BufferObj->Data
+ + (GLuint) ta->array->Ptr
+ + elt * ta->array->StrideB;
+ ta->func( ta->unit + GL_TEXTURE0_ARB, src);
}
/* Must be last
*/
for (aa = actx->arrays ; aa->func ; aa++) {
- aa->func( (char *)aa->array->Ptr + elt * aa->array->StrideB );
+ GLubyte *src = aa->array->BufferObj->Data
+ + (GLuint) aa->array->Ptr
+ + elt * aa->array->StrideB;
+ aa->func( src );
}
}
/*@}*/
+/*
+ * For GL_ARB_vertex_buffer_object we need to treat vertex array pointers
+ * as offsets into buffer stores. Since the vertex array pointer and
+ * buffer store pointer are both pointers and we need to add them, we use
+ * this macro.
+ * Both pointers/offsets are expressed in bytes.
+ */
+#define ADD_POINTERS(A, B) ( (A) + (unsigned long) (B) )
+
+
/**********************************************************************/
/** \name [Pseudo] static array declaration.
*
GLenum Access;
GLvoid *Pointer; /**< Only valid while buffer is mapped */
GLuint Size; /**< Size of data array in bytes */
- GLubyte *Data; /**< The storage */
+ GLubyte *Data; /**< The storage */
};
-
/*
* Mesa 3-D graphics library
* Version: 5.1
struct gl_client_array *tmp;
GLboolean is_writeable = 0;
struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
+ GLubyte *data;
tmp = _ac_import_vertex(ctx,
GL_FLOAT,
writeable,
&is_writeable);
- inputs->Obj.data = (GLfloat (*)[4]) tmp->Ptr;
- inputs->Obj.start = (GLfloat *) tmp->Ptr;
+ data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
+ inputs->Obj.data = (GLfloat (*)[4]) data;
+ inputs->Obj.start = (GLfloat *) data;
inputs->Obj.stride = tmp->StrideB;
inputs->Obj.size = tmp->Size;
inputs->Obj.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
struct gl_client_array *tmp;
GLboolean is_writeable = 0;
struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
+ GLubyte *data;
tmp = _ac_import_normal(ctx, GL_FLOAT,
stride ? 3*sizeof(GLfloat) : 0, writeable,
&is_writeable);
- inputs->Normal.data = (GLfloat (*)[4]) tmp->Ptr;
- inputs->Normal.start = (GLfloat *) tmp->Ptr;
+ data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
+ inputs->Normal.data = (GLfloat (*)[4]) data;
+ inputs->Normal.start = (GLfloat *) data;
inputs->Normal.stride = tmp->StrideB;
inputs->Normal.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
if (inputs->Normal.stride != 3*sizeof(GLfloat))
GLboolean stride )
{
struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
- struct gl_client_array *tmp;
+ struct gl_client_array *tmp;
GLboolean is_writeable = 0;
+ GLubyte *data;
tmp = _ac_import_fogcoord(ctx, GL_FLOAT,
stride ? sizeof(GLfloat) : 0, writeable,
&is_writeable);
- inputs->FogCoord.data = (GLfloat (*)[4]) tmp->Ptr;
- inputs->FogCoord.start = (GLfloat *) tmp->Ptr;
+ data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
+ inputs->FogCoord.data = (GLfloat (*)[4]) data;
+ inputs->FogCoord.start = (GLfloat *) data;
inputs->FogCoord.stride = tmp->StrideB;
inputs->FogCoord.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
if (inputs->FogCoord.stride != sizeof(GLfloat))
struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
struct gl_client_array *tmp;
GLboolean is_writeable = 0;
+ GLubyte *data;
tmp = _ac_import_index(ctx, GL_UNSIGNED_INT,
stride ? sizeof(GLuint) : 0, writeable,
&is_writeable);
- inputs->Index.data = (GLuint *) tmp->Ptr;
- inputs->Index.start = (GLuint *) tmp->Ptr;
+ data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
+ inputs->Index.data = (GLuint *) data;
+ inputs->Index.start = (GLuint *) data;
inputs->Index.stride = tmp->StrideB;
inputs->Index.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
if (inputs->Index.stride != sizeof(GLuint))
struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
struct gl_client_array *tmp;
GLboolean is_writeable = 0;
+ GLubyte *data;
tmp = _ac_import_texcoord(ctx, unit, GL_FLOAT,
stride ? 4 * sizeof(GLfloat) : 0,
writeable,
&is_writeable);
- inputs->TexCoord[unit].data = (GLfloat (*)[4]) tmp->Ptr;
- inputs->TexCoord[unit].start = (GLfloat *) tmp->Ptr;
+ data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
+ inputs->TexCoord[unit].data = (GLfloat (*)[4]) data;
+ inputs->TexCoord[unit].start = (GLfloat *) data;
inputs->TexCoord[unit].stride = tmp->StrideB;
inputs->TexCoord[unit].size = tmp->Size;
inputs->TexCoord[unit].flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
struct gl_client_array *tmp;
GLboolean is_writeable = 0;
+ GLubyte *data;
tmp = _ac_import_edgeflag(ctx, GL_UNSIGNED_BYTE,
stride ? sizeof(GLubyte) : 0,
0,
&is_writeable);
- inputs->EdgeFlag.data = (GLubyte *) tmp->Ptr;
- inputs->EdgeFlag.start = (GLubyte *) tmp->Ptr;
+ data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
+ inputs->EdgeFlag.data = (GLubyte *) data;
+ inputs->EdgeFlag.start = (GLubyte *) data;
inputs->EdgeFlag.stride = tmp->StrideB;
inputs->EdgeFlag.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
if (inputs->EdgeFlag.stride != sizeof(GLubyte))
struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
struct gl_client_array *tmp;
GLboolean is_writeable = 0;
+ GLubyte *data;
tmp = _ac_import_attrib(ctx, index, GL_FLOAT,
stride ? 4 * sizeof(GLfloat) : 0,
writeable,
&is_writeable);
- inputs->Attribs[index].data = (GLfloat (*)[4]) tmp->Ptr;
- inputs->Attribs[index].start = (GLfloat *) tmp->Ptr;
+ data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
+ inputs->Attribs[index].data = (GLfloat (*)[4]) data;
+ inputs->Attribs[index].start = (GLfloat *) data;
inputs->Attribs[index].stride = tmp->StrideB;
inputs->Attribs[index].size = tmp->Size;
inputs->Attribs[index].flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
GLuint start,
GLuint n )
{
+ GLubyte *fromData = ADD_POINTERS( from->Ptr, from->BufferObj->Data );
_tnl_trans_elt_1ui_tab[TYPE_IDX(from->Type)]( to,
- from->Ptr,
- from->StrideB,
- flags,
- elts,
- match,
- start,
- n );
+ fromData,
+ from->StrideB,
+ flags,
+ elts,
+ match,
+ start,
+ n );
}
GLuint start,
GLuint n )
{
+ GLubyte *fromData = ADD_POINTERS( from->Ptr, from->BufferObj->Data );
_tnl_trans_elt_1ub_tab[TYPE_IDX(from->Type)]( to,
- from->Ptr,
+ fromData,
from->StrideB,
flags,
elts,
GLuint start,
GLuint n )
{
+ GLubyte *fromData = ADD_POINTERS( from->Ptr, from->BufferObj->Data );
_tnl_trans_elt_4f_tab[from->Size][TYPE_IDX(from->Type)]( to,
- from->Ptr,
+ fromData,
from->StrideB,
flags,
elts,
GLuint start,
GLuint n )
{
+ GLubyte *fromData = ADD_POINTERS( from->Ptr, from->BufferObj->Data );
_tnl_trans_elt_4fc_tab[from->Size][TYPE_IDX(from->Type)]( to,
- from->Ptr,
+ fromData,
from->StrideB,
flags,
elts,
-
/*
* Mesa 3-D graphics library
* Version: 5.1
{
const GLfloat u1 = map->u1;
const GLfloat du = map->du;
- GLfloat (*to)[4] = (GLfloat (*)[4])dest->Ptr;
+ GLubyte *destData = ADD_POINTERS(dest->Ptr, dest->BufferObj->Data);
+ GLfloat (*to)[4] = (GLfloat (*)[4]) destData;
GLuint i;
ASSERT(dest->Type == GL_FLOAT);
const GLfloat du = map->du;
const GLfloat v1 = map->v1;
const GLfloat dv = map->dv;
- GLfloat (*to)[4] = (GLfloat (*)[4])dest->Ptr;
+ GLubyte *destData = ADD_POINTERS(dest->Ptr, dest->BufferObj->Data);
+ GLfloat (*to)[4] = (GLfloat (*)[4]) destData;
GLuint i;
ASSERT(dest->Type == GL_FLOAT);
if (req & VERT_BIT_COLOR0) {
GLuint generated = 0;
- if (copycount)
- copy_4f_stride( store->Attrib[VERT_ATTRIB_COLOR0] + IM->CopyStart,
- (GLfloat *)tmp->Color.Ptr,
- tmp->Color.StrideB,
- copycount );
+ if (copycount) {
+ GLubyte *destData = ADD_POINTERS(tmp->Color.Ptr, tmp->Color.BufferObj->Data);
+ copy_4f_stride( store->Attrib[VERT_ATTRIB_COLOR0] + IM->CopyStart,
+ (GLfloat *) destData,
+ tmp->Color.StrideB,
+ copycount );
+ }
tmp->Color.Ptr = (GLubyte *) (store->Attrib[VERT_ATTRIB_COLOR0] + IM->CopyStart);
tmp->Color.StrideB = 4 * sizeof(GLfloat);
tmp->Color.Stride = 0;
tmp->Color.StrideB = 4 * sizeof(GLfloat);
tmp->Color.Flags = 0;
+ tmp->Color.BufferObj = ctx->Array.NullBufferObj;
tmp->SecondaryColor.Ptr = NULL;
tmp->SecondaryColor.Type = GL_FLOAT;
tmp->SecondaryColor.Stride = 0;
tmp->SecondaryColor.StrideB = 4 * sizeof(GLfloat);
tmp->SecondaryColor.Flags = 0;
+ tmp->SecondaryColor.BufferObj = ctx->Array.NullBufferObj;
_mesa_vector4f_init( &tmp->FogCoord, 0, 0 );
_mesa_vector1ui_init( &tmp->Index, 0, 0 );