typedef void (GLAPIENTRY *array_func)( const void * );
typedef struct {
- const struct gl_vertex_attrib_array *array;
+ const struct gl_array_attributes *array;
const struct gl_vertex_buffer_binding *binding;
int offset;
} AEarray;
typedef void (GLAPIENTRY *attrib_func)( GLuint indx, const void *data );
typedef struct {
- const struct gl_vertex_attrib_array *array;
+ const struct gl_array_attributes *array;
const struct gl_vertex_buffer_binding *binding;
attrib_func func;
GLuint index;
typedef struct {
AEarray arrays[32];
AEattrib attribs[VERT_ATTRIB_MAX + 1];
- GLuint NewState;
/* List of VBOs we need to map before executing ArrayElements */
struct gl_buffer_object *vbo[VERT_ATTRIB_MAX];
GLuint nr_vbos;
GLboolean mapped_vbos; /**< Any currently mapped VBOs? */
+
+ bool dirty_state;
} AEcontext;
/** Cast wrapper */
-static INLINE AEcontext *
+static inline AEcontext *
AE_CONTEXT(struct gl_context *ctx)
{
return (AEcontext *) ctx->aelt_context;
* in the range [0, 7]. Luckily these type tokens are sequentially
* numbered in gl.h, except for GL_DOUBLE.
*/
-static INLINE int
+static inline int
TYPE_IDX(GLenum t)
{
return t == GL_DOUBLE ? 7 : t & 7;
}
+bool
+_ae_is_state_dirty(struct gl_context *ctx)
+{
+ return AE_CONTEXT(ctx)->dirty_state;
+}
+
+
#define NUM_TYPES 8
CALL_VertexAttribI4uivEXT(GET_DISPATCH(), (index, v));
}
+/* GL_DOUBLE unconverted attributes */
+
+static void GLAPIENTRY
+VertexAttribL1dv(GLuint index, const GLdouble *v)
+{
+ CALL_VertexAttribL1dv(GET_DISPATCH(), (index, v));
+}
+
+static void GLAPIENTRY
+VertexAttribL2dv(GLuint index, const GLdouble *v)
+{
+ CALL_VertexAttribL2dv(GET_DISPATCH(), (index, v));
+}
+
+static void GLAPIENTRY
+VertexAttribL3dv(GLuint index, const GLdouble *v)
+{
+ CALL_VertexAttribL3dv(GET_DISPATCH(), (index, v));
+}
+
+static void GLAPIENTRY
+VertexAttribL4dv(GLuint index, const GLdouble *v)
+{
+ CALL_VertexAttribL4dv(GET_DISPATCH(), (index, v));
+}
/*
* Array [unnormalized/normalized/integer][size][type] of VertexAttrib
* functions
*/
-static attrib_func AttribFuncsARB[3][4][NUM_TYPES] = {
+static const attrib_func AttribFuncsARB[4][4][NUM_TYPES] = {
{
/* non-normalized */
{
NULL, /* GL_FLOAT */
NULL /* GL_DOUBLE */
}
+ },
+ {
+ /* double-valued */
+ {
+ /* size 1 */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ (attrib_func) VertexAttribL1dv,
+ },
+ {
+ /* size 2 */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ (attrib_func) VertexAttribL2dv,
+ },
+ {
+ /* size 3 */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ (attrib_func) VertexAttribL3dv,
+ },
+ {
+ /* size 4 */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ (attrib_func) VertexAttribL4dv,
+ }
}
+
};
if (!ctx->aelt_context)
return GL_FALSE;
- AE_CONTEXT(ctx)->NewState = ~0;
+ AE_CONTEXT(ctx)->dirty_state = true;
return GL_TRUE;
}
actx->nr_vbos = 0;
/* conventional vertex arrays */
- if (vao->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) {
+ if (vao->Enabled & VERT_BIT_COLOR_INDEX) {
aa->array = &vao->VertexAttrib[VERT_ATTRIB_COLOR_INDEX];
- aa->binding = &vao->VertexBinding[aa->array->VertexBinding];
- aa->offset = IndexFuncs[TYPE_IDX(aa->array->Type)];
+ aa->binding = &vao->BufferBinding[aa->array->BufferBindingIndex];
+ aa->offset = IndexFuncs[TYPE_IDX(aa->array->Format.Type)];
check_vbo(actx, aa->binding->BufferObj);
aa++;
}
- if (vao->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) {
+ if (vao->Enabled & VERT_BIT_EDGEFLAG) {
aa->array = &vao->VertexAttrib[VERT_ATTRIB_EDGEFLAG];
- aa->binding = &vao->VertexBinding[aa->array->VertexBinding];
+ aa->binding = &vao->BufferBinding[aa->array->BufferBindingIndex];
aa->offset = _gloffset_EdgeFlagv;
check_vbo(actx, aa->binding->BufferObj);
aa++;
}
- if (vao->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) {
+ if (vao->Enabled & VERT_BIT_NORMAL) {
aa->array = &vao->VertexAttrib[VERT_ATTRIB_NORMAL];
- aa->binding = &vao->VertexBinding[aa->array->VertexBinding];
- aa->offset = NormalFuncs[TYPE_IDX(aa->array->Type)];
+ aa->binding = &vao->BufferBinding[aa->array->BufferBindingIndex];
+ aa->offset = NormalFuncs[TYPE_IDX(aa->array->Format.Type)];
check_vbo(actx, aa->binding->BufferObj);
aa++;
}
- if (vao->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) {
+ if (vao->Enabled & VERT_BIT_COLOR0) {
aa->array = &vao->VertexAttrib[VERT_ATTRIB_COLOR0];
- aa->binding = &vao->VertexBinding[aa->array->VertexBinding];
- aa->offset = ColorFuncs[aa->array->Size-3][TYPE_IDX(aa->array->Type)];
+ aa->binding = &vao->BufferBinding[aa->array->BufferBindingIndex];
+ aa->offset = ColorFuncs[aa->array->Format.Size-3][TYPE_IDX(aa->array->Format.Type)];
check_vbo(actx, aa->binding->BufferObj);
aa++;
}
- if (vao->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) {
+ if (vao->Enabled & VERT_BIT_COLOR1) {
aa->array = &vao->VertexAttrib[VERT_ATTRIB_COLOR1];
- aa->binding = &vao->VertexBinding[aa->array->VertexBinding];
- aa->offset = SecondaryColorFuncs[TYPE_IDX(aa->array->Type)];
+ aa->binding = &vao->BufferBinding[aa->array->BufferBindingIndex];
+ aa->offset = SecondaryColorFuncs[TYPE_IDX(aa->array->Format.Type)];
check_vbo(actx, aa->binding->BufferObj);
aa++;
}
- if (vao->VertexAttrib[VERT_ATTRIB_FOG].Enabled) {
+ if (vao->Enabled & VERT_BIT_FOG) {
aa->array = &vao->VertexAttrib[VERT_ATTRIB_FOG];
- aa->binding = &vao->VertexBinding[aa->array->VertexBinding];
- aa->offset = FogCoordFuncs[TYPE_IDX(aa->array->Type)];
+ aa->binding = &vao->BufferBinding[aa->array->BufferBindingIndex];
+ aa->offset = FogCoordFuncs[TYPE_IDX(aa->array->Format.Type)];
check_vbo(actx, aa->binding->BufferObj);
aa++;
}
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
- struct gl_vertex_attrib_array *attribArray =
- &vao->VertexAttrib[VERT_ATTRIB_TEX(i)];
- if (attribArray->Enabled) {
+ if (vao->Enabled & VERT_BIT_TEX(i)) {
+ struct gl_array_attributes *attribArray =
+ &vao->VertexAttrib[VERT_ATTRIB_TEX(i)];
/* NOTE: we use generic glVertexAttribNV functions here.
* If we ever remove GL_NV_vertex_program this will have to change.
*/
at->array = attribArray;
- at->binding = &vao->VertexBinding[attribArray->VertexBinding];
- ASSERT(!at->array->Normalized);
- at->func = AttribFuncsNV[at->array->Normalized]
- [at->array->Size-1]
- [TYPE_IDX(at->array->Type)];
+ at->binding = &vao->BufferBinding[attribArray->BufferBindingIndex];
+ assert(!at->array->Format.Normalized);
+ at->func = AttribFuncsNV[at->array->Format.Normalized]
+ [at->array->Format.Size-1]
+ [TYPE_IDX(at->array->Format.Type)];
at->index = VERT_ATTRIB_TEX0 + i;
check_vbo(actx, at->binding->BufferObj);
at++;
/* generic vertex attribute arrays */
for (i = 1; i < VERT_ATTRIB_GENERIC_MAX; i++) { /* skip zero! */
- struct gl_vertex_attrib_array *attribArray =
- &vao->VertexAttrib[VERT_ATTRIB_GENERIC(i)];
- if (attribArray->Enabled) {
+ if (vao->Enabled & VERT_BIT_GENERIC(i)) {
+ struct gl_array_attributes *attribArray =
+ &vao->VertexAttrib[VERT_ATTRIB_GENERIC(i)];
GLint intOrNorm;
at->array = attribArray;
- at->binding = &vao->VertexBinding[attribArray->VertexBinding];
+ at->binding = &vao->BufferBinding[attribArray->BufferBindingIndex];
/* Note: we can't grab the _glapi_Dispatch->VertexAttrib1fvNV
* function pointer here (for float arrays) since the pointer may
* change from one execution of _ae_ArrayElement() to
* the next. Doing so caused UT to break.
*/
- if (at->array->Integer)
+ if (at->array->Format.Doubles)
+ intOrNorm = 3;
+ else if (at->array->Format.Integer)
intOrNorm = 2;
- else if (at->array->Normalized)
+ else if (at->array->Format.Normalized)
intOrNorm = 1;
else
intOrNorm = 0;
at->func = AttribFuncsARB[intOrNorm]
- [at->array->Size-1]
- [TYPE_IDX(at->array->Type)];
+ [at->array->Format.Size-1]
+ [TYPE_IDX(at->array->Format.Type)];
at->index = i;
check_vbo(actx, at->binding->BufferObj);
}
/* finally, vertex position */
- if (vao->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) {
+ if (vao->Enabled & VERT_BIT_GENERIC0) {
/* Use glVertex(v) instead of glVertexAttrib(0, v) to be sure it's
* issued as the last (provoking) attribute).
*/
aa->array = &vao->VertexAttrib[VERT_ATTRIB_GENERIC0];
- aa->binding = &vao->VertexBinding[aa->array->VertexBinding];
- assert(aa->array->Size >= 2); /* XXX fix someday? */
- aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
+ aa->binding = &vao->BufferBinding[aa->array->BufferBindingIndex];
+ assert(aa->array->Format.Size >= 2); /* XXX fix someday? */
+ aa->offset = VertexFuncs[aa->array->Format.Size-2][TYPE_IDX(aa->array->Format.Type)];
check_vbo(actx, aa->binding->BufferObj);
aa++;
}
- else if (vao->VertexAttrib[VERT_ATTRIB_POS].Enabled) {
+ else if (vao->Enabled & VERT_BIT_POS) {
aa->array = &vao->VertexAttrib[VERT_ATTRIB_POS];
- aa->binding = &vao->VertexBinding[aa->array->VertexBinding];
- aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
+ aa->binding = &vao->BufferBinding[aa->array->BufferBindingIndex];
+ aa->offset = VertexFuncs[aa->array->Format.Size-2][TYPE_IDX(aa->array->Format.Type)];
check_vbo(actx, aa->binding->BufferObj);
aa++;
}
check_vbo(actx, vao->IndexBufferObj);
- ASSERT(at - actx->attribs <= VERT_ATTRIB_MAX);
- ASSERT(aa - actx->arrays < 32);
+ assert(at - actx->attribs <= VERT_ATTRIB_MAX);
+ assert(aa - actx->arrays < 32);
at->func = NULL; /* terminate the list */
aa->offset = -1; /* terminate the list */
- actx->NewState = 0;
+ actx->dirty_state = false;
}
if (actx->mapped_vbos)
return;
- if (actx->NewState)
+ if (actx->dirty_state)
_ae_update_state(ctx);
for (i = 0; i < actx->nr_vbos; i++)
if (!actx->mapped_vbos)
return;
- assert (!actx->NewState);
+ assert (!actx->dirty_state);
for (i = 0; i < actx->nr_vbos; i++)
ctx->Driver.UnmapBuffer(ctx, actx->vbo[i], MAP_INTERNAL);
}
+void
+_mesa_array_element(struct gl_context *ctx,
+ struct _glapi_table *disp, GLint elt)
+{
+ const AEcontext *actx = AE_CONTEXT(ctx);
+
+ if (actx->dirty_state)
+ _ae_update_state(ctx);
+
+ /* emit generic attribute elements */
+ for (const AEattrib *at = actx->attribs; at->func; at++) {
+ const GLubyte *src
+ = ADD_POINTERS(at->binding->BufferObj->Mappings[MAP_INTERNAL].Pointer,
+ _mesa_vertex_attrib_address(at->array, at->binding))
+ + elt * at->binding->Stride;
+ at->func(at->index, src);
+ }
+
+ /* emit conventional arrays elements */
+ for (const AEarray *aa = actx->arrays; aa->offset != -1 ; aa++) {
+ const GLubyte *src
+ = ADD_POINTERS(aa->binding->BufferObj->Mappings[MAP_INTERNAL].Pointer,
+ _mesa_vertex_attrib_address(aa->array, aa->binding))
+ + elt * aa->binding->Stride;
+ CALL_by_offset(disp, (array_func), aa->offset, ((const void *) src));
+ }
+}
+
+
/**
* Called via glArrayElement() and glDrawArrays().
* Issue the glNormal, glVertex, glColor, glVertexAttrib, etc functions
{
GET_CURRENT_CONTEXT(ctx);
const AEcontext *actx = AE_CONTEXT(ctx);
- const AEarray *aa;
- const AEattrib *at;
const struct _glapi_table * const disp = GET_DISPATCH();
GLboolean do_map;
return;
}
- if (actx->NewState) {
+ if (actx->dirty_state) {
assert(!actx->mapped_vbos);
_ae_update_state(ctx);
}
if (do_map)
_ae_map_vbos(ctx);
- /* emit generic attribute elements */
- for (at = actx->attribs; at->func; at++) {
- const GLubyte *src
- = ADD_POINTERS(at->binding->BufferObj->Mappings[MAP_INTERNAL].Pointer,
- _mesa_vertex_attrib_address(at->array, at->binding))
- + elt * at->binding->Stride;
- at->func(at->index, src);
- }
-
- /* emit conventional arrays elements */
- for (aa = actx->arrays; aa->offset != -1 ; aa++) {
- const GLubyte *src
- = ADD_POINTERS(aa->binding->BufferObj->Mappings[MAP_INTERNAL].Pointer,
- _mesa_vertex_attrib_address(aa->array, aa->binding))
- + elt * aa->binding->Stride;
- CALL_by_offset(disp, (array_func), aa->offset, ((const void *) src));
- }
+ _mesa_array_element(ctx, (struct _glapi_table *)disp, elt);
if (do_map)
_ae_unmap_vbos(ctx);
void
-_ae_invalidate_state(struct gl_context *ctx, GLuint new_state)
+_ae_invalidate_state(struct gl_context *ctx)
{
AEcontext *actx = AE_CONTEXT(ctx);
* Luckily, neither the drivers nor tnl muck with the state that
* concerns us here:
*/
- new_state &= _NEW_ARRAY | _NEW_PROGRAM;
- if (new_state) {
- assert(!actx->mapped_vbos);
- actx->NewState |= new_state;
- }
+ assert(ctx->NewState & _NEW_ARRAY);
+
+ assert(!actx->mapped_vbos);
+ actx->dirty_state = true;
}