From 770169f230a197d969f64df76cfaee1f0e27874f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 26 Dec 2000 15:14:04 +0000 Subject: [PATCH] The array cache. --- src/mesa/array_cache/ac_context.c | 257 ++++++++++++++ src/mesa/array_cache/ac_context.h | 98 ++++++ src/mesa/array_cache/ac_import.c | 712 ++++++++++++++++++++++++++++++++++++++ src/mesa/array_cache/acache.h | 122 +++++++ 4 files changed, 1189 insertions(+) create mode 100644 src/mesa/array_cache/ac_context.c create mode 100644 src/mesa/array_cache/ac_context.h create mode 100644 src/mesa/array_cache/ac_import.c create mode 100644 src/mesa/array_cache/acache.h diff --git a/src/mesa/array_cache/ac_context.c b/src/mesa/array_cache/ac_context.c new file mode 100644 index 0000000..f3609eb --- /dev/null +++ b/src/mesa/array_cache/ac_context.c @@ -0,0 +1,257 @@ +/* $Id: ac_context.c,v 1.1 2000/12/26 15:14:04 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Author: + * Keith Whitwell + */ + +#include "glheader.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "mtypes.h" + +#include "array_cache/ac_context.h" + +static void _ac_fallbacks_init( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *cl; + GLuint i; + + cl = &ac->Fallback.Normal; + cl->Size = 3; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (void *) ctx->Current.Normal; + cl->Enabled = 1; + + cl = &ac->Fallback.Color; + cl->Size = 4; + cl->Type = GL_UNSIGNED_BYTE; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (void *) ctx->Current.Color; + cl->Enabled = 1; + + cl = &ac->Fallback.SecondaryColor; + cl->Size = 3; + cl->Type = GL_UNSIGNED_BYTE; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (void *) ctx->Current.SecondaryColor; + cl->Enabled = 1; + + cl = &ac->Fallback.FogCoord; + cl->Size = 1; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (void *) &ctx->Current.FogCoord; + cl->Enabled = 1; + + cl = &ac->Fallback.Index; + cl->Size = 1; + cl->Type = GL_UNSIGNED_INT; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (void *) &ctx->Current.Index; + cl->Enabled = 1; + + for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) { + cl = &ac->Fallback.TexCoord[i]; + cl->Size = 4; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (void *) ctx->Current.Texcoord[i]; + cl->Enabled = 1; + } + + cl = &ac->Fallback.EdgeFlag; + cl->Size = 1; + cl->Type = GL_UNSIGNED_BYTE; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (void *) &ctx->Current.EdgeFlag; + cl->Enabled = 1; +} + + +static void _ac_cache_init( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *cl; + GLuint size = ctx->Const.MaxArrayLockSize + MAX_CLIPPED_VERTICES; + GLuint i; + + cl = &ac->Cache.Vertex; + cl->Size = 4; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 4 * sizeof(GLfloat); + cl->Ptr = MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + + cl = &ac->Cache.Normal; + cl->Size = 3; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 3 * sizeof(GLfloat); + cl->Ptr = MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + + cl = &ac->Cache.Color; + cl->Size = 4; + cl->Type = GL_UNSIGNED_BYTE; + cl->Stride = 0; + cl->StrideB = 4 * sizeof(GLubyte); + cl->Ptr = MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + + cl = &ac->Cache.SecondaryColor; + cl->Size = 3; + cl->Type = GL_UNSIGNED_BYTE; + cl->Stride = 0; + cl->StrideB = 4 * sizeof(GLubyte); + cl->Ptr = MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + + cl = &ac->Cache.FogCoord; + cl->Size = 1; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = sizeof(GLfloat); + cl->Ptr = MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + + cl = &ac->Cache.Index; + cl->Size = 1; + cl->Type = GL_UNSIGNED_INT; + cl->Stride = 0; + cl->StrideB = sizeof(GLuint); + cl->Ptr = MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + + for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) { + cl = &ac->Cache.TexCoord[i]; + cl->Size = 4; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 4 * sizeof(GLfloat); + cl->Ptr = MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + } + + cl = &ac->Cache.EdgeFlag; + cl->Size = 1; + cl->Type = GL_UNSIGNED_BYTE; + cl->Stride = 0; + cl->StrideB = sizeof(GLubyte); + cl->Ptr = MALLOC( cl->StrideB * size ); + cl->Enabled = 1; +} + + +/* This storage used to hold translated client data if type or stride + * need to be fixed. + */ +static void _ac_elts_init( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + GLuint size = 1000; + + ac->Elts = (GLuint *)MALLOC( sizeof(GLuint) * size ); + ac->elt_size = size; +} + +static void _ac_current_init( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + GLuint i; + + ac->Current.Color = &ac->Fallback.Color; + ac->Current.EdgeFlag = &ac->Fallback.EdgeFlag; + ac->Current.FogCoord = &ac->Fallback.FogCoord; + ac->Current.Index = &ac->Fallback.Index; + ac->Current.Normal = &ac->Fallback.Normal; + ac->Current.SecondaryColor = &ac->Fallback.SecondaryColor; + ac->Current.Vertex = &ctx->Array.Vertex; + + ac->Writeable.Color = GL_FALSE; + ac->Writeable.EdgeFlag = GL_FALSE; + ac->Writeable.FogCoord = GL_FALSE; + ac->Writeable.Index = GL_FALSE; + ac->Writeable.Normal = GL_FALSE; + ac->Writeable.SecondaryColor = GL_FALSE; + ac->Writeable.Vertex = GL_FALSE; + + for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) { + ac->Current.TexCoord[i] = &ac->Fallback.TexCoord[i]; + ac->Writeable.TexCoord[i] = GL_FALSE; + } + +} + +GLboolean _ac_CreateContext( GLcontext *ctx ) +{ + ctx->acache_context = CALLOC(sizeof(ACcontext)); + if (ctx->acache_context) { + _ac_cache_init( ctx ); + _ac_fallbacks_init( ctx ); + _ac_current_init( ctx ); + _ac_elts_init( ctx ); + return GL_TRUE; + } + return GL_FALSE; +} + +void _ac_DestroyContext( GLcontext *ctx ) +{ + 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 ); + + for (i = 0; i < MAX_TEXTURE_UNITS; i++) { + if (ac->Cache.TexCoord[i].Ptr) + FREE( ac->Cache.TexCoord[i].Ptr ); + } + + if (ac->Elts) FREE( ac->Elts ); +} + +void _ac_InvalidateState( GLcontext *ctx, GLuint new_state ) +{ + AC_CONTEXT(ctx)->NewState |= new_state; + AC_CONTEXT(ctx)->NewArrayState |= ctx->Array.NewState; +} diff --git a/src/mesa/array_cache/ac_context.h b/src/mesa/array_cache/ac_context.h new file mode 100644 index 0000000..b8c3cef --- /dev/null +++ b/src/mesa/array_cache/ac_context.h @@ -0,0 +1,98 @@ + +/* $Id: ac_context.h,v 1.1 2000/12/26 15:14:04 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Author: + * Keith Whitwell + */ + +#ifndef _AC_CONTEXT_H +#define _AC_CONTEXT_H + +#include "glheader.h" +#include "mtypes.h" + +#include "array_cache/acache.h" + +/* These are used to make the ctx->Current values look like + * arrays (with zero StrideB). + */ +struct ac_arrays { + struct gl_client_array Vertex; + struct gl_client_array Normal; + struct gl_client_array Color; + struct gl_client_array SecondaryColor; + struct gl_client_array FogCoord; + struct gl_client_array Index; + struct gl_client_array TexCoord[MAX_TEXTURE_UNITS]; + struct gl_client_array EdgeFlag; +}; + +struct ac_array_pointers { + struct gl_client_array *Vertex; + struct gl_client_array *Normal; + struct gl_client_array *Color; + struct gl_client_array *SecondaryColor; + struct gl_client_array *FogCoord; + struct gl_client_array *Index; + struct gl_client_array *TexCoord[MAX_TEXTURE_UNITS]; + struct gl_client_array *EdgeFlag; +}; + +struct ac_array_flags { + GLboolean Vertex; + GLboolean Normal; + GLboolean Color; + GLboolean SecondaryColor; + GLboolean FogCoord; + GLboolean Index; + GLboolean TexCoord[MAX_TEXTURE_UNITS]; + GLboolean EdgeFlag; +}; + + +typedef struct { + GLuint NewState; /* not needed? */ + GLuint NewArrayState; + + /* Facility for importing and caching array data: + */ + struct ac_arrays Fallback; + struct ac_arrays Cache; + struct ac_array_pointers Current; + struct ac_array_flags Writeable; + GLuint start; + GLuint count; + + /* Facility for importing element lists: + */ + GLuint *Elts; + GLuint elt_size; + +} ACcontext; + +#define AC_CONTEXT(ctx) ((ACcontext *)ctx->acache_context) + +#endif diff --git a/src/mesa/array_cache/ac_import.c b/src/mesa/array_cache/ac_import.c new file mode 100644 index 0000000..ca971dc --- /dev/null +++ b/src/mesa/array_cache/ac_import.c @@ -0,0 +1,712 @@ +/* $Id: ac_import.c,v 1.1 2000/12/26 15:14:04 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Author: + * Keith Whitwell + */ + +#include "glheader.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "mtypes.h" + +#include "array_cache/ac_context.h" + + + +/* 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); + + if (ctx->Array._Enabled & _NEW_ARRAY_TEXCOORD(unit)) + ac->Current.TexCoord[unit] = &ctx->Array.TexCoord[unit]; + else { + ac->Current.TexCoord[unit] = &ac->Fallback.TexCoord[unit]; + + if (ctx->Current.Texcoord[unit][4] != 1.0) + ac->Current.TexCoord[unit]->Size = 4; + else if (ctx->Current.Texcoord[unit][3] != 0.0) + ac->Current.TexCoord[unit]->Size = 3; + else + ac->Current.TexCoord[unit]->Size = 2; + } + + ac->Writeable.TexCoord[unit] = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_TEXCOORD(unit); +} + +static void reset_vertex( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + ASSERT(ctx->Array.Vertex.Enabled); + ac->Current.Vertex = &ctx->Array.Vertex; + ac->Writeable.Vertex = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_VERTEX; +} + + +static void reset_normal( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (ctx->Array._Enabled & _NEW_ARRAY_NORMAL) { +/* fprintf(stderr, "reset normal: using client array enab %d\n", */ +/* ctx->Array.Normal.Enabled); */ + ac->Current.Normal = &ctx->Array.Normal; + } + else { +/* fprintf(stderr, "reset normal: using fallback enab %d\n", */ +/* ctx->Array.Normal.Enabled); */ + ac->Current.Normal = &ac->Fallback.Normal; + } + + ac->Writeable.Normal = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_NORMAL; +} + + +static void reset_color( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + + if (ctx->Array._Enabled & _NEW_ARRAY_COLOR) + ac->Current.Color = &ctx->Array.Color; + else + ac->Current.Color = &ac->Fallback.Color; + +/* fprintf(stderr, "reset_color, stride now %d\n", ac->Current.Color->StrideB); */ + + ac->Writeable.Color = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_COLOR; +} + + +static void reset_secondarycolor( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (ctx->Array._Enabled & _NEW_ARRAY_SECONDARYCOLOR) + ac->Current.SecondaryColor = &ctx->Array.SecondaryColor; + else + ac->Current.SecondaryColor = &ac->Fallback.SecondaryColor; + + ac->Writeable.SecondaryColor = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_SECONDARYCOLOR; +} + + +static void reset_index( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (ctx->Array._Enabled & _NEW_ARRAY_INDEX) + ac->Current.Index = &ctx->Array.Index; + else + ac->Current.Index = &ac->Fallback.Index; + + ac->Writeable.Index = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_INDEX; +} + +static void reset_fogcoord( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (ctx->Array._Enabled & _NEW_ARRAY_FOGCOORD) + ac->Current.FogCoord = &ctx->Array.FogCoord; + else + ac->Current.FogCoord = &ac->Fallback.FogCoord; + + ac->Writeable.FogCoord = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_FOGCOORD; +} + +static void reset_edgeflag( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (ctx->Array._Enabled & _NEW_ARRAY_EDGEFLAG) + ac->Current.EdgeFlag = &ctx->Array.EdgeFlag; + else + ac->Current.EdgeFlag = &ac->Fallback.EdgeFlag; + + ac->Writeable.EdgeFlag = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_EDGEFLAG; +} + + +/* Functions to import array ranges with specified types and strides. + */ +static void import_texcoord( GLcontext *ctx, GLuint unit, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = ac->Current.TexCoord[unit]; + struct gl_client_array *to = &ac->Cache.TexCoord[unit]; + + /* Limited choices at this stage: + */ + ASSERT(type == GL_FLOAT); + ASSERT(stride == 4*sizeof(GLfloat) || stride == 0); + ASSERT(ac->count - ac->start < ctx->Const.MaxArrayLockSize); + + _math_trans_4f( to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + from->Size, + ac->start, + ac->count); + + to->Size = from->Size; + to->StrideB = 4 * sizeof(GLfloat); + to->Type = GL_FLOAT; + ac->Current.TexCoord[unit] = to; + ac->Writeable.TexCoord[unit] = GL_TRUE; +} + +static void import_vertex( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = ac->Current.Vertex; + struct gl_client_array *to = &ac->Cache.Vertex; + + /* Limited choices at this stage: + */ + ASSERT(type == GL_FLOAT); + ASSERT(stride == 4*sizeof(GLfloat) || stride == 0); + + _math_trans_4f( to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + from->Size, + ac->start, + ac->count); + + to->Size = from->Size; + to->StrideB = 4 * sizeof(GLfloat); + to->Type = GL_FLOAT; + ac->Current.Vertex = to; + ac->Writeable.Vertex = GL_TRUE; +} + +static void import_normal( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = ac->Current.Normal; + struct gl_client_array *to = &ac->Cache.Normal; + + +/* fprintf(stderr, "ac: import_normal\n"); */ + + /* Limited choices at this stage: + */ + ASSERT(type == GL_FLOAT); + ASSERT(stride == 3*sizeof(GLfloat) || stride == 0); + + _math_trans_3f( to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + ac->start, + ac->count); + + to->StrideB = 3 * sizeof(GLfloat); + to->Type = GL_FLOAT; + ac->Current.Normal = to; + ac->Writeable.Normal = GL_TRUE; +} + +static void import_color( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = ac->Current.Color; + struct gl_client_array *to = &ac->Cache.Color; + +/* fprintf(stderr, "(ac) %s\n", __FUNCTION__); */ + + /* Limited choices at this stage: + */ + ASSERT(type == GL_UNSIGNED_BYTE); + ASSERT(stride == 4*sizeof(GLubyte) || stride == 0); + + _math_trans_4ub( to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + from->Size, + ac->start, + ac->count); + + to->Size = from->Size; + to->StrideB = 4 * sizeof(GLubyte); + to->Type = GL_FLOAT; + ac->Current.Color = to; + ac->Writeable.Color = GL_TRUE; +} + +static void import_index( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = ac->Current.Index; + struct gl_client_array *to = &ac->Cache.Index; + + /* Limited choices at this stage: + */ + ASSERT(type == GL_UNSIGNED_INT); + ASSERT(stride == sizeof(GLuint) || stride == 0); + + _math_trans_1ui( to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + ac->start, + ac->count); + + to->StrideB = sizeof(GLuint); + to->Type = GL_UNSIGNED_INT; + ac->Current.Index = to; + ac->Writeable.Index = GL_TRUE; +} + +static void import_secondarycolor( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = ac->Current.SecondaryColor; + struct gl_client_array *to = &ac->Cache.SecondaryColor; + + /* Limited choices at this stage: + */ + ASSERT(type == GL_UNSIGNED_BYTE); + ASSERT(stride == 4*sizeof(GLubyte) || stride == 0); + + _math_trans_4ub( to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + from->Size, + ac->start, + ac->count); + + to->StrideB = 4 * sizeof(GLubyte); + to->Type = GL_UNSIGNED_BYTE; + ac->Current.SecondaryColor = to; + ac->Writeable.SecondaryColor = GL_TRUE; +} + +static void import_fogcoord( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = ac->Current.FogCoord; + struct gl_client_array *to = &ac->Cache.FogCoord; + + /* Limited choices at this stage: + */ + ASSERT(type == GL_FLOAT); + ASSERT(stride == sizeof(GLfloat) || stride == 0); + + _math_trans_1f( to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + ac->start, + ac->count); + + to->StrideB = sizeof(GLfloat); + to->Type = GL_FLOAT; + ac->Current.FogCoord = to; + ac->Writeable.FogCoord = GL_TRUE; +} + +static void import_edgeflag( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = ac->Current.EdgeFlag; + struct gl_client_array *to = &ac->Cache.EdgeFlag; + + /* Limited choices at this stage: + */ + ASSERT(type == GL_FLOAT); + ASSERT(stride == sizeof(GLfloat) || stride == 0); + + _math_trans_1f( to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + ac->start, + ac->count); + + to->StrideB = sizeof(GLfloat); + to->Type = GL_FLOAT; + ac->Current.EdgeFlag = to; + ac->Writeable.EdgeFlag = GL_TRUE; +} + + + +/* Externals to request arrays with specific properties: + */ +struct gl_client_array *_ac_import_texcoord( GLcontext *ctx, + GLuint unit, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_TEXCOORD(unit)) + reset_texcoord( ctx, unit ); + + /* Is the request impossible? + */ + if (reqsize != 0 && ac->Current.TexCoord[unit]->Size > reqsize) + return 0; + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Current.TexCoord[unit]->Type != type || + (reqstride != 0 && ac->Current.TexCoord[unit]->StrideB != reqstride) || + (reqwriteable && !ac->Writeable.TexCoord[unit])) + import_texcoord(ctx, unit, type, reqstride ); + + *writeable = ac->Writeable.TexCoord[unit]; + return ac->Current.TexCoord[unit]; +} + +struct gl_client_array *_ac_import_vertex( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_VERTEX) + reset_vertex( ctx ); + + /* Is the request impossible? + */ + if (reqsize != 0 && ac->Current.Vertex->Size > reqsize) + return 0; + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Current.Vertex->Type != type || + (reqstride != 0 && ac->Current.Vertex->StrideB != reqstride) || + (reqwriteable && !ac->Writeable.Vertex)) + import_vertex(ctx, type, reqstride ); + + *writeable = ac->Writeable.Vertex; + return ac->Current.Vertex; +} + +struct gl_client_array *_ac_import_normal( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + +/* fprintf(stderr, "%s %d\n", __FUNCTION__, ac->NewArrayState & _NEW_ARRAY_NORMAL); */ + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_NORMAL) + reset_normal( ctx ); + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Current.Normal->Type != type || + (reqstride != 0 && ac->Current.Normal->StrideB != reqstride) || + (reqwriteable && !ac->Writeable.Normal)) + import_normal(ctx, type, reqstride ); + + *writeable = ac->Writeable.Normal; + return ac->Current.Normal; +} + +struct gl_client_array *_ac_import_color( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + +/* fprintf(stderr, "%s stride %d sz %d wr %d\n", __FUNCTION__, */ +/* reqstride, reqsize, reqwriteable); */ + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_COLOR) + reset_color( ctx ); + + /* Is the request impossible? + */ + if (reqsize != 0 && ac->Current.Color->Size > reqsize) { +/* fprintf(stderr, "%s -- failed\n", __FUNCTION__); */ + return 0; + } + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Current.Color->Type != type || + (reqstride != 0 && ac->Current.Color->StrideB != reqstride) || + (reqwriteable && !ac->Writeable.Color)) + import_color(ctx, type, reqstride ); + + *writeable = ac->Writeable.Color; + return ac->Current.Color; +} + +struct gl_client_array *_ac_import_index( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_INDEX) + reset_index( ctx ); + + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Current.Index->Type != type || + (reqstride != 0 && ac->Current.Index->StrideB != reqstride) || + (reqwriteable && !ac->Writeable.Index)) + import_index(ctx, type, reqstride ); + + *writeable = ac->Writeable.Index; + return ac->Current.Index; +} + +struct gl_client_array *_ac_import_secondarycolor( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_SECONDARYCOLOR) + reset_secondarycolor( ctx ); + + /* Is the request impossible? + */ + if (reqsize != 0 && ac->Current.SecondaryColor->Size > reqsize) + return 0; + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Current.SecondaryColor->Type != type || + (reqstride != 0 && ac->Current.SecondaryColor->StrideB != reqstride) || + (reqwriteable && !ac->Writeable.SecondaryColor)) + import_secondarycolor( ctx, type, reqstride ); + + *writeable = ac->Writeable.SecondaryColor; + return ac->Current.SecondaryColor; +} + +struct gl_client_array *_ac_import_fogcoord( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_FOGCOORD) + reset_fogcoord( ctx ); + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Current.FogCoord->Type != type || + (reqstride != 0 && ac->Current.FogCoord->StrideB != reqstride) || + (reqwriteable && !ac->Writeable.FogCoord)) + import_fogcoord(ctx, type, reqstride ); + + *writeable = ac->Writeable.FogCoord; + return ac->Current.FogCoord; +} + + + + +struct gl_client_array *_ac_import_edgeflag( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_EDGEFLAG) + reset_edgeflag( ctx ); + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Current.EdgeFlag->Type != type || + (reqstride != 0 && ac->Current.EdgeFlag->StrideB != reqstride) || + (reqwriteable && !ac->Writeable.EdgeFlag)) + import_edgeflag(ctx, type, reqstride ); + + *writeable = ac->Writeable.EdgeFlag; + return ac->Current.EdgeFlag; +} + + + + + +/* Clients must call this function to validate state and set bounds + * before importing any data: + */ +void _ac_import_range( GLcontext *ctx, GLuint start, GLuint count ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Discard cached data which has been invalidated by state changes + * since last time. **ALREADY DONE** + if (ac->NewState) + _ac_update_state( ctx ); + */ + + if (!ctx->Array.LockCount) { + /* Not locked, discard cached data. Changes to lock + * status are caught via. _ac_invalidate_state(). + */ + ac->NewArrayState = _NEW_ARRAY_ALL; + ac->start = start; + ac->count = count; + } + else { + /* Locked, discard data for any disabled arrays. Require that + * the whole locked range always be dealt with, otherwise hard to + * maintain cached data in the face of clipping. + */ + ac->NewArrayState |= ~ctx->Array._Enabled; + ac->start = ctx->Array.LockFirst; + ac->count = ctx->Array.LockCount; + ASSERT(ac->start == start); /* hmm? */ + ASSERT(ac->count == count); + } +} + + + +/* Additional convienence function for importing a the element list + * for drawelements, drawrangeelements: + */ +CONST void * +_ac_import_elements( GLcontext *ctx, + GLenum new_type, + GLuint count, + GLenum old_type, + CONST void *indices ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (old_type == new_type) + return indices; + + if (ac->elt_size < count * sizeof(GLuint)) { + if (ac->Elts) FREE(ac->Elts); + while (ac->elt_size < count * sizeof(GLuint)) + ac->elt_size *= 2; + ac->Elts = MALLOC(ac->elt_size); + } + + switch (new_type) { + case GL_UNSIGNED_BYTE: + ASSERT(0); + return 0; + case GL_UNSIGNED_SHORT: + ASSERT(0); + return 0; + case GL_UNSIGNED_INT: { + GLuint *out = (GLuint *)ac->Elts; + GLuint i; + + switch (old_type) { + case GL_UNSIGNED_BYTE: { + CONST GLubyte *in = (CONST GLubyte *)indices; + for (i = 0 ; i < count ; i++) + out[i] = in[i]; + break; + } + case GL_UNSIGNED_SHORT: { + CONST GLushort *in = (CONST GLushort *)indices; + for (i = 0 ; i < count ; i++) + out[i] = in[i]; + break; + } + default: + ASSERT(0); + } + + return (CONST void *)out; + } + default: + ASSERT(0); + break; + } + + return 0; +} + diff --git a/src/mesa/array_cache/acache.h b/src/mesa/array_cache/acache.h new file mode 100644 index 0000000..2687239 --- /dev/null +++ b/src/mesa/array_cache/acache.h @@ -0,0 +1,122 @@ +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell + */ + +#ifndef _ARRAYCACHE_H +#define _ARRAYCACHE_H + +#include "mtypes.h" + + +extern GLboolean +_ac_CreateContext( GLcontext *ctx ); + +extern void +_ac_DestroyContext( GLcontext *ctx ); + +extern void +_ac_InvalidateState( GLcontext *ctx, GLuint new_state ); + +extern struct gl_client_array * +_ac_import_texcoord( GLcontext *ctx, + GLuint unit, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_vertex( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_normal( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_color( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_index( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_secondarycolor( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_fogcoord( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_edgeflag( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwritable, + GLboolean *writable ); + + +/* Clients must call this function to validate state and set bounds + * before importing any data: + */ +extern void +_ac_import_range( GLcontext *ctx, GLuint start, GLuint count ); + + +/* Additional convenience function: + */ +extern CONST void * +_ac_import_elements( GLcontext *ctx, + GLenum new_type, + GLuint count, + GLenum old_type, + CONST void *indices ); + + +#endif -- 2.7.4