tnl/t_array_api.c \
tnl/t_array_import.c \
tnl/t_context.c \
- tnl/t_eval_api.c \
- tnl/t_imm_alloc.c \
- tnl/t_imm_api.c \
- tnl/t_imm_debug.c \
- tnl/t_imm_dlist.c \
- tnl/t_imm_elt.c \
- tnl/t_imm_eval.c \
- tnl/t_imm_exec.c \
- tnl/t_imm_fixup.c \
tnl/t_pipeline.c \
+ tnl/t_save_api.c \
+ tnl/t_save_loopback.c \
+ tnl/t_save_playback.c \
tnl/t_vb_fog.c \
tnl/t_vb_light.c \
tnl/t_vb_normals.c \
tnl/t_vb_render.c \
tnl/t_vb_texgen.c \
tnl/t_vb_texmat.c \
- tnl/t_vb_vertex.c
+ tnl/t_vb_vertex.c \
+ tnl/t_vtx_api.c \
+ tnl/t_vtx_eval.c \
+ tnl/t_vtx_exec.c
+
ASM_C_SOURCES = \
x86/common_x86.c \
$(GLAPI_SOURCES) \
$(MATH_SOURCES) \
$(ARRAY_CACHE_SOURCES) \
+ $(TNL_SOURCES) \
$(SWRAST_SOURCES) \
$(SWRAST_SETUP_SOURCES) \
- $(TNL_SOURCES) \
$(ASM_C_SOURCES)
# This will probably get set to $(X86_SOURCES) in Make-config:
cl = &ac->Fallback.Index;
cl->Size = 1;
- cl->Type = GL_UNSIGNED_INT;
+ cl->Type = GL_FLOAT;
cl->Stride = 0;
cl->StrideB = 0;
cl->Ptr = (GLubyte *) &ctx->Current.Index;
cl = &ac->Cache.Index;
cl->Size = 1;
- cl->Type = GL_UNSIGNED_INT;
+ cl->Type = GL_FLOAT;
cl->Stride = 0;
- cl->StrideB = sizeof(GLuint);
+ cl->StrideB = sizeof(GLfloat);
cl->Ptr = (GLubyte *) MALLOC( cl->StrideB * size );
cl->Enabled = 1;
cl->Flags = 0;
#!/usr/bin/env python
-# $Id: gltable.py,v 1.4 2003/10/21 22:22:18 kendallb Exp $
# Mesa 3-D graphics library
# Version: 4.1
#!/usr/bin/env python
-# $Id: glx86asm.py,v 1.9 2003/10/23 13:28:06 dborca Exp $
# Mesa 3-D graphics library
# Version: 4.1
GLboolean _ae_create_context( GLcontext *ctx )
{
+ if (ctx->aelt_context)
+ return GL_TRUE;
+
ctx->aelt_context = MALLOC( sizeof(AEcontext) );
if (!ctx->aelt_context)
return GL_FALSE;
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 5.1
- *
- * Copyright (C) 1999-2003 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 <keith@tungstengraphics.com>
- */
-
-#include "glheader.h"
-#include "api_eval.h"
-#include "context.h"
-#include "macros.h"
-#include "math/m_eval.h"
-
-static void do_EvalCoord1f(GLcontext* ctx, GLfloat u)
-{
-
- /** Color Index **/
- if (ctx->Eval.Map1Index)
- {
- GLfloat findex;
- struct gl_1d_map *map = &ctx->EvalMap.Map1Index;
- GLfloat uu = (u - map->u1) * map->du;
- _math_horner_bezier_curve(map->Points, &findex, uu, 1, map->Order);
- glIndexi( (GLint) findex );
- }
-
- /** Color **/
- if (ctx->Eval.Map1Color4) {
- GLfloat fcolor[4];
- struct gl_1d_map *map = &ctx->EvalMap.Map1Color4;
- GLfloat uu = (u - map->u1) * map->du;
- _math_horner_bezier_curve(map->Points, fcolor, uu, 4, map->Order);
- glColor4fv( fcolor );
- }
-
- /** Normal Vector **/
- if (ctx->Eval.Map1Normal) {
- GLfloat normal[3];
- struct gl_1d_map *map = &ctx->EvalMap.Map1Normal;
- GLfloat uu = (u - map->u1) * map->du;
- _math_horner_bezier_curve(map->Points, normal, uu, 3, map->Order);
- glNormal3fv( normal );
- }
-
- /** Texture Coordinates **/
- if (ctx->Eval.Map1TextureCoord4) {
- GLfloat texcoord[4];
- struct gl_1d_map *map = &ctx->EvalMap.Map1Texture4;
- GLfloat uu = (u - map->u1) * map->du;
- _math_horner_bezier_curve(map->Points, texcoord, uu, 4, map->Order);
- glTexCoord4fv( texcoord );
- }
- else if (ctx->Eval.Map1TextureCoord3) {
- GLfloat texcoord[4];
- struct gl_1d_map *map = &ctx->EvalMap.Map1Texture3;
- GLfloat uu = (u - map->u1) * map->du;
- _math_horner_bezier_curve(map->Points, texcoord, uu, 3, map->Order);
- glTexCoord3fv( texcoord );
- }
- else if (ctx->Eval.Map1TextureCoord2) {
- GLfloat texcoord[4];
- struct gl_1d_map *map = &ctx->EvalMap.Map1Texture2;
- GLfloat uu = (u - map->u1) * map->du;
- _math_horner_bezier_curve(map->Points, texcoord, uu, 2, map->Order);
- glTexCoord2fv( texcoord );
- }
- else if (ctx->Eval.Map1TextureCoord1) {
- GLfloat texcoord[4];
- struct gl_1d_map *map = &ctx->EvalMap.Map1Texture1;
- GLfloat uu = (u - map->u1) * map->du;
- _math_horner_bezier_curve(map->Points, texcoord, uu, 1, map->Order);
- glTexCoord1fv( texcoord );
- }
-
- /** Vertex **/
- if (ctx->Eval.Map1Vertex4)
- {
- GLfloat vertex[4];
- struct gl_1d_map *map = &ctx->EvalMap.Map1Vertex4;
- GLfloat uu = (u - map->u1) * map->du;
- _math_horner_bezier_curve(map->Points, vertex, uu, 4, map->Order);
- glVertex4fv( vertex );
- }
- else if (ctx->Eval.Map1Vertex3)
- {
- GLfloat vertex[4];
- struct gl_1d_map *map = &ctx->EvalMap.Map1Vertex3;
- GLfloat uu = (u - map->u1) * map->du;
- _math_horner_bezier_curve(map->Points, vertex, uu, 3, map->Order);
- glVertex3fv( vertex );
- }
-}
-
-#define CROSS_PROD(n, u, v) \
- (n)[0] = (u)[1]*(v)[2] - (u)[2]*(v)[1]; \
- (n)[1] = (u)[2]*(v)[0] - (u)[0]*(v)[2]; \
- (n)[2] = (u)[0]*(v)[1] - (u)[1]*(v)[0]
-
-
-static void do_EvalCoord2f( GLcontext* ctx, GLfloat u, GLfloat v )
-{
- /** Color Index **/
- if (ctx->Eval.Map2Index) {
- GLfloat findex;
- struct gl_2d_map *map = &ctx->EvalMap.Map2Index;
- GLfloat uu = (u - map->u1) * map->du;
- GLfloat vv = (v - map->v1) * map->dv;
- _math_horner_bezier_surf(map->Points, &findex, uu, vv, 1,
- map->Uorder, map->Vorder);
- glIndexi( (GLuint) (GLint) findex );
- }
-
- /** Color **/
- if (ctx->Eval.Map2Color4) {
- GLfloat fcolor[4];
- struct gl_2d_map *map = &ctx->EvalMap.Map2Color4;
- GLfloat uu = (u - map->u1) * map->du;
- GLfloat vv = (v - map->v1) * map->dv;
- _math_horner_bezier_surf(map->Points, fcolor, uu, vv, 4,
- map->Uorder, map->Vorder);
- glColor4fv( fcolor );
- }
-
- /** Normal **/
- if (ctx->Eval.Map2Normal &&
- (!ctx->Eval.AutoNormal || (!ctx->Eval.Map2Vertex3 &&
- !ctx->Eval.Map2Vertex4))) {
- GLfloat normal[3];
- struct gl_2d_map *map = &ctx->EvalMap.Map2Normal;
- GLfloat uu = (u - map->u1) * map->du;
- GLfloat vv = (v - map->v1) * map->dv;
- _math_horner_bezier_surf(map->Points, normal, uu, vv, 3,
- map->Uorder, map->Vorder);
- glNormal3fv( normal );
- }
-
- /** Texture Coordinates **/
- if (ctx->Eval.Map2TextureCoord4) {
- GLfloat texcoord[4];
- struct gl_2d_map *map = &ctx->EvalMap.Map2Texture4;
- GLfloat uu = (u - map->u1) * map->du;
- GLfloat vv = (v - map->v1) * map->dv;
- _math_horner_bezier_surf(map->Points, texcoord, uu, vv, 4,
- map->Uorder, map->Vorder);
- glTexCoord4fv( texcoord );
- }
- else if (ctx->Eval.Map2TextureCoord3) {
- GLfloat texcoord[4];
- struct gl_2d_map *map = &ctx->EvalMap.Map2Texture3;
- GLfloat uu = (u - map->u1) * map->du;
- GLfloat vv = (v - map->v1) * map->dv;
- _math_horner_bezier_surf(map->Points, texcoord, uu, vv, 3,
- map->Uorder, map->Vorder);
- glTexCoord3fv( texcoord );
- }
- else if (ctx->Eval.Map2TextureCoord2) {
- GLfloat texcoord[4];
- struct gl_2d_map *map = &ctx->EvalMap.Map2Texture2;
- GLfloat uu = (u - map->u1) * map->du;
- GLfloat vv = (v - map->v1) * map->dv;
- _math_horner_bezier_surf(map->Points, texcoord, uu, vv, 2,
- map->Uorder, map->Vorder);
- glTexCoord2fv( texcoord );
- }
- else if (ctx->Eval.Map2TextureCoord1) {
- GLfloat texcoord[4];
- struct gl_2d_map *map = &ctx->EvalMap.Map2Texture1;
- GLfloat uu = (u - map->u1) * map->du;
- GLfloat vv = (v - map->v1) * map->dv;
- _math_horner_bezier_surf(map->Points, texcoord, uu, vv, 1,
- map->Uorder, map->Vorder);
- glTexCoord1fv( texcoord );
- }
-
- /** Vertex **/
- if(ctx->Eval.Map2Vertex4) {
- GLfloat vertex[4];
- GLfloat normal[3];
- struct gl_2d_map *map = &ctx->EvalMap.Map2Vertex4;
- GLfloat uu = (u - map->u1) * map->du;
- GLfloat vv = (v - map->v1) * map->dv;
-
- if (ctx->Eval.AutoNormal) {
- GLfloat du[4], dv[4];
-
- _math_de_casteljau_surf(map->Points, vertex, du, dv, uu, vv, 4,
- map->Uorder, map->Vorder);
-
- CROSS_PROD(normal, du, dv);
- NORMALIZE_3FV(normal);
- glNormal3fv( normal );
- glVertex4fv( vertex );
- }
- else {
- _math_horner_bezier_surf(map->Points, vertex, uu, vv, 4,
- map->Uorder, map->Vorder);
- glVertex4fv( vertex );
- }
- }
- else if (ctx->Eval.Map2Vertex3) {
- GLfloat vertex[4];
- struct gl_2d_map *map = &ctx->EvalMap.Map2Vertex3;
- GLfloat uu = (u - map->u1) * map->du;
- GLfloat vv = (v - map->v1) * map->dv;
- if (ctx->Eval.AutoNormal) {
- GLfloat du[3], dv[3];
- GLfloat normal[3];
- _math_de_casteljau_surf(map->Points, vertex, du, dv, uu, vv, 3,
- map->Uorder, map->Vorder);
- CROSS_PROD(normal, du, dv);
- NORMALIZE_3FV(normal);
- glNormal3fv( normal );
- glVertex3fv( vertex );
- }
- else {
- _math_horner_bezier_surf(map->Points, vertex, uu, vv, 3,
- map->Uorder, map->Vorder);
- glVertex3fv( vertex );
- }
- }
-}
-
-
-void _mesa_EvalPoint1( GLint i )
-{
- GET_CURRENT_CONTEXT( ctx );
- GLfloat du = ((ctx->Eval.MapGrid1u2 - ctx->Eval.MapGrid1u1) /
- (GLfloat) ctx->Eval.MapGrid1un);
- GLfloat u = i * du + ctx->Eval.MapGrid1u1;
-
- glEvalCoord1f( u );
-}
-
-
-void _mesa_EvalPoint2( GLint i, GLint j )
-{
- GET_CURRENT_CONTEXT( ctx );
- GLfloat du = ((ctx->Eval.MapGrid2u2 - ctx->Eval.MapGrid2u1) /
- (GLfloat) ctx->Eval.MapGrid2un);
- GLfloat dv = ((ctx->Eval.MapGrid2v2 - ctx->Eval.MapGrid2v1) /
- (GLfloat) ctx->Eval.MapGrid2vn);
- GLfloat u = i * du + ctx->Eval.MapGrid2u1;
- GLfloat v = j * dv + ctx->Eval.MapGrid2v1;
-
- glEvalCoord2f( u, v );
-}
-
-/* Wierd thing about eval is that it doesn't affect 'current' values.
- * This technique of saving and resetting current values requires
- * that:
- *
- * 1) Current values are updated immediately in the glColor,
- * etc. functions.
- *
- * 2) Hardware color values are stored seperately from ctx->Current,
- * for example in dma buffers, or direct emit to registers.
- */
-void _mesa_EvalCoord1f( GLfloat u )
-{
- GET_CURRENT_CONTEXT( ctx );
- GLfloat normal[3], texcoord[4], color[4];
- GLuint index;
-
- COPY_3FV( normal, ctx->Current.Attrib[VERT_ATTRIB_NORMAL] );
- COPY_4FV( texcoord, ctx->Current.Attrib[VERT_ATTRIB_TEX0] );
- COPY_4FV( color, ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
- index = ctx->Current.Index;
-
- do_EvalCoord1f( ctx, u );
-
- COPY_3FV( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], normal );
- COPY_4FV( ctx->Current.Attrib[VERT_ATTRIB_TEX0], texcoord );
- COPY_4FV( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], color );
- ctx->Current.Index = index;
-}
-
-void _mesa_EvalCoord2f( GLfloat u, GLfloat v )
-{
- GET_CURRENT_CONTEXT( ctx );
- GLfloat normal[3], texcoord[4], color[4];
- GLuint index;
-
- COPY_3FV( normal, ctx->Current.Attrib[VERT_ATTRIB_NORMAL] );
- COPY_4FV( texcoord, ctx->Current.Attrib[VERT_ATTRIB_TEX0] );
- COPY_4FV( color, ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
- index = ctx->Current.Index;
-
- do_EvalCoord2f( ctx, u, v );
-
- COPY_3FV( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], normal );
- COPY_4FV( ctx->Current.Attrib[VERT_ATTRIB_TEX0], texcoord );
- COPY_4FV( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], color );
- ctx->Current.Index = index;
-}
-
-void _mesa_EvalCoord1fv( const GLfloat *u )
-{
- glEvalCoord1f( u[0] );
-}
-
-void _mesa_EvalCoord2fv( const GLfloat *u )
-{
- glEvalCoord2f( u[0], u[1] );
-}
* listed in dd.h. The easiest way for a driver to do this is to
* install the supplied software t&l module.
*/
-#define COLORUBV(v) glColor4ubv(v)
#define COLORF(r,g,b,a) glColor4f(r,g,b,a)
#define VERTEX2(x,y) glVertex2f(x,y)
#define VERTEX3(x,y,z) glVertex3f(x,y,z)
#define TEXCOORD2(s,t) glTexCoord2f(s,t)
#define TEXCOORD3(s,t,u) glTexCoord3f(s,t,u)
#define TEXCOORD4(s,t,u,v) glTexCoord4f(s,t,u,v)
-#define INDEX(c) glIndexi(c)
+#define INDEX(c) glIndexf(c)
#define MULTI_TEXCOORD1(z,s) glMultiTexCoord1fARB(z,s)
#define MULTI_TEXCOORD2(z,s,t) glMultiTexCoord2fARB(z,s,t)
#define MULTI_TEXCOORD3(z,s,t,u) glMultiTexCoord3fARB(z,s,t,u)
#define MATERIALFV(a,b,c) glMaterialfv(a,b,c)
#define RECTF(a,b,c,d) glRectf(a,b,c,d)
-#define ATTRIB(index, x, y, z, w) _glapi_Dispatch->VertexAttrib4fNV(index, x, y, z, w)
-
-
-#define FOGCOORDF(x) _glapi_Dispatch->FogCoordfEXT(x)
-#define SECONDARYCOLORUB(a,b,c) _glapi_Dispatch->SecondaryColor3ubEXT(a,b,c)
-#define SECONDARYCOLORF(a,b,c) _glapi_Dispatch->SecondaryColor3fEXT(a,b,c)
-
-
-static void GLAPIENTRY
-loopback_Color3b( GLbyte red, GLbyte green, GLbyte blue )
-{
- GLubyte col[4];
- col[0] = BYTE_TO_UBYTE(red);
- col[1] = BYTE_TO_UBYTE(green);
- col[2] = BYTE_TO_UBYTE(blue);
- col[3] = 255;
- COLORUBV(col);
-}
-
-static void GLAPIENTRY
-loopback_Color3d( GLdouble red, GLdouble green, GLdouble blue )
-{
- GLubyte col[4];
- GLfloat r = (GLfloat) red;
- GLfloat g = (GLfloat) green;
- GLfloat b = (GLfloat) blue;
- UNCLAMPED_FLOAT_TO_UBYTE(col[0], r);
- UNCLAMPED_FLOAT_TO_UBYTE(col[1], g);
- UNCLAMPED_FLOAT_TO_UBYTE(col[2], b);
- col[3] = 255;
- COLORUBV( col );
-}
-
-static void GLAPIENTRY
-loopback_Color3i( GLint red, GLint green, GLint blue )
-{
- GLubyte col[4];
- col[0] = INT_TO_UBYTE(red);
- col[1] = INT_TO_UBYTE(green);
- col[2] = INT_TO_UBYTE(blue);
- col[3] = 255;
- COLORUBV(col);
-}
-
-static void GLAPIENTRY
-loopback_Color3s( GLshort red, GLshort green, GLshort blue )
-{
- GLubyte col[4];
- col[0] = SHORT_TO_UBYTE(red);
- col[1] = SHORT_TO_UBYTE(green);
- col[2] = SHORT_TO_UBYTE(blue);
- col[3] = 255;
- COLORUBV(col);
-}
-
-static void GLAPIENTRY
-loopback_Color3ui( GLuint red, GLuint green, GLuint blue )
-{
- GLubyte col[4];
- col[0] = UINT_TO_UBYTE(red);
- col[1] = UINT_TO_UBYTE(green);
- col[2] = UINT_TO_UBYTE(blue);
- col[3] = 255;
- COLORUBV(col);
-}
-
-static void GLAPIENTRY
-loopback_Color3us( GLushort red, GLushort green, GLushort blue )
-{
- GLubyte col[4];
- col[0] = USHORT_TO_UBYTE(red);
- col[1] = USHORT_TO_UBYTE(green);
- col[2] = USHORT_TO_UBYTE(blue);
- col[3] = 255;
- COLORUBV(col);
-}
-
-static void GLAPIENTRY
-loopback_Color4b( GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha )
-{
- GLubyte col[4];
- col[0] = BYTE_TO_UBYTE(red);
- col[1] = BYTE_TO_UBYTE(green);
- col[2] = BYTE_TO_UBYTE(blue);
- col[3] = 255;
- COLORUBV(col);
-}
-
-static void GLAPIENTRY
-loopback_Color4d( GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha )
-{
- GLubyte col[4];
- GLfloat r = (GLfloat) red;
- GLfloat g = (GLfloat) green;
- GLfloat b = (GLfloat) blue;
- GLfloat a = (GLfloat) alpha;
- UNCLAMPED_FLOAT_TO_UBYTE(col[0], r);
- UNCLAMPED_FLOAT_TO_UBYTE(col[1], g);
- UNCLAMPED_FLOAT_TO_UBYTE(col[2], b);
- UNCLAMPED_FLOAT_TO_UBYTE(col[3], a);
- COLORUBV( col );
-}
-
-static void GLAPIENTRY
-loopback_Color4i( GLint red, GLint green, GLint blue, GLint alpha )
-{
- GLubyte col[4];
- col[0] = INT_TO_UBYTE(red);
- col[1] = INT_TO_UBYTE(green);
- col[2] = INT_TO_UBYTE(blue);
- col[3] = INT_TO_UBYTE(alpha);
- COLORUBV(col);
-}
-
-static void GLAPIENTRY
-loopback_Color4s( GLshort red, GLshort green, GLshort blue,
- GLshort alpha )
-{
- GLubyte col[4];
- col[0] = SHORT_TO_UBYTE(red);
- col[1] = SHORT_TO_UBYTE(green);
- col[2] = SHORT_TO_UBYTE(blue);
- col[3] = SHORT_TO_UBYTE(alpha);
- COLORUBV(col);
-}
-
-static void GLAPIENTRY
-loopback_Color4ui( GLuint red, GLuint green, GLuint blue, GLuint alpha )
-{
- GLubyte col[4];
- col[0] = UINT_TO_UBYTE(red);
- col[1] = UINT_TO_UBYTE(green);
- col[2] = UINT_TO_UBYTE(blue);
- col[3] = UINT_TO_UBYTE(alpha);
- COLORUBV(col);
-}
-
-static void GLAPIENTRY
-loopback_Color4us( GLushort red, GLushort green, GLushort blue,
- GLushort alpha )
-{
- GLubyte col[4];
- col[0] = USHORT_TO_UBYTE(red);
- col[1] = USHORT_TO_UBYTE(green);
- col[2] = USHORT_TO_UBYTE(blue);
- col[3] = USHORT_TO_UBYTE(alpha);
- COLORUBV(col);
-}
-
-static void GLAPIENTRY
-loopback_Color3bv( const GLbyte *v )
-{
- GLubyte col[4];
- col[0] = BYTE_TO_UBYTE(v[0]);
- col[1] = BYTE_TO_UBYTE(v[1]);
- col[2] = BYTE_TO_UBYTE(v[2]);
- col[3] = 255;
- COLORUBV(col);
-}
-
-static void GLAPIENTRY
-loopback_Color3dv( const GLdouble *v )
-{
- GLubyte col[4];
- GLfloat r = (GLfloat) v[0];
- GLfloat g = (GLfloat) v[1];
- GLfloat b = (GLfloat) v[2];
- UNCLAMPED_FLOAT_TO_UBYTE(col[0], r);
- UNCLAMPED_FLOAT_TO_UBYTE(col[1], g);
- UNCLAMPED_FLOAT_TO_UBYTE(col[2], b);
- col[3] = 255;
- COLORUBV( col );
-}
-
-static void GLAPIENTRY
-loopback_Color3iv( const GLint *v )
-{
- GLubyte col[4];
- col[0] = INT_TO_UBYTE(v[0]);
- col[1] = INT_TO_UBYTE(v[1]);
- col[2] = INT_TO_UBYTE(v[2]);
- col[3] = 255;
- COLORUBV(col);
-}
-
-static void GLAPIENTRY
-loopback_Color3sv( const GLshort *v )
-{
- GLubyte col[4];
- col[0] = SHORT_TO_UBYTE(v[0]);
- col[1] = SHORT_TO_UBYTE(v[1]);
- col[2] = SHORT_TO_UBYTE(v[2]);
- col[3] = 255;
- COLORUBV(col);
-}
-
-static void GLAPIENTRY
-loopback_Color3uiv( const GLuint *v )
-{
- GLubyte col[4];
- col[0] = UINT_TO_UBYTE(v[0]);
- col[1] = UINT_TO_UBYTE(v[1]);
- col[2] = UINT_TO_UBYTE(v[2]);
- col[3] = 255;
- COLORUBV(col);
-}
-
-static void GLAPIENTRY
-loopback_Color3usv( const GLushort *v )
-{
- GLubyte col[4];
- col[0] = USHORT_TO_UBYTE(v[0]);
- col[1] = USHORT_TO_UBYTE(v[1]);
- col[2] = USHORT_TO_UBYTE(v[2]);
- col[3] = 255;
- COLORUBV(col);
-
-}
-
-static void GLAPIENTRY
-loopback_Color4bv( const GLbyte *v )
-{
- GLubyte col[4];
- col[0] = BYTE_TO_UBYTE(v[0]);
- col[1] = BYTE_TO_UBYTE(v[1]);
- col[2] = BYTE_TO_UBYTE(v[2]);
- col[3] = BYTE_TO_UBYTE(v[3]);
- COLORUBV(col);
-}
-
-static void GLAPIENTRY
-loopback_Color4dv( const GLdouble *v )
-{
- GLubyte col[4];
- GLfloat r = (GLfloat) v[0];
- GLfloat g = (GLfloat) v[1];
- GLfloat b = (GLfloat) v[2];
- GLfloat a = (GLfloat) v[3];
- UNCLAMPED_FLOAT_TO_UBYTE(col[0], r);
- UNCLAMPED_FLOAT_TO_UBYTE(col[1], g);
- UNCLAMPED_FLOAT_TO_UBYTE(col[2], b);
- UNCLAMPED_FLOAT_TO_UBYTE(col[3], a);
- COLORUBV( col );
-}
-
-static void GLAPIENTRY
-loopback_Color4iv( const GLint *v )
-{
- GLubyte col[4];
- col[0] = INT_TO_UBYTE(v[0]);
- col[1] = INT_TO_UBYTE(v[1]);
- col[2] = INT_TO_UBYTE(v[2]);
- col[3] = INT_TO_UBYTE(v[3]);
- COLORUBV(col);
-}
-
-static void GLAPIENTRY
-loopback_Color4sv( const GLshort *v)
-{
- GLubyte col[4];
- col[0] = SHORT_TO_UBYTE(v[0]);
- col[1] = SHORT_TO_UBYTE(v[1]);
- col[2] = SHORT_TO_UBYTE(v[2]);
- col[3] = SHORT_TO_UBYTE(v[3]);
- COLORUBV(col);
-}
-
-static void GLAPIENTRY
-loopback_Color4uiv( const GLuint *v)
-{
- GLubyte col[4];
- col[0] = UINT_TO_UBYTE(v[0]);
- col[1] = UINT_TO_UBYTE(v[1]);
- col[2] = UINT_TO_UBYTE(v[2]);
- col[3] = UINT_TO_UBYTE(v[3]);
- COLORUBV(col);
-}
-
-static void GLAPIENTRY
-loopback_Color4usv( const GLushort *v)
-{
- GLubyte col[4];
- col[0] = USHORT_TO_UBYTE(v[0]);
- col[1] = USHORT_TO_UBYTE(v[1]);
- col[2] = USHORT_TO_UBYTE(v[2]);
- col[3] = USHORT_TO_UBYTE(v[3]);
- COLORUBV(col);
-}
+/* Extension functions must be dereferenced through _glapi_Dispatch as
+ * not all libGL.so's will have all the uptodate entrypoints.
+ */
+#define ATTRIB1(index,x) _glapi_Dispatch->VertexAttrib1fNV(index,x)
+#define ATTRIB2(index,x,y) _glapi_Dispatch->VertexAttrib2fNV(index,x,y)
+#define ATTRIB3(index,x,y,z) _glapi_Dispatch->VertexAttrib3fNV(index,x,y,z)
+#define ATTRIB4(index,x,y,z,w) _glapi_Dispatch->VertexAttrib4fNV(index,x,y,z,w)
+#define FOGCOORDF(x) _glapi_Dispatch->FogCoordfEXT(x)
+#define SECONDARYCOLORF(a,b,c) _glapi_Dispatch->SecondaryColor3fEXT(a,b,c)
static void GLAPIENTRY
loopback_Color3b_f( GLbyte red, GLbyte green, GLbyte blue )
USHORT_TO_FLOAT(blue), 1.0 );
}
+static void GLAPIENTRY
+loopback_Color3ub_f( GLubyte red, GLubyte green, GLubyte blue )
+{
+ COLORF( UBYTE_TO_FLOAT(red), UBYTE_TO_FLOAT(green),
+ UBYTE_TO_FLOAT(blue), 1.0 );
+}
+
static void GLAPIENTRY
loopback_Color3bv_f( const GLbyte *v )
USHORT_TO_FLOAT(v[2]), 1.0 );
}
+static void GLAPIENTRY
+loopback_Color3ubv_f( const GLubyte *v )
+{
+ COLORF( UBYTE_TO_FLOAT(v[0]), UBYTE_TO_FLOAT(v[1]),
+ UBYTE_TO_FLOAT(v[2]), 1.0 );
+}
+
static void GLAPIENTRY
loopback_Color4b_f( GLbyte red, GLbyte green, GLbyte blue,
USHORT_TO_FLOAT(blue), USHORT_TO_FLOAT(alpha) );
}
+static void
+loopback_Color4ub_f( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha )
+{
+ COLORF( UBYTE_TO_FLOAT(red), UBYTE_TO_FLOAT(green),
+ UBYTE_TO_FLOAT(blue), UBYTE_TO_FLOAT(alpha) );
+}
+
static void GLAPIENTRY
loopback_Color4iv_f( const GLint *v )
USHORT_TO_FLOAT(v[2]), USHORT_TO_FLOAT(v[3]) );
}
+static void GLAPIENTRY
+loopback_Color4ubv_f( const GLubyte *v)
+{
+ COLORF( UBYTE_TO_FLOAT(v[0]), UBYTE_TO_FLOAT(v[1]),
+ UBYTE_TO_FLOAT(v[2]), UBYTE_TO_FLOAT(v[3]) );
+}
+
static void GLAPIENTRY
loopback_FogCoorddEXT( GLdouble d )
{
static void GLAPIENTRY
loopback_Indexd( GLdouble c )
{
- INDEX( (GLint) c );
+ INDEX( (GLfloat) c );
}
static void GLAPIENTRY
-loopback_Indexf( GLfloat c )
+loopback_Indexi( GLint c )
{
- INDEX( (GLuint) (GLint) c );
+ INDEX( (GLfloat) c );
}
static void GLAPIENTRY
loopback_Indexs( GLshort c )
{
- INDEX( (GLint) c );
+ INDEX( (GLfloat) c );
}
static void GLAPIENTRY
loopback_Indexub( GLubyte c )
{
- INDEX( (GLint) c );
+ INDEX( (GLfloat) c );
}
static void GLAPIENTRY
loopback_Indexdv( const GLdouble *c )
{
- INDEX( (GLint) (GLint) *c );
-}
-
-static void GLAPIENTRY
-loopback_Indexfv( const GLfloat *c )
-{
- INDEX( (GLint) (GLint) *c );
+ INDEX( (GLfloat) *c );
}
static void GLAPIENTRY
loopback_Indexiv( const GLint *c )
{
- INDEX( *c );
+ INDEX( (GLfloat) *c );
}
static void GLAPIENTRY
loopback_Indexsv( const GLshort *c )
{
- INDEX( (GLint) *c );
+ INDEX( (GLfloat) *c );
}
static void GLAPIENTRY
loopback_Indexubv( const GLubyte *c )
{
- INDEX( (GLint) *c );
+ INDEX( (GLfloat) *c );
}
static void GLAPIENTRY
RECTF((GLfloat) v1[0], (GLfloat) v1[1], (GLfloat) v2[0], (GLfloat) v2[1]);
}
-static void GLAPIENTRY
-loopback_SecondaryColor3bEXT( GLbyte red, GLbyte green, GLbyte blue )
-{
- SECONDARYCOLORUB( BYTE_TO_UBYTE(red),
- BYTE_TO_UBYTE(green),
- BYTE_TO_UBYTE(blue) );
-}
-
-static void GLAPIENTRY
-loopback_SecondaryColor3dEXT( GLdouble red, GLdouble green, GLdouble blue )
-{
- GLubyte col[3];
- GLfloat r = (GLfloat) red;
- GLfloat g = (GLfloat) green;
- GLfloat b = (GLfloat) blue;
- UNCLAMPED_FLOAT_TO_UBYTE(col[0], r);
- UNCLAMPED_FLOAT_TO_UBYTE(col[1], g);
- UNCLAMPED_FLOAT_TO_UBYTE(col[2], b);
- SECONDARYCOLORUB( col[0], col[1], col[2] );
-}
-
-static void GLAPIENTRY
-loopback_SecondaryColor3iEXT( GLint red, GLint green, GLint blue )
-{
- SECONDARYCOLORUB( INT_TO_UBYTE(red),
- INT_TO_UBYTE(green),
- INT_TO_UBYTE(blue));
-}
-
-static void GLAPIENTRY
-loopback_SecondaryColor3sEXT( GLshort red, GLshort green, GLshort blue )
-{
- SECONDARYCOLORUB(SHORT_TO_UBYTE(red),
- SHORT_TO_UBYTE(green),
- SHORT_TO_UBYTE(blue));
-}
-
-static void GLAPIENTRY
-loopback_SecondaryColor3uiEXT( GLuint red, GLuint green, GLuint blue )
-{
- SECONDARYCOLORUB(UINT_TO_UBYTE(red),
- UINT_TO_UBYTE(green),
- UINT_TO_UBYTE(blue));
-}
-
-static void GLAPIENTRY
-loopback_SecondaryColor3usEXT( GLushort red, GLushort green, GLushort blue )
-{
- SECONDARYCOLORUB(USHORT_TO_UBYTE(red),
- USHORT_TO_UBYTE(green),
- USHORT_TO_UBYTE(blue));
-}
-
-static void GLAPIENTRY
-loopback_SecondaryColor3bvEXT( const GLbyte *v )
-{
- const GLfloat a = BYTE_TO_FLOAT(v[0]);
- const GLfloat b = BYTE_TO_FLOAT(v[1]);
- const GLfloat c = BYTE_TO_FLOAT(v[2]);
- SECONDARYCOLORF(a,b,c);
-}
-
-static void GLAPIENTRY
-loopback_SecondaryColor3dvEXT( const GLdouble *v )
-{
- GLubyte col[3];
- GLfloat r = (GLfloat) v[0];
- GLfloat g = (GLfloat) v[1];
- GLfloat b = (GLfloat) v[2];
- UNCLAMPED_FLOAT_TO_UBYTE(col[0], r);
- UNCLAMPED_FLOAT_TO_UBYTE(col[1], g);
- UNCLAMPED_FLOAT_TO_UBYTE(col[2], b);
- SECONDARYCOLORUB( col[0], col[1], col[2] );
-}
-
-static void GLAPIENTRY
-loopback_SecondaryColor3ivEXT( const GLint *v )
-{
- SECONDARYCOLORUB(INT_TO_UBYTE(v[0]),
- INT_TO_UBYTE(v[1]),
- INT_TO_UBYTE(v[2]));
-}
-
-static void GLAPIENTRY
-loopback_SecondaryColor3svEXT( const GLshort *v )
-{
- SECONDARYCOLORUB(SHORT_TO_UBYTE(v[0]),
- SHORT_TO_UBYTE(v[1]),
- SHORT_TO_UBYTE(v[2]));
-}
-
-static void GLAPIENTRY
-loopback_SecondaryColor3uivEXT( const GLuint *v )
-{
- SECONDARYCOLORUB(UINT_TO_UBYTE(v[0]),
- UINT_TO_UBYTE(v[1]),
- UINT_TO_UBYTE(v[2]));
-}
-
-static void GLAPIENTRY
-loopback_SecondaryColor3usvEXT( const GLushort *v )
-{
- SECONDARYCOLORUB(USHORT_TO_UBYTE(v[0]),
- USHORT_TO_UBYTE(v[1]),
- USHORT_TO_UBYTE(v[2]));
-}
-
-
static void GLAPIENTRY
loopback_SecondaryColor3bEXT_f( GLbyte red, GLbyte green, GLbyte blue )
{
USHORT_TO_FLOAT(blue));
}
+static void GLAPIENTRY
+loopback_SecondaryColor3ubEXT_f( GLubyte red, GLubyte green, GLubyte blue )
+{
+ SECONDARYCOLORF(UBYTE_TO_FLOAT(red),
+ UBYTE_TO_FLOAT(green),
+ UBYTE_TO_FLOAT(blue));
+}
+
static void GLAPIENTRY
loopback_SecondaryColor3bvEXT_f( const GLbyte *v )
{
USHORT_TO_FLOAT(v[2]));
}
+static void GLAPIENTRY
+loopback_SecondaryColor3ubvEXT_f( const GLubyte *v )
+{
+ SECONDARYCOLORF(UBYTE_TO_FLOAT(v[0]),
+ UBYTE_TO_FLOAT(v[1]),
+ UBYTE_TO_FLOAT(v[2]));
+}
+
/*
* GL_NV_vertex_program
static void GLAPIENTRY
loopback_VertexAttrib1sNV(GLuint index, GLshort x)
{
- ATTRIB(index, (GLfloat) x, 0.0F, 0.0F, 1.0F);
+ ATTRIB1(index, (GLfloat) x);
}
static void GLAPIENTRY
loopback_VertexAttrib1fNV(GLuint index, GLfloat x)
{
- ATTRIB(index, x, 0.0F, 0.0F, 1.0F);
+ ATTRIB1(index, x);
}
static void GLAPIENTRY
loopback_VertexAttrib1dNV(GLuint index, GLdouble x)
{
- ATTRIB(index, (GLfloat) x, 0.0F, 0.0F, 1.0F);
+ ATTRIB1(index, (GLfloat) x);
}
static void GLAPIENTRY
loopback_VertexAttrib2sNV(GLuint index, GLshort x, GLshort y)
{
- ATTRIB(index, (GLfloat) x, y, 0.0F, 1.0F);
+ ATTRIB2(index, (GLfloat) x, y);
}
static void GLAPIENTRY
loopback_VertexAttrib2fNV(GLuint index, GLfloat x, GLfloat y)
{
- ATTRIB(index, (GLfloat) x, y, 0.0F, 1.0F);
+ ATTRIB2(index, (GLfloat) x, y);
}
static void GLAPIENTRY
loopback_VertexAttrib2dNV(GLuint index, GLdouble x, GLdouble y)
{
- ATTRIB(index, (GLfloat) x, (GLfloat) y, 0.0F, 1.0F);
+ ATTRIB2(index, (GLfloat) x, (GLfloat) y);
}
static void GLAPIENTRY
loopback_VertexAttrib3sNV(GLuint index, GLshort x, GLshort y, GLshort z)
{
- ATTRIB(index, (GLfloat) x, y, z, 1.0F);
+ ATTRIB3(index, (GLfloat) x, y, z);
}
static void GLAPIENTRY
loopback_VertexAttrib3fNV(GLuint index, GLfloat x, GLfloat y, GLfloat z)
{
- ATTRIB(index, x, y, z, 1.0F);
+ ATTRIB3(index, x, y, z);
}
static void GLAPIENTRY
loopback_VertexAttrib3dNV(GLuint index, GLdouble x, GLdouble y, GLdouble z)
{
- ATTRIB(index, (GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
+ ATTRIB4(index, (GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F);
}
static void GLAPIENTRY
loopback_VertexAttrib4sNV(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w)
{
- ATTRIB(index, (GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
+ ATTRIB4(index, (GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
}
static void GLAPIENTRY
loopback_VertexAttrib4dNV(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
{
- ATTRIB(index, (GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
+ ATTRIB4(index, (GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
}
static void GLAPIENTRY
loopback_VertexAttrib4ubNV(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w)
{
- ATTRIB(index, UBYTE_TO_FLOAT(x), UBYTE_TO_FLOAT(y),
+ ATTRIB4(index, UBYTE_TO_FLOAT(x), UBYTE_TO_FLOAT(y),
UBYTE_TO_FLOAT(z), UBYTE_TO_FLOAT(w));
}
static void GLAPIENTRY
loopback_VertexAttrib1svNV(GLuint index, const GLshort *v)
{
- ATTRIB(index, (GLfloat) v[0], 0.0F, 0.0F, 1.0F);
+ ATTRIB1(index, (GLfloat) v[0]);
}
static void GLAPIENTRY
loopback_VertexAttrib1fvNV(GLuint index, const GLfloat *v)
{
- ATTRIB(index, v[0], 0.0F, 0.0F, 1.0F);
+ ATTRIB1(index, v[0]);
}
static void GLAPIENTRY
loopback_VertexAttrib1dvNV(GLuint index, const GLdouble *v)
{
- ATTRIB(index, (GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
+ ATTRIB1(index, (GLfloat) v[0]);
}
static void GLAPIENTRY
loopback_VertexAttrib2svNV(GLuint index, const GLshort *v)
{
- ATTRIB(index, (GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
+ ATTRIB2(index, (GLfloat) v[0], (GLfloat) v[1]);
}
static void GLAPIENTRY
loopback_VertexAttrib2fvNV(GLuint index, const GLfloat *v)
{
- ATTRIB(index, v[0], v[1], 0.0F, 1.0F);
+ ATTRIB2(index, v[0], v[1]);
}
static void GLAPIENTRY
loopback_VertexAttrib2dvNV(GLuint index, const GLdouble *v)
{
- ATTRIB(index, (GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F);
+ ATTRIB2(index, (GLfloat) v[0], (GLfloat) v[1]);
}
static void GLAPIENTRY
loopback_VertexAttrib3svNV(GLuint index, const GLshort *v)
{
- ATTRIB(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
+ ATTRIB2(index, (GLfloat) v[0], (GLfloat) v[1]);
}
static void GLAPIENTRY
loopback_VertexAttrib3fvNV(GLuint index, const GLfloat *v)
{
- ATTRIB(index, v[0], v[1], v[2], 1.0F);
+ ATTRIB3(index, v[0], v[1], v[2]);
}
static void GLAPIENTRY
loopback_VertexAttrib3dvNV(GLuint index, const GLdouble *v)
{
- ATTRIB(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F);
+ ATTRIB3(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2]);
}
static void GLAPIENTRY
loopback_VertexAttrib4svNV(GLuint index, const GLshort *v)
{
- ATTRIB(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2],
+ ATTRIB4(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2],
(GLfloat)v[3]);
}
static void GLAPIENTRY
loopback_VertexAttrib4fvNV(GLuint index, const GLfloat *v)
{
- ATTRIB(index, v[0], v[1], v[2], v[3]);
+ ATTRIB4(index, v[0], v[1], v[2], v[3]);
}
static void GLAPIENTRY
loopback_VertexAttrib4dvNV(GLuint index, const GLdouble *v)
{
- ATTRIB(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
+ ATTRIB4(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
}
static void GLAPIENTRY
loopback_VertexAttrib4ubvNV(GLuint index, const GLubyte *v)
{
- ATTRIB(index, UBYTE_TO_FLOAT(v[0]), UBYTE_TO_FLOAT(v[1]),
+ ATTRIB4(index, UBYTE_TO_FLOAT(v[0]), UBYTE_TO_FLOAT(v[1]),
UBYTE_TO_FLOAT(v[2]), UBYTE_TO_FLOAT(v[3]));
}
static void GLAPIENTRY
loopback_VertexAttrib4bvARB(GLuint index, const GLbyte * v)
{
- ATTRIB(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
+ ATTRIB4(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
}
static void GLAPIENTRY
loopback_VertexAttrib4ivARB(GLuint index, const GLint * v)
{
- ATTRIB(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
+ ATTRIB4(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
}
static void GLAPIENTRY
loopback_VertexAttrib4ubvARB(GLuint index, const GLubyte * v)
{
- ATTRIB(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
+ ATTRIB4(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
}
static void GLAPIENTRY
loopback_VertexAttrib4usvARB(GLuint index, const GLushort * v)
{
- ATTRIB(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
+ ATTRIB4(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
}
static void GLAPIENTRY
loopback_VertexAttrib4uivARB(GLuint index, const GLuint * v)
{
- ATTRIB(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
+ ATTRIB4(index, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
}
static void GLAPIENTRY
loopback_VertexAttrib4NbvARB(GLuint index, const GLbyte * v)
{
- ATTRIB(index, BYTE_TO_FLOAT(v[0]), BYTE_TO_FLOAT(v[1]),
+ ATTRIB4(index, BYTE_TO_FLOAT(v[0]), BYTE_TO_FLOAT(v[1]),
BYTE_TO_FLOAT(v[2]), BYTE_TO_FLOAT(v[3]));
}
static void GLAPIENTRY
loopback_VertexAttrib4NsvARB(GLuint index, const GLshort * v)
{
- ATTRIB(index, SHORT_TO_FLOAT(v[0]), SHORT_TO_FLOAT(v[1]),
+ ATTRIB4(index, SHORT_TO_FLOAT(v[0]), SHORT_TO_FLOAT(v[1]),
SHORT_TO_FLOAT(v[2]), SHORT_TO_FLOAT(v[3]));
}
static void GLAPIENTRY
loopback_VertexAttrib4NivARB(GLuint index, const GLint * v)
{
- ATTRIB(index, INT_TO_FLOAT(v[0]), INT_TO_FLOAT(v[1]),
+ ATTRIB4(index, INT_TO_FLOAT(v[0]), INT_TO_FLOAT(v[1]),
INT_TO_FLOAT(v[2]), INT_TO_FLOAT(v[3]));
}
static void GLAPIENTRY
loopback_VertexAttrib4NusvARB(GLuint index, const GLushort * v)
{
- ATTRIB(index, USHORT_TO_FLOAT(v[0]), USHORT_TO_FLOAT(v[1]),
+ ATTRIB4(index, USHORT_TO_FLOAT(v[0]), USHORT_TO_FLOAT(v[1]),
USHORT_TO_FLOAT(v[2]), USHORT_TO_FLOAT(v[3]));
}
static void GLAPIENTRY
loopback_VertexAttrib4NuivARB(GLuint index, const GLuint * v)
{
- ATTRIB(index, UINT_TO_FLOAT(v[0]), UINT_TO_FLOAT(v[1]),
+ ATTRIB4(index, UINT_TO_FLOAT(v[0]), UINT_TO_FLOAT(v[1]),
UINT_TO_FLOAT(v[2]), UINT_TO_FLOAT(v[3]));
}
-void
-_mesa_loopback_prefer_float( struct _glapi_table *dest,
- GLboolean prefer_float_colors )
-{
- if (!prefer_float_colors) {
- dest->Color3b = loopback_Color3b;
- dest->Color3d = loopback_Color3d;
- dest->Color3i = loopback_Color3i;
- dest->Color3s = loopback_Color3s;
- dest->Color3ui = loopback_Color3ui;
- dest->Color3us = loopback_Color3us;
- dest->Color4b = loopback_Color4b;
- dest->Color4d = loopback_Color4d;
- dest->Color4i = loopback_Color4i;
- dest->Color4s = loopback_Color4s;
- dest->Color4ui = loopback_Color4ui;
- dest->Color4us = loopback_Color4us;
- dest->Color3bv = loopback_Color3bv;
- dest->Color3dv = loopback_Color3dv;
- dest->Color3iv = loopback_Color3iv;
- dest->Color3sv = loopback_Color3sv;
- dest->Color3uiv = loopback_Color3uiv;
- dest->Color3usv = loopback_Color3usv;
- dest->Color4bv = loopback_Color4bv;
- dest->Color4dv = loopback_Color4dv;
- dest->Color4iv = loopback_Color4iv;
- dest->Color4sv = loopback_Color4sv;
- dest->Color4uiv = loopback_Color4uiv;
- dest->Color4usv = loopback_Color4usv;
- dest->SecondaryColor3bEXT = loopback_SecondaryColor3bEXT;
- dest->SecondaryColor3dEXT = loopback_SecondaryColor3dEXT;
- dest->SecondaryColor3iEXT = loopback_SecondaryColor3iEXT;
- dest->SecondaryColor3sEXT = loopback_SecondaryColor3sEXT;
- dest->SecondaryColor3uiEXT = loopback_SecondaryColor3uiEXT;
- dest->SecondaryColor3usEXT = loopback_SecondaryColor3usEXT;
- dest->SecondaryColor3bvEXT = loopback_SecondaryColor3bvEXT;
- dest->SecondaryColor3dvEXT = loopback_SecondaryColor3dvEXT;
- dest->SecondaryColor3ivEXT = loopback_SecondaryColor3ivEXT;
- dest->SecondaryColor3svEXT = loopback_SecondaryColor3svEXT;
- dest->SecondaryColor3uivEXT = loopback_SecondaryColor3uivEXT;
- dest->SecondaryColor3usvEXT = loopback_SecondaryColor3usvEXT;
- }
- else {
- dest->Color3b = loopback_Color3b_f;
- dest->Color3d = loopback_Color3d_f;
- dest->Color3i = loopback_Color3i_f;
- dest->Color3s = loopback_Color3s_f;
- dest->Color3ui = loopback_Color3ui_f;
- dest->Color3us = loopback_Color3us_f;
- dest->Color4b = loopback_Color4b_f;
- dest->Color4d = loopback_Color4d_f;
- dest->Color4i = loopback_Color4i_f;
- dest->Color4s = loopback_Color4s_f;
- dest->Color4ui = loopback_Color4ui_f;
- dest->Color4us = loopback_Color4us_f;
- dest->Color3bv = loopback_Color3bv_f;
- dest->Color3dv = loopback_Color3dv_f;
- dest->Color3iv = loopback_Color3iv_f;
- dest->Color3sv = loopback_Color3sv_f;
- dest->Color3uiv = loopback_Color3uiv_f;
- dest->Color3usv = loopback_Color3usv_f;
- dest->Color4bv = loopback_Color4bv_f;
- dest->Color4dv = loopback_Color4dv_f;
- dest->Color4iv = loopback_Color4iv_f;
- dest->Color4sv = loopback_Color4sv_f;
- dest->Color4uiv = loopback_Color4uiv_f;
- dest->Color4usv = loopback_Color4usv_f;
- dest->SecondaryColor3bEXT = loopback_SecondaryColor3bEXT_f;
- dest->SecondaryColor3dEXT = loopback_SecondaryColor3dEXT_f;
- dest->SecondaryColor3iEXT = loopback_SecondaryColor3iEXT_f;
- dest->SecondaryColor3sEXT = loopback_SecondaryColor3sEXT_f;
- dest->SecondaryColor3uiEXT = loopback_SecondaryColor3uiEXT_f;
- dest->SecondaryColor3usEXT = loopback_SecondaryColor3usEXT_f;
- dest->SecondaryColor3bvEXT = loopback_SecondaryColor3bvEXT_f;
- dest->SecondaryColor3dvEXT = loopback_SecondaryColor3dvEXT_f;
- dest->SecondaryColor3ivEXT = loopback_SecondaryColor3ivEXT_f;
- dest->SecondaryColor3svEXT = loopback_SecondaryColor3svEXT_f;
- dest->SecondaryColor3uivEXT = loopback_SecondaryColor3uivEXT_f;
- dest->SecondaryColor3usvEXT = loopback_SecondaryColor3usvEXT_f;
- }
-}
-/* Passing prefer_float_colors as true will mean that all colors
- * *except* Color{34}ub{v} are passed as floats. Setting it false will
- * mean all colors *except* Color{34}f{v} are passed as ubytes.
- *
+/*
* This code never registers handlers for any of the entry points
* listed in vtxfmt.h.
*/
void
-_mesa_loopback_init_api_table( struct _glapi_table *dest,
- GLboolean prefer_float_colors )
-{
- _mesa_loopback_prefer_float( dest, prefer_float_colors );
-
+_mesa_loopback_init_api_table( struct _glapi_table *dest )
+{
+ dest->Color3b = loopback_Color3b_f;
+ dest->Color3d = loopback_Color3d_f;
+ dest->Color3i = loopback_Color3i_f;
+ dest->Color3s = loopback_Color3s_f;
+ dest->Color3ui = loopback_Color3ui_f;
+ dest->Color3us = loopback_Color3us_f;
+ dest->Color3ub = loopback_Color3ub_f;
+ dest->Color4b = loopback_Color4b_f;
+ dest->Color4d = loopback_Color4d_f;
+ dest->Color4i = loopback_Color4i_f;
+ dest->Color4s = loopback_Color4s_f;
+ dest->Color4ui = loopback_Color4ui_f;
+ dest->Color4us = loopback_Color4us_f;
+ dest->Color4ub = loopback_Color4ub_f;
+ dest->Color3bv = loopback_Color3bv_f;
+ dest->Color3dv = loopback_Color3dv_f;
+ dest->Color3iv = loopback_Color3iv_f;
+ dest->Color3sv = loopback_Color3sv_f;
+ dest->Color3uiv = loopback_Color3uiv_f;
+ dest->Color3usv = loopback_Color3usv_f;
+ dest->Color3ubv = loopback_Color3ubv_f;
+ dest->Color4bv = loopback_Color4bv_f;
+ dest->Color4dv = loopback_Color4dv_f;
+ dest->Color4iv = loopback_Color4iv_f;
+ dest->Color4sv = loopback_Color4sv_f;
+ dest->Color4uiv = loopback_Color4uiv_f;
+ dest->Color4usv = loopback_Color4usv_f;
+ dest->Color4ubv = loopback_Color4ubv_f;
+
+ dest->SecondaryColor3bEXT = loopback_SecondaryColor3bEXT_f;
+ dest->SecondaryColor3dEXT = loopback_SecondaryColor3dEXT_f;
+ dest->SecondaryColor3iEXT = loopback_SecondaryColor3iEXT_f;
+ dest->SecondaryColor3sEXT = loopback_SecondaryColor3sEXT_f;
+ dest->SecondaryColor3uiEXT = loopback_SecondaryColor3uiEXT_f;
+ dest->SecondaryColor3usEXT = loopback_SecondaryColor3usEXT_f;
+ dest->SecondaryColor3ubEXT = loopback_SecondaryColor3ubEXT_f;
+ dest->SecondaryColor3bvEXT = loopback_SecondaryColor3bvEXT_f;
+ dest->SecondaryColor3dvEXT = loopback_SecondaryColor3dvEXT_f;
+ dest->SecondaryColor3ivEXT = loopback_SecondaryColor3ivEXT_f;
+ dest->SecondaryColor3svEXT = loopback_SecondaryColor3svEXT_f;
+ dest->SecondaryColor3uivEXT = loopback_SecondaryColor3uivEXT_f;
+ dest->SecondaryColor3usvEXT = loopback_SecondaryColor3usvEXT_f;
+ dest->SecondaryColor3ubvEXT = loopback_SecondaryColor3ubvEXT_f;
+
dest->Indexd = loopback_Indexd;
- dest->Indexf = loopback_Indexf;
+ dest->Indexi = loopback_Indexi;
dest->Indexs = loopback_Indexs;
dest->Indexub = loopback_Indexub;
dest->Indexdv = loopback_Indexdv;
- dest->Indexfv = loopback_Indexfv;
dest->Indexiv = loopback_Indexiv;
dest->Indexsv = loopback_Indexsv;
dest->Indexubv = loopback_Indexubv;
struct _glapi_table;
-extern void _mesa_loopback_prefer_float( struct _glapi_table *dest,
- GLboolean prefer_float_colors );
-
-extern void _mesa_loopback_init_api_table( struct _glapi_table *dest,
- GLboolean prefer_float_colors );
+extern void _mesa_loopback_init_api_table( struct _glapi_table *dest );
#endif
#include "glheader.h"
#include "api_noop.h"
#include "api_validate.h"
+#include "api_arrayelt.h"
#include "context.h"
#include "colormac.h"
#include "light.h"
#include "macros.h"
#include "mtypes.h"
+#include "dlist.h"
/* In states where certain vertex components are required for t&l or
ctx->Current.EdgeFlag = *b;
}
-void _mesa_noop_FogCoordfEXT( GLfloat a )
+void _mesa_noop_Indexf( GLfloat f )
{
GET_CURRENT_CONTEXT(ctx);
- ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = a;
+ ctx->Current.Index = f;
}
-void _mesa_noop_FogCoordfvEXT( const GLfloat *v )
+void _mesa_noop_Indexfv( const GLfloat *v )
{
GET_CURRENT_CONTEXT(ctx);
- ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = *v;
+ ctx->Current.Index = *v;
}
-void _mesa_noop_Indexi( GLint i )
+void _mesa_noop_FogCoordfEXT( GLfloat a )
{
GET_CURRENT_CONTEXT(ctx);
- ctx->Current.Index = i;
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_FOG];
+ dest[0] = a;
+ dest[1] = 0.0;
+ dest[2] = 0.0;
+ dest[3] = 1.0;
}
-void _mesa_noop_Indexiv( const GLint *v )
+void _mesa_noop_FogCoordfvEXT( const GLfloat *v )
{
GET_CURRENT_CONTEXT(ctx);
- ctx->Current.Index = *v;
+ GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
+ dest[0] = v[0];
+ dest[1] = 0.0;
+ dest[2] = 0.0;
+ dest[3] = 1.0;
}
void _mesa_noop_Normal3f( GLfloat a, GLfloat b, GLfloat c )
{
GET_CURRENT_CONTEXT(ctx);
GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
- COPY_FLOAT(dest[0], a);
- COPY_FLOAT(dest[1], b);
- COPY_FLOAT(dest[2], c);
+ dest[0] = a;
+ dest[1] = b;
+ dest[2] = c;
+ dest[3] = 1.0;
}
void _mesa_noop_Normal3fv( const GLfloat *v )
{
GET_CURRENT_CONTEXT(ctx);
GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
- COPY_FLOAT(dest[0], v[0]);
- COPY_FLOAT(dest[1], v[1]);
- COPY_FLOAT(dest[2], v[2]);
-}
-
-void _mesa_noop_Materialfv( GLenum face, GLenum pname, const GLfloat *params )
-{
- GET_CURRENT_CONTEXT(ctx);
- GLint i, nr;
- struct gl_material *mat = &ctx->Light.Material;
- GLuint bitmask = _mesa_material_bitmask( ctx, face, pname, ~0,
- "_mesa_noop_Materialfv" );
-
- if (ctx->Light.ColorMaterialEnabled)
- bitmask &= ~ctx->Light.ColorMaterialBitmask;
-
- if (bitmask == 0)
- return;
-
- switch (face) {
- case GL_SHININESS: nr = 1; break;
- case GL_COLOR_INDEXES: nr = 3; break;
- default: nr = 4 ; break;
- }
-
- for (i = 0 ; i < MAT_ATTRIB_MAX ; i++)
- if (bitmask & (1<<i))
- COPY_SZ_4V( mat->Attrib[i], nr, params );
-
- _mesa_update_material( ctx, bitmask );
-}
-
-void _mesa_noop_Color4ub( GLubyte a, GLubyte b, GLubyte c, GLubyte d )
-{
- GET_CURRENT_CONTEXT(ctx);
- GLfloat *color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
- color[0] = UBYTE_TO_FLOAT(a);
- color[1] = UBYTE_TO_FLOAT(b);
- color[2] = UBYTE_TO_FLOAT(c);
- color[3] = UBYTE_TO_FLOAT(d);
-}
-
-void _mesa_noop_Color4ubv( const GLubyte *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- GLfloat *color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
- color[0] = UBYTE_TO_FLOAT(v[0]);
- color[1] = UBYTE_TO_FLOAT(v[1]);
- color[2] = UBYTE_TO_FLOAT(v[2]);
- color[3] = UBYTE_TO_FLOAT(v[3]);
+ dest[0] = v[0];
+ dest[1] = v[1];
+ dest[2] = v[2];
+ dest[3] = 1.0;
}
void _mesa_noop_Color4f( GLfloat a, GLfloat b, GLfloat c, GLfloat d )
color[3] = v[3];
}
-void _mesa_noop_Color3ub( GLubyte a, GLubyte b, GLubyte c )
-{
- GET_CURRENT_CONTEXT(ctx);
- GLfloat *color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
- color[0] = UBYTE_TO_FLOAT(a);
- color[1] = UBYTE_TO_FLOAT(b);
- color[2] = UBYTE_TO_FLOAT(c);
- color[3] = 1.0;
-}
-
-void _mesa_noop_Color3ubv( const GLubyte *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- GLfloat *color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
- color[0] = UBYTE_TO_FLOAT(v[0]);
- color[1] = UBYTE_TO_FLOAT(v[1]);
- color[2] = UBYTE_TO_FLOAT(v[2]);
- color[3] = 1.0;
-}
-
void _mesa_noop_Color3f( GLfloat a, GLfloat b, GLfloat c )
{
GET_CURRENT_CONTEXT(ctx);
if (unit < MAX_TEXTURE_COORD_UNITS)
{
GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit];
- COPY_FLOAT(dest[0], a);
+ dest[0] = a;
dest[1] = 0;
dest[2] = 0;
dest[3] = 1;
if (unit < MAX_TEXTURE_COORD_UNITS)
{
GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit];
- COPY_FLOAT(dest[0], v[0]);
+ dest[0] = v[0];
dest[1] = 0;
dest[2] = 0;
dest[3] = 1;
if (unit < MAX_TEXTURE_COORD_UNITS)
{
GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit];
- COPY_FLOAT(dest[0], a);
- COPY_FLOAT(dest[1], b);
+ dest[0] = a;
+ dest[1] = b;
dest[2] = 0;
dest[3] = 1;
}
if (unit < MAX_TEXTURE_COORD_UNITS)
{
GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit];
- COPY_FLOAT(dest[0], v[0]);
- COPY_FLOAT(dest[1], v[1]);
+ dest[0] = v[0];
+ dest[1] = v[1];
dest[2] = 0;
dest[3] = 1;
}
if (unit < MAX_TEXTURE_COORD_UNITS)
{
GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit];
- COPY_FLOAT(dest[0], a);
- COPY_FLOAT(dest[1], b);
- COPY_FLOAT(dest[2], c);
+ dest[0] = a;
+ dest[1] = b;
+ dest[2] = c;
dest[3] = 1;
}
}
if (unit < MAX_TEXTURE_COORD_UNITS)
{
GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit];
- COPY_FLOAT(dest[0], v[0]);
- COPY_FLOAT(dest[1], v[1]);
- COPY_FLOAT(dest[2], v[2]);
+ dest[0] = v[0];
+ dest[1] = v[1];
+ dest[2] = v[2];
dest[3] = 1;
}
}
if (unit < MAX_TEXTURE_COORD_UNITS)
{
GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit];
- COPY_FLOAT(dest[0], a);
- COPY_FLOAT(dest[1], b);
- COPY_FLOAT(dest[2], c);
+ dest[0] = a;
+ dest[1] = b;
+ dest[2] = c;
dest[3] = d;
}
}
if (unit < MAX_TEXTURE_COORD_UNITS)
{
GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit];
- COPY_FLOAT(dest[0], v[0]);
- COPY_FLOAT(dest[1], v[1]);
- COPY_FLOAT(dest[2], v[2]);
- COPY_FLOAT(dest[3], v[3]);
+ dest[0] = v[0];
+ dest[1] = v[1];
+ dest[2] = v[2];
+ dest[3] = v[3];
}
}
-void _mesa_noop_SecondaryColor3ubEXT( GLubyte a, GLubyte b, GLubyte c )
-{
- GET_CURRENT_CONTEXT(ctx);
- GLfloat *color = ctx->Current.Attrib[VERT_ATTRIB_COLOR1];
- color[0] = UBYTE_TO_FLOAT(a);
- color[1] = UBYTE_TO_FLOAT(b);
- color[2] = UBYTE_TO_FLOAT(c);
- color[3] = 1.0;
-}
-
-void _mesa_noop_SecondaryColor3ubvEXT( const GLubyte *v )
-{
- GET_CURRENT_CONTEXT(ctx);
- GLfloat *color = ctx->Current.Attrib[VERT_ATTRIB_COLOR1];
- color[0] = UBYTE_TO_FLOAT(v[0]);
- color[1] = UBYTE_TO_FLOAT(v[1]);
- color[2] = UBYTE_TO_FLOAT(v[2]);
- color[3] = 1.0;
-}
-
void _mesa_noop_SecondaryColor3fEXT( GLfloat a, GLfloat b, GLfloat c )
{
GET_CURRENT_CONTEXT(ctx);
{
GET_CURRENT_CONTEXT(ctx);
GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
- COPY_FLOAT(dest[0], a);
+ dest[0] = a;
dest[1] = 0;
dest[2] = 0;
dest[3] = 1;
{
GET_CURRENT_CONTEXT(ctx);
GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
- COPY_FLOAT(dest[0], v[0]);
+ dest[0] = v[0];
dest[1] = 0;
dest[2] = 0;
dest[3] = 1;
{
GET_CURRENT_CONTEXT(ctx);
GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
- COPY_FLOAT(dest[0], a);
- COPY_FLOAT(dest[1], b);
+ dest[0] = a;
+ dest[1] = b;
dest[2] = 0;
dest[3] = 1;
}
{
GET_CURRENT_CONTEXT(ctx);
GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
- COPY_FLOAT(dest[0], v[0]);
- COPY_FLOAT(dest[1], v[1]);
+ dest[0] = v[0];
+ dest[1] = v[1];
dest[2] = 0;
dest[3] = 1;
}
{
GET_CURRENT_CONTEXT(ctx);
GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
- COPY_FLOAT(dest[0], a);
- COPY_FLOAT(dest[1], b);
- COPY_FLOAT(dest[2], c);
+ dest[0] = a;
+ dest[1] = b;
+ dest[2] = c;
dest[3] = 1;
}
{
GET_CURRENT_CONTEXT(ctx);
GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
- COPY_FLOAT(dest[0], v[0]);
- COPY_FLOAT(dest[1], v[1]);
- COPY_FLOAT(dest[2], v[2]);
+ dest[0] = v[0];
+ dest[1] = v[1];
+ dest[2] = v[2];
dest[3] = 1;
}
{
GET_CURRENT_CONTEXT(ctx);
GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
- COPY_FLOAT(dest[0], a);
- COPY_FLOAT(dest[1], b);
- COPY_FLOAT(dest[2], c);
- COPY_FLOAT(dest[3], d);
+ dest[0] = a;
+ dest[1] = b;
+ dest[2] = c;
+ dest[3] = d;
}
void _mesa_noop_TexCoord4fv( const GLfloat *v )
{
GET_CURRENT_CONTEXT(ctx);
GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
- COPY_FLOAT(dest[0], v[0]);
- COPY_FLOAT(dest[1], v[1]);
- COPY_FLOAT(dest[2], v[2]);
- COPY_FLOAT(dest[3], v[3]);
+ dest[0] = v[0];
+ dest[1] = v[1];
+ dest[2] = v[2];
+ dest[3] = v[3];
+}
+
+
+
+void _mesa_noop_VertexAttrib1fNV( GLuint index, GLfloat x )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < 16) {
+ ASSIGN_4V(ctx->Current.Attrib[index], x, 0, 0, 1);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ );
+}
+
+void _mesa_noop_VertexAttrib1fvNV( GLuint index, const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < 16) {
+ ASSIGN_4V(ctx->Current.Attrib[index], v[0], 0, 0, 1);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ );
+}
+
+void _mesa_noop_VertexAttrib2fNV( GLuint index, GLfloat x, GLfloat y )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < 16) {
+ ASSIGN_4V(ctx->Current.Attrib[index], x, y, 0, 1);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ );
+}
+
+void _mesa_noop_VertexAttrib2fvNV( GLuint index, const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < 16) {
+ ASSIGN_4V(ctx->Current.Attrib[index], v[0], v[1], 0, 1);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ );
+}
+
+void _mesa_noop_VertexAttrib3fNV( GLuint index, GLfloat x,
+ GLfloat y, GLfloat z )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < 16) {
+ ASSIGN_4V(ctx->Current.Attrib[index], x, y, z, 1);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ );
+}
+
+void _mesa_noop_VertexAttrib3fvNV( GLuint index, const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < 16) {
+ ASSIGN_4V(ctx->Current.Attrib[index], v[0], v[1], v[2], 1);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ );
+}
+
+void _mesa_noop_VertexAttrib4fNV( GLuint index, GLfloat x,
+ GLfloat y, GLfloat z, GLfloat w )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < 16) {
+ ASSIGN_4V(ctx->Current.Attrib[index], x, y, z, w);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ );
+}
+
+void _mesa_noop_VertexAttrib4fvNV( GLuint index, const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (index < 16) {
+ ASSIGN_4V(ctx->Current.Attrib[index], v[0], v[1], v[2], v[3]);
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ );
}
-/* Useful outside begin/end?
+/* Material
+ */
+void _mesa_noop_Materialfv( GLenum face, GLenum pname, const GLfloat *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i, nr;
+ struct gl_material *mat = &ctx->Light.Material;
+ GLuint bitmask = _mesa_material_bitmask( ctx, face, pname, ~0,
+ "_mesa_noop_Materialfv" );
+
+ if (ctx->Light.ColorMaterialEnabled)
+ bitmask &= ~ctx->Light.ColorMaterialBitmask;
+
+ if (bitmask == 0)
+ return;
+
+ switch (face) {
+ case GL_SHININESS: nr = 1; break;
+ case GL_COLOR_INDEXES: nr = 3; break;
+ default: nr = 4 ; break;
+ }
+
+ for (i = 0 ; i < MAT_ATTRIB_MAX ; i++)
+ if (bitmask & (1<<i))
+ COPY_SZ_4V( mat->Attrib[i], nr, params );
+
+ _mesa_update_material( ctx, bitmask );
+}
+
+/* These really are noops outside begin/end:
*/
void _mesa_noop_Vertex2fv( const GLfloat *v )
{
(void) a; (void) b; (void) c; (void) d;
}
+/* Similarly, these have no effect outside begin/end:
+ */
+void _mesa_noop_EvalCoord1f( GLfloat a )
+{
+ (void) a;
+}
+void _mesa_noop_EvalCoord1fv( const GLfloat *v )
+{
+ (void) v;
+}
-void _mesa_noop_VertexAttrib4fNV( GLuint index, GLfloat x,
- GLfloat y, GLfloat z, GLfloat w )
+void _mesa_noop_EvalCoord2f( GLfloat a, GLfloat b )
{
- GET_CURRENT_CONTEXT(ctx);
- if (index < 16) {
- ASSIGN_4V(ctx->Current.Attrib[index], x, y, z, w);
- }
+ (void) a; (void) b;
}
-void _mesa_noop_VertexAttrib4fvNV( GLuint index, const GLfloat *v )
+void _mesa_noop_EvalCoord2fv( const GLfloat *v )
{
- GET_CURRENT_CONTEXT(ctx);
- if (index < 16) {
- ASSIGN_4V(ctx->Current.Attrib[index], v[0], v[1], v[2], v[3]);
- }
+ (void) v;
+}
+
+void _mesa_noop_EvalPoint1( GLint a )
+{
+ (void) a;
+}
+
+void _mesa_noop_EvalPoint2( GLint a, GLint b )
+{
+ (void) a; (void) b;
}
+/* Begin -- call into driver, should result in the vtxfmt being
+ * swapped out:
+ */
+void _mesa_noop_Begin( GLenum mode )
+{
+}
+
+
+/* End -- just raise an error
+ */
+void _mesa_noop_End( void )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_error( ctx, GL_INVALID_OPERATION, __FUNCTION__ );
+}
+
/* Execute a glRectf() function. This is not suitable for GL_COMPILE
* modes (as the test for outside begin/end is not compiled),
return;
glBegin(mode);
- for (i = start ; i <= count ; i++)
+ for (i = start ; i < count ; i++)
glArrayElement( i );
glEnd();
}
count, type, indices ))
glDrawElements( mode, count, type, indices );
}
+
+/*
+ * Eval Mesh
+ */
+
+/* KW: If are compiling, we don't know whether eval will produce a
+ * vertex when it is run in the future. If this is pure immediate
+ * mode, eval is a noop if neither vertex map is enabled.
+ *
+ * Thus we need to have a check in the display list code or
+ * elsewhere for eval(1,2) vertices in the case where
+ * map(1,2)_vertex is disabled, and to purge those vertices from
+ * the vb.
+ */
+void _mesa_noop_EvalMesh1( GLenum mode, GLint i1, GLint i2 )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i;
+ GLfloat u, du;
+ GLenum prim;
+
+ switch (mode) {
+ case GL_POINT:
+ prim = GL_POINTS;
+ break;
+ case GL_LINE:
+ prim = GL_LINE_STRIP;
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)" );
+ return;
+ }
+
+ /* No effect if vertex maps disabled.
+ */
+ if (!ctx->Eval.Map1Vertex4 &&
+ !ctx->Eval.Map1Vertex3 &&
+ !(ctx->VertexProgram.Enabled && ctx->Eval.Map1Attrib[VERT_ATTRIB_POS]))
+ return;
+
+ du = ctx->Eval.MapGrid1du;
+ u = ctx->Eval.MapGrid1u1 + i1 * du;
+
+ glBegin( prim );
+ for (i=i1;i<=i2;i++,u+=du) {
+ glEvalCoord1f( u );
+ }
+ glEnd();
+}
+
+
+
+void _mesa_noop_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat u, du, v, dv, v1, u1;
+ GLint i, j;
+
+ switch (mode) {
+ case GL_POINT:
+ case GL_LINE:
+ case GL_FILL:
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)" );
+ return;
+ }
+
+ /* No effect if vertex maps disabled.
+ */
+ if (!ctx->Eval.Map2Vertex4 &&
+ !ctx->Eval.Map2Vertex3 &&
+ !(ctx->VertexProgram.Enabled && ctx->Eval.Map2Attrib[VERT_ATTRIB_POS]))
+ return;
+
+ du = ctx->Eval.MapGrid2du;
+ dv = ctx->Eval.MapGrid2dv;
+ v1 = ctx->Eval.MapGrid2v1 + j1 * dv;
+ u1 = ctx->Eval.MapGrid2u1 + i1 * du;
+
+ switch (mode) {
+ case GL_POINT:
+ glBegin( GL_POINTS );
+ for (v=v1,j=j1;j<=j2;j++,v+=dv) {
+ for (u=u1,i=i1;i<=i2;i++,u+=du) {
+ glEvalCoord2f(u, v );
+ }
+ }
+ glEnd();
+ break;
+ case GL_LINE:
+ for (v=v1,j=j1;j<=j2;j++,v+=dv) {
+ glBegin( GL_LINE_STRIP );
+ for (u=u1,i=i1;i<=i2;i++,u+=du) {
+ glEvalCoord2f(u, v );
+ }
+ glEnd();
+ }
+ for (u=u1,i=i1;i<=i2;i++,u+=du) {
+ glBegin( GL_LINE_STRIP );
+ for (v=v1,j=j1;j<=j2;j++,v+=dv) {
+ glEvalCoord2f(u, v );
+ }
+ glEnd();
+ }
+ break;
+ case GL_FILL:
+ for (v=v1,j=j1;j<j2;j++,v+=dv) {
+ glBegin( GL_TRIANGLE_STRIP );
+ for (u=u1,i=i1;i<=i2;i++,u+=du) {
+ glEvalCoord2f(u, v );
+ glEvalCoord2f(u, v+dv );
+ }
+ glEnd();
+ }
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)" );
+ return;
+ }
+}
+
+
+
+/* Build a vertexformat full of things to use outside begin/end pairs.
+ *
+ * TODO -- build a whole dispatch table for this purpose, and likewise
+ * for inside begin/end.
+ */
+void _mesa_noop_vtxfmt_init( GLvertexformat *vfmt )
+{
+ vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */
+ vfmt->Begin = _mesa_noop_Begin;
+ vfmt->CallList = _mesa_CallList;
+ vfmt->CallLists = _mesa_CallLists;
+ vfmt->Color3f = _mesa_noop_Color3f;
+ vfmt->Color3fv = _mesa_noop_Color3fv;
+ vfmt->Color4f = _mesa_noop_Color4f;
+ vfmt->Color4fv = _mesa_noop_Color4fv;
+ vfmt->EdgeFlag = _mesa_noop_EdgeFlag;
+ vfmt->EdgeFlagv = _mesa_noop_EdgeFlagv;
+ vfmt->End = _mesa_noop_End;
+ vfmt->EvalCoord1f = _mesa_noop_EvalCoord1f;
+ vfmt->EvalCoord1fv = _mesa_noop_EvalCoord1fv;
+ vfmt->EvalCoord2f = _mesa_noop_EvalCoord2f;
+ vfmt->EvalCoord2fv = _mesa_noop_EvalCoord2fv;
+ vfmt->EvalPoint1 = _mesa_noop_EvalPoint1;
+ vfmt->EvalPoint2 = _mesa_noop_EvalPoint2;
+ vfmt->FogCoordfEXT = _mesa_noop_FogCoordfEXT;
+ vfmt->FogCoordfvEXT = _mesa_noop_FogCoordfvEXT;
+ vfmt->Indexf = _mesa_noop_Indexf;
+ vfmt->Indexfv = _mesa_noop_Indexfv;
+ vfmt->Materialfv = _mesa_noop_Materialfv;
+ vfmt->MultiTexCoord1fARB = _mesa_noop_MultiTexCoord1fARB;
+ vfmt->MultiTexCoord1fvARB = _mesa_noop_MultiTexCoord1fvARB;
+ vfmt->MultiTexCoord2fARB = _mesa_noop_MultiTexCoord2fARB;
+ vfmt->MultiTexCoord2fvARB = _mesa_noop_MultiTexCoord2fvARB;
+ vfmt->MultiTexCoord3fARB = _mesa_noop_MultiTexCoord3fARB;
+ vfmt->MultiTexCoord3fvARB = _mesa_noop_MultiTexCoord3fvARB;
+ vfmt->MultiTexCoord4fARB = _mesa_noop_MultiTexCoord4fARB;
+ vfmt->MultiTexCoord4fvARB = _mesa_noop_MultiTexCoord4fvARB;
+ vfmt->Normal3f = _mesa_noop_Normal3f;
+ vfmt->Normal3fv = _mesa_noop_Normal3fv;
+ vfmt->SecondaryColor3fEXT = _mesa_noop_SecondaryColor3fEXT;
+ vfmt->SecondaryColor3fvEXT = _mesa_noop_SecondaryColor3fvEXT;
+ vfmt->TexCoord1f = _mesa_noop_TexCoord1f;
+ vfmt->TexCoord1fv = _mesa_noop_TexCoord1fv;
+ vfmt->TexCoord2f = _mesa_noop_TexCoord2f;
+ vfmt->TexCoord2fv = _mesa_noop_TexCoord2fv;
+ vfmt->TexCoord3f = _mesa_noop_TexCoord3f;
+ vfmt->TexCoord3fv = _mesa_noop_TexCoord3fv;
+ vfmt->TexCoord4f = _mesa_noop_TexCoord4f;
+ vfmt->TexCoord4fv = _mesa_noop_TexCoord4fv;
+ vfmt->Vertex2f = _mesa_noop_Vertex2f;
+ vfmt->Vertex2fv = _mesa_noop_Vertex2fv;
+ vfmt->Vertex3f = _mesa_noop_Vertex3f;
+ vfmt->Vertex3fv = _mesa_noop_Vertex3fv;
+ vfmt->Vertex4f = _mesa_noop_Vertex4f;
+ vfmt->Vertex4fv = _mesa_noop_Vertex4fv;
+ vfmt->VertexAttrib1fNV = _mesa_noop_VertexAttrib1fNV;
+ vfmt->VertexAttrib1fvNV = _mesa_noop_VertexAttrib1fvNV;
+ vfmt->VertexAttrib2fNV = _mesa_noop_VertexAttrib2fNV;
+ vfmt->VertexAttrib2fvNV = _mesa_noop_VertexAttrib2fvNV;
+ vfmt->VertexAttrib3fNV = _mesa_noop_VertexAttrib3fNV;
+ vfmt->VertexAttrib3fvNV = _mesa_noop_VertexAttrib3fvNV;
+ vfmt->VertexAttrib4fNV = _mesa_noop_VertexAttrib4fNV;
+ vfmt->VertexAttrib4fvNV = _mesa_noop_VertexAttrib4fvNV;
+
+ vfmt->Rectf = _mesa_noop_Rectf;
+
+ vfmt->DrawArrays = _mesa_noop_DrawArrays;
+ vfmt->DrawElements = _mesa_noop_DrawElements;
+ vfmt->DrawRangeElements = _mesa_noop_DrawRangeElements;
+ vfmt->EvalMesh1 = _mesa_noop_EvalMesh1;
+ vfmt->EvalMesh2 = _mesa_noop_EvalMesh2;
+}
extern void _mesa_noop_FogCoordfvEXT( const GLfloat *v );
-extern void _mesa_noop_Indexi( GLint i );
+extern void _mesa_noop_Indexf( GLfloat i );
-extern void _mesa_noop_Indexiv( const GLint *v );
+extern void _mesa_noop_Indexfv( const GLfloat *v );
extern void _mesa_noop_Normal3f( GLfloat a, GLfloat b, GLfloat c );
extern void _mesa_noop_Vertex4f( GLfloat a, GLfloat b, GLfloat c, GLfloat d );
+extern void _mesa_noop_VertexAttrib1fNV( GLuint index, GLfloat x );
+
+extern void _mesa_noop_VertexAttrib1fvNV( GLuint index, const GLfloat *v );
+
+extern void _mesa_noop_VertexAttrib2fNV( GLuint index, GLfloat x, GLfloat y );
+extern void _mesa_noop_VertexAttrib2fvNV( GLuint index, const GLfloat *v );
+
+extern void _mesa_noop_VertexAttrib3fNV( GLuint index, GLfloat x,
+ GLfloat y, GLfloat z );
+extern void _mesa_noop_VertexAttrib3fvNV( GLuint index, const GLfloat *v );
+
extern void _mesa_noop_VertexAttrib4fNV( GLuint index, GLfloat x,
GLfloat y, GLfloat z, GLfloat w );
extern void _mesa_noop_VertexAttrib4fvNV( GLuint index, const GLfloat *v );
+extern void _mesa_noop_End( void );
+extern void _mesa_noop_Begin( GLenum mode );
+extern void _mesa_noop_EvalPoint2( GLint a, GLint b );
+extern void _mesa_noop_EvalPoint1( GLint a );
+extern void _mesa_noop_EvalCoord2fv( const GLfloat *v );
+extern void _mesa_noop_EvalCoord2f( GLfloat a, GLfloat b );
+extern void _mesa_noop_EvalCoord1fv( const GLfloat *v );
+extern void _mesa_noop_EvalCoord1f( GLfloat a );
+
+extern void _mesa_noop_vtxfmt_init( GLvertexformat *vfmt );
+
+extern void _mesa_noop_EvalMesh2( GLenum mode, GLint i1, GLint i2,
+ GLint j1, GLint j2 );
+
+extern void _mesa_noop_EvalMesh1( GLenum mode, GLint i1, GLint i2 );
/* Not strictly a noop -- translate Rectf down to Begin/End and
#if _HAVE_FULL_GL
_mesa_init_dlist_table(ctx->Save, dispatchSize);
+ _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
- ctx->ExecPrefersFloat = GL_FALSE;
- ctx->SavePrefersFloat = GL_FALSE;
/* Neutral tnl module stuff */
_mesa_init_exec_vtxfmt( ctx );
ctx->TnlModule.Current = NULL;
ctx->TnlModule.SwapCount = 0;
-
#endif
return GL_TRUE;
#include "glapi.h"
+#include "imports.h"
#include "mtypes.h"
/** \name Macros for contexts/flushing. */
/*@{*/
+
/**
* Flush vertices.
*
* Checks if dd_function_table::NeedFlush is marked to flush stored vertices,
* and calls dd_function_table::FlushVertices if so. Marks
* __GLcontextRec::NewState with \p newstate.
- *
- * \todo Eventually let the driver specify what state changes require a flush:
*/
#define FLUSH_VERTICES(ctx, newstate) \
do { \
* these conditions.
*/
GLuint NeedFlush;
+ GLuint SaveNeedFlush;
/**
* If inside glBegin()/glEnd(), it should ASSERT(0). Otherwise, if
* FLUSH_UPDATE_CURRENT bit, even after performing the update.
*/
void (*FlushVertices)( GLcontext *ctx, GLuint flags );
+ void (*SaveFlushVertices)( GLcontext *ctx );
+
+ /**
+ * Give the driver the opportunity to hook in its own vtxfmt for
+ * compiling optimized display lists. This is called on each valid
+ * glBegin() during list compilation.
+ */
+ GLboolean (*NotifySaveBegin)( GLcontext *ctx, GLenum mode );
/**
* Notify driver that the special derived value _NeedEyeCoords has
void (GLAPIENTRYP ArrayElement)( GLint ); /* NOTE */
void (GLAPIENTRYP Color3f)( GLfloat, GLfloat, GLfloat );
void (GLAPIENTRYP Color3fv)( const GLfloat * );
- void (GLAPIENTRYP Color3ub)( GLubyte, GLubyte, GLubyte );
- void (GLAPIENTRYP Color3ubv)( const GLubyte * );
void (GLAPIENTRYP Color4f)( GLfloat, GLfloat, GLfloat, GLfloat );
void (GLAPIENTRYP Color4fv)( const GLfloat * );
- void (GLAPIENTRYP Color4ub)( GLubyte, GLubyte, GLubyte, GLubyte );
- void (GLAPIENTRYP Color4ubv)( const GLubyte * );
void (GLAPIENTRYP EdgeFlag)( GLboolean );
void (GLAPIENTRYP EdgeFlagv)( const GLboolean * );
void (GLAPIENTRYP EvalCoord1f)( GLfloat ); /* NOTE */
void (GLAPIENTRYP EvalPoint2)( GLint, GLint ); /* NOTE */
void (GLAPIENTRYP FogCoordfEXT)( GLfloat );
void (GLAPIENTRYP FogCoordfvEXT)( const GLfloat * );
- void (GLAPIENTRYP Indexi)( GLint );
- void (GLAPIENTRYP Indexiv)( const GLint * );
+ void (GLAPIENTRYP Indexf)( GLfloat );
+ void (GLAPIENTRYP Indexfv)( const GLfloat * );
void (GLAPIENTRYP Materialfv)( GLenum face, GLenum pname, const GLfloat * ); /* NOTE */
void (GLAPIENTRYP MultiTexCoord1fARB)( GLenum, GLfloat );
void (GLAPIENTRYP MultiTexCoord1fvARB)( GLenum, const GLfloat * );
void (GLAPIENTRYP Normal3fv)( const GLfloat * );
void (GLAPIENTRYP SecondaryColor3fEXT)( GLfloat, GLfloat, GLfloat );
void (GLAPIENTRYP SecondaryColor3fvEXT)( const GLfloat * );
- void (GLAPIENTRYP SecondaryColor3ubEXT)( GLubyte, GLubyte, GLubyte );
- void (GLAPIENTRYP SecondaryColor3ubvEXT)( const GLubyte * );
void (GLAPIENTRYP TexCoord1f)( GLfloat );
void (GLAPIENTRYP TexCoord1fv)( const GLfloat * );
void (GLAPIENTRYP TexCoord2f)( GLfloat, GLfloat );
void (GLAPIENTRYP Vertex4f)( GLfloat, GLfloat, GLfloat, GLfloat );
void (GLAPIENTRYP Vertex4fv)( const GLfloat * );
void (GLAPIENTRYP CallList)( GLuint ); /* NOTE */
+ void (GLAPIENTRYP CallLists)( GLsizei, GLenum, const GLvoid * ); /* NOTE */
void (GLAPIENTRYP Begin)( GLenum );
void (GLAPIENTRYP End)( void );
+ void (GLAPIENTRYP VertexAttrib1fNV)( GLuint index, GLfloat x );
+ void (GLAPIENTRYP VertexAttrib1fvNV)( GLuint index, const GLfloat *v );
+ void (GLAPIENTRYP VertexAttrib2fNV)( GLuint index, GLfloat x, GLfloat y );
+ void (GLAPIENTRYP VertexAttrib2fvNV)( GLuint index, const GLfloat *v );
+ void (GLAPIENTRYP VertexAttrib3fNV)( GLuint index, GLfloat x, GLfloat y, GLfloat z );
+ void (GLAPIENTRYP VertexAttrib3fvNV)( GLuint index, const GLfloat *v );
void (GLAPIENTRYP VertexAttrib4fNV)( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w );
void (GLAPIENTRYP VertexAttrib4fvNV)( GLuint index, const GLfloat *v );
/*@}*/
/**
* \name Array
- *
- * These may or may not belong here. Heuristic: if an array is
- * enabled, the installed vertex format should support that array and
- * its current size natively.
*/
/*@{*/
void (GLAPIENTRYP DrawArrays)( GLenum mode, GLint start, GLsizei count );
void (GLAPIENTRYP EvalMesh2)( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 );
/*@}*/
- /**
- * Should core try to send colors to glColor4f or glColor4chan,
- * where it has a choice?
- */
- GLboolean prefer_float_colors;
} GLvertexformat;
#include "glheader.h"
#include "imports.h"
+#include "api_arrayelt.h"
#include "api_loopback.h"
#include "config.h"
#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
#include "math/m_xform.h"
+/**
+ * Flush vertices.
+ *
+ * \param ctx GL context.
+ *
+ * Checks if dd_function_table::SaveNeedFlush is marked to flush
+ * stored (save) vertices, and calls
+ * dd_function_table::SaveFlushVertices if so.
+ */
+#define SAVE_FLUSH_VERTICES(ctx) \
+do { \
+ if (ctx->Driver.SaveNeedFlush) \
+ ctx->Driver.SaveFlushVertices(ctx); \
+} while (0)
+
/**
* Macro to assert that the API call was made outside the
#define ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx) \
do { \
ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx); \
- FLUSH_VERTICES(ctx, 0); \
+ SAVE_FLUSH_VERTICES(ctx); \
} while (0)
/**
#define ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, retval)\
do { \
ASSERT_OUTSIDE_SAVE_BEGIN_END_WITH_RETVAL(ctx, retval); \
- FLUSH_VERTICES(ctx, 0); \
+ SAVE_FLUSH_VERTICES(ctx); \
} while (0)
OPCODE_PROGRAM_STRING_ARB,
OPCODE_PROGRAM_ENV_PARAMETER_ARB,
+
+ /* Vertex attributes -- fallback for when optimized display
+ * list build isn't active.
+ */
+ OPCODE_ATTR_1F,
+ OPCODE_ATTR_2F,
+ OPCODE_ATTR_3F,
+ OPCODE_ATTR_4F,
+ OPCODE_MATERIAL,
+ OPCODE_INDEX,
+ OPCODE_EDGEFLAG,
+ OPCODE_BEGIN,
+ OPCODE_END,
+ OPCODE_RECTF,
+ OPCODE_EVAL_C1,
+ OPCODE_EVAL_C2,
+ OPCODE_EVAL_P1,
+ OPCODE_EVAL_P2,
+
+
/* The following three are meta instructions */
OPCODE_ERROR, /* raise compiled-in error */
OPCODE_CONTINUE,
InstSize[OPCODE_PROGRAM_STRING_ARB] = 5;
InstSize[OPCODE_PROGRAM_ENV_PARAMETER_ARB] = 7;
#endif
+ InstSize[OPCODE_ATTR_1F] = 3;
+ InstSize[OPCODE_ATTR_2F] = 4;
+ InstSize[OPCODE_ATTR_3F] = 5;
+ InstSize[OPCODE_ATTR_4F] = 6;
+ InstSize[OPCODE_MATERIAL] = 7;
+ InstSize[OPCODE_INDEX] = 2;
+ InstSize[OPCODE_EDGEFLAG] = 2;
+ InstSize[OPCODE_BEGIN] = 2;
+ InstSize[OPCODE_END] = 1;
+ InstSize[OPCODE_RECTF] = 5;
+ InstSize[OPCODE_EVAL_C1] = 2;
+ InstSize[OPCODE_EVAL_C2] = 3;
+ InstSize[OPCODE_EVAL_P1] = 2;
+ InstSize[OPCODE_EVAL_P2] = 3;
}
init_flag = 1;
}
}
#endif
- if (ctx->CurrentPos + count + 2 > BLOCK_SIZE) {
+ if (ctx->ListState.CurrentPos + count + 2 > BLOCK_SIZE) {
/* This block is full. Allocate a new block and chain to it */
- n = ctx->CurrentBlock + ctx->CurrentPos;
+ n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos;
n[0].opcode = OPCODE_CONTINUE;
newblock = (Node *) MALLOC( sizeof(Node) * BLOCK_SIZE );
if (!newblock) {
return NULL;
}
n[1].next = (Node *) newblock;
- ctx->CurrentBlock = newblock;
- ctx->CurrentPos = 0;
+ ctx->ListState.CurrentBlock = newblock;
+ ctx->ListState.CurrentPos = 0;
}
- n = ctx->CurrentBlock + ctx->CurrentPos;
- ctx->CurrentPos += count;
+ n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos;
+ ctx->ListState.CurrentPos += count;
n[0].opcode = (OpCode) opcode;
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- FLUSH_CURRENT(ctx, 0);
+ SAVE_FLUSH_VERTICES(ctx);
n = ALLOC_INSTRUCTION( ctx, OPCODE_CALL_LIST, 1 );
if (n) {
n[1].ui = list;
}
+
+ /* After this, we don't know what begin/end state we're in:
+ */
+ ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
+
if (ctx->ExecuteFlag) {
(*ctx->Exec->CallList)( list );
}
GLint i;
GLboolean typeErrorFlag;
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- FLUSH_CURRENT(ctx, 0);
+ SAVE_FLUSH_VERTICES(ctx);
switch (type) {
case GL_BYTE:
n[2].b = typeErrorFlag;
}
}
+
+ /* After this, we don't know what begin/end state we're in:
+ */
+ ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
+
if (ctx->ExecuteFlag) {
(*ctx->Exec->CallLists)( n, type, lists );
}
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- FLUSH_CURRENT(ctx, 0);
n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_MATERIAL, 2 );
if (n) {
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- FLUSH_CURRENT(ctx, 0);
(void) ALLOC_INSTRUCTION( ctx, OPCODE_POP_MATRIX, 0 );
if (ctx->ExecuteFlag) {
(*ctx->Exec->PopMatrix)();
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- FLUSH_CURRENT(ctx, 0);
n = ALLOC_INSTRUCTION( ctx, OPCODE_PUSH_ATTRIB, 1 );
if (n) {
n[1].bf = mask;
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- FLUSH_CURRENT(ctx, 0);
n = ALLOC_INSTRUCTION( ctx, OPCODE_RASTER_POS, 4 );
if (n) {
n[1].f = x;
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- FLUSH_CURRENT(ctx, 0);
n = ALLOC_INSTRUCTION( ctx, OPCODE_WINDOW_POS, 4 );
if (n) {
n[1].f = x;
+
+static void save_Attr1f( GLenum attr, GLfloat x )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES( ctx );
+ n = ALLOC_INSTRUCTION( ctx, OPCODE_ATTR_1F, 2 );
+ if (n) {
+ n[1].e = attr;
+ n[2].f = x;
+ }
+
+ ctx->ListState.ActiveAttribSize[attr] = 1;
+ ASSIGN_4V( ctx->ListState.CurrentAttrib[attr], x, 0, 0, 1);
+
+ if (ctx->ExecuteFlag) {
+ (*ctx->Exec->VertexAttrib1fNV)( attr, x );
+ }
+}
+
+static void save_Attr2f( GLenum attr, GLfloat x, GLfloat y )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES( ctx );
+ n = ALLOC_INSTRUCTION( ctx, OPCODE_ATTR_2F, 3 );
+ if (n) {
+ n[1].e = attr;
+ n[2].f = x;
+ n[3].f = y;
+ }
+
+ ctx->ListState.ActiveAttribSize[attr] = 2;
+ ASSIGN_4V( ctx->ListState.CurrentAttrib[attr], x, y, 0, 1);
+
+ if (ctx->ExecuteFlag) {
+ (*ctx->Exec->VertexAttrib2fNV)( attr, x, y );
+ }
+}
+
+static void save_Attr3f( GLenum attr, GLfloat x, GLfloat y, GLfloat z )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES( ctx );
+ n = ALLOC_INSTRUCTION( ctx, OPCODE_ATTR_3F, 4 );
+ if (n) {
+ n[1].e = attr;
+ n[2].f = x;
+ n[3].f = y;
+ n[4].f = z;
+ }
+
+ ctx->ListState.ActiveAttribSize[attr] = 3;
+ ASSIGN_4V( ctx->ListState.CurrentAttrib[attr], x, y, z, 1);
+
+ if (ctx->ExecuteFlag) {
+ (*ctx->Exec->VertexAttrib3fNV)( attr, x, y, z );
+ }
+}
+
+static void save_Attr4f( GLenum attr, GLfloat x, GLfloat y, GLfloat z,
+ GLfloat w )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES( ctx );
+ n = ALLOC_INSTRUCTION( ctx, OPCODE_ATTR_4F, 5 );
+ if (n) {
+ n[1].e = attr;
+ n[2].f = x;
+ n[3].f = y;
+ n[4].f = z;
+ n[5].f = w;
+ }
+
+ ctx->ListState.ActiveAttribSize[attr] = 4;
+ ASSIGN_4V( ctx->ListState.CurrentAttrib[attr], x, y, z, w);
+
+ if (ctx->ExecuteFlag) {
+ (*ctx->Exec->VertexAttrib4fNV)( attr, x, y, z, w );
+ }
+}
+
+static void save_EvalCoord1f( GLfloat x )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES( ctx );
+ n = ALLOC_INSTRUCTION( ctx, OPCODE_EVAL_C1, 1 );
+ if (n) {
+ n[1].f = x;
+ }
+ if (ctx->ExecuteFlag) {
+ (*ctx->Exec->EvalCoord1f)( x );
+ }
+}
+
+static void save_EvalCoord1fv( const GLfloat *v )
+{
+ save_EvalCoord1f( v[0] );
+}
+
+static void save_EvalCoord2f( GLfloat x, GLfloat y )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES( ctx );
+ n = ALLOC_INSTRUCTION( ctx, OPCODE_EVAL_C2, 2 );
+ if (n) {
+ n[1].f = x;
+ n[2].f = y;
+ }
+ if (ctx->ExecuteFlag) {
+ (*ctx->Exec->EvalCoord2f)( x, y );
+ }
+}
+
+static void save_EvalCoord2fv( const GLfloat *v )
+{
+ save_EvalCoord2f( v[0], v[1] );
+}
+
+
+static void save_EvalPoint1( GLint x )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES( ctx );
+ n = ALLOC_INSTRUCTION( ctx, OPCODE_EVAL_P1, 1 );
+ if (n) {
+ n[1].i = x;
+ }
+ if (ctx->ExecuteFlag) {
+ (*ctx->Exec->EvalPoint1)( x );
+ }
+}
+
+static void save_EvalPoint2( GLint x, GLint y )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES( ctx );
+ n = ALLOC_INSTRUCTION( ctx, OPCODE_EVAL_P2, 2 );
+ if (n) {
+ n[1].i = x;
+ n[2].i = y;
+ }
+ if (ctx->ExecuteFlag) {
+ (*ctx->Exec->EvalPoint2)( x, y );
+ }
+}
+
+static void save_Indexf( GLfloat x )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES( ctx );
+ n = ALLOC_INSTRUCTION( ctx, OPCODE_INDEX, 1 );
+ if (n) {
+ n[1].f = x;
+ }
+
+ ctx->ListState.ActiveIndex = 1;
+ ctx->ListState.CurrentIndex = x;
+
+ if (ctx->ExecuteFlag) {
+ (*ctx->Exec->Indexi)( x );
+ }
+}
+
+static void save_Indexfv( const GLfloat *v )
+{
+ save_Indexf( v[0] );
+}
+
+static void save_EdgeFlag( GLboolean x )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES( ctx );
+ n = ALLOC_INSTRUCTION( ctx, OPCODE_EDGEFLAG, 1 );
+ if (n) {
+ n[1].b = x;
+ }
+
+ ctx->ListState.ActiveEdgeFlag = 1;
+ ctx->ListState.CurrentEdgeFlag = x;
+
+ if (ctx->ExecuteFlag) {
+ (*ctx->Exec->EdgeFlag)( x );
+ }
+}
+
+static void save_EdgeFlagv( const GLboolean *v )
+{
+ save_EdgeFlag( v[0] );
+}
+
+static void save_Materialfv( GLenum face, GLenum pname, const GLfloat *param )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ int args, i;
+
+ SAVE_FLUSH_VERTICES( ctx );
+
+ switch (face) {
+ case GL_BACK:
+ case GL_FRONT:
+ case GL_FRONT_AND_BACK:
+ break;
+ default:
+ _mesa_compile_error( ctx, GL_INVALID_ENUM, "material(face)" );
+ return;
+ }
+
+ switch (pname) {
+ case GL_EMISSION:
+ case GL_AMBIENT:
+ case GL_DIFFUSE:
+ case GL_SPECULAR:
+ case GL_AMBIENT_AND_DIFFUSE:
+ args = 4;
+ break;
+ case GL_SHININESS:
+ args = 1;
+ break;
+ case GL_COLOR_INDEXES:
+ args = 3;
+ break;
+ default:
+ _mesa_compile_error( ctx, GL_INVALID_ENUM, "material(pname)" );
+ return;
+ }
+
+ n = ALLOC_INSTRUCTION( ctx, OPCODE_MATERIAL, 6 );
+ if (n) {
+ n[1].e = face;
+ n[2].e = pname;
+ for (i = 0 ; i < args ; i++)
+ n[3+i].f = param[i];
+ }
+
+ {
+ GLuint bitmask = _mesa_material_bitmask( ctx, face, pname, ~0, 0 );
+ for (i = 0 ; i < MAT_ATTRIB_MAX ; i++)
+ if (bitmask & (1<<i)) {
+ ctx->ListState.ActiveMaterialSize[i] = args;
+ COPY_SZ_4V( ctx->ListState.CurrentMaterial[i], args, param );
+ }
+ }
+
+ if (ctx->ExecuteFlag) {
+ (*ctx->Exec->Materialfv)( face, pname, param );
+ }
+}
+
+static void save_Begin( GLenum mode )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ GLboolean error = GL_FALSE;
+
+ if (mode < GL_POINTS || mode > GL_POLYGON) {
+ _mesa_compile_error( ctx, GL_INVALID_ENUM, "Begin (mode)");
+ error = GL_TRUE;
+ }
+ else if (ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN) {
+ /* Typically the first begin. This may raise an error on
+ * playback, depending on whether CallList is issued from inside
+ * a begin/end or not.
+ */
+ ctx->Driver.CurrentSavePrimitive = PRIM_INSIDE_UNKNOWN_PRIM;
+ }
+ else if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END) {
+ ctx->Driver.CurrentSavePrimitive = mode;
+ }
+ else {
+ _mesa_compile_error( ctx, GL_INVALID_OPERATION, "recursive begin" );
+ error = GL_TRUE;
+ }
+
+ if (!error) {
+ /* Give the driver an opportunity to hook in an optimized
+ * display list compiler.
+ */
+ if (ctx->Driver.NotifySaveBegin( ctx, mode ))
+ return;
+
+ SAVE_FLUSH_VERTICES( ctx );
+ n = ALLOC_INSTRUCTION( ctx, OPCODE_BEGIN, 1 );
+ if (n) {
+ n[1].e = mode;
+ }
+ }
+
+ if (ctx->ExecuteFlag) {
+ (*ctx->Exec->Begin)( mode );
+ }
+}
+
+static void save_End( void )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ SAVE_FLUSH_VERTICES( ctx );
+ (void) ALLOC_INSTRUCTION( ctx, OPCODE_END, 0 );
+ ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
+ if (ctx->ExecuteFlag) {
+ (*ctx->Exec->End)( );
+ }
+}
+
+static void save_Rectf( GLfloat a, GLfloat b,
+ GLfloat c, GLfloat d )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ SAVE_FLUSH_VERTICES( ctx );
+ n = ALLOC_INSTRUCTION( ctx, OPCODE_RECTF, 4 );
+ if (n) {
+ n[1].f = a;
+ n[2].f = b;
+ n[3].f = c;
+ n[4].f = d;
+ }
+ if (ctx->ExecuteFlag) {
+ (*ctx->Exec->Rectf)( a, b, c, d );
+ }
+}
+
+/*
+ */
+static void save_Vertex2f( GLfloat x, GLfloat y )
+{
+ save_Attr2f( VERT_ATTRIB_POS, x, y );
+}
+
+static void save_Vertex2fv( const GLfloat *v )
+{
+ save_Attr2f( VERT_ATTRIB_POS, v[0], v[1] );
+}
+
+static void save_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
+{
+ save_Attr3f( VERT_ATTRIB_POS, x, y, z );
+}
+
+static void save_Vertex3fv( const GLfloat *v )
+{
+ save_Attr3f( VERT_ATTRIB_POS, v[0], v[1], v[2] );
+}
+
+static void save_Vertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
+{
+ save_Attr4f( VERT_ATTRIB_POS, x, y, z, w );
+}
+
+static void save_Vertex4fv( const GLfloat *v )
+{
+ save_Attr4f( VERT_ATTRIB_POS, v[0], v[1], v[2], v[3] );
+}
+
+static void save_TexCoord1f( GLfloat x )
+{
+ save_Attr1f( VERT_ATTRIB_TEX0, x );
+}
+
+static void save_TexCoord1fv( const GLfloat *v )
+{
+ save_Attr1f( VERT_ATTRIB_TEX0, v[0] );
+}
+
+static void save_TexCoord2f( GLfloat x, GLfloat y )
+{
+ save_Attr2f( VERT_ATTRIB_TEX0, x, y );
+}
+
+static void save_TexCoord2fv( const GLfloat *v )
+{
+ save_Attr2f( VERT_ATTRIB_TEX0, v[0], v[1] );
+}
+
+static void save_TexCoord3f( GLfloat x, GLfloat y, GLfloat z )
+{
+ save_Attr3f( VERT_ATTRIB_TEX0, x, y, z );
+}
+
+static void save_TexCoord3fv( const GLfloat *v )
+{
+ save_Attr3f( VERT_ATTRIB_TEX0, v[0], v[1], v[2] );
+}
+
+static void save_TexCoord4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
+{
+ save_Attr4f( VERT_ATTRIB_TEX0, x, y, z, w );
+}
+
+static void save_TexCoord4fv( const GLfloat *v )
+{
+ save_Attr4f( VERT_ATTRIB_TEX0, v[0], v[1], v[2], v[3] );
+}
+
+static void save_Normal3f( GLfloat x, GLfloat y, GLfloat z )
+{
+ save_Attr3f( VERT_ATTRIB_NORMAL, x, y, z );
+}
+
+static void save_Normal3fv( const GLfloat *v )
+{
+ save_Attr3f( VERT_ATTRIB_NORMAL, v[0], v[1], v[2] );
+}
+
+static void save_FogCoordfEXT( GLfloat x )
+{
+ save_Attr1f( VERT_ATTRIB_FOG, x );
+}
+
+static void save_FogCoordfvEXT( const GLfloat *v )
+{
+ save_Attr1f( VERT_ATTRIB_FOG, v[0] );
+}
+
+static void save_Color3f( GLfloat x, GLfloat y, GLfloat z )
+{
+ save_Attr3f( VERT_ATTRIB_COLOR0, x, y, z );
+}
+
+static void save_Color3fv( const GLfloat *v )
+{
+ save_Attr3f( VERT_ATTRIB_COLOR0, v[0], v[1], v[2] );
+}
+
+static void save_Color4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
+{
+ save_Attr4f( VERT_ATTRIB_COLOR0, x, y, z, w );
+}
+
+static void save_Color4fv( const GLfloat *v )
+{
+ save_Attr4f( VERT_ATTRIB_COLOR0, v[0], v[1], v[2], v[3] );
+}
+
+static void save_SecondaryColor3fEXT( GLfloat x, GLfloat y, GLfloat z )
+{
+ save_Attr3f( VERT_ATTRIB_COLOR1, x, y, z );
+}
+
+static void save_SecondaryColor3fvEXT( const GLfloat *v )
+{
+ save_Attr3f( VERT_ATTRIB_COLOR1, v[0], v[1], v[2] );
+}
+
+
+/* Just call the respective ATTR for texcoord
+ */
+static void save_MultiTexCoord1f( GLenum target, GLfloat x )
+{
+ GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
+ save_Attr1f( attr, x );
+}
+
+static void save_MultiTexCoord1fv( GLenum target, const GLfloat *v )
+{
+ GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
+ save_Attr1f( attr, v[0] );
+}
+
+static void save_MultiTexCoord2f( GLenum target, GLfloat x, GLfloat y )
+{
+ GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
+ save_Attr2f( attr, x, y );
+}
+
+static void save_MultiTexCoord2fv( GLenum target, const GLfloat *v )
+{
+ GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
+ save_Attr2f( attr, v[0], v[1] );
+}
+
+static void save_MultiTexCoord3f( GLenum target, GLfloat x, GLfloat y,
+ GLfloat z)
+{
+ GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
+ save_Attr3f( attr, x, y, z );
+}
+
+static void save_MultiTexCoord3fv( GLenum target, const GLfloat *v )
+{
+ GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
+ save_Attr3f( attr, v[0], v[1], v[2] );
+}
+
+static void save_MultiTexCoord4f( GLenum target, GLfloat x, GLfloat y,
+ GLfloat z, GLfloat w )
+{
+ GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
+ save_Attr4f( attr, x, y, z, w );
+}
+
+static void save_MultiTexCoord4fv( GLenum target, const GLfloat *v )
+{
+ GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
+ save_Attr4f( attr, v[0], v[1], v[2], v[3] );
+}
+
+
+static void enum_error()
+{
+ GET_CURRENT_CONTEXT( ctx );
+ _mesa_error( ctx, GL_INVALID_ENUM, "VertexAttribfNV" );
+}
+
+/* First level for NV_vertex_program:
+ *
+ * Check for errors at compile time?.
+ */
+static void save_VertexAttrib1fNV( GLuint index, GLfloat x )
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr1f( index, x );
+ else
+ enum_error();
+}
+
+static void save_VertexAttrib1fvNV( GLuint index, const GLfloat *v )
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr1f( index, v[0] );
+ else
+ enum_error();
+}
+
+static void save_VertexAttrib2fNV( GLuint index, GLfloat x, GLfloat y )
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr2f( index, x, y );
+ else
+ enum_error();
+}
+
+static void save_VertexAttrib2fvNV( GLuint index, const GLfloat *v )
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr2f( index, v[0], v[1] );
+ else
+ enum_error();
+}
+
+static void save_VertexAttrib3fNV( GLuint index, GLfloat x, GLfloat y,
+ GLfloat z )
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr3f( index, x, y, z );
+ else
+ enum_error();
+}
+
+static void save_VertexAttrib3fvNV( GLuint index, const GLfloat *v )
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr3f( index, v[0], v[1], v[2] );
+ else
+ enum_error();
+}
+
+static void save_VertexAttrib4fNV( GLuint index, GLfloat x, GLfloat y,
+ GLfloat z, GLfloat w )
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr4f( index, x, y, z, w );
+ else
+ enum_error();
+}
+
+static void save_VertexAttrib4fvNV( GLuint index, const GLfloat *v )
+{
+ if (index < VERT_ATTRIB_MAX)
+ save_Attr4f( index, v[0], v[1], v[2], v[3] );
+ else
+ enum_error();
+}
+
+
+
+
+
/* KW: Compile commands
*
* Will appear in the list before the vertex buffer containing the
if (ctx->Driver.BeginCallList)
ctx->Driver.BeginCallList( ctx, list );
- ctx->CallDepth++;
+ ctx->ListState.CallDepth++;
n = (Node *) _mesa_HashLookup(ctx->Shared->DisplayList, list);
break;
case OPCODE_CALL_LIST:
/* Generated by glCallList(), don't add ListBase */
- if (ctx->CallDepth<MAX_LIST_NESTING) {
+ if (ctx->ListState.CallDepth<MAX_LIST_NESTING) {
execute_list( ctx, n[1].ui );
}
break;
/* user specified a bad data type at compile time */
_mesa_error(ctx, GL_INVALID_ENUM, "glCallLists(type)");
}
- else if (ctx->CallDepth < MAX_LIST_NESTING) {
+ else if (ctx->ListState.CallDepth < MAX_LIST_NESTING) {
execute_list( ctx, ctx->List.ListBase + n[1].ui );
}
break;
n[4].f, n[5].f, n[6].f);
break;
#endif
+
+ case OPCODE_ATTR_1F:
+ (*ctx->Exec->VertexAttrib1fNV)(n[1].e, n[2].f);
+ break;
+ case OPCODE_ATTR_2F:
+ (*ctx->Exec->VertexAttrib2fvNV)(n[1].e, &n[2].f);
+ break;
+ case OPCODE_ATTR_3F:
+ (*ctx->Exec->VertexAttrib3fvNV)(n[1].e, &n[2].f);
+ break;
+ case OPCODE_ATTR_4F:
+ (*ctx->Exec->VertexAttrib4fvNV)(n[1].e, &n[2].f);
+ break;
+ case OPCODE_MATERIAL:
+ (*ctx->Exec->Materialfv)(n[1].e, n[2].e, &n[3].f);
+ break;
+ case OPCODE_INDEX:
+ (*ctx->Exec->Indexi)(n[1].i);
+ break;
+ case OPCODE_EDGEFLAG:
+ (*ctx->Exec->EdgeFlag)(n[1].b);
+ break;
+ case OPCODE_BEGIN:
+ (*ctx->Exec->Begin)(n[1].e);
+ break;
+ case OPCODE_END:
+ (*ctx->Exec->End)();
+ break;
+ case OPCODE_RECTF:
+ (*ctx->Exec->Rectf)(n[1].f, n[2].f, n[3].f, n[4].f);
+ break;
+ case OPCODE_EVAL_C1:
+ (*ctx->Exec->EvalCoord1f)(n[1].f);
+ break;
+ case OPCODE_EVAL_C2:
+ (*ctx->Exec->EvalCoord2fv)(&n[1].f);
+ break;
+ case OPCODE_EVAL_P1:
+ (*ctx->Exec->EvalPoint1)(n[1].i);
+ break;
+ case OPCODE_EVAL_P2:
+ (*ctx->Exec->EvalPoint2)(n[1].i, n[2].i);
+ break;
+
+
+
+
case OPCODE_CONTINUE:
n = (Node *) n[1].next;
break;
}
}
}
- ctx->CallDepth--;
+ ctx->ListState.CallDepth--;
if (ctx->Driver.EndCallList)
ctx->Driver.EndCallList( ctx );
_mesa_NewList( GLuint list, GLenum mode )
{
GET_CURRENT_CONTEXT(ctx);
+ GLint i;
+
FLUSH_CURRENT(ctx, 0); /* must be called before assert */
ASSERT_OUTSIDE_BEGIN_END(ctx);
return;
}
- if (ctx->CurrentListPtr) {
+ if (ctx->ListState.CurrentListPtr) {
/* already compiling a display list */
_mesa_error( ctx, GL_INVALID_OPERATION, "glNewList" );
return;
}
- /* Allocate new display list */
- ctx->CurrentListNum = list;
- ctx->CurrentBlock = (Node *) MALLOC( sizeof(Node) * BLOCK_SIZE );
- ctx->CurrentListPtr = ctx->CurrentBlock;
- ctx->CurrentPos = 0;
ctx->CompileFlag = GL_TRUE;
ctx->ExecuteFlag = (mode == GL_COMPILE_AND_EXECUTE);
+ /* Allocate new display list */
+ ctx->ListState.CurrentListNum = list;
+ ctx->ListState.CurrentBlock = (Node *) MALLOC( sizeof(Node) * BLOCK_SIZE );
+ ctx->ListState.CurrentListPtr = ctx->ListState.CurrentBlock;
+ ctx->ListState.CurrentPos = 0;
+
+ /* Reset acumulated list state:
+ */
+ for (i = 0; i < VERT_ATTRIB_MAX; i++)
+ ctx->ListState.ActiveAttribSize[i] = 0;
+
+ for (i = 0; i < MAT_ATTRIB_MAX; i++)
+ ctx->ListState.ActiveMaterialSize[i] = 0;
+
+ ctx->ListState.ActiveIndex = 0;
+ ctx->ListState.ActiveEdgeFlag = 0;
+
+ ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
ctx->Driver.NewList( ctx, list, mode );
ctx->CurrentDispatch = ctx->Save;
/*
- * End definition of current display list. Is the current
- * ASSERT_OUTSIDE_BEGIN_END strong enough to really guarentee that
- * we are outside begin/end calls?
+ * End definition of current display list.
*/
void GLAPIENTRY
_mesa_EndList( void )
{
GET_CURRENT_CONTEXT(ctx);
- FLUSH_CURRENT(ctx, 0); /* must be called before assert */
+ SAVE_FLUSH_VERTICES(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (MESA_VERBOSE&VERBOSE_API)
_mesa_debug(ctx, "glEndList\n");
/* Check that a list is under construction */
- if (!ctx->CurrentListPtr) {
+ if (!ctx->ListState.CurrentListPtr) {
_mesa_error( ctx, GL_INVALID_OPERATION, "glEndList" );
return;
}
(void) ALLOC_INSTRUCTION( ctx, OPCODE_END_OF_LIST, 0 );
/* Destroy old list, if any */
- _mesa_destroy_list(ctx, ctx->CurrentListNum);
+ _mesa_destroy_list(ctx, ctx->ListState.CurrentListNum);
/* Install the list */
- _mesa_HashInsert(ctx->Shared->DisplayList, ctx->CurrentListNum, ctx->CurrentListPtr);
+ _mesa_HashInsert(ctx->Shared->DisplayList, ctx->ListState.CurrentListNum, ctx->ListState.CurrentListPtr);
if (MESA_VERBOSE & VERBOSE_DISPLAY_LIST)
- mesa_print_display_list(ctx->CurrentListNum);
+ mesa_print_display_list(ctx->ListState.CurrentListNum);
- ctx->CurrentListNum = 0;
- ctx->CurrentListPtr = NULL;
+ ctx->ListState.CurrentListNum = 0;
+ ctx->ListState.CurrentListPtr = NULL;
ctx->ExecuteFlag = GL_TRUE;
ctx->CompileFlag = GL_FALSE;
{
_mesa_init_no_op_table(table, tableSize);
- _mesa_loopback_init_api_table( table, GL_TRUE );
+ _mesa_loopback_init_api_table( table );
/* GL 1.0 */
table->Accum = save_Accum;
/***** Initialization *****/
/**********************************************************************/
+
+void _mesa_save_vtxfmt_init( GLvertexformat *vfmt )
+{
+ vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */
+ vfmt->Begin = save_Begin;
+ vfmt->CallList = _mesa_save_CallList;
+ vfmt->CallLists = _mesa_save_CallLists;
+ vfmt->Color3f = save_Color3f;
+ vfmt->Color3fv = save_Color3fv;
+ vfmt->Color4f = save_Color4f;
+ vfmt->Color4fv = save_Color4fv;
+ vfmt->EdgeFlag = save_EdgeFlag;
+ vfmt->EdgeFlagv = save_EdgeFlagv;
+ vfmt->End = save_End;
+ vfmt->EvalCoord1f = save_EvalCoord1f;
+ vfmt->EvalCoord1fv = save_EvalCoord1fv;
+ vfmt->EvalCoord2f = save_EvalCoord2f;
+ vfmt->EvalCoord2fv = save_EvalCoord2fv;
+ vfmt->EvalPoint1 = save_EvalPoint1;
+ vfmt->EvalPoint2 = save_EvalPoint2;
+ vfmt->FogCoordfEXT = save_FogCoordfEXT;
+ vfmt->FogCoordfvEXT = save_FogCoordfvEXT;
+ vfmt->Indexf = save_Indexf;
+ vfmt->Indexfv = save_Indexfv;
+ vfmt->Materialfv = save_Materialfv;
+ vfmt->MultiTexCoord1fARB = save_MultiTexCoord1f;
+ vfmt->MultiTexCoord1fvARB = save_MultiTexCoord1fv;
+ vfmt->MultiTexCoord2fARB = save_MultiTexCoord2f;
+ vfmt->MultiTexCoord2fvARB = save_MultiTexCoord2fv;
+ vfmt->MultiTexCoord3fARB = save_MultiTexCoord3f;
+ vfmt->MultiTexCoord3fvARB = save_MultiTexCoord3fv;
+ vfmt->MultiTexCoord4fARB = save_MultiTexCoord4f;
+ vfmt->MultiTexCoord4fvARB = save_MultiTexCoord4fv;
+ vfmt->Normal3f = save_Normal3f;
+ vfmt->Normal3fv = save_Normal3fv;
+ vfmt->SecondaryColor3fEXT = save_SecondaryColor3fEXT;
+ vfmt->SecondaryColor3fvEXT = save_SecondaryColor3fvEXT;
+ vfmt->TexCoord1f = save_TexCoord1f;
+ vfmt->TexCoord1fv = save_TexCoord1fv;
+ vfmt->TexCoord2f = save_TexCoord2f;
+ vfmt->TexCoord2fv = save_TexCoord2fv;
+ vfmt->TexCoord3f = save_TexCoord3f;
+ vfmt->TexCoord3fv = save_TexCoord3fv;
+ vfmt->TexCoord4f = save_TexCoord4f;
+ vfmt->TexCoord4fv = save_TexCoord4fv;
+ vfmt->Vertex2f = save_Vertex2f;
+ vfmt->Vertex2fv = save_Vertex2fv;
+ vfmt->Vertex3f = save_Vertex3f;
+ vfmt->Vertex3fv = save_Vertex3fv;
+ vfmt->Vertex4f = save_Vertex4f;
+ vfmt->Vertex4fv = save_Vertex4fv;
+ vfmt->VertexAttrib1fNV = save_VertexAttrib1fNV;
+ vfmt->VertexAttrib1fvNV = save_VertexAttrib1fvNV;
+ vfmt->VertexAttrib2fNV = save_VertexAttrib2fNV;
+ vfmt->VertexAttrib2fvNV = save_VertexAttrib2fvNV;
+ vfmt->VertexAttrib3fNV = save_VertexAttrib3fNV;
+ vfmt->VertexAttrib3fvNV = save_VertexAttrib3fvNV;
+ vfmt->VertexAttrib4fNV = save_VertexAttrib4fNV;
+ vfmt->VertexAttrib4fvNV = save_VertexAttrib4fvNV;
+
+ vfmt->EvalMesh1 = _mesa_save_EvalMesh1;
+ vfmt->EvalMesh2 = _mesa_save_EvalMesh2;
+ vfmt->Rectf = save_Rectf;
+
+ /* The driver is required to implement these as
+ * 1) They can probably do a better job.
+ * 2) A lot of new mechanisms would have to be added to this module
+ * to support it. That code would probably never get used,
+ * because of (1).
+ */
+#if 0
+ vfmt->DrawArrays = 0;
+ vfmt->DrawElements = 0;
+ vfmt->DrawRangeElements = 0;
+#endif
+}
+
+
+
void _mesa_init_display_list( GLcontext * ctx )
{
/* Display list */
- ctx->CallDepth = 0;
+ ctx->ListState.CallDepth = 0;
ctx->ExecuteFlag = GL_TRUE;
ctx->CompileFlag = GL_FALSE;
- ctx->CurrentListPtr = NULL;
- ctx->CurrentBlock = NULL;
- ctx->CurrentListNum = 0;
- ctx->CurrentPos = 0;
+ ctx->ListState.CurrentListPtr = NULL;
+ ctx->ListState.CurrentBlock = NULL;
+ ctx->ListState.CurrentListNum = 0;
+ ctx->ListState.CurrentPos = 0;
/* Display List group */
ctx->List.ListBase = 0;
+ _mesa_save_vtxfmt_init( &ctx->ListState.ListVtxfmt );
}
extern void GLAPIENTRY _mesa_save_CallLists( GLsizei n, GLenum type, const GLvoid *lists );
extern void GLAPIENTRY _mesa_save_CallList( GLuint list );
extern void _mesa_init_display_list( GLcontext * ctx );
+extern void _mesa_save_vtxfmt_init( GLvertexformat *vfmt );
+
#else
/** No-op */
#define _mesa_init_display_list(c) ((void)0)
+/** No-op */
+#define _mesa_save_vtxfmt_init(v) ((void)0)
+
#endif
#endif
break;
case GL_CURRENT_INDEX:
FLUSH_CURRENT(ctx, 0);
- *params = INT_TO_BOOL(ctx->Current.Index);
+ *params = FLOAT_TO_BOOL(ctx->Current.Index);
break;
case GL_CURRENT_NORMAL:
FLUSH_CURRENT(ctx, 0);
*params = INT_TO_BOOL(ctx->List.ListBase);
break;
case GL_LIST_INDEX:
- *params = INT_TO_BOOL( ctx->CurrentListNum );
+ *params = INT_TO_BOOL( ctx->ListState.CurrentListNum );
break;
case GL_LIST_MODE:
if (!ctx->CompileFlag)
*params = (GLdouble) ctx->List.ListBase;
break;
case GL_LIST_INDEX:
- *params = (GLdouble) ctx->CurrentListNum;
+ *params = (GLdouble) ctx->ListState.CurrentListNum;
break;
case GL_LIST_MODE:
if (!ctx->CompileFlag)
*params = (GLfloat) ctx->List.ListBase;
break;
case GL_LIST_INDEX:
- *params = (GLfloat) ctx->CurrentListNum;
+ *params = (GLfloat) ctx->ListState.CurrentListNum;
break;
case GL_LIST_MODE:
if (!ctx->CompileFlag)
*params = (GLint) ctx->List.ListBase;
break;
case GL_LIST_INDEX:
- *params = (GLint) ctx->CurrentListNum;
+ *params = (GLint) ctx->ListState.CurrentListNum;
break;
case GL_LIST_MODE:
if (!ctx->CompileFlag)
#define STRIDE_UI(p, i) (p = (GLuint *)((GLubyte *)p + i))
/** Stepping a GLubyte[4] pointer by a byte stride */
#define STRIDE_4UB(p, i) (p = (GLubyte (*)[4])((GLubyte *)p + i))
+/** Stepping a GLfloat[4] pointer by a byte stride */
+#define STRIDE_4F(p, i) (p = (GLfloat (*)[4])((GLubyte *)p + i))
/** Stepping a GLchan[4] pointer by a byte stride */
#define STRIDE_4CHAN(p, i) (p = (GLchan (*)[4])((GLubyte *)p + i))
/** Stepping a GLchan pointer by a byte stride */
/*@{*/
GLfloat Attrib[VERT_ATTRIB_MAX][4]; /**< Current vertex attributes
* indexed by VERT_ATTRIB_* */
- GLuint Index; /**< Current color index */
+ GLfloat Index; /**< Current color index */
GLboolean EdgeFlag; /**< Current edge flag */
/*@}*/
/*@}*/
};
+struct mesa_list_state {
+ GLuint CallDepth; /**< Current recursion calling depth */
+ Node *CurrentListPtr; /**< Head of list being compiled */
+ GLuint CurrentListNum; /**< Number of the list being compiled */
+ Node *CurrentBlock; /**< Pointer to current block of nodes */
+ GLuint CurrentPos; /**< Index into current block of nodes */
+ GLvertexformat ListVtxfmt;
+
+ GLubyte ActiveAttribSize[VERT_ATTRIB_MAX];
+ GLfloat CurrentAttrib[VERT_ATTRIB_MAX][4];
+
+ GLubyte ActiveMaterialSize[MAT_ATTRIB_MAX];
+ GLfloat CurrentMaterial[MAT_ATTRIB_MAX][4];
+
+ GLubyte ActiveIndex;
+ GLfloat CurrentIndex;
+
+ GLubyte ActiveEdgeFlag;
+ GLboolean CurrentEdgeFlag;
+};
+
/**
* Mesa context
struct _glapi_table *CurrentDispatch; /**< == Save or Exec !! */
/*@}*/
- GLboolean ExecPrefersFloat; /**< What preference for color conversion? */
- GLboolean SavePrefersFloat;
-
GLvisual Visual;
GLframebuffer *DrawBuffer; /**< buffer for writing */
GLframebuffer *ReadBuffer; /**< buffer for reading */
GLmatrix _ModelProjectMatrix;
/** \name Display lists */
- /*@{*/
- GLuint CallDepth; /**< Current recursion calling depth */
+ struct mesa_list_state ListState;
+
GLboolean ExecuteFlag; /**< Execute GL commands? */
GLboolean CompileFlag; /**< Compile GL commands into display list? */
- Node *CurrentListPtr; /**< Head of list being compiled */
- GLuint CurrentListNum; /**< Number of the list being compiled */
- Node *CurrentBlock; /**< Pointer to current block of nodes */
- GLuint CurrentPos; /**< Index into current block of nodes */
- /*@}*/
/** Extensions */
struct gl_extensions Extensions;
_mesa_init_no_op_table(exec, tableSize);
#if _HAVE_FULL_GL
- _mesa_loopback_init_api_table( exec, GL_TRUE );
+ _mesa_loopback_init_api_table( exec );
#endif
/* load the dispatch slots we understand */
tab->ArrayElement = vfmt->ArrayElement;
tab->Color3f = vfmt->Color3f;
tab->Color3fv = vfmt->Color3fv;
- tab->Color3ub = vfmt->Color3ub;
- tab->Color3ubv = vfmt->Color3ubv;
tab->Color4f = vfmt->Color4f;
tab->Color4fv = vfmt->Color4fv;
- tab->Color4ub = vfmt->Color4ub;
- tab->Color4ubv = vfmt->Color4ubv;
tab->EdgeFlag = vfmt->EdgeFlag;
tab->EdgeFlagv = vfmt->EdgeFlagv;
tab->EvalCoord1f = vfmt->EvalCoord1f;
tab->EvalPoint2 = vfmt->EvalPoint2;
tab->FogCoordfEXT = vfmt->FogCoordfEXT;
tab->FogCoordfvEXT = vfmt->FogCoordfvEXT;
- tab->Indexi = vfmt->Indexi;
- tab->Indexiv = vfmt->Indexiv;
+ tab->Indexf = vfmt->Indexf;
+ tab->Indexfv = vfmt->Indexfv;
tab->Materialfv = vfmt->Materialfv;
tab->MultiTexCoord1fARB = vfmt->MultiTexCoord1fARB;
tab->MultiTexCoord1fvARB = vfmt->MultiTexCoord1fvARB;
tab->Normal3fv = vfmt->Normal3fv;
tab->SecondaryColor3fEXT = vfmt->SecondaryColor3fEXT;
tab->SecondaryColor3fvEXT = vfmt->SecondaryColor3fvEXT;
- tab->SecondaryColor3ubEXT = vfmt->SecondaryColor3ubEXT;
- tab->SecondaryColor3ubvEXT = vfmt->SecondaryColor3ubvEXT;
tab->TexCoord1f = vfmt->TexCoord1f;
tab->TexCoord1fv = vfmt->TexCoord1fv;
tab->TexCoord2f = vfmt->TexCoord2f;
tab->Vertex4f = vfmt->Vertex4f;
tab->Vertex4fv = vfmt->Vertex4fv;
tab->CallList = vfmt->CallList;
+ tab->CallLists = vfmt->CallLists;
tab->Begin = vfmt->Begin;
tab->End = vfmt->End;
+ tab->VertexAttrib1fNV = vfmt->VertexAttrib1fNV;
+ tab->VertexAttrib1fvNV = vfmt->VertexAttrib1fvNV;
+ tab->VertexAttrib2fNV = vfmt->VertexAttrib2fNV;
+ tab->VertexAttrib2fvNV = vfmt->VertexAttrib2fvNV;
+ tab->VertexAttrib3fNV = vfmt->VertexAttrib3fNV;
+ tab->VertexAttrib3fvNV = vfmt->VertexAttrib3fvNV;
tab->VertexAttrib4fNV = vfmt->VertexAttrib4fNV;
tab->VertexAttrib4fvNV = vfmt->VertexAttrib4fvNV;
tab->Rectf = vfmt->Rectf;
{
ctx->TnlModule.Current = vfmt;
_mesa_restore_exec_vtxfmt( ctx );
- if ( ctx->ExecPrefersFloat != vfmt->prefer_float_colors )
- _mesa_loopback_prefer_float( ctx->Exec, vfmt->prefer_float_colors );
}
void _mesa_install_save_vtxfmt( GLcontext *ctx, GLvertexformat *vfmt )
{
install_vtxfmt( ctx->Save, vfmt );
- if ( ctx->SavePrefersFloat != vfmt->prefer_float_colors )
- _mesa_loopback_prefer_float( ctx->Save, vfmt->prefer_float_colors );
}
_glapi_Dispatch->Color3fv( v );
}
-static void GLAPIENTRY TAG(Color3ub)( GLubyte r, GLubyte g, GLubyte b )
-{
- PRE_LOOPBACK( Color3ub );
- _glapi_Dispatch->Color3ub( r, g, b );
-}
-
-static void GLAPIENTRY TAG(Color3ubv)( const GLubyte *v )
-{
- PRE_LOOPBACK( Color3ubv );
- _glapi_Dispatch->Color3ubv( v );
-}
-
static void GLAPIENTRY TAG(Color4f)( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
{
PRE_LOOPBACK( Color4f );
_glapi_Dispatch->Color4fv( v );
}
-static void GLAPIENTRY TAG(Color4ub)( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
-{
- PRE_LOOPBACK( Color4ub );
- _glapi_Dispatch->Color4ub( r, g, b, a );
-}
-
-static void GLAPIENTRY TAG(Color4ubv)( const GLubyte *v )
-{
- PRE_LOOPBACK( Color4ubv );
- _glapi_Dispatch->Color4ubv( v );
-}
-
static void GLAPIENTRY TAG(EdgeFlag)( GLboolean e )
{
PRE_LOOPBACK( EdgeFlag );
_glapi_Dispatch->FogCoordfvEXT( v );
}
-static void GLAPIENTRY TAG(Indexi)( GLint i )
+static void GLAPIENTRY TAG(Indexf)( GLfloat f )
{
- PRE_LOOPBACK( Indexi );
- _glapi_Dispatch->Indexi( i );
+ PRE_LOOPBACK( Indexf );
+ _glapi_Dispatch->Indexf( f );
}
-static void GLAPIENTRY TAG(Indexiv)( const GLint *v )
+static void GLAPIENTRY TAG(Indexfv)( const GLfloat *v )
{
- PRE_LOOPBACK( Indexiv );
- _glapi_Dispatch->Indexiv( v );
+ PRE_LOOPBACK( Indexfv );
+ _glapi_Dispatch->Indexfv( v );
}
static void GLAPIENTRY TAG(Materialfv)( GLenum face, GLenum pname, const GLfloat *v )
_glapi_Dispatch->SecondaryColor3fvEXT( v );
}
-static void GLAPIENTRY TAG(SecondaryColor3ubEXT)( GLubyte r, GLubyte g, GLubyte b )
-{
- PRE_LOOPBACK( SecondaryColor3ubEXT );
- _glapi_Dispatch->SecondaryColor3ubEXT( r, g, b );
-}
-
-static void GLAPIENTRY TAG(SecondaryColor3ubvEXT)( const GLubyte *v )
-{
- PRE_LOOPBACK( SecondaryColor3ubvEXT );
- _glapi_Dispatch->SecondaryColor3ubvEXT( v );
-}
-
static void GLAPIENTRY TAG(TexCoord1f)( GLfloat s )
{
PRE_LOOPBACK( TexCoord1f );
_glapi_Dispatch->CallList( i );
}
+static void GLAPIENTRY TAG(CallLists)( GLsizei sz, GLenum type, const GLvoid *v )
+{
+ PRE_LOOPBACK( CallLists );
+ _glapi_Dispatch->CallLists( sz, type, v );
+}
+
static void GLAPIENTRY TAG(Begin)( GLenum mode )
{
PRE_LOOPBACK( Begin );
_glapi_Dispatch->EvalMesh2( mode, i1, i2, j1, j2 );
}
+static void GLAPIENTRY TAG(VertexAttrib1fNV)( GLuint index, GLfloat x )
+{
+ PRE_LOOPBACK( VertexAttrib1fNV );
+ _glapi_Dispatch->VertexAttrib1fNV( index, x );
+}
+
+static void GLAPIENTRY TAG(VertexAttrib1fvNV)( GLuint index, const GLfloat *v )
+{
+ PRE_LOOPBACK( VertexAttrib1fvNV );
+ _glapi_Dispatch->VertexAttrib1fvNV( index, v );
+}
+
+static void GLAPIENTRY TAG(VertexAttrib2fNV)( GLuint index, GLfloat x, GLfloat y )
+{
+ PRE_LOOPBACK( VertexAttrib2fNV );
+ _glapi_Dispatch->VertexAttrib2fNV( index, x, y );
+}
+
+static void GLAPIENTRY TAG(VertexAttrib2fvNV)( GLuint index, const GLfloat *v )
+{
+ PRE_LOOPBACK( VertexAttrib2fvNV );
+ _glapi_Dispatch->VertexAttrib2fvNV( index, v );
+}
+
+static void GLAPIENTRY TAG(VertexAttrib3fNV)( GLuint index, GLfloat x, GLfloat y, GLfloat z )
+{
+ PRE_LOOPBACK( VertexAttrib3fNV );
+ _glapi_Dispatch->VertexAttrib3fNV( index, x, y, z );
+}
+
+static void GLAPIENTRY TAG(VertexAttrib3fvNV)( GLuint index, const GLfloat *v )
+{
+ PRE_LOOPBACK( VertexAttrib3fvNV );
+ _glapi_Dispatch->VertexAttrib3fvNV( index, v );
+}
+
static void GLAPIENTRY TAG(VertexAttrib4fNV)( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w )
{
PRE_LOOPBACK( VertexAttrib4fNV );
TAG(ArrayElement),
TAG(Color3f),
TAG(Color3fv),
- TAG(Color3ub),
- TAG(Color3ubv),
TAG(Color4f),
TAG(Color4fv),
- TAG(Color4ub),
- TAG(Color4ubv),
TAG(EdgeFlag),
TAG(EdgeFlagv),
TAG(EvalCoord1f),
TAG(EvalPoint2),
TAG(FogCoordfEXT),
TAG(FogCoordfvEXT),
- TAG(Indexi),
- TAG(Indexiv),
+ TAG(Indexf),
+ TAG(Indexfv),
TAG(Materialfv),
TAG(MultiTexCoord1fARB),
TAG(MultiTexCoord1fvARB),
TAG(Normal3fv),
TAG(SecondaryColor3fEXT),
TAG(SecondaryColor3fvEXT),
- TAG(SecondaryColor3ubEXT),
- TAG(SecondaryColor3ubvEXT),
TAG(TexCoord1f),
TAG(TexCoord1fv),
TAG(TexCoord2f),
TAG(Vertex4f),
TAG(Vertex4fv),
TAG(CallList),
+ TAG(CallLists),
TAG(Begin),
TAG(End),
+ TAG(VertexAttrib1fNV),
+ TAG(VertexAttrib1fvNV),
+ TAG(VertexAttrib2fNV),
+ TAG(VertexAttrib2fvNV),
+ TAG(VertexAttrib3fNV),
+ TAG(VertexAttrib3fvNV),
TAG(VertexAttrib4fNV),
TAG(VertexAttrib4fvNV),
TAG(Rectf),
v->flags = size_bits[4] | flags ;
}
-void _mesa_vector3f_init( GLvector3f *v, GLuint flags, GLfloat (*storage)[3] )
-{
- v->stride = 3 * sizeof(GLfloat);
- v->data = storage;
- v->start = (GLfloat *) storage;
- v->count = 0;
- v->flags = flags ;
-}
-void _mesa_vector1f_init( GLvector1f *v, GLuint flags, GLfloat *storage )
-{
- v->stride = 1*sizeof(GLfloat);
- v->data = storage;
- v->start = (GLfloat *)storage;
- v->count = 0;
- v->flags = flags ;
-}
-
-void _mesa_vector4ub_init( GLvector4ub *v, GLuint flags, GLubyte (*storage)[4] )
-{
- v->stride = 4 * sizeof(GLubyte);
- v->data = storage;
- v->start = (GLubyte *) storage;
- v->count = 0;
- v->flags = flags ;
-}
-
-void _mesa_vector4chan_init( GLvector4chan *v, GLuint flags, GLchan (*storage)[4] )
-{
- v->stride = 4 * sizeof(GLchan);
- v->data = storage;
- v->start = (GLchan *) storage;
- v->count = 0;
- v->flags = flags ;
-}
-
-void _mesa_vector4us_init( GLvector4us *v, GLuint flags, GLushort (*storage)[4] )
-{
- v->stride = 4 * sizeof(GLushort);
- v->data = storage;
- v->start = (GLushort *) storage;
- v->count = 0;
- v->flags = flags ;
-}
-
-void _mesa_vector1ub_init( GLvector1ub *v, GLuint flags, GLubyte *storage )
-{
- v->stride = 1 * sizeof(GLubyte);
- v->data = storage;
- v->start = (GLubyte *) storage;
- v->count = 0;
- v->flags = flags ;
-}
-
-void _mesa_vector1ui_init( GLvector1ui *v, GLuint flags, GLuint *storage )
-{
- v->stride = 1 * sizeof(GLuint);
- v->data = storage;
- v->start = (GLuint *) storage;
- v->count = 0;
- v->flags = flags ;
-}
/*
v->flags = size_bits[4] | flags | VEC_MALLOC ;
}
-void _mesa_vector3f_alloc( GLvector3f *v, GLuint flags, GLuint count,
- GLuint alignment )
-{
- v->stride = 3 * sizeof(GLfloat);
- v->storage = ALIGN_MALLOC( count * 3 * sizeof(GLfloat), alignment );
- v->start = (GLfloat *) v->storage;
- v->data = (GLfloat (*)[3]) v->storage;
- v->count = 0;
- v->flags = flags | VEC_MALLOC ;
-}
-
-void _mesa_vector1f_alloc( GLvector1f *v, GLuint flags, GLuint count,
- GLuint alignment )
-{
- v->stride = sizeof(GLfloat);
- v->storage = v->start = (GLfloat *)
- ALIGN_MALLOC( count * sizeof(GLfloat), alignment );
- v->data = v->start;
- v->count = 0;
- v->flags = flags | VEC_MALLOC ;
-}
-
-void _mesa_vector4ub_alloc( GLvector4ub *v, GLuint flags, GLuint count,
- GLuint alignment )
-{
- v->stride = 4 * sizeof(GLubyte);
- v->storage = ALIGN_MALLOC( count * 4 * sizeof(GLubyte), alignment );
- v->start = (GLubyte *) v->storage;
- v->data = (GLubyte (*)[4]) v->storage;
- v->count = 0;
- v->flags = flags | VEC_MALLOC ;
-}
-
-void _mesa_vector4chan_alloc( GLvector4chan *v, GLuint flags, GLuint count,
- GLuint alignment )
-{
- v->stride = 4 * sizeof(GLchan);
- v->storage = ALIGN_MALLOC( count * 4 * sizeof(GLchan), alignment );
- v->start = (GLchan *) v->storage;
- v->data = (GLchan (*)[4]) v->storage;
- v->count = 0;
- v->flags = flags | VEC_MALLOC ;
-}
-
-void _mesa_vector4us_alloc( GLvector4us *v, GLuint flags, GLuint count,
- GLuint alignment )
-{
- v->stride = 4 * sizeof(GLushort);
- v->storage = ALIGN_MALLOC( count * 4 * sizeof(GLushort), alignment );
- v->start = (GLushort *) v->storage;
- v->data = (GLushort (*)[4]) v->storage;
- v->count = 0;
- v->flags = flags | VEC_MALLOC ;
-}
-
-void _mesa_vector1ub_alloc( GLvector1ub *v, GLuint flags, GLuint count,
- GLuint alignment )
-{
- v->stride = 1 * sizeof(GLubyte);
- v->storage = ALIGN_MALLOC( count * sizeof(GLubyte), alignment );
- v->start = (GLubyte *) v->storage;
- v->data = (GLubyte *) v->storage;
- v->count = 0;
- v->flags = flags | VEC_MALLOC ;
-}
-
-void _mesa_vector1ui_alloc( GLvector1ui *v, GLuint flags, GLuint count,
- GLuint alignment )
-{
- v->stride = 1 * sizeof(GLuint);
- v->storage = ALIGN_MALLOC( count * sizeof(GLuint), alignment );
- v->start = (GLuint *) v->storage;
- v->data = (GLuint *) v->storage;
- v->count = 0;
- v->flags = flags | VEC_MALLOC ;
-}
}
}
-void _mesa_vector3f_free( GLvector3f *v )
-{
- if (v->flags & VEC_MALLOC) {
- ALIGN_FREE( v->storage );
- v->data = 0;
- v->start = 0;
- v->storage = 0;
- v->flags &= ~VEC_MALLOC;
- }
-}
-
-void _mesa_vector1f_free( GLvector1f *v )
-{
- if (v->flags & VEC_MALLOC) {
- ALIGN_FREE( v->storage );
- v->data = NULL;
- v->start = NULL;
- v->storage = NULL;
- v->flags &= ~VEC_MALLOC;
- }
-}
-
-void _mesa_vector4ub_free( GLvector4ub *v )
-{
- if (v->flags & VEC_MALLOC) {
- ALIGN_FREE( v->storage );
- v->data = NULL;
- v->start = NULL;
- v->storage = NULL;
- v->flags &= ~VEC_MALLOC;
- }
-}
-
-void _mesa_vector4chan_free( GLvector4chan *v )
-{
- if (v->flags & VEC_MALLOC) {
- ALIGN_FREE( v->storage );
- v->data = NULL;
- v->start = NULL;
- v->storage = NULL;
- v->flags &= ~VEC_MALLOC;
- }
-}
-
-void _mesa_vector4us_free( GLvector4us *v )
-{
- if (v->flags & VEC_MALLOC) {
- ALIGN_FREE( v->storage );
- v->data = NULL;
- v->start = NULL;
- v->storage = NULL;
- v->flags &= ~VEC_MALLOC;
- }
-}
-
-void _mesa_vector1ub_free( GLvector1ub *v )
-{
- if (v->flags & VEC_MALLOC) {
- ALIGN_FREE( v->storage );
- v->data = NULL;
- v->start = NULL;
- v->storage = NULL;
- v->flags &= ~VEC_MALLOC;
- }
-}
-
-void _mesa_vector1ui_free( GLvector1ui *v )
-{
- if (v->flags & VEC_MALLOC) {
- ALIGN_FREE( v->storage );
- v->data = NULL;
- v->start = NULL;
- v->storage = NULL;
- v->flags &= ~VEC_MALLOC;
- }
-}
-
/*
* For debugging
}
-/*
- * For debugging
- */
-void _mesa_vector3f_print( GLvector3f *v, GLubyte *cullmask, GLboolean culling )
-{
- GLfloat *d = (GLfloat *)v->data;
- GLuint i = 0, count;
-
- _mesa_printf("data-start\n");
- for ( ; d != v->start ; STRIDE_F(d,v->stride), i++)
- _mesa_printf( "%u:\t%f, %f, %f\n", i, d[0], d[1], d[2]);
-
- _mesa_printf("start-count(%u)\n", v->count);
- count = i + v->count;
-
- if (culling) {
- for ( ; i < count ; STRIDE_F(d,v->stride), i++)
- if (cullmask[i])
- _mesa_printf("%u:\t%f, %f, %f\n", i, d[0], d[1], d[2]);
- }
- else {
- for ( ; i < count ; STRIDE_F(d,v->stride), i++)
- _mesa_printf("%u:\t%f, %f, %f\n", i, d[0], d[1], d[2]);
- }
-}
extern void _mesa_vector4f_clean_elem( GLvector4f *vec, GLuint nr, GLuint elt );
-/* Could use a single vector type for normals and vertices, but
- * this way avoids some casts.
- */
-typedef struct {
- GLfloat (*data)[3];
- GLfloat *start;
- GLuint count;
- GLuint stride;
- GLuint flags;
- void *storage;
-} GLvector3f;
-
-extern void _mesa_vector3f_init( GLvector3f *v, GLuint flags, GLfloat (*)[3] );
-extern void _mesa_vector3f_alloc( GLvector3f *v, GLuint flags, GLuint count,
- GLuint alignment );
-extern void _mesa_vector3f_free( GLvector3f *v );
-extern void _mesa_vector3f_print( GLvector3f *v, GLubyte *, GLboolean );
-
-
-typedef struct {
- GLfloat *data;
- GLfloat *start;
- GLuint count;
- GLuint stride;
- GLuint flags;
- void *storage;
-} GLvector1f;
-
-extern void _mesa_vector1f_free( GLvector1f *v );
-extern void _mesa_vector1f_init( GLvector1f *v, GLuint flags, GLfloat * );
-extern void _mesa_vector1f_alloc( GLvector1f *v, GLuint flags, GLuint count,
- GLuint alignment );
-
-
-/* For 4ub rgba values.
- */
-typedef struct {
- GLubyte (*data)[4];
- GLubyte *start;
- GLuint count;
- GLuint stride;
- GLuint flags;
- void *storage;
-} GLvector4ub;
-
-extern void _mesa_vector4ub_init( GLvector4ub *v, GLuint flags,
- GLubyte (*storage)[4] );
-extern void _mesa_vector4ub_alloc( GLvector4ub *v, GLuint flags, GLuint count,
- GLuint alignment );
-extern void _mesa_vector4ub_free( GLvector4ub * );
-
-
-/* For 4 * GLchan values.
- */
-typedef struct {
- GLchan (*data)[4];
- GLchan *start;
- GLuint count;
- GLuint stride;
- GLuint flags;
- void *storage;
-} GLvector4chan;
-
-extern void _mesa_vector4chan_init( GLvector4chan *v, GLuint flags,
- GLchan (*storage)[4] );
-extern void _mesa_vector4chan_alloc( GLvector4chan *v, GLuint flags, GLuint count,
- GLuint alignment );
-extern void _mesa_vector4chan_free( GLvector4chan * );
-
-
-
-
-/* For 4 * GLushort rgba values.
- */
-typedef struct {
- GLushort (*data)[4];
- GLushort *start;
- GLuint count;
- GLuint stride;
- GLuint flags;
- void *storage;
-} GLvector4us;
-
-extern void _mesa_vector4us_init( GLvector4us *v, GLuint flags,
- GLushort (*storage)[4] );
-extern void _mesa_vector4us_alloc( GLvector4us *v, GLuint flags, GLuint count,
- GLuint alignment );
-extern void _mesa_vector4us_free( GLvector4us * );
-
-
-
-
-/* For 1ub values, eg edgeflag.
- */
-typedef struct {
- GLubyte *data;
- GLubyte *start;
- GLuint count;
- GLuint stride;
- GLuint flags;
- void *storage;
-} GLvector1ub;
-
-extern void _mesa_vector1ub_init( GLvector1ub *v, GLuint flags, GLubyte *storage);
-extern void _mesa_vector1ub_alloc( GLvector1ub *v, GLuint flags, GLuint count,
- GLuint alignment );
-extern void _mesa_vector1ub_free( GLvector1ub * );
-
-
-
-
-/* For, eg Index, Array element.
- */
-typedef struct {
- GLuint *data;
- GLuint *start;
- GLuint count;
- GLuint stride;
- GLuint flags;
- void *storage;
-} GLvector1ui;
-
-extern void _mesa_vector1ui_init( GLvector1ui *v, GLuint flags, GLuint *storage );
-extern void _mesa_vector1ui_alloc( GLvector1ui *v, GLuint flags, GLuint count,
- GLuint alignment );
-extern void _mesa_vector1ui_free( GLvector1ui * );
_swrast_flush(ctx);
}
-#define SS_COLOR(a,b) COPY_CHAN4(a,b)
-#define SS_SPEC(a,b) COPY_3V(a,b)
+#define SS_COLOR(a,b) UNCLAMPED_FLOAT_TO_RGBA_CHAN(a,b)
+#define SS_SPEC(a,b) UNCLAMPED_FLOAT_TO_RGB_CHAN(a,b)
#define SS_IND(a,b) (a = b)
#define IND (0)
if (facing == 1) {
if (IND & SS_TWOSIDE_BIT) {
if (IND & SS_RGBA_BIT) {
- GLchan (*vbcolor)[4] = (GLchan (*)[4])VB->ColorPtr[1]->Ptr;
+ GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
SS_COLOR(v[0]->color, vbcolor[e0]);
SS_COLOR(v[1]->color, vbcolor[e1]);
SS_COLOR(v[2]->color, vbcolor[e2]);
if (VB->SecondaryColorPtr[1]) {
- GLchan (*vbspec)[4] = (GLchan (*)[4])VB->SecondaryColorPtr[1]->Ptr;
+ GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
SS_SPEC(v[0]->specular, vbspec[e0]);
SS_SPEC(v[1]->specular, vbspec[e1]);
SS_SPEC(v[2]->specular, vbspec[e2]);
}
} else {
- GLuint *vbindex = VB->IndexPtr[1]->data;
+ GLfloat *vbindex = (GLfloat *)VB->IndexPtr[1]->data;
SS_IND(v[0]->index, vbindex[e0]);
SS_IND(v[1]->index, vbindex[e1]);
SS_IND(v[2]->index, vbindex[e2]);
if (IND & SS_TWOSIDE_BIT) {
if (facing == 1) {
if (IND & SS_RGBA_BIT) {
- GLchan (*vbcolor)[4] = (GLchan (*)[4])VB->ColorPtr[0]->Ptr;
+ GLfloat (*vbcolor)[4] = VB->ColorPtr[0]->data;
SS_COLOR(v[0]->color, vbcolor[e0]);
SS_COLOR(v[1]->color, vbcolor[e1]);
SS_COLOR(v[2]->color, vbcolor[e2]);
if (VB->SecondaryColorPtr[0]) {
- GLchan (*vbspec)[4] = (GLchan (*)[4])VB->SecondaryColorPtr[0]->Ptr;
+ GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[0]->data;
SS_SPEC(v[0]->specular, vbspec[e0]);
SS_SPEC(v[1]->specular, vbspec[e1]);
SS_SPEC(v[2]->specular, vbspec[e2]);
}
} else {
- GLuint *vbindex = VB->IndexPtr[0]->data;
+ GLfloat *vbindex = (GLfloat *)VB->IndexPtr[0]->data;
SS_IND(v[0]->index, vbindex[e0]);
SS_IND(v[1]->index, vbindex[e1]);
SS_IND(v[2]->index, vbindex[e2]);
#include "ss_context.h"
#include "ss_vb.h"
+
+#if 0
static void do_import( struct vertex_buffer *VB,
struct gl_client_array *to,
struct gl_client_array *from )
do_import( VB, to, VB->SecondaryColorPtr[0] );
VB->SecondaryColorPtr[0] = to;
}
-
+#endif
/* Provides a RasterSetup function which prebuilds vertices for the
* software rasterizer. This is required for the triangle functions
* Additional setup and interp for back color and edgeflag.
***********************************************************************/
-#define GET_COLOR(ptr, idx) (((GLchan (*)[4])((ptr)->Ptr))[idx])
+#define GET_COLOR(ptr, idx) (((GLfloat (*)[4])((ptr)->data))[idx])
static void interp_extras( GLcontext *ctx,
GLfloat t,
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
if (VB->ColorPtr[1]) {
- INTERP_4CHAN( t,
+ INTERP_4F( t,
GET_COLOR(VB->ColorPtr[1], dst),
GET_COLOR(VB->ColorPtr[1], out),
GET_COLOR(VB->ColorPtr[1], in) );
if (VB->SecondaryColorPtr[1]) {
- INTERP_3CHAN( t,
+ INTERP_3F( t,
GET_COLOR(VB->SecondaryColorPtr[1], dst),
GET_COLOR(VB->SecondaryColorPtr[1], out),
GET_COLOR(VB->SecondaryColorPtr[1], in) );
}
}
else if (VB->IndexPtr[1]) {
- VB->IndexPtr[1]->data[dst] = (GLuint) (GLint)
- LINTERP( t,
- (GLfloat) VB->IndexPtr[1]->data[out],
- (GLfloat) VB->IndexPtr[1]->data[in] );
+ VB->IndexPtr[1]->data[dst][0] = LINTERP( t,
+ VB->IndexPtr[1]->data[out][0],
+ VB->IndexPtr[1]->data[in][0] );
}
if (VB->EdgeFlag) {
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
if (VB->ColorPtr[1]) {
- COPY_CHAN4( GET_COLOR(VB->ColorPtr[1], dst),
- GET_COLOR(VB->ColorPtr[1], src) );
+ COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst),
+ GET_COLOR(VB->ColorPtr[1], src) );
if (VB->SecondaryColorPtr[1]) {
COPY_3V( GET_COLOR(VB->SecondaryColorPtr[1], dst),
}
}
else if (VB->IndexPtr[1]) {
- VB->IndexPtr[1]->data[dst] = VB->IndexPtr[1]->data[src];
+ VB->IndexPtr[1]->data[dst][0] = VB->IndexPtr[1]->data[src][0];
}
copy_pv_tab[SWSETUP_CONTEXT(ctx)->SetupIndex](ctx, dst, src);
SWvertex *v;
const GLfloat *ndc; /* NDC (i.e. projected clip coordinates) */
const GLfloat *tc[MAX_TEXTURE_COORD_UNITS];
- const GLchan *color;
- const GLchan *spec;
- const GLuint *index;
+ const GLfloat *color;
+ const GLfloat *spec;
+ const GLfloat *index;
const GLfloat *fog;
const GLfloat *pointSize;
GLuint tsz[MAX_TEXTURE_COORD_UNITS];
fog_stride = VB->FogCoordPtr->stride;
}
if (IND & COLOR) {
- if (VB->ColorPtr[0]->Type != CHAN_TYPE)
- import_float_colors( ctx );
-
- color = (GLchan *) VB->ColorPtr[0]->Ptr;
- color_stride = VB->ColorPtr[0]->StrideB;
+ color = (GLfloat *) VB->ColorPtr[0]->data;
+ color_stride = VB->ColorPtr[0]->stride;
}
if (IND & SPEC) {
- if (VB->SecondaryColorPtr[0]->Type != CHAN_TYPE)
- import_float_spec_colors( ctx );
-
- spec = (GLchan *) VB->SecondaryColorPtr[0]->Ptr;
- spec_stride = VB->SecondaryColorPtr[0]->StrideB;
+ spec = (GLfloat *) VB->SecondaryColorPtr[0]->data;
+ spec_stride = VB->SecondaryColorPtr[0]->stride;
}
if (IND & INDEX) {
- index = VB->IndexPtr[0]->data;
+ index = (GLfloat *) VB->IndexPtr[0]->data;
index_stride = VB->IndexPtr[0]->stride;
}
if (IND & POINT) {
}
if (IND & COLOR) {
- COPY_CHAN4(v->color, color);
- STRIDE_CHAN(color, color_stride);
+ UNCLAMPED_FLOAT_TO_RGBA_CHAN(v->color, color);
+ STRIDE_F(color, color_stride);
}
if (IND & SPEC) {
- COPY_CHAN4(v->specular, spec);
- STRIDE_CHAN(spec, spec_stride);
+ UNCLAMPED_FLOAT_TO_RGBA_CHAN(v->specular, spec);
+ STRIDE_F(spec, spec_stride);
}
if (IND & FOG) {
if (IND & INDEX) {
v->index = index[0];
- STRIDE_UI(index, index_stride);
+ STRIDE_F(index, index_stride);
}
if (IND & POINT) {
#include "t_array_api.h"
#include "t_array_import.h"
-#include "t_imm_api.h"
-#include "t_imm_exec.h"
+#include "t_save_api.h"
#include "t_context.h"
#include "t_pipeline.h"
static void fallback_drawarrays( GLcontext *ctx, GLenum mode, GLint start,
GLsizei count )
{
- if (_tnl_hard_begin( ctx, mode )) {
- GLint i;
- for (i = start; i < count; i++)
- glArrayElement( i );
- glEnd();
- }
+ GLint i;
+
+ assert(!ctx->CompileFlag);
+ assert(ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1);
+
+ glBegin(mode);
+ for (i = start; i < count; i++)
+ glArrayElement( i );
+ glEnd();
}
static void fallback_drawelements( GLcontext *ctx, GLenum mode, GLsizei count,
const GLuint *indices)
{
- if (_tnl_hard_begin(ctx, mode)) {
- GLint i;
- if (ctx->Array.ElementArrayBufferObj->Name) {
- /* use indices in the buffer object */
- ASSERT(ctx->Array.ElementArrayBufferObj->Data);
- indices = (const GLuint *) ctx->Array.ElementArrayBufferObj->Data;
- }
- for (i = 0 ; i < count ; i++) {
- glArrayElement( indices[i] );
- }
- glEnd();
+ GLint i;
+
+ assert(!ctx->CompileFlag);
+ assert(ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1);
+
+ /* Here, indices will already reflect the buffer object if active */
+
+ glBegin(mode);
+ for (i = 0 ; i < count ; i++) {
+ glArrayElement( indices[i] );
}
+ glEnd();
}
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct tnl_prim prim;
int i;
FLUSH_CURRENT( ctx, 0 );
- /* _mesa_debug(ctx, "%s\n", __FUNCTION__); */
if (tnl->pipeline.build_state_changes)
_tnl_validate_pipeline( ctx );
_tnl_vb_bind_arrays( ctx, start, end );
- tnl->vb.FirstPrimitive = 0;
- tnl->vb.Primitive[0] = mode | PRIM_BEGIN | PRIM_END | PRIM_LAST;
- tnl->vb.PrimitiveLength[0] = count;
+ tnl->vb.Primitive = &prim;
+ tnl->vb.Primitive[0].mode = mode | PRIM_BEGIN | PRIM_END;
+ tnl->vb.Primitive[0].start = 0;
+ tnl->vb.Primitive[0].count = count;
+ tnl->vb.PrimitiveCount = 1;
+
tnl->vb.Elts = (GLuint *)indices;
- for (i = 0 ; i < count ; i++)
- indices[i] -= start;
+ if (start)
+ for (i = 0 ; i < count ; i++)
+ indices[i] -= start;
if (ctx->Array.LockCount)
tnl->Driver.RunPipeline( ctx );
tnl->pipeline.run_input_changes |= ctx->Array._Enabled;
}
- for (i = 0 ; i < count ; i++)
- indices[i] += start;
+ if (start)
+ for (i = 0 ; i < count ; i++)
+ indices[i] += start;
}
{
GET_CURRENT_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
- struct vertex_buffer *VB = &tnl->vb;
GLuint thresh = (ctx->Driver.NeedFlush & FLUSH_STORED_VERTICES) ? 30 : 10;
if (MESA_VERBOSE & VERBOSE_API)
if (tnl->pipeline.build_state_changes)
_tnl_validate_pipeline( ctx );
- if (ctx->CompileFlag) {
- fallback_drawarrays( ctx, mode, start, start + count );
- }
- else if (!ctx->Array.LockCount && (GLuint) count < thresh) {
+ assert(!ctx->CompileFlag);
+
+ if (!ctx->Array.LockCount && (GLuint) count < thresh) {
/* Small primitives: attempt to share a vb (at the expense of
* using the immediate interface).
*/
else if (ctx->Array.LockCount &&
count < (GLint) ctx->Const.MaxArrayLockSize) {
+ struct tnl_prim prim;
+
/* Locked primitives which can fit in a single vertex buffer:
*/
FLUSH_CURRENT( ctx, 0 );
/* Locked drawarrays. Reuse any previously transformed data.
*/
_tnl_vb_bind_arrays( ctx, ctx->Array.LockFirst, ctx->Array.LockCount );
- VB->FirstPrimitive = start;
- VB->Primitive[start] = mode | PRIM_BEGIN | PRIM_END | PRIM_LAST;
- VB->PrimitiveLength[start] = count;
+
+ tnl->vb.Primitive = &prim;
+ tnl->vb.Primitive[0].mode = mode | PRIM_BEGIN | PRIM_END;
+ tnl->vb.Primitive[0].start = start;
+ tnl->vb.Primitive[0].count = count;
+ tnl->vb.PrimitiveCount = 1;
+
tnl->Driver.RunPipeline( ctx );
}
else {
for (j = start + minimum ; j < count ; j += nr + skip ) {
+ struct tnl_prim prim;
+
nr = MIN2( bufsz, count - j );
_tnl_vb_bind_arrays( ctx, j - minimum, j + nr );
- VB->FirstPrimitive = 0;
- VB->Primitive[0] = mode | PRIM_BEGIN | PRIM_END | PRIM_LAST;
- VB->PrimitiveLength[0] = nr + minimum;
+ tnl->vb.Primitive = &prim;
+ tnl->vb.Primitive[0].mode = mode;
+
+ if (j == start + minimum)
+ tnl->vb.Primitive[0].mode |= PRIM_BEGIN;
+
+ if (j + nr + skip >= count)
+ tnl->vb.Primitive[0].mode |= PRIM_END;
+
+ tnl->vb.Primitive[0].start = 0;
+ tnl->vb.Primitive[0].count = nr + minimum;
+ tnl->vb.PrimitiveCount = 1;
+
tnl->pipeline.run_input_changes |= ctx->Array._Enabled;
tnl->Driver.RunPipeline( ctx );
tnl->pipeline.run_input_changes |= ctx->Array._Enabled;
count, type, indices );
- if (ctx->CompileFlag) {
- /* Can't do anything when compiling:
- */
- fallback_drawelements( ctx, mode, count, ui_indices );
- }
- else if (ctx->Array.LockCount) {
+ assert(!ctx->CompileFlag);
+
+ if (ctx->Array.LockCount) {
/* Are the arrays already locked? If so we currently have to look
* at the whole locked range.
*/
ui_indices = (GLuint *)_ac_import_elements( ctx, GL_UNSIGNED_INT,
count, type, indices );
- if (ctx->CompileFlag) {
- /* Can't do anything when compiling:
- */
- fallback_drawelements( ctx, mode, count, ui_indices );
- }
- else if (ctx->Array.LockCount) {
+ assert(!ctx->CompileFlag);
+
+ if (ctx->Array.LockCount) {
_tnl_draw_range_elements( ctx, mode,
ctx->Array.LockFirst,
ctx->Array.LockCount,
void _tnl_array_init( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
- struct vertex_arrays *tmp = &tnl->array_inputs;
- GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->vtxfmt);
+ struct tnl_vertex_arrays *tmp = &tnl->array_inputs;
+ GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->exec_vtxfmt);
GLuint i;
vfmt->DrawArrays = _tnl_DrawArrays;
_mesa_vector4f_init( &tmp->Obj, 0, 0 );
_mesa_vector4f_init( &tmp->Normal, 0, 0 );
_mesa_vector4f_init( &tmp->FogCoord, 0, 0 );
- _mesa_vector1ui_init( &tmp->Index, 0, 0 );
- _mesa_vector1ub_init( &tmp->EdgeFlag, 0, 0 );
+ _mesa_vector4f_init( &tmp->Index, 0, 0 );
for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
_mesa_vector4f_init( &tmp->TexCoord[i], 0, 0);
-
- tnl->tmp_primitive = (GLuint *)MALLOC(sizeof(GLuint)*tnl->vb.Size);
- tnl->tmp_primitive_length = (GLuint *)MALLOC(sizeof(GLuint)*tnl->vb.Size);
}
*/
void _tnl_array_destroy( GLcontext *ctx )
{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- if (tnl->tmp_primitive_length) FREE(tnl->tmp_primitive_length);
- if (tnl->tmp_primitive) FREE(tnl->tmp_primitive);
}
#include "t_array_import.h"
#include "t_context.h"
-#include "t_imm_debug.h"
static void _tnl_import_vertex( GLcontext *ctx,
{
struct gl_client_array *tmp;
GLboolean is_writeable = 0;
- struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
+ struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
const GLubyte *data;
tmp = _ac_import_vertex(ctx,
writeable,
&is_writeable);
-#if 0
- /* guess we really don't need to add pointers here - BP */
- data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
-#else
data = tmp->Ptr;
-#endif
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);
- if (inputs->Obj.stride != 4*sizeof(GLfloat))
- inputs->Obj.flags |= VEC_BAD_STRIDE;
- if (!is_writeable)
- inputs->Obj.flags |= VEC_NOT_WRITEABLE;
}
static void _tnl_import_normal( GLcontext *ctx,
{
struct gl_client_array *tmp;
GLboolean is_writeable = 0;
- struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
+ struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
const GLubyte *data;
tmp = _ac_import_normal(ctx, GL_FLOAT,
stride ? 3*sizeof(GLfloat) : 0, writeable,
&is_writeable);
-#if 0
- data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
-#else
data = tmp->Ptr;
-#endif
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))
- inputs->Normal.flags |= VEC_BAD_STRIDE;
- if (!is_writeable)
- inputs->Normal.flags |= VEC_NOT_WRITEABLE;
}
static void _tnl_import_color( GLcontext *ctx,
- GLenum type,
GLboolean writeable,
GLboolean stride )
{
struct gl_client_array *tmp;
GLboolean is_writeable = 0;
- struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
+ struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
+ GLubyte *data;
tmp = _ac_import_color(ctx,
- type,
+ GL_FLOAT,
stride ? 4*sizeof(GLfloat) : 0,
4,
writeable,
&is_writeable);
- inputs->Color = *tmp;
+ data = tmp->Ptr;
+ inputs->Color.data = (GLfloat (*)[4]) data;
+ inputs->Color.start = (GLfloat *) data;
+ inputs->Color.stride = tmp->StrideB;
+ inputs->Color.size = tmp->Size;
}
static void _tnl_import_secondarycolor( GLcontext *ctx,
- GLenum type,
GLboolean writeable,
GLboolean stride )
{
struct gl_client_array *tmp;
GLboolean is_writeable = 0;
- struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
+ struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
+ GLubyte *data;
tmp = _ac_import_secondarycolor(ctx,
- type,
+ GL_FLOAT,
stride ? 4*sizeof(GLfloat) : 0,
4,
writeable,
&is_writeable);
- inputs->SecondaryColor = *tmp;
+ data = tmp->Ptr;
+ inputs->SecondaryColor.data = (GLfloat (*)[4]) data;
+ inputs->SecondaryColor.start = (GLfloat *) data;
+ inputs->SecondaryColor.stride = tmp->StrideB;
+ inputs->SecondaryColor.size = tmp->Size;
}
static void _tnl_import_fogcoord( GLcontext *ctx,
GLboolean writeable,
GLboolean stride )
{
- struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
+ struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
struct gl_client_array *tmp;
GLboolean is_writeable = 0;
const GLubyte *data;
stride ? sizeof(GLfloat) : 0, writeable,
&is_writeable);
-#if 0
- data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
-#else
data = tmp->Ptr;
-#endif
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))
- inputs->FogCoord.flags |= VEC_BAD_STRIDE;
- if (!is_writeable)
- inputs->FogCoord.flags |= VEC_NOT_WRITEABLE;
}
static void _tnl_import_index( GLcontext *ctx,
GLboolean writeable,
GLboolean stride )
{
- struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
+ struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
struct gl_client_array *tmp;
GLboolean is_writeable = 0;
const GLubyte *data;
- tmp = _ac_import_index(ctx, GL_UNSIGNED_INT,
- stride ? sizeof(GLuint) : 0, writeable,
+ tmp = _ac_import_index(ctx, GL_FLOAT,
+ stride ? sizeof(GLfloat) : 0, writeable,
&is_writeable);
-#if 0
- data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
-#else
data = tmp->Ptr;
-#endif
- inputs->Index.data = (GLuint *) data;
- inputs->Index.start = (GLuint *) data;
+ inputs->Index.data = (GLfloat (*)[4]) data;
+ inputs->Index.start = (GLfloat *) data;
inputs->Index.stride = tmp->StrideB;
- inputs->Index.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
- if (inputs->Index.stride != sizeof(GLuint))
- inputs->Index.flags |= VEC_BAD_STRIDE;
- if (!is_writeable)
- inputs->Index.flags |= VEC_NOT_WRITEABLE;
}
GLboolean writeable,
GLboolean stride )
{
- struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
+ struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
struct gl_client_array *tmp;
GLboolean is_writeable = 0;
const GLubyte *data;
writeable,
&is_writeable);
-#if 0
- data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
-#else
data = tmp->Ptr;
-#endif
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);
- if (inputs->TexCoord[unit].stride != 4*sizeof(GLfloat))
- inputs->TexCoord[unit].flags |= VEC_BAD_STRIDE;
- if (!is_writeable)
- inputs->TexCoord[unit].flags |= VEC_NOT_WRITEABLE;
}
GLboolean writeable,
GLboolean stride )
{
- struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
+ struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
struct gl_client_array *tmp;
GLboolean is_writeable = 0;
const GLubyte *data;
tmp = _ac_import_edgeflag(ctx, GL_UNSIGNED_BYTE,
- stride ? sizeof(GLubyte) : 0,
+ sizeof(GLubyte),
0,
&is_writeable);
-#if 0
- data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
-#else
data = tmp->Ptr;
-#endif
- 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))
- inputs->EdgeFlag.flags |= VEC_BAD_STRIDE;
- if (!is_writeable)
- inputs->EdgeFlag.flags |= VEC_NOT_WRITEABLE;
+ inputs->EdgeFlag = (GLubyte *) data;
}
GLboolean writeable,
GLboolean stride )
{
- struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
+ struct tnl_vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
struct gl_client_array *tmp;
GLboolean is_writeable = 0;
const GLubyte *data;
writeable,
&is_writeable);
-#if 0
- data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
-#else
data = tmp->Ptr;
-#endif
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);
- if (inputs->Attribs[index].stride != 4 * sizeof(GLfloat))
- inputs->Attribs[index].flags |= VEC_BAD_STRIDE;
- if (!is_writeable)
- inputs->Attribs[index].flags |= VEC_NOT_WRITEABLE;
}
-/**
- * Callback for VB stages that need to improve the quality of arrays
- * bound to the VB. This is only necessary for client arrays which
- * have not been transformed at any point in the pipeline.
- * \param required - bitmask of VERT_*_BIT flags
- * \param flags - bitmask of VEC_* flags (ex: VEC_NOT_WRITABLE)
- */
-static void _tnl_upgrade_client_data( GLcontext *ctx,
- GLuint required,
- GLuint flags )
-{
- GLuint i;
- struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
- GLboolean writeable = (flags & VEC_NOT_WRITEABLE) != 0;
- GLboolean stride = (flags & VEC_BAD_STRIDE) != 0;
- struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
- GLuint ca_flags = 0;
- (void) inputs;
-
- if (writeable || stride) ca_flags |= CA_CLIENT_DATA;
-
- if ((required & VERT_BIT_CLIP) && VB->ClipPtr == VB->ObjPtr)
- required |= VERT_BIT_POS;
-
-/* _tnl_print_vert_flags("_tnl_upgrade_client_data", required); */
-
- if ((required & VERT_BIT_POS) && (VB->ObjPtr->flags & flags)) {
- ASSERT(VB->ObjPtr == &inputs->Obj);
- _tnl_import_vertex( ctx, writeable, stride );
- VB->importable_data &= ~(VERT_BIT_POS|VERT_BIT_CLIP);
- }
-
- if ((required & VERT_BIT_NORMAL) && (VB->NormalPtr->flags & flags)) {
- ASSERT(VB->NormalPtr == &inputs->Normal);
- _tnl_import_normal( ctx, writeable, stride );
- VB->importable_data &= ~VERT_BIT_NORMAL;
- }
-
- if ((required & VERT_BIT_COLOR0) && (VB->ColorPtr[0]->Flags & ca_flags)) {
- ASSERT(VB->ColorPtr[0] == &inputs->Color);
- _tnl_import_color( ctx, GL_FLOAT, writeable, stride );
- VB->importable_data &= ~VERT_BIT_COLOR0;
- }
-
- if ((required & VERT_BIT_COLOR1) &&
- (VB->SecondaryColorPtr[0]->Flags & ca_flags)) {
- ASSERT(VB->SecondaryColorPtr[0] == &inputs->SecondaryColor);
- _tnl_import_secondarycolor( ctx, GL_FLOAT, writeable, stride );
- VB->importable_data &= ~VERT_BIT_COLOR1;
- }
-
- if ((required & VERT_BIT_FOG)
- && (VB->FogCoordPtr->flags & flags)) {
- ASSERT(VB->FogCoordPtr == &inputs->FogCoord);
- _tnl_import_fogcoord( ctx, writeable, stride );
- VB->importable_data &= ~VERT_BIT_FOG;
- }
-
- if ((required & VERT_BIT_INDEX) && (VB->IndexPtr[0]->flags & flags)) {
- ASSERT(VB->IndexPtr[0] == &inputs->Index);
- _tnl_import_index( ctx, writeable, stride );
- VB->importable_data &= ~VERT_BIT_INDEX;
- }
-
- if (required & VERT_BITS_TEX_ANY)
- for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
- if ((required & VERT_BIT_TEX(i)) && (VB->TexCoordPtr[i]->flags & flags)) {
- ASSERT(VB->TexCoordPtr[i] == &inputs->TexCoord[i]);
- _tnl_import_texcoord( ctx, i, writeable, stride );
- VB->importable_data &= ~VERT_BIT_TEX(i);
- }
-
- /* XXX not sure what to do here for vertex program arrays */
-}
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint inputs = tnl->pipeline.inputs;
- struct vertex_arrays *tmp = &tnl->array_inputs;
-
-/* _mesa_debug(ctx, "%s %d..%d // %d..%d\n", __FUNCTION__, */
-/* start, count, ctx->Array.LockFirst, ctx->Array.LockCount); */
-/* _tnl_print_vert_flags(" inputs", inputs); */
-/* _tnl_print_vert_flags(" _Enabled", ctx->Array._Enabled); */
-/* _tnl_print_vert_flags(" importable", inputs & VERT_BITS_FIXUP); */
+ struct tnl_vertex_arrays *tmp = &tnl->array_inputs;
+ GLuint i;
VB->Count = count - start;
- VB->FirstClipped = VB->Count;
VB->Elts = NULL;
- VB->MaterialMask = NULL;
- VB->Material = NULL;
- VB->Flag = NULL;
- VB->Primitive = tnl->tmp_primitive;
- VB->PrimitiveLength = tnl->tmp_primitive_length;
- VB->import_data = _tnl_upgrade_client_data;
- VB->importable_data = inputs & VERT_BITS_FIXUP;
if (ctx->Array.LockCount) {
- ASSERT(start == (GLint) ctx->Array.LockFirst);
- ASSERT(count == (GLint) ctx->Array.LockCount);
+ assert(start == (GLint) ctx->Array.LockFirst);
+ assert(count == (GLint) ctx->Array.LockCount);
}
_ac_import_range( ctx, start, count );
VB->AttribPtr[index] = &tmp->Attribs[index];
}
}
+ else {
+
+ /*
+ * Conventional attributes
+ */
+ if (inputs & _TNL_BIT_POS) {
+ _tnl_import_vertex( ctx, 0, 0 );
+ tmp->Obj.count = VB->Count;
+ VB->AttribPtr[_TNL_ATTRIB_POS] = &tmp->Obj;
+ }
- /*
- * Conventional attributes
- */
- if (inputs & VERT_BIT_POS) {
- _tnl_import_vertex( ctx, 0, 0 );
- tmp->Obj.count = VB->Count;
- VB->ObjPtr = &tmp->Obj;
- }
-
- if (inputs & VERT_BIT_NORMAL) {
- _tnl_import_normal( ctx, 0, 0 );
- tmp->Normal.count = VB->Count;
- VB->NormalPtr = &tmp->Normal;
- }
-
- if (inputs & VERT_BIT_COLOR0) {
- _tnl_import_color( ctx, 0, 0, 0 );
- VB->ColorPtr[0] = &tmp->Color;
- VB->ColorPtr[1] = 0;
- }
+ if (inputs & _TNL_BIT_NORMAL) {
+ _tnl_import_normal( ctx, 0, 0 );
+ tmp->Normal.count = VB->Count;
+ VB->AttribPtr[_TNL_ATTRIB_NORMAL] = &tmp->Normal;
+ }
- if (inputs & VERT_BITS_TEX_ANY) {
- GLuint unit;
- for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
- if (inputs & VERT_BIT_TEX(unit)) {
- _tnl_import_texcoord( ctx, unit, GL_FALSE, GL_FALSE );
- tmp->TexCoord[unit].count = VB->Count;
- VB->TexCoordPtr[unit] = &tmp->TexCoord[unit];
- }
+ if (inputs & _TNL_BIT_COLOR0) {
+ _tnl_import_color( ctx, 0, 0 );
+ tmp->Color.count = VB->Count;
+ VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &tmp->Color;
}
- }
- if (inputs & (VERT_BIT_INDEX | VERT_BIT_FOG |
- VERT_BIT_EDGEFLAG | VERT_BIT_COLOR1)) {
- if (inputs & VERT_BIT_INDEX) {
+ if (inputs & _TNL_BIT_INDEX) {
_tnl_import_index( ctx, 0, 0 );
tmp->Index.count = VB->Count;
- VB->IndexPtr[0] = &tmp->Index;
- VB->IndexPtr[1] = 0;
+ VB->AttribPtr[_TNL_ATTRIB_INDEX] = &tmp->Index;
}
- if (inputs & VERT_BIT_FOG) {
+ if (inputs & _TNL_BIT_FOG) {
_tnl_import_fogcoord( ctx, 0, 0 );
tmp->FogCoord.count = VB->Count;
- VB->FogCoordPtr = &tmp->FogCoord;
+ VB->AttribPtr[_TNL_ATTRIB_FOG] = &tmp->FogCoord;
}
- if (inputs & VERT_BIT_EDGEFLAG) {
+ if (inputs & _TNL_BIT_EDGEFLAG) {
_tnl_import_edgeflag( ctx, GL_TRUE, sizeof(GLboolean) );
- VB->EdgeFlag = (GLboolean *) tmp->EdgeFlag.data;
+ VB->EdgeFlag = (GLboolean *) tmp->EdgeFlag;
+ }
+
+ if (inputs & _TNL_BIT_COLOR1) {
+ _tnl_import_secondarycolor( ctx, 0, 0 );
+ tmp->SecondaryColor.count = VB->Count;
+ VB->AttribPtr[_TNL_ATTRIB_COLOR1] = &tmp->SecondaryColor;
}
- if (inputs & VERT_BIT_COLOR1) {
- _tnl_import_secondarycolor( ctx, 0, 0, 0 );
- VB->SecondaryColorPtr[0] = &tmp->SecondaryColor;
- VB->SecondaryColorPtr[1] = 0;
+
+ if (inputs & _TNL_BITS_TEX_ANY) {
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+ if (inputs & _TNL_BIT_TEX(i)) {
+ _tnl_import_texcoord( ctx, i, GL_FALSE, GL_FALSE );
+ tmp->TexCoord[i].count = VB->Count;
+ VB->AttribPtr[_TNL_ATTRIB_TEX0 + i] = &tmp->TexCoord[i];
+ }
+ }
}
}
+
+
+ /* These are constant & can be precalculated:
+ */
+ if (inputs & _TNL_BITS_MAT_ANY) {
+ for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT; i < _TNL_ATTRIB_INDEX; i++) {
+ tmp->Attribs[i].count = count;
+ tmp->Attribs[i].data = (GLfloat (*)[4]) tnl->vtx.current[i];
+ tmp->Attribs[i].start = tnl->vtx.current[i];
+ tmp->Attribs[i].size = 4;
+ tmp->Attribs[i].stride = 0;
+ VB->AttribPtr[i] = &tmp->Attribs[i];
+ }
+ }
+
+
+ /* Legacy pointers -- remove one day.
+ */
+ VB->ObjPtr = VB->AttribPtr[_TNL_ATTRIB_POS];
+ VB->NormalPtr = VB->AttribPtr[_TNL_ATTRIB_NORMAL];
+ VB->ColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR0];
+ VB->ColorPtr[1] = 0;
+ VB->IndexPtr[0] = VB->AttribPtr[_TNL_ATTRIB_INDEX];
+ VB->IndexPtr[1] = 0;
+ VB->SecondaryColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR1];
+ VB->SecondaryColorPtr[1] = 0;
+
+ for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
+ VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i];
+ }
+
}
*/
+#include "api_arrayelt.h"
#include "glheader.h"
#include "imports.h"
#include "macros.h"
#include "t_context.h"
#include "t_array_api.h"
-#include "t_eval_api.h"
-#include "t_imm_alloc.h"
-#include "t_imm_api.h"
-#include "t_imm_exec.h"
-#include "t_imm_dlist.h"
+#include "t_vtx_api.h"
+#include "t_save_api.h"
#include "t_pipeline.h"
#include "tnl.h"
-#ifndef THREADS
-struct immediate *_tnl_CurrentInput = NULL;
-#endif
void
GLframebuffer *drawBuffer,
GLframebuffer *readBuffer )
{
-#ifndef THREADS
- SET_IMMEDIATE( ctx, TNL_CURRENT_IM(ctx) );
-#endif
}
{
ctx->Driver.NewList = _tnl_NewList;
ctx->Driver.EndList = _tnl_EndList;
- ctx->Driver.FlushVertices = _tnl_flush_vertices;
+ ctx->Driver.FlushVertices = _tnl_FlushVertices;
+ ctx->Driver.SaveFlushVertices = _tnl_SaveFlushVertices;
ctx->Driver.MakeCurrent = _tnl_MakeCurrent;
ctx->Driver.BeginCallList = _tnl_BeginCallList;
ctx->Driver.EndCallList = _tnl_EndCallList;
/* Initialize the VB.
*/
- tnl->vb.Size = MAX2( IMM_SIZE,
- ctx->Const.MaxArrayLockSize + MAX_CLIPPED_VERTICES);
+ tnl->vb.Size = ctx->Const.MaxArrayLockSize + MAX_CLIPPED_VERTICES;
/* Initialize tnl state and tnl->vtxfmt.
*/
- _tnl_dlist_init( ctx );
+ _tnl_save_init( ctx );
_tnl_array_init( ctx );
- _tnl_imm_init( ctx );
- _tnl_eval_init( ctx );
+ _tnl_vtx_init( ctx );
_tnl_install_pipeline( ctx, _tnl_default_pipeline );
+ /* Initialize the arrayelt helper
+ */
+ if (!_ae_create_context( ctx ))
+ return GL_FALSE;
+
tnl->NeedNdcCoords = GL_TRUE;
tnl->LoopbackDListCassettes = GL_FALSE;
/* Hook our functions into exec and compile dispatch tables.
*/
- _mesa_install_exec_vtxfmt( ctx, &tnl->vtxfmt );
-
- tnl->save_vtxfmt = tnl->vtxfmt;
- tnl->save_vtxfmt.CallList = _mesa_save_CallList;
- tnl->save_vtxfmt.EvalMesh1 = _mesa_save_EvalMesh1;
- tnl->save_vtxfmt.EvalMesh2 = _mesa_save_EvalMesh2;
- tnl->save_vtxfmt.Begin = _tnl_save_Begin;
-
- _mesa_install_save_vtxfmt( ctx, &tnl->save_vtxfmt );
+ _mesa_install_exec_vtxfmt( ctx, &tnl->exec_vtxfmt );
/* Set a few default values in the driver struct.
*/
install_driver_callbacks(ctx);
- ctx->Driver.NeedFlush = FLUSH_UPDATE_CURRENT;
+ ctx->Driver.NeedFlush = 0;
ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
tnl->Driver.NotifyMaterialChange = _mesa_validate_all_lighting_tables;
-
-
return GL_TRUE;
}
TNLcontext *tnl = TNL_CONTEXT(ctx);
_tnl_array_destroy( ctx );
- _tnl_imm_destroy( ctx );
+ _tnl_vtx_destroy( ctx );
+ _tnl_save_destroy( ctx );
_tnl_destroy_pipeline( ctx );
- _tnl_free_immediate( ctx, tnl->freed_immediate );
FREE(tnl);
ctx->swtnl_context = 0;
TNLcontext *tnl = TNL_CONTEXT(ctx);
if (new_state & _NEW_ARRAY) {
- struct immediate *IM = TNL_CURRENT_IM(ctx);
- IM->ArrayEltFlags = ~ctx->Array._Enabled;
- IM->ArrayEltFlush = (ctx->Array.LockCount
- ? FLUSH_ELT_LAZY : FLUSH_ELT_EAGER);
- IM->ArrayEltIncr = (ctx->Array.Vertex.Enabled ||
- (ctx->VertexProgram.Enabled &&
- ctx->Array.VertexAttrib[0].Enabled)) ? 1 : 0;
tnl->pipeline.run_input_changes |= ctx->Array.NewState; /* overkill */
}
tnl->pipeline.build_state_changes |= (new_state &
tnl->pipeline.build_state_trigger);
- tnl->eval.EvalNewState |= new_state;
+ tnl->vtx.eval.new_state |= new_state;
}
/* Hook our functions into exec and compile dispatch tables.
*/
- _mesa_install_exec_vtxfmt( ctx, &tnl->vtxfmt );
+ _mesa_install_exec_vtxfmt( ctx, &tnl->exec_vtxfmt );
/* Call all appropriate driver callbacks to revive state.
*/
tnl->pipeline.run_input_changes = ~0;
if (ctx->Light.ColorMaterialEnabled) {
- _mesa_update_color_material( ctx, ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
+ _mesa_update_color_material( ctx,
+ ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
}
-
}
/*
- * Mesa 3-D graphics library
+ * mesa 3-D graphics library
* Version: 5.1
*
* Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
* necessary transformations (rotations, clipping, vertex shader etc.)
* and passes then the output to the rasterizer.
*
- * The gl_pipeline contains the array of all stages, which should be
+ * The tnl_pipeline contains the array of all stages, which should be
* applied. Each stage is a black-box, which is described by an
- * gl_pipeline_stage. The function ::_tnl_run_pipeline applies all the
+ * tnl_pipeline_stage. The function ::_tnl_run_pipeline applies all the
* stages to the vertex_buffer TNLcontext::vb, where the vertex data
* is stored. The last stage in the pipeline is the rasterizer.
*
* into TNLcontext::vb, so that the pipeline can be started.
*/
-/* What is ELT? */
#ifndef _T_CONTEXT_H
#define _T_CONTEXT_H
#define MAX_PIPELINE_STAGES 30
-/* Numbers for sizing immediate structs.
+enum {
+ _TNL_ATTRIB_POS = 0,
+ _TNL_ATTRIB_WEIGHT = 1,
+ _TNL_ATTRIB_NORMAL = 2,
+ _TNL_ATTRIB_COLOR0 = 3,
+ _TNL_ATTRIB_COLOR1 = 4,
+ _TNL_ATTRIB_FOG = 5,
+ _TNL_ATTRIB_SIX = 6,
+ _TNL_ATTRIB_SEVEN = 7,
+ _TNL_ATTRIB_TEX0 = 8,
+ _TNL_ATTRIB_TEX1 = 9,
+ _TNL_ATTRIB_TEX2 = 10,
+ _TNL_ATTRIB_TEX3 = 11,
+ _TNL_ATTRIB_TEX4 = 12,
+ _TNL_ATTRIB_TEX5 = 13,
+ _TNL_ATTRIB_TEX6 = 14,
+ _TNL_ATTRIB_TEX7 = 15,
+ _TNL_ATTRIB_MAT_FRONT_AMBIENT = 16,
+ _TNL_ATTRIB_MAT_BACK_AMBIENT = 17,
+ _TNL_ATTRIB_MAT_FRONT_DIFFUSE = 18,
+ _TNL_ATTRIB_MAT_BACK_DIFFUSE = 19,
+ _TNL_ATTRIB_MAT_FRONT_SPECULAR = 20,
+ _TNL_ATTRIB_MAT_BACK_SPECULAR = 21,
+ _TNL_ATTRIB_MAT_FRONT_EMISSION = 22,
+ _TNL_ATTRIB_MAT_BACK_EMISSION = 23,
+ _TNL_ATTRIB_MAT_FRONT_SHININESS = 24,
+ _TNL_ATTRIB_MAT_BACK_SHININESS = 25,
+ _TNL_ATTRIB_MAT_FRONT_INDEXES = 26,
+ _TNL_ATTRIB_MAT_BACK_INDEXES = 27,
+ _TNL_ATTRIB_INDEX = 28,
+ _TNL_ATTRIB_EDGEFLAG = 29,
+ _TNL_ATTRIB_MAX = 30
+} ;
+
+/* Will probably have to revise this scheme fairly shortly, eg. by
+ * compacting all the MAT flags down to one bit, or by using two
+ * dwords to store the flags.
*/
-#define IMM_MAX_COPIED_VERTS 3
-#define IMM_MAXDATA (216 + IMM_MAX_COPIED_VERTS)
-#define IMM_SIZE (IMM_MAXDATA + MAX_CLIPPED_VERTICES)
+#define _TNL_BIT_POS (1<<0)
+#define _TNL_BIT_WEIGHT (1<<1)
+#define _TNL_BIT_NORMAL (1<<2)
+#define _TNL_BIT_COLOR0 (1<<3)
+#define _TNL_BIT_COLOR1 (1<<4)
+#define _TNL_BIT_FOG (1<<5)
+#define _TNL_BIT_SIX (1<<6)
+#define _TNL_BIT_SEVEN (1<<7)
+#define _TNL_BIT_TEX0 (1<<8)
+#define _TNL_BIT_TEX1 (1<<9)
+#define _TNL_BIT_TEX2 (1<<10)
+#define _TNL_BIT_TEX3 (1<<11)
+#define _TNL_BIT_TEX4 (1<<12)
+#define _TNL_BIT_TEX5 (1<<13)
+#define _TNL_BIT_TEX6 (1<<14)
+#define _TNL_BIT_TEX7 (1<<15)
+#define _TNL_BIT_MAT_FRONT_AMBIENT (1<<16)
+#define _TNL_BIT_MAT_BACK_AMBIENT (1<<17)
+#define _TNL_BIT_MAT_FRONT_DIFFUSE (1<<18)
+#define _TNL_BIT_MAT_BACK_DIFFUSE (1<<19)
+#define _TNL_BIT_MAT_FRONT_SPECULAR (1<<20)
+#define _TNL_BIT_MAT_BACK_SPECULAR (1<<21)
+#define _TNL_BIT_MAT_FRONT_EMISSION (1<<22)
+#define _TNL_BIT_MAT_BACK_EMISSION (1<<23)
+#define _TNL_BIT_MAT_FRONT_SHININESS (1<<24)
+#define _TNL_BIT_MAT_BACK_SHININESS (1<<25)
+#define _TNL_BIT_MAT_FRONT_INDEXES (1<<26)
+#define _TNL_BIT_MAT_BACK_INDEXES (1<<27)
+#define _TNL_BIT_INDEX (1<<28)
+#define _TNL_BIT_EDGEFLAG (1<<29)
+
+#define _TNL_BIT_TEX(u) (1 << (_TNL_ATTRIB_TEX0 + (u)))
+
+
+#define _TNL_BITS_MAT_ANY (_TNL_BIT_MAT_FRONT_AMBIENT | \
+ _TNL_BIT_MAT_BACK_AMBIENT | \
+ _TNL_BIT_MAT_FRONT_DIFFUSE | \
+ _TNL_BIT_MAT_BACK_DIFFUSE | \
+ _TNL_BIT_MAT_FRONT_SPECULAR | \
+ _TNL_BIT_MAT_BACK_SPECULAR | \
+ _TNL_BIT_MAT_FRONT_EMISSION | \
+ _TNL_BIT_MAT_BACK_EMISSION | \
+ _TNL_BIT_MAT_FRONT_SHININESS | \
+ _TNL_BIT_MAT_BACK_SHININESS | \
+ _TNL_BIT_MAT_FRONT_INDEXES | \
+ _TNL_BIT_MAT_BACK_INDEXES)
+
+
+#define _TNL_BITS_TEX_ANY (_TNL_BIT_TEX0 | \
+ _TNL_BIT_TEX1 | \
+ _TNL_BIT_TEX2 | \
+ _TNL_BIT_TEX3 | \
+ _TNL_BIT_TEX4 | \
+ _TNL_BIT_TEX5 | \
+ _TNL_BIT_TEX6 | \
+ _TNL_BIT_TEX7)
+
+
+#define _TNL_BITS_PROG_ANY (_TNL_BIT_POS | \
+ _TNL_BIT_WEIGHT | \
+ _TNL_BIT_NORMAL | \
+ _TNL_BIT_COLOR0 | \
+ _TNL_BIT_COLOR1 | \
+ _TNL_BIT_FOG | \
+ _TNL_BIT_SIX | \
+ _TNL_BIT_SEVEN | \
+ _TNL_BITS_TEX_ANY)
+
+
+
+#define PRIM_BEGIN 0x10
+#define PRIM_END 0x20
+#define PRIM_WEAK 0x40
+#define PRIM_MODE_MASK 0x0f
+
+/*
+ */
+struct tnl_prim {
+ GLuint mode;
+ GLuint start;
+ GLuint count;
+};
-/* Values for IM->BeginState
- */
-#define VERT_BEGIN_0 0x1 /* glBegin (if initially inside beg/end) */
-#define VERT_BEGIN_1 0x2 /* glBegin (if initially outside beg/end) */
-#define VERT_ERROR_0 0x4 /* invalid_operation in initial state 0 */
-#define VERT_ERROR_1 0x8 /* invalid_operation in initial state 1 */
+struct tnl_eval1_map {
+ struct gl_1d_map *map;
+ GLuint sz;
+};
-/* Flags to be added to the primitive enum in VB->Primitive.
- */
-#define PRIM_MODE_MASK 0xff /* Extract the actual primitive */
-#define PRIM_BEGIN 0x100 /* The prim starts here (not wrapped) */
-#define PRIM_END 0x200 /* The prim ends in this VB (does not wrap) */
-#define PRIM_PARITY 0x400 /* The prim wrapped on an odd number of verts */
-#define PRIM_LAST 0x800 /* No more prims in the VB */
+struct tnl_eval2_map {
+ struct gl_2d_map *map;
+ GLuint sz;
+};
+
+struct tnl_eval {
+ GLuint new_state;
+ struct tnl_eval1_map map1[_TNL_ATTRIB_INDEX + 1];
+ struct tnl_eval2_map map2[_TNL_ATTRIB_INDEX + 1];
+};
-/**
- * Flags that describe the inputs and outputs of pipeline stages, and
- * the contents of a vertex-cassette. We reuse the VERT_BIT_* flags
- * defined in mtypes.h and add a bunch of new ones.
- */
-/* bits 0..5 defined in mtypes.h */
-#define VERT_BIT_INDEX VERT_BIT_SIX /* a free vertex attrib bit */
-#define VERT_BIT_EDGEFLAG VERT_BIT_SEVEN /* a free vertex attrib bit */
-/* bits 8..15 defined in mtypes.h */
-#define VERT_BIT_EVAL_C1 (1 << 16) /* imm only */
-#define VERT_BIT_EVAL_C2 (1 << 17) /* imm only */
-#define VERT_BIT_EVAL_P1 (1 << 18) /* imm only */
-#define VERT_BIT_EVAL_P2 (1 << 19) /* imm only */
-#define VERT_BIT_OBJ_3 (1 << 20) /* imm only */
-#define VERT_BIT_OBJ_4 (1 << 21) /* imm only */
-#define VERT_BIT_MATERIAL (1 << 22) /* imm only, but tested in vb code */
-#define VERT_BIT_ELT (1 << 23) /* imm only */
-#define VERT_BIT_BEGIN (1 << 24) /* imm only, but tested in vb code */
-#define VERT_BIT_END (1 << 25) /* imm only, but tested in vb code */
-#define VERT_BIT_END_VB (1 << 26) /* imm only, but tested in vb code */
-#define VERT_BIT_POINT_SIZE (1 << 27) /* vb only, could reuse a bit */
-#define VERT_BIT_EYE VERT_BIT_BEGIN /* vb only, reuse imm bit */
-#define VERT_BIT_CLIP VERT_BIT_END /* vb only, reuse imm bit*/
-
-
-/* Flags for IM->TexCoordSize. Enough flags for 16 units.
+#define TNL_MAX_PRIM 16
+#define TNL_MAX_COPIED_VERTS 3
+
+struct tnl_copied_vtx {
+ GLfloat buffer[_TNL_ATTRIB_MAX * 4 * TNL_MAX_COPIED_VERTS];
+ GLuint nr;
+};
+
+#define VERT_BUFFER_SIZE 2048 /* 8kbytes */
+
+typedef void (*attrfv_func)( const GLfloat * );
+
+/* The assembly of vertices in immediate mode is separated from
+ * display list compilation. This allows a simpler immediate mode
+ * treatment and a display list compiler better suited to
+ * hardware-acceleration.
*/
-#define TEX_0_SIZE_3 (unsigned)0x1
-#define TEX_0_SIZE_4 (unsigned)0x10001
-#define TEX_SIZE_3(unit) (TEX_0_SIZE_3 << (unit))
-#define TEX_SIZE_4(unit) (TEX_0_SIZE_4 << (unit))
+struct tnl_vtx {
+ GLfloat buffer[VERT_BUFFER_SIZE];
+ GLubyte attrsz[_TNL_ATTRIB_MAX];
+ GLuint vertex_size;
+ struct tnl_prim prim[TNL_MAX_PRIM];
+ GLuint prim_count;
+ GLfloat *vbptr; /* cursor, points into buffer */
+ GLfloat vertex[_TNL_ATTRIB_MAX*4]; /* current vertex */
+ GLfloat *attrptr[_TNL_ATTRIB_MAX]; /* points into vertex */
+ GLfloat *current[_TNL_ATTRIB_MAX]; /* points into ctx->Current, etc */
+ GLuint counter, initial_counter;
+ struct tnl_copied_vtx copied;
+ attrfv_func tabfv[_TNL_ATTRIB_MAX][4];
+ struct tnl_eval eval;
+ GLboolean *edgeflag_tmp;
+};
+
+
-/* Shorthands.
+/* For display lists, this structure holds a run of vertices of the
+ * same format, and a strictly well-formed set of begin/end pairs,
+ * starting on the first vertex and ending at the last. Vertex
+ * copying on buffer breaks is precomputed according to these
+ * primitives, though there are situations where the copying will need
+ * correction at execute-time, perhaps by replaying the list as
+ * immediate mode commands.
+ *
+ * On executing this list, the 'current' values may be updated with
+ * the values of the final vertex, and often no fixup of the start of
+ * the vertex list is required.
+ *
+ * Eval and other commands that don't fit into these vertex lists are
+ * compiled using the fallback opcode mechanism provided by dlist.c.
*/
-#define VERT_BITS_OBJ_23 (VERT_BIT_POS | VERT_BIT_OBJ_3)
-#define VERT_BITS_OBJ_234 (VERT_BIT_POS | VERT_BIT_OBJ_3 | VERT_BIT_OBJ_4)
-
-#define VERT_BITS_TEX_ANY (VERT_BIT_TEX0 | \
- VERT_BIT_TEX1 | \
- VERT_BIT_TEX2 | \
- VERT_BIT_TEX3 | \
- VERT_BIT_TEX4 | \
- VERT_BIT_TEX5 | \
- VERT_BIT_TEX6 | \
- VERT_BIT_TEX7)
-
-#define VERT_BITS_EVAL_ANY (VERT_BIT_EVAL_C1 | VERT_BIT_EVAL_P1 | \
- VERT_BIT_EVAL_C2 | VERT_BIT_EVAL_P2)
-
-#define VERT_BITS_FIXUP (VERT_BITS_TEX_ANY | \
- VERT_BIT_COLOR0 | \
- VERT_BIT_COLOR1 | \
- VERT_BIT_FOG | \
- VERT_BIT_INDEX | \
- VERT_BIT_EDGEFLAG | \
- VERT_BIT_NORMAL)
-
-#define VERT_BITS_CURRENT_DATA (VERT_BITS_FIXUP | \
- VERT_BIT_MATERIAL)
-
-#define VERT_BITS_DATA (VERT_BITS_TEX_ANY | \
- VERT_BIT_COLOR0 | \
- VERT_BIT_COLOR1 | \
- VERT_BIT_FOG | \
- VERT_BIT_INDEX | \
- VERT_BIT_EDGEFLAG | \
- VERT_BIT_NORMAL | \
- VERT_BIT_POS | \
- VERT_BIT_MATERIAL | \
- VERT_BIT_ELT | \
- VERT_BITS_EVAL_ANY)
+struct tnl_vertex_list {
+ GLubyte attrsz[_TNL_ATTRIB_MAX];
+ GLuint vertex_size;
+
+ GLfloat *buffer;
+ GLuint count;
+ GLuint wrap_count; /* number of copied vertices at start */
+ GLuint dangling_attr_ref; /* current attr implicitly referenced
+ outside the list */
+
+ GLfloat *normal_lengths;
+ struct tnl_prim *prim;
+ GLuint prim_count;
+
+ struct tnl_vertex_store *vertex_store;
+ struct tnl_primitive_store *prim_store;
+};
+/* These buffers should be a reasonable size to support upload to
+ * hardware? Maybe drivers should stitch them back together, or
+ * specify a desired size?
+ */
+#define SAVE_BUFFER_SIZE (16*1024)
+#define SAVE_PRIM_SIZE 128
-/**
- * \struct immediate
- * Stores everything that can take place between a glBegin and glEnd.
- * Adjacent glBegin/glEnd pairs are stored back-to-back when there's no
- * state changes between them.
- * Used for immediate mode rendering and display lists.
+/* Storage to be shared among several vertex_lists.
*/
-struct immediate
-{
- GLuint id, ref_count;
+struct tnl_vertex_store {
+ GLfloat buffer[SAVE_BUFFER_SIZE];
+ GLuint used;
+ GLuint refcount;
+};
- /* This must be saved when immediates are shared in display lists.
- */
- GLuint CopyStart, Start, Count;
- GLuint LastData; /* count or count+1 */
- GLuint AndFlag, OrFlag;
- GLuint TexSize; /* keep track of texcoord sizes */
- GLuint BeginState, SavedBeginState;
- GLuint LastPrimitive;
+struct tnl_primitive_store {
+ struct tnl_prim buffer[SAVE_PRIM_SIZE];
+ GLuint used;
+ GLuint refcount;
+};
- GLuint ArrayEltFlags; /* precalc'ed for glArrayElt */
- GLuint ArrayEltIncr;
- GLuint ArrayEltFlush;
-#define FLUSH_ELT_EAGER 0x1
-#define FLUSH_ELT_LAZY 0x2
- GLuint FlushElt;
+struct tnl_save {
+ GLubyte attrsz[_TNL_ATTRIB_MAX];
+ GLuint vertex_size;
- GLuint MaxTextureUnits; /* precalc'ed for glMultiTexCoordARB */
+ GLfloat *buffer;
+ GLuint count;
+ GLuint wrap_count;
- /* Temporary values created when vertices are copied into the
- * first 3 slots of the struct:
- */
- GLuint CopyOrFlag;
- GLuint CopyAndFlag;
- GLuint CopyTexSize;
- GLuint Evaluated;
+ struct tnl_prim *prim;
+ GLuint prim_count, prim_max;
+ struct tnl_vertex_store *vertex_store;
+ struct tnl_primitive_store *prim_store;
- /* allocate storage for these on demand:
- */
- struct gl_material *Material;
- GLuint *MaterialMask;
- GLuint LastMaterial;
- GLuint MaterialOrMask;
- GLuint MaterialAndMask;
-
- GLuint Primitive[IMM_SIZE]; /* BEGIN/END */
- GLuint PrimitiveLength[IMM_SIZE]; /* BEGIN/END */
- GLuint Flag[IMM_SIZE]; /* VERT_BIT_* flags */
-
- /* Attrib is an array [MAX_VERT_ATTRIBS] of pointer to array [][4]
- * of GLfloat.
- * We only pre-allocate the vertex position array. The other vertex
- * attribute arrays are only allocated when needed to save memory.
- */
- GLfloat (*Attrib[VERT_ATTRIB_MAX])[4];
+ GLfloat *vbptr; /* cursor, points into buffer */
+ GLfloat vertex[_TNL_ATTRIB_MAX*4]; /* current values */
+ GLfloat *attrptr[_TNL_ATTRIB_MAX];
+ GLuint counter, initial_counter;
+ GLuint dangling_attr_ref;
+
+ GLuint opcode_vertex_list;
+
+ struct tnl_copied_vtx copied;
- GLfloat *NormalLengthPtr; /* length of normal vectors (display list only) */
+ GLfloat *current[_TNL_ATTRIB_MAX]; /* points into ctx->ListState */
+ GLubyte *currentsz[_TNL_ATTRIB_MAX];
- GLuint Elt[IMM_SIZE];
- GLubyte EdgeFlag[IMM_SIZE];
- GLuint Index[IMM_SIZE];
+ void (*tabfv[_TNL_ATTRIB_MAX][4])( const GLfloat * );
};
-struct vertex_arrays
+
+
+
+
+
+struct tnl_vertex_arrays
{
/* Conventional vertex attribute arrays */
GLvector4f Obj;
GLvector4f Normal;
- struct gl_client_array Color;
- struct gl_client_array SecondaryColor;
+ GLvector4f Color;
+ GLvector4f SecondaryColor;
GLvector4f FogCoord;
GLvector4f TexCoord[MAX_TEXTURE_COORD_UNITS];
- GLvector1ub EdgeFlag;
- GLvector1ui Index;
- GLvector1ui Elt;
+ GLvector4f Index;
+
+ GLubyte *EdgeFlag;
+ GLuint *Elt;
/* These attributes don't alias with the conventional attributes.
* The GL_NV_vertex_program extension defines 16 extra sets of vertex
* arrays which have precedent over the conventional arrays when enabled.
*/
- GLvector4f Attribs[VERT_ATTRIB_MAX];
+ GLvector4f Attribs[_TNL_ATTRIB_MAX];
};
/**
* Contains the current state of a running pipeline.
*/
-typedef struct vertex_buffer
+struct vertex_buffer
{
/* Constant over life of the vertex_buffer.
*/
- GLuint Size;
+ GLuint Size;
/* Constant over the pipeline.
*/
- GLuint Count; /* for everything except Elts */
- GLuint FirstClipped; /* temp verts for clipping */
- GLuint FirstPrimitive; /* usually zero */
+ GLuint Count; /* for everything except Elts */
/* Pointers to current data.
*/
- GLuint *Elts; /* VERT_BIT_ELT */
- GLvector4f *ObjPtr; /* VERT_BIT_POS */
- GLvector4f *EyePtr; /* VERT_BIT_EYE */
- GLvector4f *ClipPtr; /* VERT_BIT_CLIP */
- GLvector4f *NdcPtr; /* VERT_BIT_CLIP (2) */
- GLubyte ClipOrMask; /* VERT_BIT_CLIP (3) */
- GLubyte *ClipMask; /* VERT_BIT_CLIP (4) */
- GLvector4f *NormalPtr; /* VERT_BIT_NORMAL */
- GLfloat *NormalLengthPtr; /* VERT_BIT_NORMAL */
- GLboolean *EdgeFlag; /* VERT_BIT_EDGEFLAG */
+ GLuint *Elts;
+ GLvector4f *ObjPtr; /* _TNL_BIT_POS */
+ GLvector4f *EyePtr; /* _TNL_BIT_POS */
+ GLvector4f *ClipPtr; /* _TNL_BIT_POS */
+ GLvector4f *NdcPtr; /* _TNL_BIT_POS */
+ GLubyte ClipOrMask; /* _TNL_BIT_POS */
+ GLubyte *ClipMask; /* _TNL_BIT_POS */
+ GLvector4f *NormalPtr; /* _TNL_BIT_NORMAL */
+ GLfloat *NormalLengthPtr; /* _TNL_BIT_NORMAL */
+ GLboolean *EdgeFlag; /* _TNL_BIT_EDGEFLAG */
GLvector4f *TexCoordPtr[MAX_TEXTURE_COORD_UNITS]; /* VERT_TEX_0..n */
- GLvector1ui *IndexPtr[2]; /* VERT_BIT_INDEX */
- struct gl_client_array *ColorPtr[2]; /* VERT_BIT_COLOR0 */
- struct gl_client_array *SecondaryColorPtr[2];/* VERT_BIT_COLOR1 */
- GLvector4f *PointSizePtr; /* VERT_BIT_POINT_SIZE */
- GLvector4f *FogCoordPtr; /* VERT_BIT_FOG */
- struct gl_material *Material; /* VERT_BIT_MATERIAL, optional */
- GLuint *MaterialMask; /* VERT_BIT_MATERIAL, optional */
- GLuint *Flag; /* VERT_BIT_* flags, optional */
- GLuint *Primitive; /* GL_(mode)|PRIM_* flags */
- GLuint *PrimitiveLength; /* integers */
+ GLvector4f *IndexPtr[2]; /* _TNL_BIT_INDEX */
+ GLvector4f *ColorPtr[2]; /* _TNL_BIT_COLOR0 */
+ GLvector4f *SecondaryColorPtr[2]; /* _TNL_BIT_COLOR1 */
+ GLvector4f *PointSizePtr; /* _TNL_BIT_POS */
+ GLvector4f *FogCoordPtr; /* _TNL_BIT_FOG */
+
+ struct tnl_prim *Primitive;
+ GLuint PrimitiveCount;
/* Inputs to the vertex program stage */
- GLvector4f *AttribPtr[VERT_ATTRIB_MAX]; /* GL_NV_vertex_program */
-
- GLuint importable_data;
- void *import_source;
- void (*import_data)( GLcontext *ctx, GLuint flags, GLuint vecflags );
- /* Callback to the provider of the untransformed input for the
- * render stage (or other stages) to call if they need to write into
- * write-protected arrays, or fixup the stride on input arrays.
- *
- * This is currently only necessary for client arrays that make it
- * as far down the pipeline as the render stage.
- */
+ GLvector4f *AttribPtr[_TNL_ATTRIB_MAX]; /* GL_NV_vertex_program */
GLuint LastClipped;
/* Private data from _tnl_render_stage that has no business being
* in this struct.
*/
-} TNLvertexbuffer;
+};
/** Describes an individual operation on the pipeline.
*/
-struct gl_pipeline_stage {
+struct tnl_pipeline_stage {
const char *name;
GLuint check_state; /* All state referenced in check() --
* When is the pipeline_stage struct
/* Free private data. May not be null.
*/
- void (*destroy)( struct gl_pipeline_stage * );
+ void (*destroy)( struct tnl_pipeline_stage * );
/* Called from _tnl_validate_pipeline(). Must update all fields in
* the pipeline_stage struct for the current state.
*/
- void (*check)( GLcontext *ctx, struct gl_pipeline_stage * );
+ void (*check)( GLcontext *ctx, struct tnl_pipeline_stage * );
/* Called from _tnl_run_pipeline(). The stage.changed_inputs value
* encodes all inputs to thee struct which have changed. If
* Return value: GL_TRUE - keep going
* GL_FALSE - finished pipeline
*/
- GLboolean (*run)( GLcontext *ctx, struct gl_pipeline_stage * );
+ GLboolean (*run)( GLcontext *ctx, struct tnl_pipeline_stage * );
};
/** Contains the array of all pipeline stages.
* The default values are defined at the end of t_pipeline.c */
-struct gl_pipeline {
+struct tnl_pipeline {
GLuint build_state_trigger; /**< state changes which require build */
GLuint build_state_changes; /**< state changes since last build */
GLuint run_state_changes; /**< state changes since last run */
GLuint run_input_changes; /**< VERT_* changes since last run */
GLuint inputs; /**< VERT_* inputs to pipeline */
/** This array has to end with a NULL-pointer. */
- struct gl_pipeline_stage stages[MAX_PIPELINE_STAGES+1];
+ struct tnl_pipeline_stage stages[MAX_PIPELINE_STAGES+1];
GLuint nr_stages;
};
-struct tnl_eval_store {
- GLuint EvalMap1Flags;
- GLuint EvalMap2Flags;
- GLuint EvalMap1AttribFlags; /* GL_NV_vertex_program */
- GLuint EvalMap2AttribFlags; /* GL_NV_vertex_program */
- GLuint EvalNewState;
- struct immediate *im; /* used for temporary data */
-};
typedef void (*points_func)( GLcontext *ctx, GLuint first, GLuint last );
*/
struct tnl_device_driver Driver;
- /* Track whether the module is active.
+ /* Execute:
*/
- GLboolean bound_exec;
-
- /* Display list extensions
+ struct tnl_vtx vtx;
+
+ /* Compile:
*/
- GLuint opcode_vertex_cassette;
+ struct tnl_save save;
/* Pipeline
*/
- struct gl_pipeline pipeline;
+ struct tnl_pipeline pipeline;
struct vertex_buffer vb;
/* GLvectors for binding to vb:
*/
- struct vertex_arrays imm_inputs;
- struct vertex_arrays array_inputs;
- GLuint *tmp_primitive;
- GLuint *tmp_primitive_length;
-
- /* Set when executing an internally generated begin/end object. If
- * such an object is encountered in a display list, it will be
- * replayed only if the list is outside any existing begin/end
- * objects.
- */
- GLboolean ReplayHardBeginEnd;
+ struct tnl_vertex_arrays vtx_inputs;
+ struct tnl_vertex_arrays save_inputs;
+ struct tnl_vertex_arrays current;
+ struct tnl_vertex_arrays array_inputs;
- /* Note which vertices need copying over succesive immediates.
- * Will add save versions to precompute vertex copying where
- * possible.
- */
- struct immediate *ExecCopySource;
- GLuint ExecCopyCount;
- GLuint ExecCopyElts[IMM_MAX_COPIED_VERTS];
- GLuint ExecCopyTexSize;
- GLuint ExecParity;
-
- GLuint DlistPrimitive;
- GLuint DlistPrimitiveLength;
- GLuint DlistLastPrimitive;
-
- /* Cache a single free immediate (refcount == 0)
- */
- struct immediate *freed_immediate;
/* Probably need a better configuration mechanism:
*/
GLboolean CalcDListNormalLengths;
GLboolean IsolateMaterials;
- /* Derived state and storage for _tnl_eval_vb:
- */
- struct tnl_eval_store eval;
- /* Functions to be plugged into dispatch when tnl is active.
- */
- GLvertexformat vtxfmt;
+ GLvertexformat exec_vtxfmt;
GLvertexformat save_vtxfmt;
} TNLcontext;
#define TNL_CONTEXT(ctx) ((TNLcontext *)(ctx->swtnl_context))
-#define TNL_CURRENT_IM(ctx) ((struct immediate *)(ctx->swtnl_im))
#define TYPE_IDX(t) ((t) & 0xf)
GLframebuffer *readBuffer );
-/*
- * Macros for fetching current input buffer.
- */
-#ifdef THREADS
-#define GET_IMMEDIATE struct immediate *IM = TNL_CURRENT_IM(((GLcontext *) (_glapi_Context ? _glapi_Context : _glapi_get_context())))
-#define SET_IMMEDIATE(ctx, im) ctx->swtnl_im = (void *)im
-#else
-extern struct immediate *_tnl_CurrentInput;
-#define GET_IMMEDIATE struct immediate *IM = _tnl_CurrentInput
-#define SET_IMMEDIATE(ctx, im) \
-do { \
- ctx->swtnl_im = (void *)im; \
- _tnl_CurrentInput = im; \
-} while (0)
-#endif
#endif
+++ /dev/null
-
-/*
- * Mesa 3-D graphics library
- * Version: 5.1
- *
- * Copyright (C) 1999-2003 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 <keith@tungstengraphics.com>
- */
-
-#include "glheader.h"
-#include "imports.h"
-#include "mtypes.h"
-
-#include "t_imm_alloc.h"
-
-
-static int id = 0; /* give each struct immediate a unique ID number */
-
-
-static struct immediate *
-real_alloc_immediate( GLcontext *ctx )
-{
- struct immediate *immed = ALIGN_CALLOC_STRUCT( immediate, 32 );
-
- if (!immed)
- return NULL;
-
- immed->id = id++;
- immed->ref_count = 0;
- immed->FlushElt = 0;
- immed->LastPrimitive = IMM_MAX_COPIED_VERTS;
- immed->Count = IMM_MAX_COPIED_VERTS;
- immed->Start = IMM_MAX_COPIED_VERTS;
- immed->Material = 0;
- immed->MaterialMask = 0;
- immed->MaxTextureUnits = ctx->Const.MaxTextureCoordUnits;
- immed->TexSize = 0;
- immed->NormalLengthPtr = 0;
-
- /* Only allocate space for vertex positions right now. Color, texcoord,
- * etc storage will be allocated as needed.
- */
- immed->Attrib[VERT_ATTRIB_POS] = (GLfloat (*)[4]) _mesa_malloc(IMM_SIZE * 4 * sizeof(GLfloat));
-
- /* Enable this to allocate all attribute arrays up front */
- if (0)
- {
- int i;
- for (i = 1; i < VERT_ATTRIB_MAX; i++) {
- immed->Attrib[i] = (GLfloat (*)[4]) _mesa_malloc(IMM_SIZE * 4 * sizeof(GLfloat));
- }
- }
-
- immed->CopyTexSize = 0;
- immed->CopyStart = immed->Start;
-
- return immed;
-}
-
-
-static void
-real_free_immediate( struct immediate *immed )
-{
- static int freed = 0;
- GLuint i;
-
- for (i =0; i < VERT_ATTRIB_MAX; i++) {
- if (immed->Attrib[i])
- _mesa_free(immed->Attrib[i]);
- immed->Attrib[i] = NULL;
- }
-
- if (immed->Material) {
- FREE( immed->Material );
- FREE( immed->MaterialMask );
- immed->Material = 0;
- immed->MaterialMask = 0;
- }
-
- if (immed->NormalLengthPtr)
- ALIGN_FREE( immed->NormalLengthPtr );
-
- ALIGN_FREE( immed );
- freed++;
-/* printf("outstanding %d\n", id - freed); */
-}
-
-
-/**
- * Return a pointer to a new 'struct immediate' object.
- * We actually keep a spare/cached one to reduce malloc calls.
- */
-struct immediate *
-_tnl_alloc_immediate( GLcontext *ctx )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- struct immediate *tmp = tnl->freed_immediate;
-
- if (tmp) {
- tnl->freed_immediate = 0;
- return tmp;
- }
- else
- return real_alloc_immediate( ctx );
-}
-
-/**
- * Free a 'struct immediate' object.
- * May be called after tnl is destroyed.
- */
-void
-_tnl_free_immediate( GLcontext *ctx, struct immediate *immed )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
-
- ASSERT(immed->ref_count == 0);
-
- if (immed->NormalLengthPtr) {
- ALIGN_FREE(immed->NormalLengthPtr);
- immed->NormalLengthPtr = NULL;
- }
-
- if (!tnl) {
- real_free_immediate( immed );
- }
- else {
- if (tnl->freed_immediate)
- real_free_immediate( tnl->freed_immediate );
-
- tnl->freed_immediate = immed;
- }
-}
+++ /dev/null
-
-/*
- * Mesa 3-D graphics library
- * Version: 3.5
- *
- * Copyright (C) 1999-2001 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.
- */
-
-
-#ifndef _T_IMM_ALLOC_H
-#define _T_IMM_ALLOC_H
-
-#include "mtypes.h"
-#include "t_context.h"
-
-
-extern struct immediate *_tnl_alloc_immediate( GLcontext *ctx );
-
-extern void _tnl_free_immediate( GLcontext *ctx, struct immediate *im );
-
-
-#endif
+++ /dev/null
-
-/*
- * Mesa 3-D graphics library
- * Version: 5.1
- *
- * Copyright (C) 1999-2002 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.
- */
-
-#include "mtypes.h"
-#include "context.h"
-#include "imports.h"
-#include "t_context.h"
-#include "t_imm_debug.h"
-
-
-void _tnl_print_vert_flags( const char *name, GLuint flags )
-{
- _mesa_debug(NULL,
- "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
- name,
- flags,
- (flags & VERT_BIT_CLIP) ? "clip/proj-clip/glend, " : "",
- (flags & VERT_BIT_EDGEFLAG) ? "edgeflag, " : "",
- (flags & VERT_BIT_ELT) ? "array-elt, " : "",
- (flags & VERT_BIT_END_VB) ? "end-vb, " : "",
- (flags & VERT_BITS_EVAL_ANY) ? "eval-coord, " : "",
- (flags & VERT_BIT_EYE) ? "eye/glbegin, " : "",
- (flags & VERT_BIT_FOG) ? "fog-coord, " : "",
- (flags & VERT_BIT_INDEX) ? "index, " : "",
- (flags & VERT_BIT_MATERIAL) ? "material, " : "",
- (flags & VERT_BIT_NORMAL) ? "normals, " : "",
- (flags & VERT_BIT_POS) ? "obj, " : "",
- (flags & VERT_BIT_OBJ_3) ? "obj-3, " : "",
- (flags & VERT_BIT_OBJ_4) ? "obj-4, " : "",
- (flags & VERT_BIT_POINT_SIZE) ? "point-size, " : "",
- (flags & VERT_BIT_COLOR0) ? "colors, " : "",
- (flags & VERT_BIT_COLOR1) ? "specular, " : "",
- (flags & VERT_BIT_TEX0) ? "texcoord0, " : "",
- (flags & VERT_BIT_TEX1) ? "texcoord1, " : "",
- (flags & VERT_BIT_TEX2) ? "texcoord2, " : "",
- (flags & VERT_BIT_TEX3) ? "texcoord3, " : "",
- (flags & VERT_BIT_TEX4) ? "texcoord4, " : "",
- (flags & VERT_BIT_TEX5) ? "texcoord5, " : "",
- (flags & VERT_BIT_TEX6) ? "texcoord6, " : "",
- (flags & VERT_BIT_TEX7) ? "texcoord7, " : ""
- );
-}
-
-void _tnl_print_cassette( struct immediate *IM )
-{
- GLuint i;
- GLuint *flags = IM->Flag;
- GLuint andflag = IM->CopyAndFlag;
- GLuint orflag = (IM->CopyOrFlag|IM->Evaluated);
- GLuint state = IM->BeginState;
- GLuint req = ~0;
-
- _mesa_debug(NULL, "Cassette id %d, %u rows.\n", IM->id,
- IM->Count - IM->CopyStart);
-
- _tnl_print_vert_flags("Contains at least one", orflag);
-
- if (IM->Count != IM->CopyStart)
- {
- _tnl_print_vert_flags("Contains a full complement of", andflag);
-
- _mesa_debug(NULL, "Final begin/end state %s/%s, errors %s/%s\n",
- (state & VERT_BEGIN_0) ? "in" : "out",
- (state & VERT_BEGIN_1) ? "in" : "out",
- (state & VERT_ERROR_0) ? "y" : "n",
- (state & VERT_ERROR_1) ? "y" : "n");
-
- }
-
- for (i = IM->CopyStart ; i <= IM->Count ; i++) {
- _mesa_debug(NULL, "%u: ", i);
- if (req & VERT_BITS_OBJ_234) {
- if (flags[i] & VERT_BIT_EVAL_C1)
- _mesa_debug(NULL, "EvalCoord %f ",
- IM->Attrib[VERT_ATTRIB_POS][i][0]);
- else if (flags[i] & VERT_BIT_EVAL_P1)
- _mesa_debug(NULL, "EvalPoint %.0f ",
- IM->Attrib[VERT_ATTRIB_POS][i][0]);
- else if (flags[i] & VERT_BIT_EVAL_C2)
- _mesa_debug(NULL, "EvalCoord %f %f ",
- IM->Attrib[VERT_ATTRIB_POS][i][0],
- IM->Attrib[VERT_ATTRIB_POS][i][1]);
- else if (flags[i] & VERT_BIT_EVAL_P2)
- _mesa_debug(NULL, "EvalPoint %.0f %.0f ",
- IM->Attrib[VERT_ATTRIB_POS][i][0],
- IM->Attrib[VERT_ATTRIB_POS][i][1]);
- else if (i < IM->Count && (flags[i] & VERT_BITS_OBJ_234)) {
- _mesa_debug(NULL, "Obj %f %f %f %f",
- IM->Attrib[VERT_ATTRIB_POS][i][0],
- IM->Attrib[VERT_ATTRIB_POS][i][1],
- IM->Attrib[VERT_ATTRIB_POS][i][2],
- IM->Attrib[VERT_ATTRIB_POS][i][3]);
- }
- }
-
- if (req & flags[i] & VERT_BIT_ELT)
- _mesa_debug(NULL, " Elt %u\t", IM->Elt[i]);
-
- if (req & flags[i] & VERT_BIT_NORMAL)
- _mesa_debug(NULL, " Norm %f %f %f ",
- IM->Attrib[VERT_ATTRIB_NORMAL][i][0],
- IM->Attrib[VERT_ATTRIB_NORMAL][i][1],
- IM->Attrib[VERT_ATTRIB_NORMAL][i][2]);
-
- if (req & flags[i] & VERT_BITS_TEX_ANY) {
- GLuint j;
- for (j = 0 ; j < MAX_TEXTURE_COORD_UNITS ; j++) {
- if (req & flags[i] & VERT_BIT_TEX(j)) {
- _mesa_debug(NULL, "TC%d %f %f %f %f", j,
- IM->Attrib[VERT_ATTRIB_TEX0 + j][i][0],
- IM->Attrib[VERT_ATTRIB_TEX0 + j][i][1],
- IM->Attrib[VERT_ATTRIB_TEX0 + j][i][2],
- IM->Attrib[VERT_ATTRIB_TEX0 + j][i][3]);
- }
- }
- }
-
- if (req & flags[i] & VERT_BIT_COLOR0)
- _mesa_debug(NULL, " Rgba %f %f %f %f ",
- IM->Attrib[VERT_ATTRIB_COLOR0][i][0],
- IM->Attrib[VERT_ATTRIB_COLOR0][i][1],
- IM->Attrib[VERT_ATTRIB_COLOR0][i][2],
- IM->Attrib[VERT_ATTRIB_COLOR0][i][3]);
-
- if (req & flags[i] & VERT_BIT_COLOR1)
- _mesa_debug(NULL, " Spec %f %f %f ",
- IM->Attrib[VERT_ATTRIB_COLOR1][i][0],
- IM->Attrib[VERT_ATTRIB_COLOR1][i][1],
- IM->Attrib[VERT_ATTRIB_COLOR1][i][2]);
-
- if (req & flags[i] & VERT_BIT_FOG)
- _mesa_debug(NULL, " Fog %f ", IM->Attrib[VERT_ATTRIB_FOG][i][0]);
-
- if (req & flags[i] & VERT_BIT_INDEX)
- _mesa_debug(NULL, " Index %u ", IM->Index[i]);
-
- if (req & flags[i] & VERT_BIT_EDGEFLAG)
- _mesa_debug(NULL, " Edgeflag %d ", IM->EdgeFlag[i]);
-
- if (req & flags[i] & VERT_BIT_MATERIAL)
- _mesa_debug(NULL, " Material ");
-
-
- /* The order of these two is not easily knowable, but this is
- * the usually correct way to look at them.
- */
- if (req & flags[i] & VERT_BIT_END)
- _mesa_debug(NULL, " END ");
-
- if (req & flags[i] & VERT_BIT_BEGIN)
- _mesa_debug(NULL, " BEGIN(%s) (%s%s%s%s)",
- _mesa_prim_name[IM->Primitive[i] & PRIM_MODE_MASK],
- (IM->Primitive[i] & PRIM_LAST) ? "LAST," : "",
- (IM->Primitive[i] & PRIM_BEGIN) ? "BEGIN," : "",
- (IM->Primitive[i] & PRIM_END) ? "END," : "",
- (IM->Primitive[i] & PRIM_PARITY) ? "PARITY," : "");
-
- _mesa_debug(NULL, "\n");
- }
-}
+++ /dev/null
-
-/*
- * Mesa 3-D graphics library
- * Version: 3.5
- *
- * Copyright (C) 1999-2001 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 <keith@tungstengraphics.com>
- */
-
-#ifndef _T_DEBUG_H
-#define _T_DEBUG_H
-
-#include "mtypes.h"
-#include "t_context.h"
-
-void _tnl_print_cassette( struct immediate *IM );
-void _tnl_print_vert_flags( const char *name, GLuint flags );
-
-#endif
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 5.1
- *
- * Copyright (C) 1999-2003 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 <keith@tungstengraphics.com>
- */
-
-
-#include "glheader.h"
-#include "context.h"
-#include "dlist.h"
-#include "debug.h"
-#include "macros.h"
-#include "imports.h"
-#include "state.h"
-
-#include "t_context.h"
-#include "t_imm_api.h"
-#include "t_imm_elt.h"
-#include "t_imm_alloc.h"
-#include "t_imm_dlist.h"
-#include "t_imm_debug.h"
-#include "t_imm_exec.h"
-#include "t_imm_fixup.h"
-#include "t_pipeline.h"
-
-typedef struct {
- struct immediate *IM;
- GLuint Start;
- GLuint Count;
- GLuint BeginState;
- GLuint SavedBeginState;
- GLuint OrFlag;
- GLuint AndFlag;
- GLuint TexSize;
- GLuint LastData;
- GLuint LastPrimitive;
- GLuint LastMaterial;
- GLuint MaterialOrMask;
- GLuint MaterialAndMask;
-} TNLvertexcassette;
-
-static void execute_compiled_cassette( GLcontext *ctx, void *data );
-static void loopback_compiled_cassette( GLcontext *ctx, struct immediate *IM );
-
-
-static void
-build_normal_lengths( struct immediate *IM )
-{
- GLuint i;
- GLfloat len;
- GLfloat (*data)[4] = IM->Attrib[VERT_ATTRIB_NORMAL] + IM->Start;
- GLfloat *dest = IM->NormalLengthPtr;
- const GLuint *flags = IM->Flag + IM->Start;
- const GLuint count = IM->Count - IM->Start;
-
- if (!dest) {
- dest = IM->NormalLengthPtr = (GLfloat *) ALIGN_MALLOC( IMM_SIZE*sizeof(GLfloat), 32 );
- if (!dest) return;
- }
- dest += IM->Start;
-
- len = (GLfloat) LEN_3FV( data[0] );
- if (len > 0.0F) len = 1.0F / len;
-
- for (i = 0 ; i < count ; ) {
- dest[i] = len;
- if (flags[++i] & VERT_BIT_NORMAL) {
- len = (GLfloat) LEN_3FV( data[i] );
- if (len > 0.0F) len = 1.0F / len;
- }
- }
-}
-
-
-static void
-fixup_normal_lengths( struct immediate *IM )
-{
- GLuint i;
- GLfloat len = 1.0F; /* just to silence warnings */
- GLfloat (*data)[4] = IM->Attrib[VERT_ATTRIB_NORMAL];
- GLfloat *dest = IM->NormalLengthPtr;
- const GLuint *flags = IM->Flag;
-
- for (i = IM->CopyStart ; i <= IM->Start ; i++) {
- len = (GLfloat) LEN_3FV( data[i] );
- if (len > 0.0F)
- len = 1.0F / len;
- dest[i] = len;
- }
-
- if (i < IM->Count) {
- while (!(flags[i] & (VERT_BIT_NORMAL|VERT_BIT_END_VB))) {
- dest[i] = len;
- i++;
- }
- }
-}
-
-
-
-/* Insert the active immediate struct onto the display list currently
- * being built.
- */
-void
-_tnl_compile_cassette( GLcontext *ctx, struct immediate *IM )
-{
- struct immediate *im = TNL_CURRENT_IM(ctx);
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- TNLvertexcassette *node;
- GLuint new_beginstate;
-
- if (MESA_VERBOSE & VERBOSE_DISPLAY_LIST)
- _mesa_debug(ctx, "_tnl_compiled_cassette IM: %d\n", IM->id);
-
- if (IM->FlushElt) {
- ASSERT (IM->FlushElt == FLUSH_ELT_LAZY);
- _tnl_translate_array_elts( ctx, IM, IM->Start, IM->Count );
- }
-
- _tnl_compute_orflag( IM, IM->Start );
-
- /* Need to clear this flag, or fixup gets confused. (The
- * array-elements have been translated away by now, so it's ok to
- * remove it.)
- */
- IM->OrFlag &= ~VERT_BIT_ELT;
- IM->AndFlag &= ~VERT_BIT_ELT;
-
- _tnl_fixup_input( ctx, IM );
-
- /* Allocate space for this structure in the display list currently
- * being compiled.
- */
- node = (TNLvertexcassette *)
- _mesa_alloc_instruction(ctx,
- tnl->opcode_vertex_cassette,
- sizeof(TNLvertexcassette));
- if (!node)
- return;
-
- node->IM = im; im->ref_count++;
- node->Start = im->Start;
- node->Count = im->Count;
- node->BeginState = im->BeginState;
- node->SavedBeginState = im->SavedBeginState;
- node->OrFlag = im->OrFlag;
- node->TexSize = im->TexSize;
- node->AndFlag = im->AndFlag;
- node->LastData = im->LastData;
- node->LastPrimitive = im->LastPrimitive;
- node->LastMaterial = im->LastMaterial;
- node->MaterialOrMask = im->MaterialOrMask;
- node->MaterialAndMask = im->MaterialAndMask;
-
- /*
- * XXX always allocate VERT_ATTRIB_NORMAL array now???
- */
- if (tnl->CalcDListNormalLengths && IM->Attrib[VERT_ATTRIB_NORMAL]) {
- build_normal_lengths( im );
- }
-
- if (ctx->ExecuteFlag) {
- execute_compiled_cassette( ctx, (void *)node );
- }
-
- /* Discard any errors raised in the last cassette.
- */
- new_beginstate = node->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1);
-
- /* Decide whether this immediate struct is full, or can be used for
- * the next batch of vertices as well.
- */
- if (im->Count > IMM_MAXDATA - 16) {
- /* Call it full...
- */
- struct immediate *new_im = _tnl_alloc_immediate(ctx);
- new_im->ref_count++;
- im->ref_count--; /* remove CURRENT_IM reference */
- ASSERT(im->ref_count > 0); /* it is compiled into a display list */
- SET_IMMEDIATE( ctx, new_im );
- _tnl_reset_compile_input( ctx, IMM_MAX_COPIED_VERTS,
- new_beginstate, node->SavedBeginState );
- } else {
- /* Still some room in the current immediate.
- */
- _tnl_reset_compile_input( ctx, im->Count+1+IMM_MAX_COPIED_VERTS,
- new_beginstate, node->SavedBeginState);
- }
-}
-
-
-static void
-fixup_compiled_primitives( GLcontext *ctx, struct immediate *IM )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
-
- /* Can potentially overwrite primitive details - need to save the
- * first slot:
- */
- tnl->DlistPrimitive = IM->Primitive[IM->Start];
- tnl->DlistPrimitiveLength = IM->PrimitiveLength[IM->Start];
- tnl->DlistLastPrimitive = IM->LastPrimitive;
-
- /* The first primitive may be different from what was recorded in
- * the immediate struct. Consider an immediate that starts with a
- * glBegin, compiled in a display list, which is called from within
- * an existing Begin/End object.
- */
- if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) {
- GLuint i;
-
- if (IM->BeginState & VERT_ERROR_1)
- _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin/glEnd");
-
- for (i = IM->Start ; i <= IM->Count ; i += IM->PrimitiveLength[i])
- if (IM->Flag[i] & (VERT_BIT_BEGIN|VERT_BIT_END_VB))
- break;
-
- /* Would like to just ignore vertices upto this point. Can't
- * set copystart because it might skip materials?
- */
- ASSERT(IM->Start == IM->CopyStart);
- if (i > IM->CopyStart || !(IM->Flag[IM->Start] & VERT_BIT_BEGIN)) {
- IM->Primitive[IM->CopyStart] = GL_POLYGON+1;
- IM->PrimitiveLength[IM->CopyStart] = i - IM->CopyStart;
- if (IM->Flag[i] & VERT_BIT_END_VB) {
- IM->Primitive[IM->CopyStart] |= PRIM_LAST;
- IM->LastPrimitive = IM->CopyStart;
- }
- }
- }
- else {
- GLuint i;
-
- if (IM->BeginState & VERT_ERROR_0)
- _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin/glEnd");
-
- if (IM->CopyStart == IM->Start &&
- IM->Flag[IM->Start] & (VERT_BIT_END | VERT_BIT_END_VB))
- {
- /* nothing */
- }
- else
- {
- IM->Primitive[IM->CopyStart] = ctx->Driver.CurrentExecPrimitive;
- if (tnl->ExecParity)
- IM->Primitive[IM->CopyStart] |= PRIM_PARITY;
-
- /* one of these should be true, else we'll be in an infinite loop
- */
- ASSERT(IM->PrimitiveLength[IM->Start] > 0 ||
- IM->Flag[IM->Start] & (VERT_BIT_END | VERT_BIT_END_VB));
-
- for (i = IM->Start ; i <= IM->Count ; i += IM->PrimitiveLength[i]) {
- if (IM->Flag[i] & (VERT_BIT_END | VERT_BIT_END_VB)) {
- IM->PrimitiveLength[IM->CopyStart] = i - IM->CopyStart;
- if (IM->Flag[i] & VERT_BIT_END_VB) {
- IM->Primitive[IM->CopyStart] |= PRIM_LAST;
- IM->LastPrimitive = IM->CopyStart;
- }
- if (IM->Flag[i] & VERT_BIT_END) {
- IM->Primitive[IM->CopyStart] |= PRIM_END;
- }
- break;
- }
- }
- }
- }
-}
-
-
-/* Undo any changes potentially made to the immediate in the range
- * IM->Start..IM->Count above.
- */
-static void
-restore_compiled_primitives( GLcontext *ctx, struct immediate *IM )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- IM->Primitive[IM->Start] = tnl->DlistPrimitive;
- IM->PrimitiveLength[IM->Start] = tnl->DlistPrimitiveLength;
-}
-
-
-static void
-execute_compiled_cassette( GLcontext *ctx, void *data )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- TNLvertexcassette *node = (TNLvertexcassette *)data;
- struct immediate *IM = node->IM;
-
-/* _mesa_debug("%s\n", __FUNCTION__); */
-
- IM->Start = node->Start;
- IM->CopyStart = node->Start;
- IM->Count = node->Count;
- IM->BeginState = node->BeginState;
- IM->SavedBeginState = node->SavedBeginState;
- IM->OrFlag = node->OrFlag;
- IM->TexSize = node->TexSize;
- IM->AndFlag = node->AndFlag;
- IM->LastData = node->LastData;
- IM->LastPrimitive = node->LastPrimitive;
- IM->LastMaterial = node->LastMaterial;
- IM->MaterialOrMask = node->MaterialOrMask;
- IM->MaterialAndMask = node->MaterialAndMask;
-
- if ((MESA_VERBOSE & VERBOSE_DISPLAY_LIST) &&
- (MESA_VERBOSE & VERBOSE_IMMEDIATE))
- _tnl_print_cassette( IM );
-
- if (MESA_VERBOSE & VERBOSE_DISPLAY_LIST) {
- _mesa_debug(ctx, "Run cassette %d, rows %d..%d, beginstate %x ",
- IM->id, IM->Start, IM->Count, IM->BeginState);
- _tnl_print_vert_flags("orflag", IM->OrFlag);
- }
-
-
- /* Need to respect 'HardBeginEnd' even if the commands are looped
- * back to a driver tnl module.
- */
- if (IM->SavedBeginState) {
- if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1)
- tnl->ReplayHardBeginEnd = 1;
- if (!tnl->ReplayHardBeginEnd) {
- /* This is a user error. Whatever operation (like glRectf)
- * decomposed to this hard begin/end pair is now being run
- * inside a begin/end object -- illegally. Reject it and
- * raise an error.
- */
- _mesa_error(ctx, GL_INVALID_OPERATION, "hard replay");
- return;
- }
- }
-
- if (tnl->LoopbackDListCassettes) {
-/* (tnl->IsolateMaterials && (IM->OrFlag & VERT_MATERIAL)) ) { */
- fixup_compiled_primitives( ctx, IM );
- loopback_compiled_cassette( ctx, IM );
- restore_compiled_primitives( ctx, IM );
- }
- else {
- if (ctx->NewState)
- _mesa_update_state(ctx);
-
- if (tnl->pipeline.build_state_changes)
- _tnl_validate_pipeline( ctx );
-
- _tnl_fixup_compiled_cassette( ctx, IM );
- fixup_compiled_primitives( ctx, IM );
-
- if (IM->Primitive[IM->LastPrimitive] & PRIM_END)
- ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1;
- else if ((IM->Primitive[IM->LastPrimitive] & PRIM_BEGIN) ||
- (IM->Primitive[IM->LastPrimitive] & PRIM_MODE_MASK) ==
- PRIM_OUTSIDE_BEGIN_END) {
- ctx->Driver.CurrentExecPrimitive =
- IM->Primitive[IM->LastPrimitive] & PRIM_MODE_MASK;
- }
-
- _tnl_get_exec_copy_verts( ctx, IM );
-
- if (IM->NormalLengthPtr)
- fixup_normal_lengths( IM );
-
- if (IM->Count == IM->Start)
- _tnl_copy_to_current( ctx, IM, IM->OrFlag, IM->LastData );
- else {
-/* _tnl_print_cassette( IM ); */
- _tnl_run_cassette( ctx, IM );
- }
-
- restore_compiled_primitives( ctx, IM );
- }
-
- if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1)
- tnl->ReplayHardBeginEnd = 0;
-}
-
-
-static void
-destroy_compiled_cassette( GLcontext *ctx, void *data )
-{
- TNLvertexcassette *node = (TNLvertexcassette *)data;
-
- if ( --node->IM->ref_count == 0 )
- _tnl_free_immediate( ctx, node->IM );
-}
-
-
-static void
-print_compiled_cassette( GLcontext *ctx, void *data )
-{
- TNLvertexcassette *node = (TNLvertexcassette *)data;
- struct immediate *IM = node->IM;
-
- _mesa_debug(ctx, "TNL-VERTEX-CASSETTE, id %u, rows %u..%u\n",
- node->IM->id, node->Start, node->Count);
-
- IM->Start = node->Start;
- IM->CopyStart = node->Start;
- IM->Count = node->Count;
- IM->BeginState = node->BeginState;
- IM->OrFlag = node->OrFlag;
- IM->TexSize = node->TexSize;
- IM->AndFlag = node->AndFlag;
- IM->LastData = node->LastData;
- IM->LastPrimitive = node->LastPrimitive;
- IM->LastMaterial = node->LastMaterial;
- IM->MaterialOrMask = node->MaterialOrMask;
- IM->MaterialAndMask = node->MaterialAndMask;
-
- _tnl_print_cassette( node->IM );
-}
-
-
-void
-_tnl_BeginCallList( GLcontext *ctx, GLuint list )
-{
- (void) ctx;
- (void) list;
- FLUSH_CURRENT(ctx, 0);
-}
-
-
-/* Called at the tail of a CallList. Make current immediate aware of
- * any new to-be-copied vertices.
- */
-void
-_tnl_EndCallList( GLcontext *ctx )
-{
- GLuint beginstate = 0;
-
- if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END)
- beginstate = VERT_BEGIN_0|VERT_BEGIN_1;
-
- _tnl_reset_exec_input( ctx, TNL_CURRENT_IM(ctx)->Start, beginstate, 0 );
-}
-
-
-void
-_tnl_EndList( GLcontext *ctx )
-{
- struct immediate *IM = TNL_CURRENT_IM(ctx);
-
- ctx->swtnl_im = 0;
- IM->ref_count--;
-
- /* outside begin/end, even in COMPILE_AND_EXEC,
- * so no vertices to copy, right?
- */
- ASSERT(TNL_CONTEXT(ctx)->ExecCopyCount == 0);
-
- /* If this one isn't free, get a clean one. (Otherwise we'll be
- * using one that's already half full).
- */
- if (IM->ref_count != 0)
- IM = _tnl_alloc_immediate( ctx );
-
- ASSERT(IM->ref_count == 0);
-
- SET_IMMEDIATE( ctx, IM );
- IM->ref_count++;
-
- _tnl_reset_exec_input( ctx, IMM_MAX_COPIED_VERTS, 0, 0 );
-}
-
-
-void
-_tnl_NewList( GLcontext *ctx, GLuint list, GLenum mode )
-{
- struct immediate *IM = TNL_CURRENT_IM(ctx);
-
- /* Use the installed immediate struct. No vertices in the current
- * immediate, no copied vertices in the system.
- */
- ASSERT(TNL_CURRENT_IM(ctx));
- ASSERT(TNL_CURRENT_IM(ctx)->Start == IMM_MAX_COPIED_VERTS);
- ASSERT(TNL_CURRENT_IM(ctx)->Start == TNL_CURRENT_IM(ctx)->Count);
- ASSERT(TNL_CONTEXT(ctx)->ExecCopyCount == 0);
-
- /* Set current Begin/End state to unknown:
- */
- IM->BeginState = VERT_BEGIN_0;
- ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
-}
-
-
-void
-_tnl_dlist_init( GLcontext *ctx )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
-
- tnl->opcode_vertex_cassette =
- _mesa_alloc_opcode( ctx,
- sizeof(TNLvertexcassette),
- execute_compiled_cassette,
- destroy_compiled_cassette,
- print_compiled_cassette );
-}
-
-
-/**
- * Call glMaterialfv for the attributes specified by bitmask, using the
- * material colors in src.
- */
-static void
-emit_material( const struct gl_material *src, GLuint bitmask )
-{
- const GLfloat (*attr)[4] = src->Attrib;
-
- if (bitmask & MAT_BIT_FRONT_EMISSION)
- glMaterialfv( GL_FRONT, GL_EMISSION, attr[MAT_ATTRIB_FRONT_EMISSION] );
-
- if (bitmask & MAT_BIT_BACK_EMISSION)
- glMaterialfv( GL_BACK, GL_EMISSION, attr[MAT_ATTRIB_BACK_EMISSION] );
-
- if (bitmask & MAT_BIT_FRONT_AMBIENT)
- glMaterialfv( GL_FRONT, GL_AMBIENT, attr[MAT_ATTRIB_FRONT_AMBIENT] );
-
- if (bitmask & MAT_BIT_BACK_AMBIENT)
- glMaterialfv( GL_BACK, GL_AMBIENT, attr[MAT_ATTRIB_BACK_AMBIENT] );
-
- if (bitmask & MAT_BIT_FRONT_DIFFUSE)
- glMaterialfv( GL_FRONT, GL_DIFFUSE, attr[MAT_ATTRIB_FRONT_DIFFUSE] );
-
- if (bitmask & MAT_BIT_BACK_DIFFUSE)
- glMaterialfv( GL_BACK, GL_DIFFUSE, attr[MAT_ATTRIB_BACK_DIFFUSE] );
-
- if (bitmask & MAT_BIT_FRONT_SPECULAR)
- glMaterialfv( GL_FRONT, GL_SPECULAR, attr[MAT_ATTRIB_FRONT_SPECULAR] );
-
- if (bitmask & MAT_BIT_BACK_SPECULAR)
- glMaterialfv( GL_BACK, GL_SPECULAR, attr[MAT_ATTRIB_BACK_SPECULAR] );
-
- if (bitmask & MAT_BIT_FRONT_SHININESS)
- glMaterialfv( GL_FRONT, GL_SHININESS, attr[MAT_ATTRIB_FRONT_SHININESS] );
-
- if (bitmask & MAT_BIT_BACK_SHININESS)
- glMaterialfv( GL_BACK, GL_SHININESS, attr[MAT_ATTRIB_BACK_SHININESS] );
-
- if (bitmask & MAT_BIT_FRONT_INDEXES)
- glMaterialfv( GL_FRONT, GL_COLOR_INDEXES, attr[MAT_ATTRIB_FRONT_INDEXES]);
-
- if (bitmask & MAT_BIT_BACK_INDEXES)
- glMaterialfv( GL_BACK, GL_COLOR_INDEXES, attr[MAT_ATTRIB_BACK_INDEXES] );
-}
-
-
-/* Low-performance helper function to allow driver-supplied tnl
- * modules to process tnl display lists. This is primarily supplied
- * to avoid fallbacks if CallList is invoked inside a Begin/End pair.
- * For higher performance, drivers should fallback to tnl (if outside
- * begin/end), or (for tnl hardware) implement their own display list
- * mechanism.
- */
-static void
-loopback_compiled_cassette( GLcontext *ctx, struct immediate *IM )
-{
- const GLuint *flags = IM->Flag;
- const GLuint orflag = IM->OrFlag;
- void (GLAPIENTRY *vertex)( const GLfloat * );
- void (GLAPIENTRY *texcoordfv[MAX_TEXTURE_COORD_UNITS])( GLenum, const GLfloat * );
- GLuint i, j, p, length, prim = 0, maxtex = 0;
-
- if (orflag & VERT_BITS_OBJ_234)
- vertex = (void (GLAPIENTRY *)(const GLfloat *)) glVertex4fv;
- else
- vertex = (void (GLAPIENTRY *)(const GLfloat *)) glVertex3fv;
-
- if (orflag & VERT_BITS_TEX_ANY) {
- for (j = 0 ; j < ctx->Const.MaxTextureCoordUnits ; j++) {
- if (orflag & VERT_BIT_TEX(j)) {
- maxtex = j+1;
- if ((IM->TexSize & TEX_SIZE_4(j)) == TEX_SIZE_4(j))
- texcoordfv[j] = glMultiTexCoord4fvARB;
- else if (IM->TexSize & TEX_SIZE_3(j))
- texcoordfv[j] = glMultiTexCoord3fvARB;
- else
- texcoordfv[j] = glMultiTexCoord2fvARB;
- }
- }
- }
-
- for (p = IM->Start ; !(prim & PRIM_LAST) ; p += length)
- {
- prim = IM->Primitive[p];
- length= IM->PrimitiveLength[p];
- ASSERT(length || (prim & PRIM_LAST));
- ASSERT((prim & PRIM_MODE_MASK) <= GL_POLYGON+1);
-
- if (prim & PRIM_BEGIN) {
- glBegin(prim & PRIM_MODE_MASK);
- }
-
- for ( i = p ; i <= p+length ; i++) {
- if (flags[i] & VERT_BITS_TEX_ANY) {
- GLuint k;
- for (k = 0 ; k < maxtex ; k++) {
- if (flags[i] & VERT_BIT_TEX(k)) {
- texcoordfv[k]( GL_TEXTURE0_ARB + k,
- IM->Attrib[VERT_ATTRIB_TEX0 + k][i] );
- }
- }
- }
-
- /* XXX Maybe we should jump through _glapi->Dispatch all the time?? */
- if (flags[i] & VERT_BIT_NORMAL)
- glNormal3fv(IM->Attrib[VERT_ATTRIB_NORMAL][i]);
-
- if (flags[i] & VERT_BIT_COLOR0)
- glColor4fv( IM->Attrib[VERT_ATTRIB_COLOR0][i] );
-
- if (flags[i] & VERT_BIT_COLOR1)
- _glapi_Dispatch->SecondaryColor3fvEXT( IM->Attrib[VERT_ATTRIB_COLOR1][i] );
-
- if (flags[i] & VERT_BIT_FOG)
- _glapi_Dispatch->FogCoordfEXT( IM->Attrib[VERT_ATTRIB_FOG][i][0] );
-
- if (flags[i] & VERT_BIT_INDEX)
- glIndexi( IM->Index[i] );
-
- if (flags[i] & VERT_BIT_EDGEFLAG)
- glEdgeFlag( IM->EdgeFlag[i] );
-
- if (flags[i] & VERT_BIT_MATERIAL)
- emit_material( &IM->Material[i], IM->MaterialMask[i] );
-
- if (flags[i]&VERT_BITS_OBJ_234)
- vertex( IM->Attrib[VERT_ATTRIB_POS][i] );
- else if (flags[i] & VERT_BIT_EVAL_C1)
- glEvalCoord1f( IM->Attrib[VERT_ATTRIB_POS][i][0] );
- else if (flags[i] & VERT_BIT_EVAL_P1)
- glEvalPoint1( (GLint) IM->Attrib[VERT_ATTRIB_POS][i][0] );
- else if (flags[i] & VERT_BIT_EVAL_C2)
- glEvalCoord2f( IM->Attrib[VERT_ATTRIB_POS][i][0],
- IM->Attrib[VERT_ATTRIB_POS][i][1] );
- else if (flags[i] & VERT_BIT_EVAL_P2)
- glEvalPoint2( (GLint) IM->Attrib[VERT_ATTRIB_POS][i][0],
- (GLint) IM->Attrib[VERT_ATTRIB_POS][i][1] );
- }
-
- if (prim & PRIM_END) {
- glEnd();
- }
- }
-}
+++ /dev/null
-
-/*
- * Mesa 3-D graphics library
- * Version: 3.5
- *
- * Copyright (C) 1999-2001 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 <keith@tungstengraphics.com>
- */
-
-#ifndef _T_DLIST_H
-#define _T_DLIST_H
-
-#include "mtypes.h"
-#include "t_context.h"
-
-extern void _tnl_dlist_init( GLcontext *ctx );
-
-extern void _tnl_compile_cassette( GLcontext *ctx, struct immediate *IM );
-extern void _tnl_EndList( GLcontext *ctx );
-extern void _tnl_NewList( GLcontext *ctx, GLuint list, GLenum mode );
-
-extern void _tnl_EndCallList( GLcontext *ctx );
-extern void _tnl_BeginCallList( GLcontext *ctx, GLuint list );
-
-#endif
+++ /dev/null
-
-/*
- * Mesa 3-D graphics library
- * Version: 3.5
- *
- * Copyright (C) 1999-2001 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 <keith@tungstengraphics.com>
- */
-
-
-#ifndef _T_IMM_ELT_H_
-#define _T_IMM_ELT_H_
-
-#include "mtypes.h"
-#include "t_context.h"
-
-
-extern void _tnl_imm_elt_init( void );
-
-extern void _tnl_translate_array_elts( GLcontext *ctx,
- struct immediate *IM,
- GLuint start,
- GLuint end );
-
-
-#endif
+++ /dev/null
-
-/*
- * Mesa 3-D graphics library
- * Version: 3.5
- *
- * Copyright (C) 1999-2001 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.
- */
-
-
-#ifndef _T_IMM_EVAL_H
-#define _T_IMM_EVAL_H
-
-
-#include "mtypes.h"
-#include "t_context.h"
-
-extern void _tnl_eval_init( void );
-
-extern void _tnl_eval_immediate( GLcontext *ctx, struct immediate *IM );
-
-#endif
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 5.1
- *
- * Copyright (C) 1999-2003 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.
- */
-
-/**
- * \file tnl/t_imm_exec.c
- * \brief Setup to execute immediate-mode vertex data.
- * \author Keith Whitwell
- */
-
-#include "glheader.h"
-#include "colormac.h"
-#include "context.h"
-#include "enums.h"
-#include "dlist.h"
-#include "macros.h"
-#include "imports.h"
-#include "light.h"
-#include "state.h"
-#include "mtypes.h"
-
-#include "math/m_matrix.h"
-#include "math/m_xform.h"
-
-#include "t_context.h"
-#include "t_array_import.h"
-#include "t_imm_alloc.h"
-#include "t_imm_api.h"
-#include "t_imm_debug.h"
-#include "t_imm_dlist.h"
-#include "t_imm_eval.h"
-#include "t_imm_elt.h"
-#include "t_imm_exec.h"
-#include "t_imm_fixup.h"
-#include "t_pipeline.h"
-
-
-
-static void reset_input( GLcontext *ctx,
- GLuint start,
- GLuint beginstate,
- GLuint savedbeginstate )
-{
- struct immediate *IM = TNL_CURRENT_IM(ctx);
-
- /* Clear the dirty part of the flag array.
- */
- if (start < IM->Count+2)
- MEMSET(IM->Flag + start, 0, sizeof(GLuint) * (IM->Count+2-start));
-
- if (MESA_VERBOSE & VERBOSE_IMMEDIATE)
- _mesa_debug(ctx, "reset_input: IM(%d) new %x\n", IM->id, beginstate);
-
- IM->Start = start;
- IM->Count = start;
- IM->LastMaterial = start;
- IM->BeginState = beginstate;
- IM->SavedBeginState = savedbeginstate;
- IM->TexSize = 0;
- IM->MaterialOrMask = 0;
-
- if (IM->MaterialMask)
- IM->MaterialMask[IM->Start] = 0;
-
- IM->ArrayEltFlags = ~ctx->Array._Enabled;
- IM->ArrayEltIncr = (ctx->Array.Vertex.Enabled ||
- (ctx->VertexProgram.Enabled &&
- ctx->Array.VertexAttrib[0].Enabled)) ? 1 : 0;
- IM->ArrayEltFlush = ctx->Array.LockCount ? FLUSH_ELT_LAZY : FLUSH_ELT_EAGER;
-}
-
-void _tnl_reset_exec_input( GLcontext *ctx,
- GLuint start,
- GLuint beginstate,
- GLuint savedbeginstate )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- struct immediate *IM = TNL_CURRENT_IM(ctx);
-
- reset_input( ctx, start, beginstate, savedbeginstate );
-
- IM->CopyStart = start - tnl->ExecCopyCount;
-
- IM->Primitive[IM->CopyStart] = ctx->Driver.CurrentExecPrimitive;
- if (tnl->ExecParity)
- IM->Primitive[IM->CopyStart] |= PRIM_PARITY;
-
- IM->LastPrimitive = IM->CopyStart;
-}
-
-
-void _tnl_reset_compile_input( GLcontext *ctx,
- GLuint start,
- GLuint beginstate,
- GLuint savedbeginstate )
-{
- struct immediate *IM = TNL_CURRENT_IM(ctx);
-
- reset_input( ctx, start, beginstate, savedbeginstate );
- IM->CopyStart = start;
- IM->LastPrimitive = IM->Start;
-}
-
-
-/**
- * Copy the last specified normal, color, texcoord, edge flag, etc
- * from the immediate struct into the ctx->Current attribute group.
- */
-void _tnl_copy_to_current( GLcontext *ctx, struct immediate *IM,
- GLuint flag, GLuint count )
-{
- GLuint attr;
-
- if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
- _tnl_print_vert_flags("copy to current", flag);
-
- for (attr = 1; attr < VERT_ATTRIB_MAX; attr++) {
- if ((flag & (1 << attr)) && IM->Attrib[attr]) {
- COPY_4FV(ctx->Current.Attrib[attr], IM->Attrib[attr][count]);
- }
- }
-
- /* special cases */
- if (flag & VERT_BIT_INDEX)
- ctx->Current.Index = IM->Index[count];
-
- if (flag & VERT_BIT_EDGEFLAG)
- ctx->Current.EdgeFlag = IM->EdgeFlag[count];
-
- if ((flag & VERT_BIT_COLOR0) && ctx->Light.ColorMaterialEnabled) {
- _mesa_update_color_material(ctx,
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
- TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx );
- }
-
- if (flag & VERT_BIT_MATERIAL) {
- _mesa_copy_materials( &ctx->Light.Material,
- &IM->Material[IM->LastMaterial],
- IM->MaterialOrMask );
-
- _mesa_update_material( ctx, IM->MaterialOrMask );
-
- TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx );
- }
-}
-
-
-
-void _tnl_compute_orflag( struct immediate *IM, GLuint start )
-{
- GLuint count = IM->Count;
- GLuint orflag = 0;
- GLuint andflag = ~0U;
- GLuint i;
-
- IM->LastData = count-1;
-
-
- /* Compute the flags for the whole buffer.
- */
- for (i = start ; i < count ; i++) {
- andflag &= IM->Flag[i];
- orflag |= IM->Flag[i];
- }
-
- /* It is possible there will be data in the buffer arising from
- * calls like 'glNormal', 'glMaterial' that occur after the final
- * glVertex, glEval, etc. Additionally, a buffer can consist of
- * eg. a single glMaterial call, in which case IM->Start ==
- * IM->Count, but the buffer is definitely not empty.
- */
- if (IM->Flag[i] & VERT_BITS_DATA) {
- IM->LastData++;
- orflag |= IM->Flag[i];
- }
-
- IM->Flag[IM->LastData+1] |= VERT_BIT_END_VB;
- IM->CopyAndFlag = IM->AndFlag = andflag;
- IM->OrFlag = orflag;
- IM->CopyOrFlag = orflag;
- IM->Evaluated = 0;
-}
-
-
-/**
- * This is where the vertex data is transfered from the 'struct immediate
- * into the 'struct vertex_buffer'.
- *
- * Note: The 'start' member of the GLvector structs is now redundant
- * because we always re-transform copied vertices, and the vectors
- * below are set up so that the first copied vertex (if any) appears
- * at position zero.
- */
-static void _tnl_vb_bind_immediate( GLcontext *ctx, struct immediate *IM )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- struct vertex_buffer *VB = &tnl->vb;
- struct vertex_arrays *tmp = &tnl->imm_inputs;
- GLuint inputs = tnl->pipeline.inputs; /* for copy-to-current */
- const GLuint start = IM->CopyStart;
- const GLuint count = IM->Count - start;
-
- /* TODO: optimize the case where nothing has changed. (Just bind
- * tmp to vb).
- */
-
- /* Setup constant data in the VB.
- */
- VB->Count = count;
- VB->FirstClipped = IMM_MAXDATA - IM->CopyStart;
- VB->import_data = NULL;
- VB->importable_data = 0;
-
- /* Need an IM->FirstPrimitive?
- */
- VB->Primitive = IM->Primitive + IM->CopyStart;
- VB->PrimitiveLength = IM->PrimitiveLength + IM->CopyStart;
- VB->FirstPrimitive = 0;
-
- VB->Flag = IM->Flag + start;
-
- /* TexCoordPtr's are zeroed in loop below.
- */
- VB->NormalPtr = NULL;
- VB->NormalLengthPtr = NULL;
- VB->EdgeFlag = NULL;
- VB->IndexPtr[0] = NULL;
- VB->IndexPtr[1] = NULL;
- VB->ColorPtr[0] = NULL;
- VB->ColorPtr[1] = NULL;
- VB->SecondaryColorPtr[0] = NULL;
- VB->SecondaryColorPtr[1] = NULL;
- VB->Elts = NULL;
- VB->MaterialMask = NULL;
- VB->Material = NULL;
-
-/* _tnl_print_vert_flags("copy-orflag", IM->CopyOrFlag); */
-/* _tnl_print_vert_flags("orflag", IM->OrFlag); */
-/* _tnl_print_vert_flags("inputs", inputs); */
-
- /* Setup the initial values of array pointers in the vb.
- */
- if (inputs & VERT_BIT_POS) {
- tmp->Obj.data = IM->Attrib[VERT_ATTRIB_POS] + start;
- tmp->Obj.start = (GLfloat *)(IM->Attrib[VERT_ATTRIB_POS] + start);
- tmp->Obj.count = count;
- VB->ObjPtr = &tmp->Obj;
- if ((IM->CopyOrFlag & VERT_BITS_OBJ_234) == VERT_BITS_OBJ_234)
- tmp->Obj.size = 4;
- else if ((IM->CopyOrFlag & VERT_BITS_OBJ_234) == VERT_BITS_OBJ_23)
- tmp->Obj.size = 3;
- else
- tmp->Obj.size = 2;
- }
-
- if (inputs & VERT_BIT_NORMAL) {
- tmp->Normal.data = IM->Attrib[VERT_ATTRIB_NORMAL] + start;
- tmp->Normal.start = (GLfloat *) (IM->Attrib[VERT_ATTRIB_NORMAL] + start);
- tmp->Normal.count = count;
- tmp->Normal.size = 3; /* just to be safe */
- VB->NormalPtr = &tmp->Normal;
- if (IM->NormalLengthPtr)
- VB->NormalLengthPtr = IM->NormalLengthPtr + start;
- }
-
- if (inputs & VERT_BIT_INDEX) {
- tmp->Index.count = count;
- tmp->Index.data = IM->Index + start;
- tmp->Index.start = IM->Index + start;
- VB->IndexPtr[0] = &tmp->Index;
- }
-
- if (inputs & VERT_BIT_FOG) {
- tmp->FogCoord.data = IM->Attrib[VERT_ATTRIB_FOG] + start;
- tmp->FogCoord.start = (GLfloat *) (IM->Attrib[VERT_ATTRIB_FOG] + start);
- tmp->FogCoord.count = count;
- VB->FogCoordPtr = &tmp->FogCoord;
- }
-
- if (inputs & VERT_BIT_COLOR1) {
- tmp->SecondaryColor.Ptr = (GLubyte *) (IM->Attrib[VERT_ATTRIB_COLOR1] + start);
- VB->SecondaryColorPtr[0] = &tmp->SecondaryColor;
- }
-
- if (inputs & VERT_BIT_EDGEFLAG) {
- VB->EdgeFlag = IM->EdgeFlag + start;
- }
-
- if (inputs & VERT_BIT_COLOR0) {
- if (IM->CopyOrFlag & VERT_BIT_COLOR0) {
- tmp->Color.Ptr = (GLubyte *) (IM->Attrib[VERT_ATTRIB_COLOR0] + start);
- tmp->Color.StrideB = 4 * sizeof(GLfloat);
- tmp->Color.Flags = 0;
- }
- else {
- tmp->Color.Ptr = (GLubyte *) ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
- tmp->Color.StrideB = 0;
- tmp->Color.Flags = CA_CLIENT_DATA; /* hack */
- VB->import_source = IM;
- VB->importable_data |= VERT_BIT_COLOR0;
- VB->import_data = _tnl_upgrade_current_data;
- }
- VB->ColorPtr[0] = &tmp->Color;
- }
-
- if (inputs & VERT_BITS_TEX_ANY) {
- GLuint i;
- for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
- VB->TexCoordPtr[i] = NULL;
- if (inputs & VERT_BIT_TEX(i)) {
- tmp->TexCoord[i].count = count;
- tmp->TexCoord[i].data = IM->Attrib[VERT_ATTRIB_TEX0 + i] + start;
- tmp->TexCoord[i].start = (GLfloat *)(IM->Attrib[VERT_ATTRIB_TEX0 + i] + start);
- tmp->TexCoord[i].size = 2;
- if (IM->TexSize & TEX_SIZE_3(i)) {
- tmp->TexCoord[i].size = 3;
- if (IM->TexSize & TEX_SIZE_4(i))
- tmp->TexCoord[i].size = 4;
- }
- VB->TexCoordPtr[i] = &tmp->TexCoord[i];
- }
- }
- }
-
- if ((inputs & IM->OrFlag & VERT_BIT_MATERIAL) && IM->Material) {
- VB->MaterialMask = IM->MaterialMask + start;
- VB->Material = IM->Material + start;
- }
-
- /* GL_NV_vertex_program */
- if (ctx->VertexProgram.Enabled) {
- GLuint attr;
- for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
- tmp->Attribs[attr].count = count;
- tmp->Attribs[attr].data = IM->Attrib[attr] + start;
- tmp->Attribs[attr].start = (GLfloat *) (IM->Attrib[attr] + start);
- tmp->Attribs[attr].size = 4;
- VB->AttribPtr[attr] = &(tmp->Attribs[attr]);
- }
- }
-}
-
-
-
-
-/**
- * Called by exec_vert_cassette, execute_compiled_cassette, but not
- * exec_elt_cassette.
- */
-void _tnl_run_cassette( GLcontext *ctx, struct immediate *IM )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
-
- _tnl_vb_bind_immediate( ctx, IM );
-
- if (IM->OrFlag & VERT_BITS_EVAL_ANY)
- _tnl_eval_immediate( ctx, IM );
-
- /* Invalidate all stored data before and after run:
- */
- tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
- tnl->Driver.RunPipeline( ctx );
- tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
-
- _tnl_copy_to_current( ctx, IM, IM->OrFlag, IM->LastData );
-}
-
-
-/**
- * Called for regular vertex cassettes.
- */
-static void exec_vert_cassette( GLcontext *ctx, struct immediate *IM )
-{
- if (IM->FlushElt) {
- /* Orflag is computed twice, but only reach this code if app is
- * using a mixture of glArrayElement() and glVertex() while
- * arrays are locked (else would be in exec_elt_cassette now).
- */
- ASSERT(ctx->Array.LockCount);
- ASSERT(IM->FlushElt == FLUSH_ELT_LAZY);
- _tnl_translate_array_elts( ctx, IM, IM->CopyStart, IM->Count );
- _tnl_compute_orflag( IM, IM->CopyStart );
- }
-
- _tnl_fixup_input( ctx, IM );
-/* _tnl_print_cassette( IM ); */
- _tnl_run_cassette( ctx, IM );
-}
-
-
-/* Called for pure, locked VERT_BIT_ELT cassettes instead of
- * _tnl_run_cassette.
- */
-static void exec_elt_cassette( GLcontext *ctx, struct immediate *IM )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- struct vertex_buffer *VB = &tnl->vb;
-
- _tnl_vb_bind_arrays( ctx, ctx->Array.LockFirst, ctx->Array.LockCount );
-
- /* Take only elements and primitive information from the immediate:
- */
- VB->Elts = IM->Elt + IM->CopyStart;
- VB->Primitive = IM->Primitive + IM->CopyStart;
- VB->PrimitiveLength = IM->PrimitiveLength + IM->CopyStart;
- VB->FirstPrimitive = 0;
-
- /* Run the pipeline. No input changes as a result of this action.
- */
- tnl->Driver.RunPipeline( ctx );
-
- /* Still need to update current values:
- */
- if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) {
- _tnl_translate_array_elts( ctx, IM, IM->LastData, IM->LastData );
- _tnl_copy_to_current( ctx, IM, ctx->Array._Enabled, IM->LastData );
- }
-}
-
-
-static void
-exec_empty_cassette( GLcontext *ctx, struct immediate *IM )
-{
- if (IM->FlushElt)
- _tnl_translate_array_elts( ctx, IM, IM->CopyStart, IM->CopyStart );
-
- _tnl_copy_to_current( ctx, IM, IM->OrFlag, IM->LastData );
-}
-
-
-
-/**
- * Called for all cassettes when not compiling or playing a display
- * list.
- */
-void _tnl_execute_cassette( GLcontext *ctx, struct immediate *IM )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
-
- _tnl_compute_orflag( IM, IM->Start );
- _tnl_copy_immediate_vertices( ctx, IM );
- _tnl_get_exec_copy_verts( ctx, IM );
-
- if (tnl->pipeline.build_state_changes)
- _tnl_validate_pipeline( ctx );
-
- if (IM->CopyStart == IM->Count) {
- exec_empty_cassette( ctx, IM );
- }
- else if ((IM->CopyOrFlag & VERT_BITS_DATA) == VERT_BIT_ELT &&
- ctx->Array.LockCount &&
- (ctx->Array.Vertex.Enabled ||
- (ctx->VertexProgram.Enabled &&
- ctx->Array.VertexAttrib[0].Enabled))) {
- exec_elt_cassette( ctx, IM );
- }
- else {
- exec_vert_cassette( ctx, IM );
- }
-
- /* Only reuse the immediate if there are no copied vertices living
- * inside it:
- */
- {
- GLuint begin_state = IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1);
- GLuint saved_begin_state = IM->SavedBeginState;
-
- if (--IM->ref_count != 0) {
- IM = _tnl_alloc_immediate( ctx );
- SET_IMMEDIATE( ctx, IM );
- }
-
- IM->ref_count++;
-
- _tnl_reset_exec_input( ctx, IMM_MAX_COPIED_VERTS,
- begin_state, saved_begin_state );
- }
-
- /* Don't unset FLUSH_STORED_VERTICES flag here as the driver might
- * have other stored data of its own & be relying on the
- * FlushVertices notification to clear it.
- */
-}
-
-
-
-
-/**
- * Setup vector pointers that will be used to bind immediates to VB's.
- */
-void _tnl_imm_init( GLcontext *ctx )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- struct vertex_arrays *tmp = &tnl->imm_inputs;
- GLuint i;
- static int firsttime = 1;
-
- if (firsttime) {
- firsttime = 0;
- _tnl_imm_elt_init();
- }
-
- ctx->swtnl_im = _tnl_alloc_immediate( ctx );
- TNL_CURRENT_IM(ctx)->ref_count++;
-
- tnl->ExecCopyTexSize = 0;
- tnl->ExecCopyCount = 0;
- tnl->ExecCopySource = 0;
-
- TNL_CURRENT_IM(ctx)->CopyStart = IMM_MAX_COPIED_VERTS;
-
- _mesa_vector4f_init( &tmp->Obj, 0, 0 );
- _mesa_vector4f_init( &tmp->Normal, 0, 0 );
-
- tmp->Color.Ptr = NULL;
- tmp->Color.Type = GL_FLOAT;
- tmp->Color.Size = 4;
- 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.Size = 4;
- 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 );
- _mesa_vector1ub_init( &tmp->EdgeFlag, 0, 0 );
-
- for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++)
- _mesa_vector4f_init( &tmp->TexCoord[i], 0, 0);
-
- /* Install the first immediate. Intially outside begin/end.
- */
- _tnl_reset_exec_input( ctx, IMM_MAX_COPIED_VERTS, 0, 0 );
- tnl->ReplayHardBeginEnd = 0;
-
- _tnl_imm_vtxfmt_init( ctx );
-}
-
-
-/**
- * Deallocate the immediate-mode buffer for the given context, if
- * its reference count goes to zero.
- */
-void _tnl_imm_destroy( GLcontext *ctx )
-{
- if (TNL_CURRENT_IM(ctx)) {
- TNL_CURRENT_IM(ctx)->ref_count--;
- if (TNL_CURRENT_IM(ctx)->ref_count == 0)
- _tnl_free_immediate( ctx, TNL_CURRENT_IM(ctx) );
- /*
- * Don't use SET_IMMEDIATE here, or else we'll whack the
- * _tnl_CurrentInput pointer - not good when another
- * context has already been made current.
- * So we just set the context's own tnl immediate pointer
- * to 0.
- */
- ctx->swtnl_im = NULL;
- }
-}
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 5.1
- *
- * Copyright (C) 1999-2003 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.
- */
-
-
-#ifndef _T_IMM_EXEC_H
-#define _T_IMM_EXEC_H
-
-#include "mtypes.h"
-#include "t_context.h"
-
-
-/* Hook for ctx->Driver.FlushVertices:
- */
-extern void _tnl_flush_vertices( GLcontext *ctx, GLuint flush_flags );
-
-/* Called from imm_api.c and _tnl_flush_vertices:
- */
-extern void _tnl_flush_immediate( GLcontext *ctx, struct immediate *IM );
-
-/* Called from imm_dlist.c and _tnl_flush_immediate:
- */
-extern void _tnl_run_cassette( GLcontext *ctx, struct immediate *IM );
-extern void _tnl_copy_to_current( GLcontext *ctx, struct immediate *IM,
- GLuint flag, GLuint row );
-
-/* Initialize some stuff:
- */
-extern void _tnl_imm_init( GLcontext *ctx );
-
-extern void _tnl_imm_destroy( GLcontext *ctx );
-
-extern void _tnl_reset_exec_input( GLcontext *ctx,
- GLuint start,
- GLuint beginstate,
- GLuint savedbeginstate );
-
-extern void _tnl_reset_compile_input( GLcontext *ctx,
- GLuint start,
- GLuint beginstate,
- GLuint savedbeginstate );
-
-extern void _tnl_compute_orflag( struct immediate *IM, GLuint start );
-extern void _tnl_execute_cassette( GLcontext *ctx, struct immediate *IM );
-
-
-
-#endif
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 5.1
- *
- * Copyright (C) 1999-2003 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 <keith@tungstengraphics.com>
- */
-
-
-#include "glheader.h"
-#include "context.h"
-#include "enums.h"
-#include "dlist.h"
-#include "colormac.h"
-#include "light.h"
-#include "macros.h"
-#include "imports.h"
-#include "state.h"
-#include "mtypes.h"
-
-#include "math/m_matrix.h"
-#include "math/m_xform.h"
-
-#include "t_context.h"
-#include "t_imm_alloc.h"
-#include "t_imm_debug.h"
-#include "t_imm_elt.h"
-#include "t_imm_fixup.h"
-#include "t_imm_exec.h"
-#include "t_pipeline.h"
-
-
-/*
- * Indexed by primitive type (GL_POINTS=0, GL_LINES=1, GL_LINE_LOOP=2, etc)
- */
-static const GLuint increment[GL_POLYGON+2] = { 1,2,1,1,3,1,1,4,2,1,1 };
-static const GLuint intro[GL_POLYGON+2] = { 0,0,2,2,0,2,2,0,2,2,0 };
-
-
-void
-_tnl_fixup_4f( GLfloat data[][4], const GLuint flag[],
- GLuint start, GLuint match )
-{
- GLuint i = start;
-
- for (;;) {
- if ((flag[++i] & match) == 0) {
- COPY_4FV(data[i], data[i-1]);
- if (flag[i] & VERT_BIT_END_VB) break;
- }
- }
-}
-
-
-void
-_tnl_fixup_1ui( GLuint *data, GLuint flag[], GLuint start, GLuint match )
-{
- GLuint i = start;
-
- for (;;) {
- if ((flag[++i] & match) == 0) {
- data[i] = data[i-1];
- if (flag[i] & VERT_BIT_END_VB) break;
- }
- }
- flag[i] |= match;
-}
-
-
-void
-_tnl_fixup_1ub( GLubyte *data, GLuint flag[], GLuint start, GLuint match)
-{
- GLuint i = start;
-
- for (;;) {
- if ((flag[++i] & match) == 0) {
- data[i] = data[i-1];
- if (flag[i] & VERT_BIT_END_VB) break;
- }
- }
- flag[i] |= match;
-}
-
-
-static void
-fixup_first_4f( GLfloat data[][4], const GLuint flag[], GLuint match,
- GLuint start, const GLfloat *dflt )
-{
- GLuint i = start-1;
- match |= VERT_BIT_END_VB;
-
- while ((flag[++i]&match) == 0)
- COPY_4FV(data[i], dflt);
-}
-
-
-static void
-fixup_first_1ui( GLuint data[], const GLuint flag[], GLuint match,
- GLuint start, const GLuint dflt )
-{
- GLuint i = start-1;
- match |= VERT_BIT_END_VB;
-
- while ((flag[++i]&match) == 0)
- data[i] = dflt;
-}
-
-
-static void
-fixup_first_1ub( GLubyte data[], const GLuint flag[], GLuint match,
- GLuint start, GLubyte dflt )
-{
- GLuint i = start-1;
- match |= VERT_BIT_END_VB;
-
- while ((flag[++i]&match) == 0)
- data[i] = dflt;
-}
-
-
-/**
- * Copy vertex attributes from the ctx->Current group into the immediate
- * struct at the given position according to copyMask.
- */
-static void
-copy_from_current( GLcontext *ctx, struct immediate *IM,
- GLuint pos, GLuint copyMask )
-{
- GLuint attrib, attribBit;
-
- if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
- _tnl_print_vert_flags("copy from current", copyMask);
-
- for (attrib = 0, attribBit = 1; attrib < 16; attrib++, attribBit <<= 1) {
- if (copyMask & attribBit) {
- if (!IM->Attrib[attrib]) {
- IM->Attrib[attrib] = (GLfloat (*)[4]) _mesa_malloc(IMM_SIZE * 4 * sizeof(GLfloat));
- if (!IM->Attrib[attrib]) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "vertex processing3");
- return;
- }
- }
- COPY_4FV( IM->Attrib[attrib][pos], ctx->Current.Attrib[attrib]);
- }
- }
-
- if (copyMask & VERT_BIT_INDEX)
- IM->Index[pos] = ctx->Current.Index;
-
- if (copyMask & VERT_BIT_EDGEFLAG)
- IM->EdgeFlag[pos] = ctx->Current.EdgeFlag;
-}
-
-
-/**
- * Fill in missing vertex attributes in the incoming immediate structure.
- * For example, suppose the following calls are made:
- * glBegin()
- * glColor(c1)
- * glVertex(v1)
- * glVertex(v2)
- * glEnd()
- * The v2 vertex should get color c1 since glColor wasn't called for v2.
- * This function will make c2 be c1. Same story for all vertex attribs.
- */
-void
-_tnl_fixup_input( GLcontext *ctx, struct immediate *IM )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- GLuint start = IM->CopyStart;
- GLuint andflag = IM->CopyAndFlag;
- GLuint orflag = IM->CopyOrFlag | IM->Evaluated;
- GLuint fixup;
-
- IM->CopyTexSize = IM->TexSize;
-
-/* _mesa_debug(ctx, "Fixup input, Start: %u Count: %u LastData: %u\n", */
-/* IM->Start, IM->Count, IM->LastData); */
-/* _tnl_print_vert_flags("Orflag", orflag); */
-/* _tnl_print_vert_flags("Andflag", andflag); */
-
-
- fixup = ~andflag & VERT_BITS_FIXUP;
-
- if (!ctx->CompileFlag)
- fixup &= tnl->pipeline.inputs;
-
- if (!ctx->ExecuteFlag)
- fixup &= orflag;
-
- if ((orflag & (VERT_BIT_POS|VERT_BITS_EVAL_ANY)) == 0)
- fixup = 0;
-
- if (fixup) {
- const GLuint copy = fixup & ~IM->Flag[start];
- GLuint attr;
-
- /* Equivalent to a lazy copy-from-current when setting up the
- * immediate.
- */
- if (ctx->ExecuteFlag && copy)
- copy_from_current( ctx, IM, start, copy );
-
- if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
- _tnl_print_vert_flags("fixup", fixup);
-
- for (attr = 1; attr < VERT_ATTRIB_MAX; attr++) { /* skip 0 (POS) */
- const GLuint attrBit = 1 << attr;
- if (fixup & attrBit) {
- if (!IM->Attrib[attr]) {
- IM->Attrib[attr] = (GLfloat (*)[4]) _mesa_malloc(IMM_SIZE * 4 * sizeof(GLfloat));
- if (!IM->Attrib[attr]) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "vertex processing");
- return;
- }
- }
-
- if (attr == VERT_BIT_COLOR0) {
- /* special case, darn - try to remove someday */
- if (orflag & VERT_BIT_COLOR0) {
- _tnl_fixup_4f( IM->Attrib[VERT_ATTRIB_COLOR0], IM->Flag,
- start, VERT_BIT_COLOR0 );
- }
- /* No need for else case as the drivers understand stride
- * zero here. (TODO - propogate this)
- */
- }
- else {
- /* general case */
- if (orflag & attrBit)
- _tnl_fixup_4f( IM->Attrib[attr], IM->Flag, start, attrBit );
- else
- fixup_first_4f( IM->Attrib[attr], IM->Flag, VERT_BIT_END_VB,
- start, IM->Attrib[attr][start] );
- }
- }
- }
-
- if (fixup & VERT_BIT_EDGEFLAG) {
- if (orflag & VERT_BIT_EDGEFLAG)
- _tnl_fixup_1ub( IM->EdgeFlag, IM->Flag, start, VERT_BIT_EDGEFLAG );
- else
- fixup_first_1ub( IM->EdgeFlag, IM->Flag, VERT_BIT_END_VB, start,
- IM->EdgeFlag[start] );
- }
-
- if (fixup & VERT_BIT_INDEX) {
- if (orflag & VERT_BIT_INDEX)
- _tnl_fixup_1ui( IM->Index, IM->Flag, start, VERT_BIT_INDEX );
- else
- fixup_first_1ui( IM->Index, IM->Flag, VERT_BIT_END_VB, start,
- IM->Index[start] );
- }
-
- }
-
- /* Prune possible half-filled slot.
- */
- IM->Flag[IM->LastData+1] &= ~VERT_BIT_END_VB;
- IM->Flag[IM->Count] |= VERT_BIT_END_VB;
-
-
- /* Materials:
- */
- if (IM->MaterialOrMask & ~IM->MaterialAndMask) {
- GLuint vulnerable = IM->MaterialOrMask;
- GLuint i = IM->Start;
-
- do {
- while (!(IM->Flag[i] & VERT_BIT_MATERIAL))
- i++;
-
- vulnerable &= ~IM->MaterialMask[i];
- _mesa_copy_materials( &IM->Material[i],
- &ctx->Light.Material,
- vulnerable );
-
-
- ++i;
- } while (vulnerable);
- }
-}
-
-
-static void
-copy_material( struct immediate *next,
- struct immediate *prev,
- GLuint dst, GLuint src )
-{
-/* _mesa_debug(NULL, "%s\n", __FUNCTION__); */
-
- if (next->Material == 0) {
- next->Material = (struct gl_material *)
- MALLOC( sizeof(struct gl_material) * IMM_SIZE );
- next->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * IMM_SIZE );
- }
-
- next->MaterialMask[dst] = prev->MaterialOrMask;
- MEMCPY(&next->Material[dst], &prev->Material[src],
- sizeof(struct gl_material));
-}
-
-
-
-static GLboolean is_fan_like[GL_POLYGON+1] = {
- GL_FALSE,
- GL_FALSE,
- GL_TRUE, /* line loop */
- GL_FALSE,
- GL_FALSE,
- GL_FALSE,
- GL_TRUE, /* tri fan */
- GL_FALSE,
- GL_FALSE,
- GL_TRUE /* polygon */
-};
-
-
-/**
- * Copy the untransformed data from the shared vertices of a primitive
- * that wraps over two immediate structs. This is done prior to
- * set_immediate so that prev and next may point to the same
- * structure. In general it's difficult to avoid this copy on long
- * primitives.
- *
- * Have to be careful with the transitions between display list
- * replay, compile and normal execute modes.
- */
-void
-_tnl_copy_immediate_vertices( GLcontext *ctx, struct immediate *next )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- struct immediate *prev = tnl->ExecCopySource;
- struct vertex_arrays *inputs = &tnl->imm_inputs;
- GLuint count = tnl->ExecCopyCount;
- GLuint *elts = tnl->ExecCopyElts;
- GLuint offset = IMM_MAX_COPIED_VERTS - count;
- GLuint i;
-
- if (!prev) {
- ASSERT(tnl->ExecCopyCount == 0);
- return;
- }
-
- next->CopyStart = next->Start - count;
-
- if ((prev->CopyOrFlag & VERT_BITS_DATA) == VERT_BIT_ELT &&
- ctx->Array.LockCount &&
- (ctx->Array.Vertex.Enabled ||
- (ctx->VertexProgram.Enabled && ctx->Array.VertexAttrib[0].Enabled)))
- {
- /* Copy Elt values only
- */
- for (i = 0 ; i < count ; i++)
- {
- GLuint src = elts[i+offset];
- GLuint dst = next->CopyStart+i;
- next->Elt[dst] = prev->Elt[src];
- next->Flag[dst] = VERT_BIT_ELT;
- elts[i+offset] = dst;
- }
-/* _mesa_debug(ctx, "ADDING VERT_BIT_ELT!\n"); */
- next->CopyOrFlag |= VERT_BIT_ELT;
- next->CopyAndFlag &= VERT_BIT_ELT;
- }
- else {
- GLuint copy = tnl->pipeline.inputs & (prev->CopyOrFlag|prev->Evaluated);
- GLuint flag, attr;
-
- if (is_fan_like[ctx->Driver.CurrentExecPrimitive]) {
- flag = ((prev->CopyOrFlag|prev->Evaluated) & VERT_BITS_FIXUP);
- next->CopyOrFlag |= flag;
- }
- else {
- /* Don't let an early 'glColor', etc. poison the elt path.
- */
- flag = ((prev->OrFlag|prev->Evaluated) & VERT_BITS_FIXUP);
- }
-
- next->TexSize |= tnl->ExecCopyTexSize;
- next->CopyAndFlag &= flag;
-
-
-/* _tnl_print_vert_flags("copy vertex components", copy); */
-/* _tnl_print_vert_flags("prev copyorflag", prev->CopyOrFlag); */
-/* _tnl_print_vert_flags("flag", flag); */
-
- /* Allocate attribute arrays in the destination immediate struct */
- for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
- if ((copy & (1 << attr)) && !next->Attrib[attr]) {
- next->Attrib[attr] = (GLfloat (*)[4]) _mesa_malloc(IMM_SIZE * 4 * sizeof(GLfloat));
- if (!next->Attrib[attr]) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "vertex processing");
- return;
- }
- }
- }
-
- /* Copy whole vertices
- */
- for (i = 0 ; i < count ; i++)
- {
- GLuint src = elts[i+offset];
- GLuint isrc = src - prev->CopyStart;
- GLuint dst = next->CopyStart+i;
-
- /* Values subject to eval must be copied out of the 'inputs'
- * struct. (Copied rows should not be evaluated twice).
- *
- * Note these pointers are null when inactive.
- *
- * XXX try to use a loop over vertex attribs here.
- */
- COPY_4FV( next->Attrib[VERT_ATTRIB_POS][dst],
- inputs->Obj.data[isrc] );
-
- if (copy & VERT_BIT_NORMAL) {
- COPY_3FV( next->Attrib[VERT_ATTRIB_NORMAL][dst],
- inputs->Normal.data[isrc] );
- }
-
- if (copy & VERT_BIT_COLOR0)
- COPY_4FV( next->Attrib[VERT_ATTRIB_COLOR0][dst],
- ((GLfloat (*)[4])inputs->Color.Ptr)[isrc] );
-
- if (copy & VERT_BITS_TEX_ANY) {
- GLuint i;
- for (i = 0 ; i < prev->MaxTextureUnits ; i++) {
- if (copy & VERT_BIT_TEX(i))
- COPY_4FV( next->Attrib[VERT_ATTRIB_TEX0 + i][dst],
- inputs->TexCoord[i].data[isrc] );
- }
- }
-
- /* the rest aren't used for evaluators */
- if (copy & VERT_BIT_COLOR1)
- COPY_4FV( next->Attrib[VERT_ATTRIB_COLOR1][dst],
- prev->Attrib[VERT_ATTRIB_COLOR1][src] );
-
- if (copy & VERT_BIT_FOG)
- COPY_4FV( next->Attrib[VERT_ATTRIB_FOG][dst],
- prev->Attrib[VERT_ATTRIB_FOG][src] );
-
-
- if (copy & VERT_BIT_INDEX)
- next->Index[dst] = inputs->Index.data[isrc];
-
- if (copy & VERT_BIT_EDGEFLAG)
- next->EdgeFlag[dst] = prev->EdgeFlag[src];
-
- if (copy & VERT_BIT_ELT)
- next->Elt[dst] = prev->Elt[src];
-
- if (copy & VERT_BIT_MATERIAL)
- if (prev->Flag[src] & VERT_BIT_MATERIAL)
- copy_material(next, prev, dst, src);
-
- next->Flag[dst] = flag;
- next->CopyOrFlag |= prev->Flag[src] & (VERT_BITS_FIXUP|
- VERT_BIT_MATERIAL|
- VERT_BIT_POS);
- elts[i+offset] = dst;
- }
- }
-
- if (--tnl->ExecCopySource->ref_count == 0)
- _tnl_free_immediate( ctx, tnl->ExecCopySource );
-
- tnl->ExecCopySource = next; next->ref_count++;
-}
-
-
-
-/**
- * Revive a compiled immediate struct - propogate new 'Current'
- * values. Often this is redundant because the current values were
- * known and fixed up at compile time (or in the first execution of
- * the cassette).
- */
-void
-_tnl_fixup_compiled_cassette( GLcontext *ctx, struct immediate *IM )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- GLuint fixup;
- GLuint start = IM->Start;
-
-/* _mesa_debug(ctx, "%s\n", __FUNCTION__); */
-
- IM->Evaluated = 0;
- IM->CopyOrFlag = IM->OrFlag;
- IM->CopyAndFlag = IM->AndFlag;
- IM->CopyTexSize = IM->TexSize | tnl->ExecCopyTexSize;
-
- _tnl_copy_immediate_vertices( ctx, IM );
-
- if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) {
- ASSERT(IM->CopyStart == IM->Start);
- }
-
- /* Naked array elements can be copied into the first cassette in a
- * display list. Need to translate them away:
- */
- if (IM->CopyOrFlag & VERT_BIT_ELT) {
- GLuint copy = tnl->pipeline.inputs & ~ctx->Array._Enabled;
- GLuint i;
-
- ASSERT(IM->CopyStart < IM->Start);
-
- _tnl_translate_array_elts( ctx, IM, IM->CopyStart, IM->Start );
-
- for (i = IM->CopyStart ; i < IM->Start ; i++)
- copy_from_current( ctx, IM, i, copy );
-
- _tnl_copy_to_current( ctx, IM, ctx->Array._Enabled, IM->Start );
- }
-
- fixup = tnl->pipeline.inputs & ~IM->Flag[start] & VERT_BITS_FIXUP;
-
-/* _tnl_print_vert_flags("fixup compiled", fixup); */
-
- if (fixup) {
- GLuint attr;
-
- for (attr = 1; attr < VERT_ATTRIB_MAX; attr++) { /* skip 0 (POS) */
- const GLuint attrBit = 1 << attr;
- if (fixup & attrBit) {
- if (!IM->Attrib[attr]) {
- IM->Attrib[attr] = (GLfloat (*)[4]) _mesa_malloc(IMM_SIZE * 4 * sizeof(GLfloat));
- if (!IM->Attrib[attr]) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "vertex processing");
- }
- }
- if (attr == VERT_ATTRIB_COLOR0) {
- /* special case, darn */
- if (IM->CopyOrFlag & VERT_BIT_COLOR0)
- fixup_first_4f(IM->Attrib[VERT_ATTRIB_COLOR0], IM->Flag,
- VERT_BIT_COLOR0, start,
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
- else
- fixup &= ~VERT_BIT_COLOR0;
- }
- else {
- fixup_first_4f(IM->Attrib[attr], IM->Flag,
- attrBit, start, ctx->Current.Attrib[attr] );
- }
- }
- }
-
- if (fixup & VERT_BIT_EDGEFLAG)
- fixup_first_1ub(IM->EdgeFlag, IM->Flag, VERT_BIT_EDGEFLAG, start,
- ctx->Current.EdgeFlag );
-
- if (fixup & VERT_BIT_INDEX)
- fixup_first_1ui(IM->Index, IM->Flag, VERT_BIT_INDEX, start,
- ctx->Current.Index );
-
- IM->CopyOrFlag |= fixup;
- }
-
-
- /* Materials:
- */
- if (IM->MaterialOrMask & ~IM->MaterialAndMask) {
- GLuint vulnerable = IM->MaterialOrMask;
- GLuint i = IM->Start;
-
- do {
- while (!(IM->Flag[i] & VERT_BIT_MATERIAL))
- i++;
-
- vulnerable &= ~IM->MaterialMask[i];
- _mesa_copy_materials( &IM->Material[i],
- &ctx->Light.Material,
- vulnerable );
-
-
- ++i;
- } while (vulnerable);
- }
-}
-
-
-
-static void
-copy_none( TNLcontext *tnl, GLuint start, GLuint count, GLuint ovf)
-{
- (void) (start && ovf && tnl && count);
-}
-
-static void
-copy_last( TNLcontext *tnl, GLuint start, GLuint count, GLuint ovf)
-{
- (void) start; (void) ovf;
- tnl->ExecCopyCount = 1;
- tnl->ExecCopyElts[2] = count-1;
-}
-
-static void
-copy_first_and_last( TNLcontext *tnl, GLuint start, GLuint count, GLuint ovf)
-{
- (void) ovf;
- tnl->ExecCopyCount = 2;
- tnl->ExecCopyElts[1] = start;
- tnl->ExecCopyElts[2] = count-1;
-}
-
-static void
-copy_last_three( TNLcontext *tnl, GLuint start, GLuint count, GLuint ovf )
-{
- (void) start;
- tnl->ExecCopyCount = 2+ovf;
- tnl->ExecCopyElts[0] = count-3;
- tnl->ExecCopyElts[1] = count-2;
- tnl->ExecCopyElts[2] = count-1;
-}
-
-static void
-copy_overflow( TNLcontext *tnl, GLuint start, GLuint count, GLuint ovf )
-{
- (void) start;
- tnl->ExecCopyCount = ovf;
- tnl->ExecCopyElts[0] = count-3;
- tnl->ExecCopyElts[1] = count-2;
- tnl->ExecCopyElts[2] = count-1;
-}
-
-
-typedef void (*copy_func)( TNLcontext *tnl, GLuint start, GLuint count,
- GLuint ovf );
-
-static copy_func copy_tab[GL_POLYGON+2] =
-{
- copy_none, /* GL_POINTS */
- copy_overflow, /* GL_LINES */
- copy_first_and_last, /* GL_LINE_LOOP */
- copy_last, /* GL_LINE_STRIP */
- copy_overflow, /* GL_TRIANGLES */
- copy_last_three, /* GL_TRIANGLE_STRIP */
- copy_first_and_last, /* GL_TRIANGLE_FAN */
- copy_overflow, /* GL_QUADS */
- copy_last_three, /* GL_QUAD_STRIP */
- copy_first_and_last, /* GL_POLYGON */
- copy_none
-};
-
-
-
-/**
- * Figure out what vertices need to be copied next time.
- */
-void
-_tnl_get_exec_copy_verts( GLcontext *ctx, struct immediate *IM )
-{
-
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- GLuint last = IM->LastPrimitive;
- GLuint prim = ctx->Driver.CurrentExecPrimitive;
- GLuint pincr = increment[prim];
- GLuint pintro = intro[prim];
- GLuint ovf = 0;
-
-/* _mesa_debug(ctx, "_tnl_get_exec_copy_verts %s\n", */
-/* _mesa_lookup_enum_by_nr(prim)); */
-
- if (tnl->ExecCopySource)
- if (--tnl->ExecCopySource->ref_count == 0)
- _tnl_free_immediate( ctx, tnl->ExecCopySource );
-
- if (prim == GL_POLYGON+1) {
- tnl->ExecCopySource = 0;
- tnl->ExecCopyCount = 0;
- tnl->ExecCopyTexSize = 0;
- tnl->ExecParity = 0;
- }
- else {
- /* Remember this immediate as the one to copy from.
- */
- tnl->ExecCopySource = IM; IM->ref_count++;
- tnl->ExecCopyCount = 0;
- tnl->ExecCopyTexSize = IM->CopyTexSize;
-
- if (IM->LastPrimitive != IM->CopyStart)
- tnl->ExecParity = 0;
-
- tnl->ExecParity ^= IM->PrimitiveLength[IM->LastPrimitive] & 1;
-
-
- if (pincr != 1 && (IM->Count - last - pintro))
- ovf = (IM->Count - last - pintro) % pincr;
-
- if (last < IM->Count)
- copy_tab[prim]( tnl, last, IM->Count, ovf );
- }
-}
-
-
-/**
- * Recalculate ExecCopyElts, ExecParity, etc.
- */
-void
-_tnl_get_purged_copy_verts( GLcontext *ctx, struct immediate *IM )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
-
- if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) {
- GLuint last = IM->LastPrimitive;
- GLenum prim = IM->Primitive[last];
- GLuint pincr = increment[prim];
- GLuint pintro = intro[prim];
- GLuint ovf = 0, i;
-
- tnl->ExecCopyCount = 0;
- if (IM->LastPrimitive != IM->CopyStart)
- tnl->ExecParity = 0;
-
- tnl->ExecParity ^= IM->PrimitiveLength[IM->LastPrimitive] & 1;
-
- if (pincr != 1 && (IM->Count - last - pintro))
- ovf = (IM->Count - last - pintro) % pincr;
-
- if (last < IM->Count)
- copy_tab[prim]( tnl, last, IM->Count, ovf );
-
- for (i = 0 ; i < tnl->ExecCopyCount ; i++)
- tnl->ExecCopyElts[i] = IM->Elt[tnl->ExecCopyElts[i]];
- }
-}
-
-
-/**
- * Called via the VB->import_data function pointer.
- */
-void
-_tnl_upgrade_current_data( GLcontext *ctx, GLuint required, GLuint flags )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- struct vertex_buffer *VB = &tnl->vb;
- struct immediate *IM = (struct immediate *)VB->import_source;
-
- ASSERT(IM);
-
-/* _tnl_print_vert_flags("_tnl_upgrade_client_data", required); */
-
- if ((required & VERT_BIT_COLOR0) && (VB->ColorPtr[0]->Flags & CA_CLIENT_DATA)) {
- struct gl_client_array *tmp = &tnl->imm_inputs.Color;
- GLuint start = IM->CopyStart;
-
- tmp->Ptr = (GLubyte *) (IM->Attrib[VERT_ATTRIB_COLOR0] + start);
- tmp->StrideB = 4 * sizeof(GLfloat);
- tmp->Flags = 0;
-
- COPY_4FV( IM->Attrib[VERT_ATTRIB_COLOR0][start],
- ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
-
- /*
- ASSERT(IM->Flag[IM->LastData+1] & VERT_BIT_END_VB);
- */
-
- fixup_first_4f( IM->Attrib[VERT_ATTRIB_COLOR0], IM->Flag,
- VERT_BIT_END_VB,
- start, IM->Attrib[VERT_ATTRIB_COLOR0][start] );
-
- VB->importable_data &= ~VERT_BIT_COLOR0;
- }
-}
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 5.1
- *
- * Copyright (C) 1999-2003 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.
- */
-
-
-#ifndef _T_IMM_FIXUP_H
-#define _T_IMM_FIXUP_H
-
-#include "mtypes.h"
-#include "t_context.h"
-
-extern void _tnl_fixup_1ub( GLubyte *data, GLuint flag[],
- GLuint start, GLuint match );
-
-extern void _tnl_fixup_1ui( GLuint *data, GLuint flag[],
- GLuint start, GLuint match );
-
-extern void _tnl_fixup_4f( GLfloat data[][4], const GLuint flag[],
- GLuint start, GLuint match );
-
-extern void _tnl_fixup_input( GLcontext *ctx, struct immediate *IM );
-
-extern void _tnl_fixup_compiled_cassette( GLcontext *ctx,
- struct immediate *IM );
-
-extern void _tnl_copy_immediate_vertices( GLcontext *ctx,
- struct immediate *IM );
-
-extern void _tnl_get_purged_copy_verts( GLcontext *ctx, struct immediate *IM );
-
-extern void _tnl_get_exec_copy_verts( GLcontext *ctx, struct immediate *IM );
-
-extern void _tnl_upgrade_current_data( GLcontext *ctx, GLuint required,
- GLuint flags );
-
-#endif
void _tnl_install_pipeline( GLcontext *ctx,
- const struct gl_pipeline_stage **stages )
+ const struct tnl_pipeline_stage **stages )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
- struct gl_pipeline *pipe = &tnl->pipeline;
+ struct tnl_pipeline *pipe = &tnl->pipeline;
GLuint i;
ASSERT(pipe->nr_stages == 0);
void _tnl_validate_pipeline( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
- struct gl_pipeline *pipe = &tnl->pipeline;
- struct gl_pipeline_stage *s = pipe->stages;
+ struct tnl_pipeline *pipe = &tnl->pipeline;
+ struct tnl_pipeline_stage *s = pipe->stages;
GLuint newstate = pipe->build_state_changes;
GLuint generated = 0;
GLuint changed_inputs = 0;
void _tnl_run_pipeline( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
- struct vertex_buffer *VB = &tnl->vb;
- struct gl_pipeline *pipe = &tnl->pipeline;
- struct gl_pipeline_stage *s = pipe->stages;
+ struct tnl_pipeline *pipe = &tnl->pipeline;
+ struct tnl_pipeline_stage *s = pipe->stages;
GLuint changed_state = pipe->run_state_changes;
GLuint changed_inputs = pipe->run_input_changes;
GLboolean running = GL_TRUE;
running = s->run( ctx, s );
s->changed_inputs = 0;
- VB->importable_data &= ~s->outputs;
}
}
*
* - inserting optimized (but specialized) stages ahead of the
* general-purpose fallback implementation. For example, the old
- * fastpath mechanism, which only works when the VERT_BIT_ELT input is
+ * fastpath mechanism, which only works when the VB->Elts input is
* available, can be duplicated by placing the fastpath stage at the
* head of this pipeline. Such specialized stages are currently
* constrained to have no outputs (ie. they must either finish the *
* Some work can be done to lift some of the restrictions in the final
* case, if it becomes necessary to do so.
*/
-const struct gl_pipeline_stage *_tnl_default_pipeline[] = {
+const struct tnl_pipeline_stage *_tnl_default_pipeline[] = {
&_tnl_vertex_transform_stage,
&_tnl_normal_transform_stage,
&_tnl_lighting_stage,
extern void _tnl_destroy_pipeline( GLcontext *ctx );
extern void _tnl_install_pipeline( GLcontext *ctx,
- const struct gl_pipeline_stage **stages );
+ const struct tnl_pipeline_stage **stages );
/* These are implemented in the t_vb_*.c files:
*/
-extern const struct gl_pipeline_stage _tnl_vertex_transform_stage;
-extern const struct gl_pipeline_stage _tnl_normal_transform_stage;
-extern const struct gl_pipeline_stage _tnl_lighting_stage;
-extern const struct gl_pipeline_stage _tnl_fog_coordinate_stage;
-extern const struct gl_pipeline_stage _tnl_texgen_stage;
-extern const struct gl_pipeline_stage _tnl_texture_transform_stage;
-extern const struct gl_pipeline_stage _tnl_point_attenuation_stage;
-extern const struct gl_pipeline_stage _tnl_vertex_program_stage;
-extern const struct gl_pipeline_stage _tnl_render_stage;
+extern const struct tnl_pipeline_stage _tnl_vertex_transform_stage;
+extern const struct tnl_pipeline_stage _tnl_normal_transform_stage;
+extern const struct tnl_pipeline_stage _tnl_lighting_stage;
+extern const struct tnl_pipeline_stage _tnl_fog_coordinate_stage;
+extern const struct tnl_pipeline_stage _tnl_texgen_stage;
+extern const struct tnl_pipeline_stage _tnl_texture_transform_stage;
+extern const struct tnl_pipeline_stage _tnl_point_attenuation_stage;
+extern const struct tnl_pipeline_stage _tnl_vertex_program_stage;
+extern const struct tnl_pipeline_stage _tnl_render_stage;
/* Shorthand to plug in the default pipeline:
*/
-extern const struct gl_pipeline_stage *_tnl_default_pipeline[];
+extern const struct tnl_pipeline_stage *_tnl_default_pipeline[];
/* Convenience routines provided by t_vb_render.c:
--- /dev/null
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas.
+
+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
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, 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 (including the next
+paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS 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 <keith@tungstengraphics.com>
+ */
+
+
+
+/* Display list compiler attempts to store lists of vertices with the
+ * same vertex layout. Additionally it attempts to minimize the need
+ * for execute-time fixup of these vertex lists, allowing them to be
+ * cached on hardware.
+ *
+ * There are still some circumstances where this can be thwarted, for
+ * example by building a list that consists of one very long primitive
+ * (eg Begin(Triangles), 1000 vertices, End), and calling that list
+ * from inside a different begin/end object (Begin(Lines), CallList,
+ * End).
+ *
+ * In that case the code will have to replay the list as individual
+ * commands through the Exec dispatch table, or fix up the copied
+ * vertices at execute-time.
+ *
+ * The other case where fixup is required is when a vertex attribute
+ * is introduced in the middle of a primitive. Eg:
+ * Begin(Lines)
+ * TexCoord1f() Vertex2f()
+ * TexCoord1f() Color3f() Vertex2f()
+ * End()
+ *
+ * If the current value of Color isn't known at compile-time, this
+ * primitive will require fixup.
+ *
+ *
+ * The list compiler currently doesn't attempt to compile lists
+ * containing EvalCoord or EvalPoint commands. On encountering one of
+ * these, compilation falls back to opcodes.
+ *
+ * This could be improved to fallback only when a mix of EvalCoord and
+ * Vertex commands are issued within a single primitive.
+ */
+
+
+#include "context.h"
+#include "dlist.h"
+#include "enums.h"
+#include "macros.h"
+#include "api_validate.h"
+#include "api_arrayelt.h"
+#include "vtxfmt.h"
+#include "t_save_api.h"
+
+/*
+ * NOTE: Old 'parity' issue is gone, but copying can still be
+ * wrong-footed on replay.
+ */
+static GLuint _save_copy_vertices( GLcontext *ctx,
+ struct tnl_vertex_list *node )
+{
+ TNLcontext *tnl = TNL_CONTEXT( ctx );
+ struct tnl_prim *prim = &node->prim[node->prim_count-1];
+ GLuint nr = prim->count;
+ GLuint sz = tnl->save.vertex_size;
+ GLfloat *src = node->buffer + prim->start * sz;
+ GLfloat *dst = tnl->save.copied.buffer;
+ GLuint ovf, i;
+
+ if (prim->mode & PRIM_END)
+ return 0;
+
+ switch( prim->mode & PRIM_MODE_MASK )
+ {
+ case GL_POINTS:
+ return 0;
+ case GL_LINES:
+ ovf = nr&1;
+ for (i = 0 ; i < ovf ; i++)
+ memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) );
+ return i;
+ case GL_TRIANGLES:
+ ovf = nr%3;
+ for (i = 0 ; i < ovf ; i++)
+ memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) );
+ return i;
+ case GL_QUADS:
+ ovf = nr&3;
+ for (i = 0 ; i < ovf ; i++)
+ memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) );
+ return i;
+ case GL_LINE_STRIP:
+ if (nr == 0)
+ return 0;
+ else {
+ memcpy( dst, src+(nr-1)*sz, sz*sizeof(GLfloat) );
+ return 1;
+ }
+ case GL_LINE_LOOP:
+ case GL_TRIANGLE_FAN:
+ case GL_POLYGON:
+ if (nr == 0)
+ return 0;
+ else if (nr == 1) {
+ memcpy( dst, src+0, sz*sizeof(GLfloat) );
+ return 1;
+ } else {
+ memcpy( dst, src+0, sz*sizeof(GLfloat) );
+ memcpy( dst+sz, src+(nr-1)*sz, sz*sizeof(GLfloat) );
+ return 2;
+ }
+ case GL_TRIANGLE_STRIP:
+ case GL_QUAD_STRIP:
+ switch (nr) {
+ case 0: ovf = 0; break;
+ case 1: ovf = 1; break;
+ default: ovf = 2 + (nr&1); break;
+ }
+ for (i = 0 ; i < ovf ; i++)
+ memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) );
+ return i;
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
+
+static void
+build_normal_lengths( struct tnl_vertex_list *node )
+{
+ GLuint i;
+ GLfloat *len;
+ GLfloat *n = node->buffer;
+ GLuint stride = node->vertex_size;
+ GLuint count = node->count;
+
+ len = node->normal_lengths = MALLOC( count * sizeof(GLfloat) );
+ if (!len)
+ return;
+
+ /* Find the normal of the first vertex:
+ */
+ for (i = 0 ; i < _TNL_ATTRIB_NORMAL ; i++)
+ n += node->attrsz[i];
+
+ for (i = 0 ; i < count ; i++, n += stride) {
+ len[i] = LEN_3FV( n );
+ if (len[i] > 0.0F) len[i] = 1.0F / len[i];
+ }
+}
+
+static struct tnl_vertex_store *alloc_vertex_store( GLcontext *ctx )
+{
+ struct tnl_vertex_store *store = MALLOC( sizeof(*store) );
+ store->used = 0;
+ store->refcount = 1;
+ return store;
+}
+
+static struct tnl_primitive_store *alloc_prim_store( GLcontext *ctx )
+{
+ struct tnl_primitive_store *store = MALLOC( sizeof(*store) );
+ store->used = 0;
+ store->refcount = 1;
+ return store;
+}
+
+static void _save_reset_counters( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+ tnl->save.prim = tnl->save.prim_store->buffer + tnl->save.prim_store->used;
+ tnl->save.buffer = (tnl->save.vertex_store->buffer +
+ tnl->save.vertex_store->used);
+
+ if (tnl->save.vertex_size)
+ tnl->save.initial_counter = ((SAVE_BUFFER_SIZE -
+ tnl->save.vertex_store->used) /
+ tnl->save.vertex_size);
+ else
+ tnl->save.initial_counter = 0;
+
+ if (tnl->save.initial_counter > ctx->Const.MaxArrayLockSize )
+ tnl->save.initial_counter = ctx->Const.MaxArrayLockSize;
+
+ tnl->save.counter = tnl->save.initial_counter;
+ tnl->save.prim_count = 0;
+ tnl->save.prim_max = SAVE_PRIM_SIZE - tnl->save.prim_store->used;
+ tnl->save.copied.nr = 0;
+ tnl->save.dangling_attr_ref = 0;
+}
+
+
+/* Insert the active immediate struct onto the display list currently
+ * being built.
+ */
+static void _save_compile_vertex_list( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct tnl_vertex_list *node;
+
+ /* Allocate space for this structure in the display list currently
+ * being compiled.
+ */
+ node = (struct tnl_vertex_list *)
+ _mesa_alloc_instruction(ctx, tnl->save.opcode_vertex_list, sizeof(*node));
+
+ if (!node)
+ return;
+
+ /* Duplicate our template, increment refcounts to the storage structs:
+ */
+ memcpy(node->attrsz, tnl->save.attrsz, sizeof(node->attrsz));
+ node->vertex_size = tnl->save.vertex_size;
+ node->buffer = tnl->save.buffer;
+ node->wrap_count = tnl->save.copied.nr;
+ node->count = tnl->save.initial_counter - tnl->save.counter;
+ node->prim = tnl->save.prim;
+ node->prim_count = tnl->save.prim_count;
+ node->vertex_store = tnl->save.vertex_store;
+ node->prim_store = tnl->save.prim_store;
+ node->dangling_attr_ref = tnl->save.dangling_attr_ref;
+ node->normal_lengths = 0;
+
+ node->vertex_store->refcount++;
+ node->prim_store->refcount++;
+
+ assert(node->attrsz[_TNL_ATTRIB_POS] != 0);
+
+ /* Maybe calculate normal lengths:
+ */
+ if (tnl->CalcDListNormalLengths &&
+ node->attrsz[_TNL_ATTRIB_NORMAL] == 3 &&
+ !node->dangling_attr_ref)
+ build_normal_lengths( node );
+
+ tnl->save.vertex_store->used += tnl->save.vertex_size * node->count;
+ tnl->save.prim_store->used += node->prim_count;
+
+ /* Decide whether the storage structs are full, or can be used for
+ * the next vertex lists as well.
+ */
+ if (tnl->save.vertex_store->used >
+ SAVE_BUFFER_SIZE - 16 * (tnl->save.vertex_size + 4)) {
+
+ tnl->save.vertex_store->refcount--;
+ assert(tnl->save.vertex_store->refcount != 0);
+ tnl->save.vertex_store = alloc_vertex_store( ctx );
+ tnl->save.vbptr = tnl->save.vertex_store->buffer;
+ }
+
+ if (tnl->save.prim_store->used > SAVE_PRIM_SIZE - 6) {
+ tnl->save.prim_store->refcount--;
+ assert(tnl->save.prim_store->refcount != 0);
+ tnl->save.prim_store = alloc_prim_store( ctx );
+ }
+
+ /* Reset our structures for the next run of vertices:
+ */
+ _save_reset_counters( ctx );
+
+ /* Copy duplicated vertices
+ */
+ tnl->save.copied.nr = _save_copy_vertices( ctx, node );
+
+
+ /* Deal with GL_COMPILE_AND_EXECUTE:
+ */
+ if (ctx->ExecuteFlag) {
+ _tnl_playback_vertex_list( ctx, (void *)node );
+ }
+}
+
+
+/* TODO -- If no new vertices have been stored, don't bother saving
+ * it.
+ */
+static void _save_wrap_buffers( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLint i = tnl->save.prim_count - 1;
+ GLenum mode;
+
+ assert(i < tnl->save.prim_max);
+ assert(i >= 0);
+
+ /* Close off in-progress primitive.
+ */
+ tnl->save.prim[i].count = ((tnl->save.initial_counter - tnl->save.counter) -
+ tnl->save.prim[i].start);
+ mode = tnl->save.prim[i].mode & ~(PRIM_BEGIN|PRIM_END);
+
+ /* store the copied vertices, and allocate a new list.
+ */
+ _save_compile_vertex_list( ctx );
+
+ /* Restart interrupted primitive
+ */
+ tnl->save.prim[0].mode = mode;
+ tnl->save.prim[0].start = 0;
+ tnl->save.prim[0].count = 0;
+ tnl->save.prim_count = 1;
+}
+
+
+
+/* Called only when buffers are wrapped as the result of filling the
+ * vertex_store struct.
+ */
+static void _save_wrap_filled_vertex( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLfloat *data = tnl->save.copied.buffer;
+ int i;
+
+ /* Emit a glEnd to close off the last vertex list.
+ */
+ _save_wrap_buffers( ctx );
+
+ /* Copy stored stored vertices to start of new list.
+ */
+ assert(tnl->save.counter > tnl->save.copied.nr);
+
+ for (i = 0 ; i < tnl->save.copied.nr ; i++) {
+ memcpy( tnl->save.vbptr, data, tnl->save.vertex_size * sizeof(GLfloat));
+ data += tnl->save.vertex_size;
+ tnl->save.vbptr += tnl->save.vertex_size;
+ tnl->save.counter--;
+ }
+}
+
+
+static void _save_copy_to_current( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLuint i;
+
+ for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_INDEX ; i++) {
+ if (tnl->save.attrsz[i]) {
+ tnl->save.currentsz[i][0] = tnl->save.attrsz[i];
+ ASSIGN_4V(tnl->save.current[i], 0, 0, 0, 1);
+ COPY_SZ_4V(tnl->save.current[i],
+ tnl->save.attrsz[i],
+ tnl->save.attrptr[i]);
+ }
+ }
+
+ /* Edgeflag requires special treatment:
+ */
+ if (tnl->save.attrsz[_TNL_ATTRIB_EDGEFLAG]) {
+ ctx->ListState.ActiveEdgeFlag = 1;
+ ctx->ListState.CurrentEdgeFlag =
+ (tnl->save.attrptr[_TNL_ATTRIB_EDGEFLAG][0] == 1.0);
+ }
+}
+
+
+static void _save_copy_from_current( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLint i;
+
+ for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_INDEX ; i++)
+ switch (tnl->save.attrsz[i]) {
+ case 4: tnl->save.attrptr[i][3] = tnl->save.current[i][3];
+ case 3: tnl->save.attrptr[i][2] = tnl->save.current[i][2];
+ case 2: tnl->save.attrptr[i][1] = tnl->save.current[i][1];
+ case 1: tnl->save.attrptr[i][0] = tnl->save.current[i][0];
+ case 0: break;
+ }
+
+ /* Edgeflag requires special treatment:
+ */
+ if (tnl->save.attrsz[_TNL_ATTRIB_EDGEFLAG])
+ tnl->save.attrptr[_TNL_ATTRIB_EDGEFLAG][0] =
+ (GLfloat)ctx->ListState.CurrentEdgeFlag;
+}
+
+
+
+
+/* Flush existing data, set new attrib size, replay copied vertices.
+ */
+static void _save_upgrade_vertex( GLcontext *ctx,
+ GLuint attr,
+ GLuint newsz )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLuint oldsz;
+ GLuint i;
+ GLfloat *tmp;
+
+ /* Store the current run of vertices, and emit a GL_END. Emit a
+ * BEGIN in the new buffer.
+ */
+ if (tnl->save.initial_counter != tnl->save.counter)
+ _save_wrap_buffers( ctx );
+ else
+ assert( tnl->save.copied.nr == 0 );
+
+ /* Do a COPY_TO_CURRENT to ensure back-copying works for the case
+ * when the attribute already exists in the vertex and is having
+ * its size increased.
+ */
+ _save_copy_to_current( ctx );
+
+ /* Fix up sizes:
+ */
+ oldsz = tnl->save.attrsz[attr];
+ tnl->save.attrsz[attr] = newsz;
+
+ tnl->save.vertex_size += newsz - oldsz;
+ tnl->save.counter = ((SAVE_BUFFER_SIZE - tnl->save.vertex_store->used) /
+ tnl->save.vertex_size);
+ tnl->save.initial_counter = tnl->save.counter;
+
+
+ /* Recalculate all the attrptr[] values:
+ */
+ for (i = 0, tmp = tnl->save.vertex ; i < _TNL_ATTRIB_MAX ; i++) {
+ if (tnl->save.attrsz[i]) {
+ tnl->save.attrptr[i] = tmp;
+ tmp += tnl->save.attrsz[i];
+ }
+ else
+ tnl->save.attrptr[i] = 0; /* will not be dereferenced. */
+ }
+
+ /* Copy from current to repopulate the vertex with correct values.
+ */
+ _save_copy_from_current( ctx );
+
+
+ /* Replay stored vertices to translate them to new format here.
+ *
+ * If there are copied vertices and the new (upgraded) attribute
+ * has not been defined before, this list is somewhat degenerate,
+ * and will need fixup at runtime.
+ */
+ if (tnl->save.copied.nr)
+ {
+ GLfloat *data = tnl->save.copied.buffer;
+ GLfloat *dest = tnl->save.buffer;
+ GLint j;
+
+ /* Need to note this and fix up at runtime (or loopback):
+ */
+ if (tnl->save.currentsz[attr] == 0) {
+ assert(oldsz == 0);
+ tnl->save.dangling_attr_ref = attr;
+ _mesa_debug(0, "%s: dangling reference attr %d\n",
+ __FUNCTION__, attr);
+
+#if 0
+ /* The current strategy is to punt these degenerate cases
+ * through _tnl_loopback_vertex_list(), a lower-performance
+ * option. To minimize the impact of this, artificially
+ * reduce the size of this vertex_list.
+ */
+ if (t->save.counter > 10) {
+ t->save.initial_counter = 10;
+ t->save.counter = 10;
+ }
+#endif
+ }
+
+ for (i = 0 ; i < tnl->save.copied.nr ; i++) {
+ for (j = 0 ; j < _TNL_ATTRIB_MAX ; j++) {
+ if (tnl->save.attrsz[j]) {
+ if (j == attr) {
+ ASSIGN_4V( dest, 0, 0, 0, 1 );
+ COPY_SZ_4V( dest, oldsz, data );
+ data += oldsz;
+ dest += newsz;
+ }
+ else {
+ GLint sz = tnl->save.attrsz[j];
+ COPY_SZ_4V( dest, sz, data );
+ data += sz;
+ dest += sz;
+ }
+ }
+ }
+ }
+
+ tnl->save.vbptr = dest;
+ tnl->save.counter -= tnl->save.copied.nr;
+ }
+}
+
+
+
+
+/* Helper function for 'CHOOSE' macro. Do what's necessary when an
+ * entrypoint is called for the first time.
+ */
+static void do_choose( GLuint attr, GLuint sz,
+ void (*attr_func)( const GLfloat *),
+ void (*choose1)( const GLfloat *),
+ void (*choose2)( const GLfloat *),
+ void (*choose3)( const GLfloat *),
+ void (*choose4)( const GLfloat *),
+ const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT( ctx );
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ static GLfloat id[4] = { 0, 0, 0, 1 };
+ int i;
+
+ if (tnl->save.attrsz[attr] < sz) {
+ /* New size is larger. Need to flush existing vertices and get
+ * an enlarged vertex format.
+ */
+ _save_upgrade_vertex( ctx, attr, sz );
+ }
+ else {
+ /* New size is equal or smaller - just need to fill in some
+ * zeros.
+ */
+ for (i = sz ; i <= tnl->save.attrsz[attr] ; i++)
+ tnl->save.attrptr[attr][i-1] = id[i-1];
+ }
+
+ /* Reset any active pointers for this attribute
+ */
+ tnl->save.tabfv[attr][0] = choose1;
+ tnl->save.tabfv[attr][1] = choose2;
+ tnl->save.tabfv[attr][2] = choose3;
+ tnl->save.tabfv[attr][3] = choose4;
+
+ /* Update the secondary dispatch table with the new function
+ */
+ tnl->save.tabfv[attr][sz-1] = attr_func;
+
+ (*attr_func)(v);
+}
+
+
+
+/* Only one size for each attribute may be active at once. Eg. if
+ * Color3f is installed/active, then Color4f may not be, even if the
+ * vertex actually contains 4 color coordinates. This is because the
+ * 3f version won't otherwise set color[3] to 1.0 -- this is the job
+ * of the chooser function when switching between Color4f and Color3f.
+ */
+#define ATTRFV( ATTR, N ) \
+static void save_choose_##ATTR##_##N( const GLfloat *v ); \
+ \
+static void save_attrib_##ATTR##_##N( const GLfloat *v ) \
+{ \
+ GET_CURRENT_CONTEXT( ctx ); \
+ TNLcontext *tnl = TNL_CONTEXT(ctx); \
+ \
+ if ((ATTR) == 0) { \
+ int i; \
+ \
+ if (N>0) tnl->save.vbptr[0] = v[0]; \
+ if (N>1) tnl->save.vbptr[1] = v[1]; \
+ if (N>2) tnl->save.vbptr[2] = v[2]; \
+ if (N>3) tnl->save.vbptr[3] = v[3]; \
+ \
+ for (i = N; i < tnl->save.vertex_size; i++) \
+ tnl->save.vbptr[i] = tnl->save.vertex[i]; \
+ \
+ tnl->save.vbptr += tnl->save.vertex_size; \
+ \
+ if (--tnl->save.counter == 0) \
+ _save_wrap_filled_vertex( ctx ); \
+ } \
+ else { \
+ GLfloat *dest = tnl->save.attrptr[ATTR]; \
+ if (N>0) dest[0] = v[0]; \
+ if (N>1) dest[1] = v[1]; \
+ if (N>2) dest[2] = v[2]; \
+ if (N>3) dest[3] = v[3]; \
+ } \
+}
+
+#define CHOOSE( ATTR, N ) \
+static void save_choose_##ATTR##_##N( const GLfloat *v ) \
+{ \
+ do_choose(ATTR, N, \
+ save_attrib_##ATTR##_##N, \
+ save_choose_##ATTR##_1, \
+ save_choose_##ATTR##_2, \
+ save_choose_##ATTR##_3, \
+ save_choose_##ATTR##_4, \
+ v ); \
+}
+
+#define INIT(ATTR) \
+static void save_init_##ATTR( TNLcontext *tnl ) \
+{ \
+ tnl->save.tabfv[ATTR][0] = save_choose_##ATTR##_1; \
+ tnl->save.tabfv[ATTR][1] = save_choose_##ATTR##_2; \
+ tnl->save.tabfv[ATTR][2] = save_choose_##ATTR##_3; \
+ tnl->save.tabfv[ATTR][3] = save_choose_##ATTR##_4; \
+}
+
+#define ATTRS( ATTRIB ) \
+ ATTRFV( ATTRIB, 1 ) \
+ ATTRFV( ATTRIB, 2 ) \
+ ATTRFV( ATTRIB, 3 ) \
+ ATTRFV( ATTRIB, 4 ) \
+ CHOOSE( ATTRIB, 1 ) \
+ CHOOSE( ATTRIB, 2 ) \
+ CHOOSE( ATTRIB, 3 ) \
+ CHOOSE( ATTRIB, 4 ) \
+ INIT( ATTRIB ) \
+
+
+/* Generate a lot of functions. These are the actual worker
+ * functions, which are equivalent to those generated via codegen
+ * elsewhere.
+ */
+ATTRS( 0 )
+ATTRS( 1 )
+ATTRS( 2 )
+ATTRS( 3 )
+ATTRS( 4 )
+ATTRS( 5 )
+ATTRS( 6 )
+ATTRS( 7 )
+ATTRS( 8 )
+ATTRS( 9 )
+ATTRS( 10 )
+ATTRS( 11 )
+ATTRS( 12 )
+ATTRS( 13 )
+ATTRS( 14 )
+ATTRS( 15 )
+
+
+static void _save_reset_vertex( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLuint i;
+
+ save_init_0( tnl );
+ save_init_1( tnl );
+ save_init_2( tnl );
+ save_init_3( tnl );
+ save_init_4( tnl );
+ save_init_5( tnl );
+ save_init_6( tnl );
+ save_init_7( tnl );
+ save_init_8( tnl );
+ save_init_9( tnl );
+ save_init_10( tnl );
+ save_init_11( tnl );
+ save_init_12( tnl );
+ save_init_13( tnl );
+ save_init_14( tnl );
+ save_init_15( tnl );
+
+ for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++)
+ tnl->save.attrsz[i] = 0;
+
+ tnl->save.vertex_size = 0;
+
+ _save_reset_counters( ctx );
+}
+
+
+
+/* Cope with aliasing of classic Vertex, Normal, etc. and the fan-out
+ * of glMultTexCoord and glProgramParamterNV by routing all these
+ * through a second level dispatch table.
+ */
+#define DISPATCH_ATTRFV( ATTR, COUNT, P ) \
+do { \
+ GET_CURRENT_CONTEXT( ctx ); \
+ TNLcontext *tnl = TNL_CONTEXT(ctx); \
+ tnl->save.tabfv[ATTR][COUNT-1]( P ); \
+} while (0)
+
+#define DISPATCH_ATTR1FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 1, V )
+#define DISPATCH_ATTR2FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 2, V )
+#define DISPATCH_ATTR3FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 3, V )
+#define DISPATCH_ATTR4FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 4, V )
+
+#define DISPATCH_ATTR1F( ATTR, S ) DISPATCH_ATTRFV( ATTR, 1, &(S) )
+
+#define DISPATCH_ATTR2F( ATTR, S,T ) \
+do { \
+ GLfloat v[2]; \
+ v[0] = S; v[1] = T; \
+ DISPATCH_ATTR2FV( ATTR, v ); \
+} while (0)
+#define DISPATCH_ATTR3F( ATTR, S,T,R ) \
+do { \
+ GLfloat v[3]; \
+ v[0] = S; v[1] = T; v[2] = R; \
+ DISPATCH_ATTR3FV( ATTR, v ); \
+} while (0)
+#define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) \
+do { \
+ GLfloat v[4]; \
+ v[0] = S; v[1] = T; v[2] = R; v[3] = Q; \
+ DISPATCH_ATTR4FV( ATTR, v ); \
+} while (0)
+
+
+static void enum_error( void )
+{
+ GET_CURRENT_CONTEXT( ctx );
+ _mesa_compile_error( ctx, GL_INVALID_ENUM, __FUNCTION__ );
+}
+
+static void _save_Vertex2f( GLfloat x, GLfloat y )
+{
+ DISPATCH_ATTR2F( _TNL_ATTRIB_POS, x, y );
+}
+
+static void _save_Vertex2fv( const GLfloat *v )
+{
+ DISPATCH_ATTR2FV( _TNL_ATTRIB_POS, v );
+}
+
+static void _save_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
+{
+ DISPATCH_ATTR3F( _TNL_ATTRIB_POS, x, y, z );
+}
+
+static void _save_Vertex3fv( const GLfloat *v )
+{
+ DISPATCH_ATTR3FV( _TNL_ATTRIB_POS, v );
+}
+
+static void _save_Vertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
+{
+ DISPATCH_ATTR4F( _TNL_ATTRIB_POS, x, y, z, w );
+}
+
+static void _save_Vertex4fv( const GLfloat *v )
+{
+ DISPATCH_ATTR4FV( _TNL_ATTRIB_POS, v );
+}
+
+static void _save_TexCoord1f( GLfloat x )
+{
+ DISPATCH_ATTR1F( _TNL_ATTRIB_TEX0, x );
+}
+
+static void _save_TexCoord1fv( const GLfloat *v )
+{
+ DISPATCH_ATTR1FV( _TNL_ATTRIB_TEX0, v );
+}
+
+static void _save_TexCoord2f( GLfloat x, GLfloat y )
+{
+ DISPATCH_ATTR2F( _TNL_ATTRIB_TEX0, x, y );
+}
+
+static void _save_TexCoord2fv( const GLfloat *v )
+{
+ DISPATCH_ATTR2FV( _TNL_ATTRIB_TEX0, v );
+}
+
+static void _save_TexCoord3f( GLfloat x, GLfloat y, GLfloat z )
+{
+ DISPATCH_ATTR3F( _TNL_ATTRIB_TEX0, x, y, z );
+}
+
+static void _save_TexCoord3fv( const GLfloat *v )
+{
+ DISPATCH_ATTR3FV( _TNL_ATTRIB_TEX0, v );
+}
+
+static void _save_TexCoord4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
+{
+ DISPATCH_ATTR4F( _TNL_ATTRIB_TEX0, x, y, z, w );
+}
+
+static void _save_TexCoord4fv( const GLfloat *v )
+{
+ DISPATCH_ATTR4FV( _TNL_ATTRIB_TEX0, v );
+}
+
+static void _save_Normal3f( GLfloat x, GLfloat y, GLfloat z )
+{
+ DISPATCH_ATTR3F( _TNL_ATTRIB_NORMAL, x, y, z );
+}
+
+static void _save_Normal3fv( const GLfloat *v )
+{
+ DISPATCH_ATTR3FV( _TNL_ATTRIB_NORMAL, v );
+}
+
+static void _save_FogCoordfEXT( GLfloat x )
+{
+ DISPATCH_ATTR1F( _TNL_ATTRIB_FOG, x );
+}
+
+static void _save_FogCoordfvEXT( const GLfloat *v )
+{
+ DISPATCH_ATTR1FV( _TNL_ATTRIB_FOG, v );
+}
+
+static void _save_Color3f( GLfloat x, GLfloat y, GLfloat z )
+{
+ DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR0, x, y, z );
+}
+
+static void _save_Color3fv( const GLfloat *v )
+{
+ DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR0, v );
+}
+
+static void _save_Color4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
+{
+ DISPATCH_ATTR4F( _TNL_ATTRIB_COLOR0, x, y, z, w );
+}
+
+static void _save_Color4fv( const GLfloat *v )
+{
+ DISPATCH_ATTR4FV( _TNL_ATTRIB_COLOR0, v );
+}
+
+static void _save_SecondaryColor3fEXT( GLfloat x, GLfloat y, GLfloat z )
+{
+ DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR1, x, y, z );
+}
+
+static void _save_SecondaryColor3fvEXT( const GLfloat *v )
+{
+ DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR1, v );
+}
+
+static void _save_MultiTexCoord1f( GLenum target, GLfloat x )
+{
+ GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
+ DISPATCH_ATTR1F( attr, x );
+}
+
+static void _save_MultiTexCoord1fv( GLenum target, const GLfloat *v )
+{
+ GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
+ DISPATCH_ATTR1FV( attr, v );
+}
+
+static void _save_MultiTexCoord2f( GLenum target, GLfloat x, GLfloat y )
+{
+ GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
+ DISPATCH_ATTR2F( attr, x, y );
+}
+
+static void _save_MultiTexCoord2fv( GLenum target, const GLfloat *v )
+{
+ GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
+ DISPATCH_ATTR2FV( attr, v );
+}
+
+static void _save_MultiTexCoord3f( GLenum target, GLfloat x, GLfloat y,
+ GLfloat z)
+{
+ GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
+ DISPATCH_ATTR3F( attr, x, y, z );
+}
+
+static void _save_MultiTexCoord3fv( GLenum target, const GLfloat *v )
+{
+ GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
+ DISPATCH_ATTR3FV( attr, v );
+}
+
+static void _save_MultiTexCoord4f( GLenum target, GLfloat x, GLfloat y,
+ GLfloat z, GLfloat w )
+{
+ GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
+ DISPATCH_ATTR4F( attr, x, y, z, w );
+}
+
+static void _save_MultiTexCoord4fv( GLenum target, const GLfloat *v )
+{
+ GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
+ DISPATCH_ATTR4FV( attr, v );
+}
+
+static void _save_VertexAttrib1fNV( GLuint index, GLfloat x )
+{
+ if (index >= VERT_ATTRIB_POS && index < VERT_ATTRIB_MAX)
+ DISPATCH_ATTR1F( index, x );
+ else
+ enum_error();
+}
+
+static void _save_VertexAttrib1fvNV( GLuint index, const GLfloat *v )
+{
+ if (index >= VERT_ATTRIB_POS && index < VERT_ATTRIB_MAX)
+ DISPATCH_ATTR1FV( index, v );
+ else
+ enum_error();
+}
+
+static void _save_VertexAttrib2fNV( GLuint index, GLfloat x, GLfloat y )
+{
+ if (index >= VERT_ATTRIB_POS && index < VERT_ATTRIB_MAX)
+ DISPATCH_ATTR2F( index, x, y );
+ else
+ enum_error();
+}
+
+static void _save_VertexAttrib2fvNV( GLuint index, const GLfloat *v )
+{
+ if (index >= VERT_ATTRIB_POS && index < VERT_ATTRIB_MAX)
+ DISPATCH_ATTR2FV( index, v );
+ else
+ enum_error();
+}
+
+static void _save_VertexAttrib3fNV( GLuint index, GLfloat x, GLfloat y,
+ GLfloat z )
+{
+ if (index >= VERT_ATTRIB_POS && index < VERT_ATTRIB_MAX)
+ DISPATCH_ATTR3F( index, x, y, z );
+ else
+ enum_error();
+}
+
+static void _save_VertexAttrib3fvNV( GLuint index, const GLfloat *v )
+{
+ if (index >= VERT_ATTRIB_POS && index < VERT_ATTRIB_MAX)
+ DISPATCH_ATTR3FV( index, v );
+ else
+ enum_error();
+}
+
+static void _save_VertexAttrib4fNV( GLuint index, GLfloat x, GLfloat y,
+ GLfloat z, GLfloat w )
+{
+ if (index >= VERT_ATTRIB_POS && index < VERT_ATTRIB_MAX)
+ DISPATCH_ATTR4F( index, x, y, z, w );
+ else
+ enum_error();
+}
+
+static void _save_VertexAttrib4fvNV( GLuint index, const GLfloat *v )
+{
+ if (index >= VERT_ATTRIB_POS && index < VERT_ATTRIB_MAX)
+ DISPATCH_ATTR4FV( index, v );
+ else
+ enum_error();
+}
+
+
+/* Materials:
+ *
+ * These are treated as per-vertex attributes, at indices above where
+ * the NV_vertex_program leaves off. There are a lot of good things
+ * about treating materials this way.
+ *
+ * However: I don't want to double the number of generated functions
+ * just to cope with this, so I unroll the 'C' varients of CHOOSE and
+ * ATTRF into this function, and dispense with codegen and
+ * second-level dispatch.
+ *
+ * There is no aliasing of material attributes with other entrypoints.
+ */
+#define MAT_ATTR( A, N, params ) \
+do { \
+ if (tnl->save.attrsz[A] < N) { \
+ _save_upgrade_vertex( ctx, A, N ); \
+ } \
+ \
+ { \
+ GLfloat *dest = tnl->save.attrptr[A]; \
+ if (N>0) dest[0] = params[0]; \
+ if (N>1) dest[1] = params[1]; \
+ if (N>2) dest[2] = params[2]; \
+ if (N>3) dest[3] = params[3]; \
+ } \
+} while (0)
+
+
+#define MAT( ATTR, N, face, params ) \
+do { \
+ if (face != GL_BACK) \
+ MAT_ATTR( ATTR, N, params ); /* front */ \
+ if (face != GL_FRONT) \
+ MAT_ATTR( ATTR + 1, N, params ); /* back */ \
+} while (0)
+
+
+/* NOTE: Have to remove/deal-with colormaterial crossovers, probably
+ * later on - in the meantime just store everything.
+ */
+static void _save_Materialfv( GLenum face, GLenum pname,
+ const GLfloat *params )
+{
+ GET_CURRENT_CONTEXT( ctx );
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+ switch (pname) {
+ case GL_EMISSION:
+ MAT( _TNL_ATTRIB_MAT_FRONT_EMISSION, 4, face, params );
+ break;
+ case GL_AMBIENT:
+ MAT( _TNL_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params );
+ break;
+ case GL_DIFFUSE:
+ MAT( _TNL_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params );
+ break;
+ case GL_SPECULAR:
+ MAT( _TNL_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params );
+ break;
+ case GL_SHININESS:
+ MAT( _TNL_ATTRIB_MAT_FRONT_SHININESS, 1, face, params );
+ break;
+ case GL_COLOR_INDEXES:
+ MAT( _TNL_ATTRIB_MAT_FRONT_INDEXES, 3, face, params );
+ break;
+ case GL_AMBIENT_AND_DIFFUSE:
+ MAT( _TNL_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params );
+ MAT( _TNL_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params );
+ break;
+ default:
+ _mesa_compile_error( ctx, GL_INVALID_ENUM, __FUNCTION__ );
+ return;
+ }
+}
+
+
+#define IDX_ATTR( A, IDX ) \
+do { \
+ GET_CURRENT_CONTEXT( ctx ); \
+ TNLcontext *tnl = TNL_CONTEXT(ctx); \
+ \
+ if (tnl->save.attrsz[A] < 1) { \
+ _save_upgrade_vertex( ctx, A, 1 ); \
+ } \
+ \
+ { \
+ GLfloat *dest = tnl->save.attrptr[A]; \
+ dest[0] = IDX; \
+ } \
+} while (0)
+
+
+static void _save_EdgeFlag( GLboolean b )
+{
+ IDX_ATTR( _TNL_ATTRIB_EDGEFLAG, (GLfloat)b );
+}
+
+static void _save_EdgeFlagv( const GLboolean *v )
+{
+ IDX_ATTR( _TNL_ATTRIB_EDGEFLAG, (GLfloat)(v[0]) );
+}
+
+static void _save_Indexf( GLfloat f )
+{
+ IDX_ATTR( _TNL_ATTRIB_INDEX, f );
+}
+
+static void _save_Indexfv( const GLfloat *f )
+{
+ IDX_ATTR( _TNL_ATTRIB_INDEX, f[0] );
+}
+
+
+
+
+/* Cope with EvalCoord/CallList called within a begin/end object:
+ * -- Flush current buffer
+ * -- Fallback to opcodes for the rest of the begin/end object.
+ */
+#define FALLBACK(ctx) \
+do { \
+ TNLcontext *tnl = TNL_CONTEXT(ctx); \
+ \
+ fprintf(stderr, "fallback %s inside begin/end\n", __FUNCTION__); \
+ \
+ if (tnl->save.initial_counter != tnl->save.counter || \
+ tnl->save.prim_count) \
+ _save_compile_vertex_list( ctx ); \
+ \
+ _save_copy_to_current( ctx ); \
+ _save_reset_vertex( ctx ); \
+ _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); \
+ ctx->Driver.SaveNeedFlush = 0; \
+} while (0)
+
+static void _save_EvalCoord1f( GLfloat u )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FALLBACK(ctx);
+ ctx->Save->EvalCoord1f( u );
+}
+
+static void _save_EvalCoord1fv( const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FALLBACK(ctx);
+ ctx->Save->EvalCoord1fv( v );
+}
+
+static void _save_EvalCoord2f( GLfloat u, GLfloat v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FALLBACK(ctx);
+ ctx->Save->EvalCoord2f( u, v );
+}
+
+static void _save_EvalCoord2fv( const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FALLBACK(ctx);
+ ctx->Save->EvalCoord2fv( v );
+}
+
+static void _save_EvalPoint1( GLint i )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FALLBACK(ctx);
+ ctx->Save->EvalPoint1( i );
+}
+
+static void _save_EvalPoint2( GLint i, GLint j )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FALLBACK(ctx);
+ ctx->Save->EvalPoint2( i, j );
+}
+
+static void _save_CallList( GLuint l )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ fprintf(stderr, "%s\n", __FUNCTION__);
+ FALLBACK(ctx);
+ ctx->Save->CallList( l );
+}
+
+static void _save_CallLists( GLsizei n, GLenum type, const GLvoid *v )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ fprintf(stderr, "%s\n", __FUNCTION__);
+ FALLBACK(ctx);
+ ctx->Save->CallLists( n, type, v );
+}
+
+
+
+
+/* This begin is hooked into ... Updating of
+ * ctx->Driver.CurrentSavePrimitive is already taken care of.
+ */
+static GLboolean _save_NotifyBegin( GLcontext *ctx, GLenum mode )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+ if (1) {
+ int i = tnl->save.prim_count++;
+
+ assert(i < tnl->save.prim_max);
+ tnl->save.prim[i].mode = mode | PRIM_BEGIN;
+ tnl->save.prim[i].start = tnl->save.initial_counter - tnl->save.counter;
+ tnl->save.prim[i].count = 0;
+
+ _mesa_install_save_vtxfmt( ctx, &tnl->save_vtxfmt );
+ ctx->Driver.SaveNeedFlush = 1;
+ return GL_TRUE;
+ }
+ else
+ return GL_FALSE;
+}
+
+
+
+static void _save_End( void )
+{
+ GET_CURRENT_CONTEXT( ctx );
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ int i = tnl->save.prim_count - 1;
+
+ ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
+ tnl->save.prim[i].mode |= PRIM_END;
+ tnl->save.prim[i].count = ((tnl->save.initial_counter - tnl->save.counter) -
+ tnl->save.prim[i].start);
+
+ if (i == tnl->save.prim_max - 1) {
+ _save_compile_vertex_list( ctx );
+ assert(tnl->save.copied.nr == 0);
+ }
+
+ /* Swap out this vertex format while outside begin/end. Any color,
+ * etc. received between here and the next begin will be compiled
+ * as opcodes.
+ */
+ _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
+}
+
+
+/* These are all errors as this vtxfmt is only installed inside
+ * begin/end pairs.
+ */
+static void _save_DrawElements(GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_compile_error( ctx, GL_INVALID_OPERATION, __FUNCTION__);
+}
+
+
+static void _save_DrawRangeElements(GLenum mode,
+ GLuint start, GLuint end,
+ GLsizei count, GLenum type,
+ const GLvoid *indices)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_compile_error( ctx, GL_INVALID_OPERATION, __FUNCTION__);
+}
+
+static void _save_DrawArrays(GLenum mode, GLint start, GLsizei count)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_compile_error( ctx, GL_INVALID_OPERATION, __FUNCTION__);
+}
+
+static void _save_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_compile_error( ctx, GL_INVALID_OPERATION, __FUNCTION__);
+}
+
+static void _save_EvalMesh1( GLenum mode, GLint i1, GLint i2 )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_compile_error( ctx, GL_INVALID_OPERATION, __FUNCTION__);
+}
+
+static void _save_EvalMesh2( GLenum mode, GLint i1, GLint i2,
+ GLint j1, GLint j2 )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_compile_error( ctx, GL_INVALID_OPERATION, __FUNCTION__);
+}
+
+static void _save_Begin( GLenum mode )
+{
+ GET_CURRENT_CONTEXT( ctx );
+ _mesa_compile_error( ctx, GL_INVALID_OPERATION, "Recursive begin" );
+}
+
+
+/* Unlike the functions above, these are to be hooked into the vtxfmt
+ * maintained in ctx->ListState, active when the list is known or
+ * suspected to be outside any begin/end primitive.
+ */
+static void _save_OBE_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ _save_NotifyBegin( ctx, GL_QUADS | PRIM_WEAK );
+ glVertex2f( x1, y1 );
+ glVertex2f( x2, y1 );
+ glVertex2f( x2, y2 );
+ glVertex2f( x1, y2 );
+ glEnd();
+}
+
+
+static void _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i;
+
+ if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
+ return;
+
+ _save_NotifyBegin( ctx, mode | PRIM_WEAK );
+ for (i = start ; i < count ; i++)
+ glArrayElement( i );
+ glEnd();
+}
+
+
+static void _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i;
+
+ if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
+ return;
+
+ _save_NotifyBegin( ctx, mode | PRIM_WEAK );
+
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ for (i = 0 ; i < count ; i++)
+ glArrayElement( ((GLubyte *)indices)[i] );
+ break;
+ case GL_UNSIGNED_SHORT:
+ for (i = 0 ; i < count ; i++)
+ glArrayElement( ((GLushort *)indices)[i] );
+ break;
+ case GL_UNSIGNED_INT:
+ for (i = 0 ; i < count ; i++)
+ glArrayElement( ((GLuint *)indices)[i] );
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
+ break;
+ }
+
+ glEnd();
+}
+
+static void _save_OBE_DrawRangeElements(GLenum mode,
+ GLuint start, GLuint end,
+ GLsizei count, GLenum type,
+ const GLvoid *indices)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (_mesa_validate_DrawRangeElements( ctx, mode,
+ start, end,
+ count, type, indices ))
+ _save_OBE_DrawElements( mode, count, type, indices );
+}
+
+
+
+
+
+static void _save_vtxfmt_init( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLvertexformat *vfmt = &tnl->save_vtxfmt;
+
+ vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */
+ vfmt->Begin = _save_Begin;
+ vfmt->Color3f = _save_Color3f;
+ vfmt->Color3fv = _save_Color3fv;
+ vfmt->Color4f = _save_Color4f;
+ vfmt->Color4fv = _save_Color4fv;
+ vfmt->EdgeFlag = _save_EdgeFlag;
+ vfmt->EdgeFlagv = _save_EdgeFlagv;
+ vfmt->End = _save_End;
+ vfmt->FogCoordfEXT = _save_FogCoordfEXT;
+ vfmt->FogCoordfvEXT = _save_FogCoordfvEXT;
+ vfmt->Indexf = _save_Indexf;
+ vfmt->Indexfv = _save_Indexfv;
+ vfmt->Materialfv = _save_Materialfv;
+ vfmt->MultiTexCoord1fARB = _save_MultiTexCoord1f;
+ vfmt->MultiTexCoord1fvARB = _save_MultiTexCoord1fv;
+ vfmt->MultiTexCoord2fARB = _save_MultiTexCoord2f;
+ vfmt->MultiTexCoord2fvARB = _save_MultiTexCoord2fv;
+ vfmt->MultiTexCoord3fARB = _save_MultiTexCoord3f;
+ vfmt->MultiTexCoord3fvARB = _save_MultiTexCoord3fv;
+ vfmt->MultiTexCoord4fARB = _save_MultiTexCoord4f;
+ vfmt->MultiTexCoord4fvARB = _save_MultiTexCoord4fv;
+ vfmt->Normal3f = _save_Normal3f;
+ vfmt->Normal3fv = _save_Normal3fv;
+ vfmt->SecondaryColor3fEXT = _save_SecondaryColor3fEXT;
+ vfmt->SecondaryColor3fvEXT = _save_SecondaryColor3fvEXT;
+ vfmt->TexCoord1f = _save_TexCoord1f;
+ vfmt->TexCoord1fv = _save_TexCoord1fv;
+ vfmt->TexCoord2f = _save_TexCoord2f;
+ vfmt->TexCoord2fv = _save_TexCoord2fv;
+ vfmt->TexCoord3f = _save_TexCoord3f;
+ vfmt->TexCoord3fv = _save_TexCoord3fv;
+ vfmt->TexCoord4f = _save_TexCoord4f;
+ vfmt->TexCoord4fv = _save_TexCoord4fv;
+ vfmt->Vertex2f = _save_Vertex2f;
+ vfmt->Vertex2fv = _save_Vertex2fv;
+ vfmt->Vertex3f = _save_Vertex3f;
+ vfmt->Vertex3fv = _save_Vertex3fv;
+ vfmt->Vertex4f = _save_Vertex4f;
+ vfmt->Vertex4fv = _save_Vertex4fv;
+ vfmt->VertexAttrib1fNV = _save_VertexAttrib1fNV;
+ vfmt->VertexAttrib1fvNV = _save_VertexAttrib1fvNV;
+ vfmt->VertexAttrib2fNV = _save_VertexAttrib2fNV;
+ vfmt->VertexAttrib2fvNV = _save_VertexAttrib2fvNV;
+ vfmt->VertexAttrib3fNV = _save_VertexAttrib3fNV;
+ vfmt->VertexAttrib3fvNV = _save_VertexAttrib3fvNV;
+ vfmt->VertexAttrib4fNV = _save_VertexAttrib4fNV;
+ vfmt->VertexAttrib4fvNV = _save_VertexAttrib4fvNV;
+
+ /* This will all require us to fallback to saving the list as opcodes:
+ */
+ vfmt->CallList = _save_CallList; /* inside begin/end */
+ vfmt->CallLists = _save_CallLists; /* inside begin/end */
+ vfmt->EvalCoord1f = _save_EvalCoord1f;
+ vfmt->EvalCoord1fv = _save_EvalCoord1fv;
+ vfmt->EvalCoord2f = _save_EvalCoord2f;
+ vfmt->EvalCoord2fv = _save_EvalCoord2fv;
+ vfmt->EvalPoint1 = _save_EvalPoint1;
+ vfmt->EvalPoint2 = _save_EvalPoint2;
+
+ /* These are all errors as we at least know we are in some sort of
+ * begin/end pair:
+ */
+ vfmt->EvalMesh1 = _save_EvalMesh1;
+ vfmt->EvalMesh2 = _save_EvalMesh2;
+ vfmt->Begin = _save_Begin;
+ vfmt->Rectf = _save_Rectf;
+ vfmt->DrawArrays = _save_DrawArrays;
+ vfmt->DrawElements = _save_DrawElements;
+ vfmt->DrawRangeElements = _save_DrawRangeElements;
+
+}
+
+
+void _tnl_SaveFlushVertices( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+ /* Noop when we are actually active:
+ */
+ if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM ||
+ ctx->Driver.CurrentSavePrimitive <= GL_POLYGON)
+ return;
+
+ if (tnl->save.initial_counter != tnl->save.counter ||
+ tnl->save.prim_count)
+ _save_compile_vertex_list( ctx );
+
+ _save_copy_to_current( ctx );
+ _save_reset_vertex( ctx );
+ ctx->Driver.SaveNeedFlush = 0;
+}
+
+void _tnl_NewList( GLcontext *ctx, GLuint list, GLenum mode )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+ if (!tnl->save.prim_store)
+ tnl->save.prim_store = alloc_prim_store( ctx );
+
+ if (!tnl->save.vertex_store) {
+ tnl->save.vertex_store = alloc_vertex_store( ctx );
+ tnl->save.vbptr = tnl->save.vertex_store->buffer;
+ }
+
+ _save_reset_vertex( ctx );
+ ctx->Driver.SaveNeedFlush = 0;
+}
+
+void _tnl_EndList( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ assert(tnl->save.vertex_size == 0);
+}
+
+void _tnl_BeginCallList( GLcontext *ctx, GLuint list )
+{
+}
+
+void _tnl_EndCallList( GLcontext *ctx )
+{
+}
+
+
+static void _tnl_destroy_vertex_list( GLcontext *ctx, void *data )
+{
+ struct tnl_vertex_list *node = (struct tnl_vertex_list *)data;
+
+ if ( --node->vertex_store->refcount == 0 )
+ FREE( node->vertex_store );
+
+ if ( --node->prim_store->refcount == 0 )
+ FREE( node->prim_store );
+
+ if ( node->normal_lengths )
+ FREE( node->normal_lengths );
+}
+
+
+static void _tnl_print_vertex_list( GLcontext *ctx, void *data )
+{
+ struct tnl_vertex_list *node = (struct tnl_vertex_list *)data;
+ GLuint i;
+
+ _mesa_debug(0, "TNL-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n",
+ node->count,
+ node->prim_count,
+ node->vertex_size);
+
+ for (i = 0 ; i < node->prim_count ; i++) {
+ struct tnl_prim *prim = &node->prim[i];
+ _mesa_debug(0, " prim %d: %s %d..%d %s %s\n",
+ i,
+ _mesa_lookup_enum_by_nr(prim->mode & PRIM_MODE_MASK),
+ prim->start,
+ prim->start + prim->count,
+ (prim->mode & PRIM_BEGIN) ? "BEGIN" : "(wrap)",
+ (prim->mode & PRIM_END) ? "END" : "(wrap)");
+ }
+}
+
+
+static void _save_current_init( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLint i;
+
+ for (i = 0; i < _TNL_ATTRIB_MAT_FRONT_AMBIENT; i++) {
+ tnl->save.currentsz[i] = &ctx->ListState.ActiveAttribSize[i];
+ tnl->save.current[i] = ctx->ListState.CurrentAttrib[i];
+ }
+
+ for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT; i < _TNL_ATTRIB_INDEX; i++) {
+ tnl->save.currentsz[i] = &ctx->ListState.ActiveMaterialSize[i];
+ tnl->save.current[i] = ctx->ListState.CurrentMaterial[i];
+ }
+
+ tnl->save.currentsz[_TNL_ATTRIB_INDEX] = &ctx->ListState.ActiveIndex;
+ tnl->save.current[_TNL_ATTRIB_INDEX] = &ctx->ListState.CurrentIndex;
+
+ /* Current edgeflag is handled individually */
+}
+
+/**
+ * Initialize the display list compiler
+ */
+void _tnl_save_init( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct tnl_vertex_arrays *tmp = &tnl->save_inputs;
+ GLuint i;
+
+
+ for (i = 0; i < _TNL_ATTRIB_MAX; i++)
+ _mesa_vector4f_init( &tmp->Attribs[i], 0, 0);
+
+ tnl->save.opcode_vertex_list =
+ _mesa_alloc_opcode( ctx,
+ sizeof(struct tnl_vertex_list),
+ _tnl_playback_vertex_list,
+ _tnl_destroy_vertex_list,
+ _tnl_print_vertex_list );
+
+ ctx->Driver.NotifySaveBegin = _save_NotifyBegin;
+
+ _save_vtxfmt_init( ctx );
+ _save_current_init( ctx );
+
+ /* Hook our array functions into the outside-begin-end vtxfmt in
+ * ctx->ListState.
+ */
+ ctx->ListState.ListVtxfmt.Rectf = _save_OBE_Rectf;
+ ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays;
+ ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements;
+ ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements;
+ _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
+}
+
+
+/**
+ * Deallocate the immediate-mode buffer for the given context, if
+ * its reference count goes to zero.
+ */
+void _tnl_save_destroy( GLcontext *ctx )
+{
+}
--- /dev/null
+/* $XFree86$ */
+/**************************************************************************
+
+Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas.
+
+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
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, 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 (including the next
+paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS 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 <keith@tungstengraphics.com>
+ *
+ */
+
+#ifndef __T_SAVE_API_H__
+#define __T_SAVE_API_H__
+
+#include "t_context.h"
+
+extern GLboolean _tnl_weak_begin( GLcontext *ctx, GLenum mode );
+
+extern void _tnl_EndList( GLcontext *ctx );
+extern void _tnl_NewList( GLcontext *ctx, GLuint list, GLenum mode );
+
+extern void _tnl_EndCallList( GLcontext *ctx );
+extern void _tnl_BeginCallList( GLcontext *ctx, GLuint list );
+
+extern void _tnl_SaveFlushVertices( GLcontext *ctx );
+
+extern void _tnl_save_init( GLcontext *ctx );
+extern void _tnl_save_destroy( GLcontext *ctx );
+
+extern void _tnl_loopback_vertex_list( GLcontext *ctx,
+ struct tnl_vertex_list *list );
+
+extern void _tnl_playback_vertex_list( GLcontext *ctx, void *data );
+
+#endif
--- /dev/null
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 5.1
+ *
+ * Copyright (C) 1999-2003 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 <keith@tungstengraphics.com>
+ */
+
+#include "context.h"
+#include "enums.h"
+#include "glapi.h"
+#include "imports.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "t_context.h"
+#include "t_save_api.h"
+
+/* If someone compiles a display list like:
+ * glBegin(Triangles)
+ * glVertex()
+ * ... lots of vertices ...
+ * glEnd()
+ *
+ * or:
+ * glDrawArrays(...)
+ *
+ * and then tries to execute it like this:
+ *
+ * glBegin(Lines)
+ * glCallList()
+ * glEnd()
+ *
+ * it will wind up in here, as the vertex copying used when wrapping
+ * buffers in list compilation (Triangles) won't be right for how the
+ * list is being executed (as Lines).
+ *
+ * This could be avoided by not compiling as vertex_lists until after
+ * the first glEnd() has been seen. However, that would miss an
+ * important category of display lists, for the sake of a degenerate
+ * usage.
+ *
+ * Further, replaying degenerately-called lists in this fashion is
+ * probably still faster than the replay using opcodes.
+ */
+
+typedef void (*attr_func)( GLcontext *ctx, GLint target, const GLfloat * );
+
+
+/* Wrapper functions in case glVertexAttrib*fvNV doesn't exist */
+static void VertexAttrib1fvNV(GLcontext *ctx, GLint target, const GLfloat *v)
+{
+ ctx->Exec->VertexAttrib1fvNV(target, v);
+}
+
+static void VertexAttrib2fvNV(GLcontext *ctx, GLint target, const GLfloat *v)
+{
+ ctx->Exec->VertexAttrib2fvNV(target, v);
+}
+
+static void VertexAttrib3fvNV(GLcontext *ctx, GLint target, const GLfloat *v)
+{
+ ctx->Exec->VertexAttrib3fvNV(target, v);
+}
+
+static void VertexAttrib4fvNV(GLcontext *ctx, GLint target, const GLfloat *v)
+{
+ ctx->Exec->VertexAttrib4fvNV(target, v);
+}
+
+static attr_func vert_attrfunc[4] = {
+ VertexAttrib1fvNV,
+ VertexAttrib2fvNV,
+ VertexAttrib3fvNV,
+ VertexAttrib4fvNV
+};
+
+
+static void mat_attr1fv( GLcontext *ctx, GLint target, const GLfloat *v )
+{
+ switch (target) {
+ case _TNL_ATTRIB_MAT_FRONT_SHININESS:
+ ctx->Exec->Materialfv( GL_FRONT, GL_SHININESS, v );
+ break;
+ case _TNL_ATTRIB_MAT_BACK_SHININESS:
+ ctx->Exec->Materialfv( GL_BACK, GL_SHININESS, v );
+ break;
+ }
+}
+
+
+static void mat_attr3fv( GLcontext *ctx, GLint target, const GLfloat *v )
+{
+ switch (target) {
+ case _TNL_ATTRIB_MAT_FRONT_INDEXES:
+ ctx->Exec->Materialfv( GL_FRONT, GL_COLOR_INDEXES, v );
+ break;
+ case _TNL_ATTRIB_MAT_BACK_INDEXES:
+ ctx->Exec->Materialfv( GL_BACK, GL_COLOR_INDEXES, v );
+ break;
+ }
+}
+
+
+static void mat_attr4fv( GLcontext *ctx, GLint target, const GLfloat *v )
+{
+ switch (target) {
+ case _TNL_ATTRIB_MAT_FRONT_EMISSION:
+ ctx->Exec->Materialfv( GL_FRONT, GL_EMISSION, v );
+ break;
+ case _TNL_ATTRIB_MAT_BACK_EMISSION:
+ ctx->Exec->Materialfv( GL_BACK, GL_EMISSION, v );
+ break;
+ case _TNL_ATTRIB_MAT_FRONT_AMBIENT:
+ ctx->Exec->Materialfv( GL_FRONT, GL_AMBIENT, v );
+ break;
+ case _TNL_ATTRIB_MAT_BACK_AMBIENT:
+ ctx->Exec->Materialfv( GL_BACK, GL_AMBIENT, v );
+ break;
+ case _TNL_ATTRIB_MAT_FRONT_DIFFUSE:
+ ctx->Exec->Materialfv( GL_FRONT, GL_DIFFUSE, v );
+ break;
+ case _TNL_ATTRIB_MAT_BACK_DIFFUSE:
+ ctx->Exec->Materialfv( GL_BACK, GL_DIFFUSE, v );
+ break;
+ case _TNL_ATTRIB_MAT_FRONT_SPECULAR:
+ ctx->Exec->Materialfv( GL_FRONT, GL_SPECULAR, v );
+ break;
+ case _TNL_ATTRIB_MAT_BACK_SPECULAR:
+ ctx->Exec->Materialfv( GL_BACK, GL_SPECULAR, v );
+ break;
+ }
+}
+
+
+static attr_func mat_attrfunc[4] = {
+ mat_attr1fv,
+ 0,
+ mat_attr3fv,
+ mat_attr4fv
+};
+
+
+static void index_attr1fv(GLcontext *ctx, GLint target, const GLfloat *v)
+{
+ ctx->Exec->Indexf(v[0]);
+}
+
+static void edgeflag_attr1fv(GLcontext *ctx, GLint target, const GLfloat *v)
+{
+ ctx->Exec->EdgeFlag((v[0] == 1.0));
+}
+
+struct loopback_attr {
+ GLint target;
+ GLint sz;
+ attr_func func;
+};
+
+/* Don't emit ends and begins on wrapped primitives. Don't replay
+ * wrapped vertices. If we get here, it's probably because the the
+ * precalculated wrapping is wrong.
+ */
+static void loopback_prim( GLcontext *ctx,
+ struct tnl_vertex_list *list, GLuint i,
+ struct loopback_attr *la, GLuint nr )
+{
+ struct tnl_prim *prim = &list->prim[i];
+ GLint begin = prim->start;
+ GLint end = begin + prim->count;
+ GLfloat *data;
+ GLint j, k;
+
+ if (prim->mode & PRIM_BEGIN) {
+ glBegin( prim->mode & PRIM_MODE_MASK );
+ } else {
+ assert(i == 0);
+ assert(begin == 0);
+ begin += list->wrap_count;
+ }
+
+ data = list->buffer + begin * list->vertex_size;
+
+ for (j = begin ; j < end ; j++) {
+ GLfloat *tmp = data + la[0].sz;
+
+ for (k = 1 ; k < nr ; k++) {
+ la[k].func( ctx, la[k].target, tmp );
+ tmp += la[k].sz;
+ }
+
+ /* Fire the vertex
+ */
+ la[0].func( ctx, VERT_ATTRIB_POS, data );
+ data = tmp;
+ }
+
+ if (prim->mode & PRIM_END) {
+ glEnd();
+ }
+ else {
+ assert (i == list->prim_count-1);
+ }
+}
+
+/* Primitives generated by DrawArrays/DrawElements/Rectf may be
+ * caught here. If there is no primitive in progress, execute them
+ * normally, otherwise need to track and discard the generated
+ * primitives.
+ */
+static void loopback_weak_prim( GLcontext *ctx,
+ struct tnl_vertex_list *list, GLuint i,
+ struct loopback_attr *la, GLuint nr )
+{
+ if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END)
+ loopback_prim( ctx, list, i, la, nr );
+ else {
+ struct tnl_prim *prim = &list->prim[i];
+
+ /* Use the prim_weak flag to ensure that if this primitive
+ * wraps, we don't mistake future vertex_lists for part of the
+ * surrounding primitive.
+ *
+ * While this flag is set, we are simply disposing of data
+ * generated by an operation now known to be a noop.
+ */
+ if (prim->mode & PRIM_BEGIN)
+ ctx->Driver.CurrentExecPrimitive |= PRIM_WEAK;
+ if (prim->mode & PRIM_END)
+ ctx->Driver.CurrentExecPrimitive &= ~PRIM_WEAK;
+ }
+}
+
+
+
+void _tnl_loopback_vertex_list( GLcontext *ctx, struct tnl_vertex_list *list )
+{
+ struct loopback_attr la[_TNL_ATTRIB_MAX];
+ GLuint i, nr = 0;
+
+ for (i = 0 ; i <= _TNL_ATTRIB_TEX7 ; i++) {
+ if (list->attrsz[i]) {
+ la[nr].target = i;
+ la[nr].sz = list->attrsz[i];
+ la[nr].func = vert_attrfunc[list->attrsz[i]-1];
+ nr++;
+ }
+ }
+
+ for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT ;
+ i <= _TNL_ATTRIB_MAT_BACK_INDEXES ;
+ i++) {
+ if (list->attrsz[i]) {
+ la[nr].target = i;
+ la[nr].sz = list->attrsz[i];
+ la[nr].func = mat_attrfunc[list->attrsz[i]-1];
+ nr++;
+ }
+ }
+
+ if (list->attrsz[_TNL_ATTRIB_EDGEFLAG]) {
+ la[nr].target = _TNL_ATTRIB_EDGEFLAG;
+ la[nr].sz = list->attrsz[_TNL_ATTRIB_EDGEFLAG];
+ la[nr].func = edgeflag_attr1fv;
+ nr++;
+ }
+
+ if (list->attrsz[_TNL_ATTRIB_INDEX]) {
+ la[nr].target = _TNL_ATTRIB_INDEX;
+ la[nr].sz = list->attrsz[_TNL_ATTRIB_INDEX];
+ la[nr].func = index_attr1fv;
+ nr++;
+ }
+
+ for (i = 0 ; i < list->prim_count ; i++) {
+ if (list->prim[i].mode & PRIM_WEAK)
+ loopback_weak_prim( ctx, list, i, la, nr );
+ else
+ loopback_prim( ctx, list, i, la, nr );
+ }
+}
--- /dev/null
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 5.1
+ *
+ * Copyright (C) 1999-2003 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 <keith@tungstengraphics.com>
+ */
+
+#include "context.h"
+#include "imports.h"
+#include "mtypes.h"
+#include "macros.h"
+#include "light.h"
+#include "state.h"
+#include "t_pipeline.h"
+#include "t_save_api.h"
+#include "t_vtx_api.h"
+
+static GLint get_size( const GLfloat *f )
+{
+ if (f[3] != 1.0) return 4;
+ if (f[2] != 0.0) return 3;
+ return 2;
+}
+
+
+/* Some nasty stuff still hanging on here.
+ *
+ * TODO - remove VB->ColorPtr, etc and just use the AttrPtr's.
+ */
+static void _tnl_bind_vertex_list( GLcontext *ctx,
+ struct tnl_vertex_list *node )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct vertex_buffer *VB = &tnl->vb;
+ struct tnl_vertex_arrays *tmp = &tnl->save_inputs;
+ GLfloat *data = node->buffer;
+ GLuint attr, i;
+
+ /* Setup constant data in the VB.
+ */
+ VB->Count = node->count;
+ VB->Primitive = node->prim;
+ VB->PrimitiveCount = node->prim_count;
+ VB->Elts = NULL;
+ VB->NormalLengthPtr = node->normal_lengths;
+
+ for (attr = 0; attr <= _TNL_ATTRIB_INDEX; attr++) {
+ if (node->attrsz[attr]) {
+ tmp->Attribs[attr].count = node->count;
+ tmp->Attribs[attr].data = (GLfloat (*)[4]) data;
+ tmp->Attribs[attr].start = data;
+ tmp->Attribs[attr].size = node->attrsz[attr];
+ tmp->Attribs[attr].stride = node->vertex_size * sizeof(GLfloat);
+ VB->AttribPtr[attr] = &tmp->Attribs[attr];
+ data += node->attrsz[attr];
+ }
+ else {
+ tmp->Attribs[attr].count = node->count;
+ tmp->Attribs[attr].data = (GLfloat (*)[4]) tnl->vtx.current[attr];
+ tmp->Attribs[attr].start = tnl->vtx.current[attr];
+ tmp->Attribs[attr].size = get_size( tnl->vtx.current[attr] );
+ tmp->Attribs[attr].stride = 0;
+ VB->AttribPtr[attr] = &tmp->Attribs[attr];
+ }
+ }
+
+
+ /* Copy edgeflag to a contiguous array
+ */
+ if (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL) {
+ if (node->attrsz[_TNL_ATTRIB_EDGEFLAG]) {
+ VB->EdgeFlag = _tnl_translate_edgeflag( ctx, data,
+ node->count,
+ node->vertex_size );
+ data++;
+ }
+ else
+ VB->EdgeFlag = _tnl_import_current_edgeflag( ctx, node->count );
+ }
+
+ /* Legacy pointers -- remove one day.
+ */
+ VB->ObjPtr = VB->AttribPtr[_TNL_ATTRIB_POS];
+ VB->NormalPtr = VB->AttribPtr[_TNL_ATTRIB_NORMAL];
+ VB->ColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR0];
+ VB->ColorPtr[1] = 0;
+ VB->IndexPtr[0] = VB->AttribPtr[_TNL_ATTRIB_INDEX];
+ VB->IndexPtr[1] = 0;
+ VB->SecondaryColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR1];
+ VB->SecondaryColorPtr[1] = 0;
+
+ for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
+ VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i];
+ }
+}
+
+static void _playback_copy_to_current( GLcontext *ctx,
+ struct tnl_vertex_list *node )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLfloat *data;
+ GLuint i;
+
+ if (node->count)
+ data = node->buffer + (node->count-1) * node->vertex_size;
+ else
+ data = node->buffer;
+
+ for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_INDEX ; i++) {
+ if (node->attrsz[i]) {
+ ASSIGN_4V(tnl->vtx.current[i], 0, 0, 0, 1);
+ COPY_SZ_4V(tnl->vtx.current[i], node->attrsz[i], data);
+ data += node->attrsz[i];
+ }
+ }
+
+ /* Edgeflag requires special treatment:
+ */
+ if (node->attrsz[_TNL_ATTRIB_EDGEFLAG]) {
+ ctx->Current.EdgeFlag = (data[0] == 1.0);
+ }
+
+ /* Colormaterial -- this kindof sucks.
+ */
+ if (ctx->Light.ColorMaterialEnabled) {
+ _mesa_update_color_material(ctx, ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
+ }
+
+ /* CurrentExecPrimitive
+ */
+ if (node->prim_count) {
+ GLenum mode = node->prim[node->prim_count - 1].mode;
+ if (mode & PRIM_END)
+ ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
+ else
+ ctx->Driver.CurrentExecPrimitive = (mode & PRIM_MODE_MASK);
+ }
+}
+
+
+/**
+ * Execute the buffer and save copied verts.
+ */
+void _tnl_playback_vertex_list( GLcontext *ctx, void *data )
+{
+ struct tnl_vertex_list *node = (struct tnl_vertex_list *)data;
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+ FLUSH_CURRENT(ctx, 0);
+
+ if (node->prim_count) {
+
+ if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END &&
+ (node->prim[0].mode & PRIM_BEGIN)) {
+
+ /* Degenerate case: list is called inside begin/end pair and
+ * includes operations such as glBegin or glDrawArrays.
+ */
+ _mesa_error( ctx, GL_INVALID_OPERATION, "displaylist recursive begin");
+ _tnl_loopback_vertex_list( ctx, data );
+ return;
+ }
+ else if (tnl->LoopbackDListCassettes ||
+ node->dangling_attr_ref) {
+ /* Degenerate case: list references current data and would
+ * require fixup. Take the easier option & loop it back.
+ */
+ _mesa_debug( 0, "%s: loopback dangling attr ref\n", __FUNCTION__);
+ _tnl_loopback_vertex_list( ctx, data );
+ return;
+ }
+
+ if (ctx->NewState)
+ _mesa_update_state( ctx );
+
+ if (tnl->pipeline.build_state_changes)
+ _tnl_validate_pipeline( ctx );
+
+ _tnl_bind_vertex_list( ctx, node );
+
+ /* Invalidate all stored data before and after run:
+ */
+ tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
+ tnl->Driver.RunPipeline( ctx );
+ tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
+ }
+
+ /* Copy to current?
+ */
+ _playback_copy_to_current( ctx, node );
+}
+
+
+
+
+
GLfloat (*coord)[4] = VB->ClipPtr->data;
GLuint ii = i, jj = j, p;
- VB->LastClipped = VB->FirstClipped;
+ VB->LastClipped = VB->Count;
if (mask & 0x3f) {
LINE_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 );
ASSIGN_3V(inlist, v2, v0, v1 ); /* pv rotated to slot zero */
- VB->LastClipped = VB->FirstClipped;
+ VB->LastClipped = VB->Count;
if (mask & 0x3f) {
POLY_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 );
if (ctx->_TriangleCaps & DD_FLATSHADE) {
if (pv != inlist[0]) {
- ASSERT( inlist[0] >= VB->FirstClipped );
+ ASSERT( inlist[0] >= VB->Count );
tnl->Driver.Render.CopyPV( ctx, inlist[0], pv );
}
}
ASSIGN_4V(inlist, v3, v0, v1, v2 ); /* pv rotated to slot zero */
- VB->LastClipped = VB->FirstClipped;
+ VB->LastClipped = VB->Count;
if (mask & 0x3f) {
POLY_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 );
if (ctx->_TriangleCaps & DD_FLATSHADE) {
if (pv != inlist[0]) {
- ASSERT( inlist[0] >= VB->FirstClipped );
+ ASSERT( inlist[0] >= VB->Count );
tnl->Driver.Render.CopyPV( ctx, inlist[0], pv );
}
}
static GLboolean run_fog_stage( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
struct fog_stage_data *store = FOG_STAGE_DATA(stage);
}
-static void check_fog_stage( GLcontext *ctx, struct gl_pipeline_stage *stage )
+static void check_fog_stage( GLcontext *ctx, struct tnl_pipeline_stage *stage )
{
stage->active = ctx->Fog.Enabled && !ctx->VertexProgram.Enabled;
if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT)
- stage->inputs = VERT_BIT_EYE;
+ stage->inputs = _TNL_BIT_POS;
else
- stage->inputs = VERT_BIT_FOG;
+ stage->inputs = _TNL_BIT_FOG;
}
/* Called the first time stage->run() is invoked.
*/
static GLboolean alloc_fog_data( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct fog_stage_data *store;
}
-static void free_fog_data( struct gl_pipeline_stage *stage )
+static void free_fog_data( struct tnl_pipeline_stage *stage )
{
struct fog_stage_data *store = FOG_STAGE_DATA(stage);
if (store) {
}
-const struct gl_pipeline_stage _tnl_fog_coordinate_stage =
+const struct tnl_pipeline_stage _tnl_fog_coordinate_stage =
{
"build fog coordinates", /* name */
_NEW_FOG, /* check_state */
_NEW_FOG, /* run_state */
GL_FALSE, /* active? */
0, /* inputs */
- VERT_BIT_FOG, /* outputs */
+ _TNL_BIT_FOG, /* outputs */
0, /* changed_inputs */
NULL, /* private_data */
free_fog_data, /* dtr */
#include "t_context.h"
#include "t_pipeline.h"
-#define LIGHT_FLAGS 0x1 /* must be first */
-#define LIGHT_TWOSIDE 0x2
-#define LIGHT_COLORMATERIAL 0x4
-#define MAX_LIGHT_FUNC 0x8
+#define LIGHT_TWOSIDE 0x1
+#define LIGHT_MATERIAL 0x2
+#define MAX_LIGHT_FUNC 0x4
typedef void (*light_func)( GLcontext *ctx,
struct vertex_buffer *VB,
- struct gl_pipeline_stage *stage,
+ struct tnl_pipeline_stage *stage,
GLvector4f *input );
+struct material_cursor {
+ const GLfloat *ptr;
+ GLuint stride;
+ GLfloat *current;
+};
+
struct light_stage_data {
- struct gl_client_array FloatColor;
- struct gl_client_array LitColor[2];
- struct gl_client_array LitSecondary[2];
- GLvector1ui LitIndex[2];
+ GLvector4f Input;
+ GLvector4f LitColor[2];
+ GLvector4f LitSecondary[2];
+ GLvector4f LitIndex[2];
light_func *light_func_tab;
+
+ struct material_cursor mat[MAT_ATTRIB_MAX];
+ GLuint mat_count;
+ GLuint mat_bitmask;
};
#define LIGHT_STAGE_DATA(stage) ((struct light_stage_data *)(stage->privatePtr))
-static void import_color_material( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+
+/* In the case of colormaterial, the effected material attributes
+ * should already have been bound to point to the incoming color data,
+ * prior to running the pipeline.
+ */
+static void update_materials( GLcontext *ctx,
+ struct light_stage_data *store )
{
- struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
- struct gl_client_array *to = &LIGHT_STAGE_DATA(stage)->FloatColor;
- struct gl_client_array *from = VB->ColorPtr[0];
- GLuint count = VB->Count;
-
- if (!to->Ptr) {
- to->Ptr = (GLubyte *) ALIGN_MALLOC( VB->Size * 4 * sizeof(GLfloat), 32 );
- to->Type = GL_FLOAT;
+ GLuint i;
+
+ for (i = 0 ; i < store->mat_count ; i++) {
+ COPY_4V(store->mat[i].current, store->mat[i].ptr);
+ STRIDE_F(store->mat[i].ptr, store->mat[i].stride);
}
+
+ _mesa_update_material( ctx, store->mat_bitmask );
+ _mesa_validate_all_lighting_tables( ctx );
+}
+
+static GLuint prepare_materials( GLcontext *ctx,
+ struct vertex_buffer *VB,
+ struct light_stage_data *store )
+{
+ GLuint i;
+
+ store->mat_count = 0;
+ store->mat_bitmask = 0;
- /* No need to transform the same value 3000 times.
+ /* If ColorMaterial enabled, overwrite affected AttrPtr's with
+ * the color pointer. This could be done earlier.
*/
- if (!from->StrideB) {
- to->StrideB = 0;
- count = 1;
+ if (ctx->Light.ColorMaterialEnabled) {
+ GLuint bitmask = ctx->Light.ColorMaterialBitmask;
+ for (i = 0 ; i < MAT_ATTRIB_MAX ; i++)
+ if (bitmask & (1<<i))
+ VB->AttribPtr[_TNL_ATTRIB_MAT_FRONT_AMBIENT + i] = VB->ColorPtr[0];
+ }
+
+ for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT ; i < _TNL_ATTRIB_INDEX ; i++) {
+ if (VB->AttribPtr[i]->stride) {
+ GLuint j = store->mat_count++;
+ GLuint attr = i - _TNL_ATTRIB_MAT_FRONT_AMBIENT;
+ store->mat[j].ptr = VB->AttribPtr[i]->start;
+ store->mat[j].stride = VB->AttribPtr[i]->stride;
+ store->mat[j].current = ctx->Light.Material.Attrib[attr];
+ store->mat_bitmask |= (1<<attr);
+ }
}
- else
- to->StrideB = 4 * sizeof(GLfloat);
- _math_trans_4fc( (GLfloat (*)[4]) to->Ptr,
- from->Ptr,
- from->StrideB,
- from->Type,
- from->Size,
- 0,
- count);
-
- VB->ColorPtr[0] = to;
-}
+ /* FIXME: Is this already done?
+ */
+ _mesa_update_material( ctx, ~0 );
+ _mesa_validate_all_lighting_tables( ctx );
-static void update_materials( GLcontext *ctx,
- const struct gl_material *src,
- GLuint bitmask )
-{
- _mesa_copy_materials( &ctx->Light.Material, src, bitmask );
- _mesa_update_material( ctx, bitmask );
+ return store->mat_count;
}
/* Tables for all the shading functions.
#define IDX (0)
#include "t_vb_lighttmp.h"
-#define TAG(x) x##_tw
+#define TAG(x) x##_twoside
#define IDX (LIGHT_TWOSIDE)
#include "t_vb_lighttmp.h"
-#define TAG(x) x##_fl
-#define IDX (LIGHT_FLAGS)
-#include "t_vb_lighttmp.h"
-
-#define TAG(x) x##_tw_fl
-#define IDX (LIGHT_FLAGS|LIGHT_TWOSIDE)
+#define TAG(x) x##_material
+#define IDX (LIGHT_MATERIAL)
#include "t_vb_lighttmp.h"
-#define TAG(x) x##_cm
-#define IDX (LIGHT_COLORMATERIAL)
-#include "t_vb_lighttmp.h"
-
-#define TAG(x) x##_tw_cm
-#define IDX (LIGHT_TWOSIDE|LIGHT_COLORMATERIAL)
-#include "t_vb_lighttmp.h"
-
-#define TAG(x) x##_fl_cm
-#define IDX (LIGHT_FLAGS|LIGHT_COLORMATERIAL)
-#include "t_vb_lighttmp.h"
-
-#define TAG(x) x##_tw_fl_cm
-#define IDX (LIGHT_FLAGS|LIGHT_TWOSIDE|LIGHT_COLORMATERIAL)
+#define TAG(x) x##_twoside_material
+#define IDX (LIGHT_TWOSIDE|LIGHT_MATERIAL)
#include "t_vb_lighttmp.h"
if (!done) {
init_light_tab();
- init_light_tab_tw();
- init_light_tab_fl();
- init_light_tab_tw_fl();
- init_light_tab_cm();
- init_light_tab_tw_cm();
- init_light_tab_fl_cm();
- init_light_tab_tw_fl_cm();
+ init_light_tab_twoside();
+ init_light_tab_material();
+ init_light_tab_twoside_material();
done = 1;
}
}
-static GLboolean run_lighting( GLcontext *ctx, struct gl_pipeline_stage *stage )
+static GLboolean run_lighting( GLcontext *ctx,
+ struct tnl_pipeline_stage *stage )
{
struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLvector4f *input = ctx->_NeedEyeCoords ? VB->EyePtr : VB->ObjPtr;
- GLuint ind;
+ GLuint idx;
-/* _tnl_print_vert_flags( __FUNCTION__, stage->changed_inputs ); */
-
- /* Make sure we can talk about elements 0..2 in the vector we are
- * lighting.
+ /* Make sure we can talk about position x,y and z:
*/
- if (stage->changed_inputs & (VERT_BIT_EYE|VERT_BIT_POS)) {
- if (input->size <= 2) {
- if (input->flags & VEC_NOT_WRITEABLE) {
- ASSERT(VB->importable_data & VERT_BIT_POS);
-
- VB->import_data( ctx, VERT_BIT_POS, VEC_NOT_WRITEABLE );
- input = ctx->_NeedEyeCoords ? VB->EyePtr : VB->ObjPtr;
-
- ASSERT((input->flags & VEC_NOT_WRITEABLE) == 0);
+ if (stage->changed_inputs & _TNL_BIT_POS) {
+ if (input->size <= 2 && input == VB->ObjPtr) {
+
+ _math_trans_4f( store->Input.data,
+ VB->ObjPtr->data,
+ VB->ObjPtr->stride,
+ GL_FLOAT,
+ VB->ObjPtr->size,
+ 0,
+ VB->Count );
+
+ if (input->size <= 2) {
+ /* Clean z.
+ */
+ _mesa_vector4f_clean_elem(&store->Input, VB->Count, 2);
+ }
+
+ if (input->size <= 1) {
+ /* Clean y.
+ */
+ _mesa_vector4f_clean_elem(&store->Input, VB->Count, 1);
}
- _mesa_vector4f_clean_elem(input, VB->Count, 2);
+ input = &store->Input;
}
}
+
+ idx = 0;
- if (VB->Flag)
- ind = LIGHT_FLAGS;
- else
- ind = 0;
+ if (prepare_materials( ctx, VB, store ))
+ idx |= LIGHT_MATERIAL;
+
+ if (ctx->Light.Model.TwoSide)
+ idx |= LIGHT_TWOSIDE;
/* The individual functions know about replaying side-effects
* vs. full re-execution.
*/
- store->light_func_tab[ind]( ctx, VB, stage, input );
+ store->light_func_tab[idx]( ctx, VB, stage, input );
return GL_TRUE;
}
/* Called in place of do_lighting when the light table may have changed.
*/
static GLboolean run_validate_lighting( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
- GLuint ind = 0;
light_func *tab;
if (ctx->Visual.rgbMode) {
else
tab = _tnl_light_ci_tab;
- if (ctx->Light.ColorMaterialEnabled)
- ind |= LIGHT_COLORMATERIAL;
-
- if (ctx->Light.Model.TwoSide)
- ind |= LIGHT_TWOSIDE;
- LIGHT_STAGE_DATA(stage)->light_func_tab = &tab[ind];
+ LIGHT_STAGE_DATA(stage)->light_func_tab = tab;
/* This and the above should only be done on _NEW_LIGHT:
*/
return stage->run( ctx, stage );
}
-static void alloc_4chan( struct gl_client_array *a, GLuint sz )
-{
- a->Ptr = (GLubyte *) ALIGN_MALLOC( sz * sizeof(GLchan) * 4, 32 );
- a->Size = 4;
- a->Type = CHAN_TYPE;
- a->Stride = 0;
- a->StrideB = sizeof(GLchan) * 4;
- a->Enabled = 0;
- a->Flags = 0;
-}
/* Called the first time stage->run is called. In effect, don't
* allocate data until the first time the stage is run.
*/
static GLboolean run_init_lighting( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct light_stage_data *store;
*/
init_lighting();
- store->FloatColor.Ptr = 0;
-
- alloc_4chan( &store->LitColor[0], size );
- alloc_4chan( &store->LitColor[1], size );
- alloc_4chan( &store->LitSecondary[0], size );
- alloc_4chan( &store->LitSecondary[1], size );
+ _mesa_vector4f_alloc( &store->Input, 0, size, 32 );
+ _mesa_vector4f_alloc( &store->LitColor[0], 0, size, 32 );
+ _mesa_vector4f_alloc( &store->LitColor[1], 0, size, 32 );
+ _mesa_vector4f_alloc( &store->LitSecondary[0], 0, size, 32 );
+ _mesa_vector4f_alloc( &store->LitSecondary[1], 0, size, 32 );
+ _mesa_vector4f_alloc( &store->LitIndex[0], 0, size, 32 );
+ _mesa_vector4f_alloc( &store->LitIndex[1], 0, size, 32 );
- _mesa_vector1ui_alloc( &store->LitIndex[0], 0, size, 32 );
- _mesa_vector1ui_alloc( &store->LitIndex[1], 0, size, 32 );
+ store->LitIndex[0].size = 1;
+ store->LitIndex[0].stride = sizeof(GLfloat);
+ store->LitIndex[1].size = 1;
+ store->LitIndex[1].stride = sizeof(GLfloat);
/* Now validate the stage derived data...
*/
* Check if lighting is enabled. If so, configure the pipeline stage's
* type, inputs, and outputs.
*/
-static void check_lighting( GLcontext *ctx, struct gl_pipeline_stage *stage )
+static void check_lighting( GLcontext *ctx, struct tnl_pipeline_stage *stage )
{
stage->active = ctx->Light.Enabled && !ctx->VertexProgram.Enabled;
if (stage->active) {
if (stage->privatePtr)
stage->run = run_validate_lighting;
- stage->inputs = VERT_BIT_NORMAL|VERT_BIT_MATERIAL;
+ stage->inputs = _TNL_BIT_NORMAL|_TNL_BITS_MAT_ANY;
if (ctx->Light._NeedVertices)
- stage->inputs |= VERT_BIT_EYE; /* effectively, even when lighting in obj */
+ stage->inputs |= _TNL_BIT_POS;
if (ctx->Light.ColorMaterialEnabled)
- stage->inputs |= VERT_BIT_COLOR0;
+ stage->inputs |= _TNL_BIT_COLOR0;
- stage->outputs = VERT_BIT_COLOR0;
+ stage->outputs = _TNL_BIT_COLOR0;
if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
- stage->outputs |= VERT_BIT_COLOR1;
+ stage->outputs |= _TNL_BIT_COLOR1;
}
}
-static void dtr( struct gl_pipeline_stage *stage )
+static void dtr( struct tnl_pipeline_stage *stage )
{
struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
if (store) {
- ALIGN_FREE( (void *) store->LitColor[0].Ptr );
- ALIGN_FREE( (void *) store->LitColor[1].Ptr );
- ALIGN_FREE( (void *) store->LitSecondary[0].Ptr );
- ALIGN_FREE( (void *) store->LitSecondary[1].Ptr );
-
- if (store->FloatColor.Ptr)
- ALIGN_FREE( (void *) store->FloatColor.Ptr );
-
- _mesa_vector1ui_free( &store->LitIndex[0] );
- _mesa_vector1ui_free( &store->LitIndex[1] );
+ _mesa_vector4f_free( &store->Input );
+ _mesa_vector4f_free( &store->LitColor[0] );
+ _mesa_vector4f_free( &store->LitColor[1] );
+ _mesa_vector4f_free( &store->LitSecondary[0] );
+ _mesa_vector4f_free( &store->LitSecondary[1] );
+ _mesa_vector4f_free( &store->LitIndex[0] );
+ _mesa_vector4f_free( &store->LitIndex[1] );
FREE( store );
stage->privatePtr = 0;
}
}
-const struct gl_pipeline_stage _tnl_lighting_stage =
+const struct tnl_pipeline_stage _tnl_lighting_stage =
{
"lighting", /* name */
_NEW_LIGHT, /* recheck */
_NEW_LIGHT|_NEW_MODELVIEW, /* recalc -- modelview dependency
* otherwise not captured by inputs
- * (which may be VERT_BIT_POS) */
+ * (which may be _TNL_BIT_POS) */
GL_FALSE, /* active? */
0, /* inputs */
0, /* outputs */
*/
-#if (IDX & LIGHT_FLAGS)
-# define VSTRIDE (4 * sizeof(GLfloat))
-# define NSTRIDE nstride /*(3 * sizeof(GLfloat))*/
-# define CHECK_MATERIAL(x) (flags[x] & VERT_BIT_MATERIAL)
-# define CHECK_END_VB(x) (flags[x] & VERT_BIT_END_VB)
-# if (IDX & LIGHT_COLORMATERIAL)
-# define CMSTRIDE STRIDE_F(CMcolor, CMstride)
-# define CHECK_COLOR_MATERIAL(x) (flags[x] & VERT_BIT_COLOR0)
-# define CHECK_VALIDATE(x) (flags[x] & (VERT_BIT_COLOR0|VERT_BIT_MATERIAL))
-# define DO_ANOTHER_NORMAL(x) \
- ((flags[x] & (VERT_BIT_COLOR0|VERT_BIT_NORMAL|VERT_BIT_END_VB|VERT_BIT_MATERIAL)) == VERT_BIT_NORMAL)
-# define REUSE_LIGHT_RESULTS(x) \
- ((flags[x] & (VERT_BIT_COLOR0|VERT_BIT_NORMAL|VERT_BIT_END_VB|VERT_BIT_MATERIAL)) == 0)
-# else
-# define CMSTRIDE (void)0
-# define CHECK_COLOR_MATERIAL(x) 0
-# define CHECK_VALIDATE(x) (flags[x] & (VERT_BIT_MATERIAL))
-# define DO_ANOTHER_NORMAL(x) \
- ((flags[x] & (VERT_BIT_NORMAL|VERT_BIT_END_VB|VERT_BIT_MATERIAL)) == VERT_BIT_NORMAL)
-# define REUSE_LIGHT_RESULTS(x) \
- ((flags[x] & (VERT_BIT_NORMAL|VERT_BIT_END_VB|VERT_BIT_MATERIAL)) == 0)
-# endif
-#else
-# define VSTRIDE vstride
-# define NSTRIDE nstride
-# define CHECK_MATERIAL(x) 0 /* no materials on array paths */
-# define CHECK_END_VB(XX) (XX >= nr)
-# if (IDX & LIGHT_COLORMATERIAL)
-# define CMSTRIDE STRIDE_F(CMcolor, CMstride)
-# define CHECK_COLOR_MATERIAL(x) (x < nr) /* always have colormaterial */
-# define CHECK_VALIDATE(x) (x < nr)
-# define DO_ANOTHER_NORMAL(x) 0 /* always stop to recalc colormat */
-# else
-# define CMSTRIDE (void)0
-# define CHECK_COLOR_MATERIAL(x) 0 /* no colormaterial */
-# define CHECK_VALIDATE(x) (0)
-# define DO_ANOTHER_NORMAL(XX) (XX < nr) /* keep going to end of vb */
-# endif
-# define REUSE_LIGHT_RESULTS(x) 0 /* always have a new normal */
-#endif
-
-
-
#if (IDX & LIGHT_TWOSIDE)
# define NR_SIDES 2
#else
#endif
-/* define TRACE if to trace lighting code */
+/* define TRACE to trace lighting code */
/* #define TRACE 1 */
/*
*/
static void TAG(light_rgba_spec)( GLcontext *ctx,
struct vertex_buffer *VB,
- struct gl_pipeline_stage *stage,
+ struct tnl_pipeline_stage *stage,
GLvector4f *input )
{
struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
GLfloat (*base)[3] = ctx->Light._BaseColor;
- GLchan sumA[2];
+ GLfloat sumA[2];
GLuint j;
const GLuint vstride = input->stride;
const GLuint nstride = VB->NormalPtr->stride;
const GLfloat *normal = (GLfloat *)VB->NormalPtr->data;
- GLfloat *CMcolor;
- GLuint CMstride;
-
- GLchan (*Fcolor)[4] = (GLchan (*)[4]) store->LitColor[0].Ptr;
- GLchan (*Bcolor)[4] = (GLchan (*)[4]) store->LitColor[1].Ptr;
- GLchan (*Fspec)[4] = (GLchan (*)[4]) store->LitSecondary[0].Ptr;
- GLchan (*Bspec)[4] = (GLchan (*)[4]) store->LitSecondary[1].Ptr;
+ GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;
+ GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
+ GLfloat (*Fspec)[4] = (GLfloat (*)[4]) store->LitSecondary[0].data;
+ GLfloat (*Bspec)[4] = (GLfloat (*)[4]) store->LitSecondary[1].data;
const GLuint nr = VB->Count;
- const GLuint *flags = VB->Flag;
- struct gl_material *new_material = VB->Material;
- const GLuint *new_material_mask = VB->MaterialMask;
- (void) flags;
(void) nstride;
(void) vstride;
fprintf(stderr, "%s\n", __FUNCTION__ );
#endif
- if (IDX & LIGHT_COLORMATERIAL) {
- if (VB->ColorPtr[0]->Type != GL_FLOAT ||
- VB->ColorPtr[0]->Size != 4)
- import_color_material( ctx, stage );
-
- CMcolor = (GLfloat *) VB->ColorPtr[0]->Ptr;
- CMstride = VB->ColorPtr[0]->StrideB;
- }
-
VB->ColorPtr[0] = &store->LitColor[0];
VB->SecondaryColorPtr[0] = &store->LitSecondary[0];
- UNCLAMPED_FLOAT_TO_CHAN(sumA[0], ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]);
+ sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
if (IDX & LIGHT_TWOSIDE) {
VB->ColorPtr[1] = &store->LitColor[1];
VB->SecondaryColorPtr[1] = &store->LitSecondary[1];
- UNCLAMPED_FLOAT_TO_CHAN(sumA[1], ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]);
+ sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
}
/* Side-effects done, can we finish now?
if (stage->changed_inputs == 0)
return;
- for ( j=0 ;
- j<nr ;
- j++,STRIDE_F(vertex,VSTRIDE),STRIDE_F(normal,NSTRIDE),CMSTRIDE)
- {
+ for (j = 0; j < nr; j++,STRIDE_F(vertex,vstride),STRIDE_F(normal,nstride)) {
GLfloat sum[2][3], spec[2][3];
struct gl_light *light;
- if ( CHECK_COLOR_MATERIAL(j) )
- _mesa_update_color_material( ctx, CMcolor );
-
- if ( CHECK_MATERIAL(j) )
- update_materials( ctx, &new_material[j], new_material_mask[j] );
-
- if ( CHECK_VALIDATE(j) ) {
- TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx );
- UNCLAMPED_FLOAT_TO_CHAN(sumA[0], ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]);
+ if ( IDX & LIGHT_MATERIAL ) {
+ update_materials( ctx, store );
+ sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
if (IDX & LIGHT_TWOSIDE)
- UNCLAMPED_FLOAT_TO_CHAN(sumA[1], ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]);
+ sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
}
COPY_3V(sum[0], base[0]);
}
} /*loop over lights*/
- UNCLAMPED_FLOAT_TO_RGB_CHAN( Fcolor[j], sum[0] );
- UNCLAMPED_FLOAT_TO_RGB_CHAN( Fspec[j], spec[0] );
+ COPY_3V( Fcolor[j], sum[0] );
+ COPY_3V( Fspec[j], spec[0] );
Fcolor[j][3] = sumA[0];
if (IDX & LIGHT_TWOSIDE) {
- UNCLAMPED_FLOAT_TO_RGB_CHAN( Bcolor[j], sum[1] );
- UNCLAMPED_FLOAT_TO_RGB_CHAN( Bspec[j], spec[1] );
+ COPY_3V( Bcolor[j], sum[1] );
+ COPY_3V( Bspec[j], spec[1] );
Bcolor[j][3] = sumA[1];
}
}
static void TAG(light_rgba)( GLcontext *ctx,
struct vertex_buffer *VB,
- struct gl_pipeline_stage *stage,
+ struct tnl_pipeline_stage *stage,
GLvector4f *input )
{
struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
GLuint j;
GLfloat (*base)[3] = ctx->Light._BaseColor;
- GLchan sumA[2];
+ GLfloat sumA[2];
const GLuint vstride = input->stride;
const GLfloat *vertex = (GLfloat *) input->data;
const GLuint nstride = VB->NormalPtr->stride;
const GLfloat *normal = (GLfloat *)VB->NormalPtr->data;
- GLfloat *CMcolor;
- GLuint CMstride;
-
- GLchan (*Fcolor)[4] = (GLchan (*)[4]) store->LitColor[0].Ptr;
- GLchan (*Bcolor)[4] = (GLchan (*)[4]) store->LitColor[1].Ptr;
- GLchan (*color[2])[4];
- const GLuint *flags = VB->Flag;
+ GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;
+ GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
+ GLfloat (*color[2])[4];
- struct gl_material *new_material = VB->Material;
- const GLuint *new_material_mask = VB->MaterialMask;
const GLuint nr = VB->Count;
#ifdef TRACE
fprintf(stderr, "%s\n", __FUNCTION__ );
#endif
- (void) flags;
(void) nstride;
(void) vstride;
color[0] = Fcolor;
color[1] = Bcolor;
- if (IDX & LIGHT_COLORMATERIAL) {
- if (VB->ColorPtr[0]->Type != GL_FLOAT ||
- VB->ColorPtr[0]->Size != 4)
- import_color_material( ctx, stage );
-
- CMcolor = (GLfloat *)VB->ColorPtr[0]->Ptr;
- CMstride = VB->ColorPtr[0]->StrideB;
- }
-
VB->ColorPtr[0] = &store->LitColor[0];
- UNCLAMPED_FLOAT_TO_CHAN(sumA[0], ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]);
+ sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
if (IDX & LIGHT_TWOSIDE) {
VB->ColorPtr[1] = &store->LitColor[1];
- UNCLAMPED_FLOAT_TO_CHAN(sumA[1], ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]);
+ sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
}
if (stage->changed_inputs == 0)
return;
- for ( j=0 ;
- j<nr ;
- j++,STRIDE_F(vertex,VSTRIDE), STRIDE_F(normal,NSTRIDE),CMSTRIDE)
- {
+ for (j = 0; j < nr; j++,STRIDE_F(vertex,vstride),STRIDE_F(normal,nstride)) {
GLfloat sum[2][3];
struct gl_light *light;
- if ( CHECK_COLOR_MATERIAL(j) )
- _mesa_update_color_material( ctx, CMcolor );
-
- if ( CHECK_MATERIAL(j) )
- update_materials( ctx, &new_material[j], new_material_mask[j] );
-
- if ( CHECK_VALIDATE(j) ) {
- TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx );
- UNCLAMPED_FLOAT_TO_CHAN(sumA[0], ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]);
+ if ( IDX & LIGHT_MATERIAL ) {
+ update_materials( ctx, store );
+ sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
if (IDX & LIGHT_TWOSIDE)
- UNCLAMPED_FLOAT_TO_CHAN(sumA[1], ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]);
+ sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
}
COPY_3V(sum[0], base[0]);
ACC_SCALE_SCALAR_3V( sum[side], attenuation, contrib );
}
- UNCLAMPED_FLOAT_TO_RGB_CHAN( Fcolor[j], sum[0] );
+ COPY_3V( Fcolor[j], sum[0] );
Fcolor[j][3] = sumA[0];
if (IDX & LIGHT_TWOSIDE) {
- UNCLAMPED_FLOAT_TO_RGB_CHAN( Bcolor[j], sum[1] );
+ COPY_3V( Bcolor[j], sum[1] );
Bcolor[j][3] = sumA[1];
}
}
*/
static void TAG(light_fast_rgba_single)( GLcontext *ctx,
struct vertex_buffer *VB,
- struct gl_pipeline_stage *stage,
+ struct tnl_pipeline_stage *stage,
GLvector4f *input )
{
struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
const GLuint nstride = VB->NormalPtr->stride;
const GLfloat *normal = (GLfloat *)VB->NormalPtr->data;
- GLfloat *CMcolor;
- GLuint CMstride;
- GLchan (*Fcolor)[4] = (GLchan (*)[4]) store->LitColor[0].Ptr;
- GLchan (*Bcolor)[4] = (GLchan (*)[4]) store->LitColor[1].Ptr;
+ GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;
+ GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
const struct gl_light *light = ctx->Light.EnabledList.next;
- const GLuint *flags = VB->Flag;
- GLchan basechan[2][4];
GLuint j = 0;
- struct gl_material *new_material = VB->Material;
- const GLuint *new_material_mask = VB->MaterialMask;
GLfloat base[2][3];
const GLuint nr = VB->Count;
#endif
(void) input; /* doesn't refer to Eye or Obj */
- (void) flags;
(void) nr;
(void) nstride;
- if (IDX & LIGHT_COLORMATERIAL) {
- if (VB->ColorPtr[0]->Type != GL_FLOAT ||
- VB->ColorPtr[0]->Size != 4)
- import_color_material( ctx, stage );
-
- CMcolor = (GLfloat *)VB->ColorPtr[0]->Ptr;
- CMstride = VB->ColorPtr[0]->StrideB;
- }
-
VB->ColorPtr[0] = &store->LitColor[0];
if (IDX & LIGHT_TWOSIDE)
VB->ColorPtr[1] = &store->LitColor[1];
if (stage->changed_inputs == 0)
return;
- do {
-
- if ( CHECK_COLOR_MATERIAL(j) ) {
- _mesa_update_color_material( ctx, CMcolor );
- }
-
- if ( CHECK_MATERIAL(j) )
- update_materials( ctx, &new_material[j], new_material_mask[j] );
+ for (j = 0; j < nr; j++, STRIDE_F(normal,nstride)) {
- if ( CHECK_VALIDATE(j) )
- TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx );
+ GLfloat n_dot_VP;
+ if ( IDX & LIGHT_MATERIAL )
+ update_materials( ctx, store );
/* No attenuation, so incoporate _MatAmbient into base color.
*/
- COPY_3V(base[0], light->_MatAmbient[0]);
- ACC_3V(base[0], ctx->Light._BaseColor[0] );
- UNCLAMPED_FLOAT_TO_RGB_CHAN( basechan[0], base[0] );
- UNCLAMPED_FLOAT_TO_CHAN(basechan[0][3],
- ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]);
+ if ( j == 0 || (IDX & LIGHT_MATERIAL) ) {
+ COPY_3V(base[0], light->_MatAmbient[0]);
+ ACC_3V(base[0], ctx->Light._BaseColor[0] );
+ base[0][3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
- if (IDX & LIGHT_TWOSIDE) {
- COPY_3V(base[1], light->_MatAmbient[1]);
- ACC_3V(base[1], ctx->Light._BaseColor[1]);
- UNCLAMPED_FLOAT_TO_RGB_CHAN( basechan[1], base[1]);
- UNCLAMPED_FLOAT_TO_CHAN(basechan[1][3],
- ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]);
+ if (IDX & LIGHT_TWOSIDE) {
+ COPY_3V(base[1], light->_MatAmbient[1]);
+ ACC_3V(base[1], ctx->Light._BaseColor[1]);
+ base[1][3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
+ }
}
- do {
- GLfloat n_dot_VP = DOT3(normal, light->_VP_inf_norm);
+ n_dot_VP = DOT3(normal, light->_VP_inf_norm);
- if (n_dot_VP < 0.0F) {
- if (IDX & LIGHT_TWOSIDE) {
- GLfloat n_dot_h = -DOT3(normal, light->_h_inf_norm);
- GLfloat sum[3];
- COPY_3V(sum, base[1]);
- ACC_SCALE_SCALAR_3V(sum, -n_dot_VP, light->_MatDiffuse[1]);
- if (n_dot_h > 0.0F) {
- GLfloat spec;
- GET_SHINE_TAB_ENTRY( ctx->_ShineTable[1], n_dot_h, spec );
- ACC_SCALE_SCALAR_3V(sum, spec, light->_MatSpecular[1]);
- }
- UNCLAMPED_FLOAT_TO_RGB_CHAN(Bcolor[j], sum );
- Bcolor[j][3] = basechan[1][3];
- }
- COPY_CHAN4(Fcolor[j], basechan[0]);
- }
- else {
- GLfloat n_dot_h = DOT3(normal, light->_h_inf_norm);
+ if (n_dot_VP < 0.0F) {
+ if (IDX & LIGHT_TWOSIDE) {
+ GLfloat n_dot_h = -DOT3(normal, light->_h_inf_norm);
GLfloat sum[3];
- COPY_3V(sum, base[0]);
- ACC_SCALE_SCALAR_3V(sum, n_dot_VP, light->_MatDiffuse[0]);
+ COPY_3V(sum, base[1]);
+ ACC_SCALE_SCALAR_3V(sum, -n_dot_VP, light->_MatDiffuse[1]);
if (n_dot_h > 0.0F) {
GLfloat spec;
- GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec );
- ACC_SCALE_SCALAR_3V(sum, spec, light->_MatSpecular[0]);
-
+ GET_SHINE_TAB_ENTRY( ctx->_ShineTable[1], n_dot_h, spec );
+ ACC_SCALE_SCALAR_3V(sum, spec, light->_MatSpecular[1]);
}
- UNCLAMPED_FLOAT_TO_RGB_CHAN(Fcolor[j], sum );
- Fcolor[j][3] = basechan[0][3];
- if (IDX & LIGHT_TWOSIDE) COPY_CHAN4(Bcolor[j], basechan[1]);
+ COPY_3V(Bcolor[j], sum );
+ Bcolor[j][3] = base[1][3];
}
-
- j++;
- CMSTRIDE;
- STRIDE_F(normal, NSTRIDE);
- } while (DO_ANOTHER_NORMAL(j));
-
-
- for ( ; REUSE_LIGHT_RESULTS(j) ; j++, CMSTRIDE, STRIDE_F(normal,NSTRIDE))
- {
- COPY_CHAN4(Fcolor[j], Fcolor[j-1]);
- if (IDX & LIGHT_TWOSIDE)
- COPY_CHAN4(Bcolor[j], Bcolor[j-1]);
+ COPY_4FV(Fcolor[j], base[0]);
}
+ else {
+ GLfloat n_dot_h = DOT3(normal, light->_h_inf_norm);
+ GLfloat sum[3];
+ COPY_3V(sum, base[0]);
+ ACC_SCALE_SCALAR_3V(sum, n_dot_VP, light->_MatDiffuse[0]);
+ if (n_dot_h > 0.0F) {
+ GLfloat spec;
+ GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec );
+ ACC_SCALE_SCALAR_3V(sum, spec, light->_MatSpecular[0]);
- } while (!CHECK_END_VB(j));
+ }
+ COPY_3V(Fcolor[j], sum );
+ Fcolor[j][3] = base[0][3];
+ if (IDX & LIGHT_TWOSIDE) COPY_4FV(Bcolor[j], base[1]);
+ }
+ }
}
*/
static void TAG(light_fast_rgba)( GLcontext *ctx,
struct vertex_buffer *VB,
- struct gl_pipeline_stage *stage,
+ struct tnl_pipeline_stage *stage,
GLvector4f *input )
{
struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
- GLchan sumA[2];
+ GLfloat sumA[2];
const GLuint nstride = VB->NormalPtr->stride;
const GLfloat *normal = (GLfloat *)VB->NormalPtr->data;
- GLfloat *CMcolor;
- GLuint CMstride;
- GLchan (*Fcolor)[4] = (GLchan (*)[4]) store->LitColor[0].Ptr;
- GLchan (*Bcolor)[4] = (GLchan (*)[4]) store->LitColor[1].Ptr;
- const GLuint *flags = VB->Flag;
+ GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;
+ GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
GLuint j = 0;
- struct gl_material *new_material = VB->Material;
- GLuint *new_material_mask = VB->MaterialMask;
const GLuint nr = VB->Count;
const struct gl_light *light;
#ifdef TRACE
- fprintf(stderr, "%s\n", __FUNCTION__ );
+ fprintf(stderr, "%s %d\n", __FUNCTION__, nr );
#endif
- (void) flags;
(void) input;
(void) nr;
(void) nstride;
- UNCLAMPED_FLOAT_TO_CHAN(sumA[0], ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]);
- UNCLAMPED_FLOAT_TO_CHAN(sumA[1], ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]);
-
- if (IDX & LIGHT_COLORMATERIAL) {
- if (VB->ColorPtr[0]->Type != GL_FLOAT ||
- VB->ColorPtr[0]->Size != 4)
- import_color_material( ctx, stage );
-
- CMcolor = (GLfloat *)VB->ColorPtr[0]->Ptr;
- CMstride = VB->ColorPtr[0]->StrideB;
- }
+ sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
+ sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
VB->ColorPtr[0] = &store->LitColor[0];
if (IDX & LIGHT_TWOSIDE)
if (stage->changed_inputs == 0)
return;
- do {
- do {
- GLfloat sum[2][3];
+ for (j = 0; j < nr; j++, STRIDE_F(normal,nstride)) {
- if ( CHECK_COLOR_MATERIAL(j) )
- _mesa_update_color_material( ctx, CMcolor );
+ GLfloat sum[2][3];
- if ( CHECK_MATERIAL(j) )
- update_materials( ctx, &new_material[j], new_material_mask[j] );
+ if ( IDX & LIGHT_MATERIAL ) {
+ update_materials( ctx, store );
- if ( CHECK_VALIDATE(j) ) {
- TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx );
- UNCLAMPED_FLOAT_TO_CHAN(sumA[0], ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]);
- if (IDX & LIGHT_TWOSIDE)
- UNCLAMPED_FLOAT_TO_CHAN(sumA[1],
- ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]);
- }
+ sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
+ if (IDX & LIGHT_TWOSIDE)
+ sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
+ }
- COPY_3V(sum[0], ctx->Light._BaseColor[0]);
- if (IDX & LIGHT_TWOSIDE)
- COPY_3V(sum[1], ctx->Light._BaseColor[1]);
+ COPY_3V(sum[0], ctx->Light._BaseColor[0]);
+ if (IDX & LIGHT_TWOSIDE)
+ COPY_3V(sum[1], ctx->Light._BaseColor[1]);
- foreach (light, &ctx->Light.EnabledList) {
- GLfloat n_dot_h, n_dot_VP, spec;
+ foreach (light, &ctx->Light.EnabledList) {
+ GLfloat n_dot_h, n_dot_VP, spec;
- ACC_3V(sum[0], light->_MatAmbient[0]);
- if (IDX & LIGHT_TWOSIDE)
- ACC_3V(sum[1], light->_MatAmbient[1]);
+ ACC_3V(sum[0], light->_MatAmbient[0]);
+ if (IDX & LIGHT_TWOSIDE)
+ ACC_3V(sum[1], light->_MatAmbient[1]);
- n_dot_VP = DOT3(normal, light->_VP_inf_norm);
+ n_dot_VP = DOT3(normal, light->_VP_inf_norm);
- if (n_dot_VP > 0.0F) {
- ACC_SCALE_SCALAR_3V(sum[0], n_dot_VP, light->_MatDiffuse[0]);
- n_dot_h = DOT3(normal, light->_h_inf_norm);
- if (n_dot_h > 0.0F) {
- struct gl_shine_tab *tab = ctx->_ShineTable[0];
- GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec );
- ACC_SCALE_SCALAR_3V( sum[0], spec,
- light->_MatSpecular[0]);
- }
- }
- else if (IDX & LIGHT_TWOSIDE) {
- ACC_SCALE_SCALAR_3V(sum[1], -n_dot_VP, light->_MatDiffuse[1]);
- n_dot_h = -DOT3(normal, light->_h_inf_norm);
- if (n_dot_h > 0.0F) {
- struct gl_shine_tab *tab = ctx->_ShineTable[1];
- GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec );
- ACC_SCALE_SCALAR_3V( sum[1], spec,
- light->_MatSpecular[1]);
- }
+ if (n_dot_VP > 0.0F) {
+ ACC_SCALE_SCALAR_3V(sum[0], n_dot_VP, light->_MatDiffuse[0]);
+ n_dot_h = DOT3(normal, light->_h_inf_norm);
+ if (n_dot_h > 0.0F) {
+ struct gl_shine_tab *tab = ctx->_ShineTable[0];
+ GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec );
+ ACC_SCALE_SCALAR_3V( sum[0], spec, light->_MatSpecular[0]);
}
}
-
- UNCLAMPED_FLOAT_TO_RGB_CHAN( Fcolor[j], sum[0] );
- Fcolor[j][3] = sumA[0];
-
- if (IDX & LIGHT_TWOSIDE) {
- UNCLAMPED_FLOAT_TO_RGB_CHAN( Bcolor[j], sum[1] );
- Bcolor[j][3] = sumA[1];
+ else if (IDX & LIGHT_TWOSIDE) {
+ ACC_SCALE_SCALAR_3V(sum[1], -n_dot_VP, light->_MatDiffuse[1]);
+ n_dot_h = -DOT3(normal, light->_h_inf_norm);
+ if (n_dot_h > 0.0F) {
+ struct gl_shine_tab *tab = ctx->_ShineTable[1];
+ GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec );
+ ACC_SCALE_SCALAR_3V( sum[1], spec, light->_MatSpecular[1]);
+ }
}
+ }
- j++;
- CMSTRIDE;
- STRIDE_F(normal, NSTRIDE);
- } while (DO_ANOTHER_NORMAL(j));
+ COPY_3V( Fcolor[j], sum[0] );
+ Fcolor[j][3] = sumA[0];
- /* Reuse the shading results while there is no change to
- * normal or material values.
- */
- for ( ; REUSE_LIGHT_RESULTS(j) ; j++, CMSTRIDE, STRIDE_F(normal, NSTRIDE))
- {
- COPY_CHAN4(Fcolor[j], Fcolor[j-1]);
- if (IDX & LIGHT_TWOSIDE)
- COPY_CHAN4(Bcolor[j], Bcolor[j-1]);
+ if (IDX & LIGHT_TWOSIDE) {
+ COPY_3V( Bcolor[j], sum[1] );
+ Bcolor[j][3] = sumA[1];
}
-
- } while (!CHECK_END_VB(j));
+ }
}
*/
static void TAG(light_ci)( GLcontext *ctx,
struct vertex_buffer *VB,
- struct gl_pipeline_stage *stage,
+ struct tnl_pipeline_stage *stage,
GLvector4f *input )
{
struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
const GLfloat *vertex = (GLfloat *) input->data;
const GLuint nstride = VB->NormalPtr->stride;
const GLfloat *normal = (GLfloat *)VB->NormalPtr->data;
- GLfloat *CMcolor;
- GLuint CMstride;
- const GLuint *flags = VB->Flag;
- GLuint *indexResult[2];
- struct gl_material *new_material = VB->Material;
- GLuint *new_material_mask = VB->MaterialMask;
+ GLfloat *indexResult[2];
const GLuint nr = VB->Count;
#ifdef TRACE
fprintf(stderr, "%s\n", __FUNCTION__ );
#endif
- (void) flags;
(void) nstride;
(void) vstride;
if (stage->changed_inputs == 0)
return;
- indexResult[0] = VB->IndexPtr[0]->data;
+ indexResult[0] = (GLfloat *)VB->IndexPtr[0]->data;
if (IDX & LIGHT_TWOSIDE)
- indexResult[1] = VB->IndexPtr[1]->data;
-
- if (IDX & LIGHT_COLORMATERIAL) {
- if (VB->ColorPtr[0]->Type != GL_FLOAT ||
- VB->ColorPtr[0]->Size != 4)
- import_color_material( ctx, stage );
-
- CMcolor = (GLfloat *)VB->ColorPtr[0]->Ptr;
- CMstride = VB->ColorPtr[0]->StrideB;
- }
+ indexResult[1] = (GLfloat *)VB->IndexPtr[1]->data;
/* loop over vertices */
- for ( j=0 ;
- j<nr ;
- j++,STRIDE_F(vertex,VSTRIDE),STRIDE_F(normal, NSTRIDE), CMSTRIDE)
- {
+ for (j=0; j<nr; j++,STRIDE_F(vertex,vstride),STRIDE_F(normal, nstride)) {
GLfloat diffuse[2], specular[2];
GLuint side = 0;
struct gl_light *light;
- if ( CHECK_COLOR_MATERIAL(j) )
- _mesa_update_color_material( ctx, CMcolor );
-
- if ( CHECK_MATERIAL(j) )
- update_materials( ctx, &new_material[j], new_material_mask[j] );
-
- if ( CHECK_VALIDATE(j) )
- TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx );
+ if ( IDX & LIGHT_MATERIAL )
+ update_materials( ctx, store );
diffuse[0] = specular[0] = 0.0F;
else {
GLfloat d_a = ind[MAT_INDEX_DIFFUSE] - ind[MAT_INDEX_AMBIENT];
GLfloat s_a = ind[MAT_INDEX_SPECULAR] - ind[MAT_INDEX_AMBIENT];
-
index = (ind[MAT_INDEX_AMBIENT]
+ diffuse[side] * (1.0F-specular[side]) * d_a
+ specular[side] * s_a);
index = ind[MAT_INDEX_SPECULAR];
}
}
- indexResult[side][j] = (GLuint) (GLint) index;
+ indexResult[side][j] = index;
}
} /*for vertex*/
}
#undef TAG
#undef IDX
#undef NR_SIDES
-#undef NSTRIDE
-#undef VSTRIDE
-#undef CHECK_MATERIAL
-#undef CHECK_END_VB
-#undef DO_ANOTHER_NORMAL
-#undef REUSE_LIGHT_RESULTS
-#undef CMSTRIDE
-#undef CHECK_COLOR_MATERIAL
-#undef CHECK_VALIDATE
static GLboolean run_normal_stage( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
struct normal_stage_data *store = NORMAL_STAGE_DATA(stage);
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
static GLboolean run_validate_normal_stage( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
struct normal_stage_data *store = NORMAL_STAGE_DATA(stage);
static void check_normal_transform( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
stage->active = !ctx->VertexProgram.Enabled &&
(ctx->Light.Enabled || (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS));
static GLboolean alloc_normal_data( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct normal_stage_data *store;
-static void free_normal_data( struct gl_pipeline_stage *stage )
+static void free_normal_data( struct tnl_pipeline_stage *stage )
{
struct normal_stage_data *store = NORMAL_STAGE_DATA(stage);
if (store) {
-const struct gl_pipeline_stage _tnl_normal_transform_stage =
+const struct tnl_pipeline_stage _tnl_normal_transform_stage =
{
"normal transform", /* name */
_TNL_NEW_NORMAL_TRANSFORM, /* re-check */
_TNL_NEW_NORMAL_TRANSFORM, /* re-run */
GL_FALSE, /* active? */
- VERT_BIT_NORMAL, /* inputs */
- VERT_BIT_NORMAL, /* outputs */
+ _TNL_BIT_NORMAL, /* inputs */
+ _TNL_BIT_NORMAL, /* outputs */
0, /* changed_inputs */
NULL, /* private data */
free_normal_data, /* destructor */
* Compute attenuated point sizes
*/
static GLboolean run_point_stage( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
struct point_stage_data *store = POINT_STAGE_DATA(stage);
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
/* If point size attenuation is on we'll compute the point size for
* each vertex in a special pipeline stage.
*/
-static void check_point_size( GLcontext *ctx, struct gl_pipeline_stage *d )
+static void check_point_size( GLcontext *ctx, struct tnl_pipeline_stage *d )
{
d->active = ctx->Point._Attenuated && !ctx->VertexProgram.Enabled;
}
static GLboolean alloc_point_data( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
struct point_stage_data *store;
}
-static void free_point_data( struct gl_pipeline_stage *stage )
+static void free_point_data( struct tnl_pipeline_stage *stage )
{
struct point_stage_data *store = POINT_STAGE_DATA(stage);
if (store) {
}
}
-const struct gl_pipeline_stage _tnl_point_attenuation_stage =
+const struct tnl_pipeline_stage _tnl_point_attenuation_stage =
{
"point size attenuation", /* name */
_NEW_POINT, /* build_state_change */
_NEW_POINT, /* run_state_change */
GL_FALSE, /* active */
- VERT_BIT_EYE, /* inputs */
- VERT_BIT_POINT_SIZE, /* outputs */
+ _TNL_BIT_POS, /* inputs */
+ _TNL_BIT_POS, /* outputs */
0, /* changed_inputs (temporary value) */
NULL, /* stage private data */
free_point_data, /* destructor */
#include "t_context.h"
#include "t_pipeline.h"
-#include "t_imm_api.h"
-#include "t_imm_exec.h"
/**
/** The results of running the vertex program go into these arrays. */
GLvector4f attribs[15];
- /* These point to the attribs[VERT_RESULT_COL0, COL1, BFC0, BFC1] arrays */
- struct gl_client_array color0[2]; /**< diffuse front and back */
- struct gl_client_array color1[2]; /**< specular front and back */
-
GLvector4f ndcCoords; /**< normalized device coords */
GLubyte *clipmask; /**< clip flags */
GLubyte ormask, andmask; /**< for clipping */
/**
* This function executes vertex programs
*/
-static GLboolean run_vp( GLcontext *ctx, struct gl_pipeline_stage *stage )
+static GLboolean run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vp_stage_data *store = VP_STAGE_DATA(stage);
VB->AttribPtr[2]->data[i][3]);
#endif
- /* load the input attribute registers */
- if (VB->Flag) {
- /* the traditional glBegin/glVertex/glEnd case */
- for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
- if (attr == 0 || (program->InputsRead & (1 << attr))) {
- COPY_4V(ctx->VertexProgram.Inputs[attr],
- VB->AttribPtr[attr]->data[i]);
- }
- }
- }
- else {
- /* the vertex array case */
- for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
- if (program->InputsRead & (1 << attr)) {
- const GLubyte *ptr = (const GLubyte*) VB->AttribPtr[attr]->data;
- const GLuint stride = VB->AttribPtr[attr]->stride;
- const GLfloat *data = (GLfloat *) (ptr + stride * i);
- COPY_4V(ctx->VertexProgram.Inputs[attr], data);
- /*ASSERT(VB->AttribPtr[attr]->size == 4);*/
- ASSERT(stride == 4 * sizeof(GLfloat) || stride == 0);
- }
- }
+ /* the vertex array case */
+ for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
+ if (program->InputsRead & (1 << attr)) {
+ const GLubyte *ptr = (const GLubyte*) VB->AttribPtr[attr]->data;
+ const GLuint size = VB->AttribPtr[attr]->size;
+ const GLuint stride = VB->AttribPtr[attr]->stride;
+ const GLfloat *data = (GLfloat *) (ptr + stride * i);
+ ASSIGN_4V(ctx->VertexProgram.Inputs[attr], 0, 0, 0, 1);
+ COPY_SZ_4V(ctx->VertexProgram.Inputs[attr], size, data);
+ }
}
/* execute the program */
VB->ClipPtr = &store->attribs[VERT_RESULT_HPOS];
VB->ClipPtr->size = 4;
VB->ClipPtr->count = VB->Count;
- VB->ColorPtr[0] = &store->color0[0];
- VB->ColorPtr[1] = &store->color0[1];
- VB->SecondaryColorPtr[0] = &store->color1[0];
- VB->SecondaryColorPtr[1] = &store->color1[1];
+ VB->ColorPtr[0] = &store->attribs[VERT_RESULT_COL0];
+ VB->ColorPtr[1] = &store->attribs[VERT_RESULT_BFC0];
+ VB->SecondaryColorPtr[0] = &store->attribs[VERT_RESULT_COL1];
+ VB->SecondaryColorPtr[1] = &store->attribs[VERT_RESULT_BFC1];
VB->FogCoordPtr = &store->attribs[VERT_RESULT_FOGC];
VB->PointSizePtr = &store->attribs[VERT_RESULT_PSIZ];
for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
VB->ClipOrMask = store->ormask;
VB->ClipMask = store->clipmask;
- /* XXXX what's this?
- if (VB->ClipPtr == VB->ObjPtr && (VB->importable_data & VERT_BIT_POS))
- VB->importable_data |= VERT_BIT_CLIP;
- */
-
return GL_TRUE;
}
* This function validates stuff.
*/
static GLboolean run_validate_program( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
#if 000
/* XXX do we need any validation for vertex programs? */
}
-/**
- * Initialize a gl_client_array to point into a GLvector4f color vector.
- */
-static void init_color_array( struct gl_client_array *a, GLvector4f *vec )
-{
- a->Ptr = (GLubyte *) vec->data;
- a->Size = 4;
- a->Type = GL_FLOAT;
- a->Stride = 0;
- a->StrideB = sizeof(GLfloat) * 4;
- a->Enabled = 0;
- a->Flags = 0;
-}
-
/**
* Called the first time stage->run is called. In effect, don't
* allocate data until the first time the stage is run.
*/
static GLboolean run_init_vp( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &(tnl->vb);
store->attribs[i].size = 4;
}
- /* Make the color0[] and color1[] arrays point into the attribs[] arrays */
- init_color_array( &store->color0[0], &store->attribs[VERT_RESULT_COL0] );
- init_color_array( &store->color0[1], &store->attribs[VERT_RESULT_BFC0] );
- init_color_array( &store->color1[0], &store->attribs[VERT_RESULT_COL1] );
- init_color_array( &store->color1[1], &store->attribs[VERT_RESULT_BFC1] );
-
/* a few other misc allocations */
_mesa_vector4f_alloc( &store->ndcCoords, 0, size, 32 );
store->clipmask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte)*size, 32 );
* Check if vertex program mode is enabled.
* If so, configure the pipeline stage's type, inputs, and outputs.
*/
-static void check_vp( GLcontext *ctx, struct gl_pipeline_stage *stage )
+static void check_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage )
{
stage->active = ctx->VertexProgram.Enabled;
if (stage->active) {
- /* I believe this is right - Keith?
- * Set stage->inputs equal to the bitmask of vertex attributes
+ /* Set stage->inputs equal to the bitmask of vertex attributes
* which the program needs for inputs.
*/
-
stage->inputs = ctx->VertexProgram.Current->InputsRead;
-
-#if 000
- if (stage->privatePtr)
- stage->run = run_validate_program;
- stage->inputs = VERT_BIT_NORMAL|VERT_BIT_MATERIAL;
- if (ctx->Light._NeedVertices)
- stage->inputs |= VERT_BIT_EYE; /* effectively, even when lighting in obj */
- if (ctx->Light.ColorMaterialEnabled)
- stage->inputs |= VERT_BIT_COLOR0;
-
- stage->outputs = VERT_BIT_COLOR0;
- if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
- stage->outputs |= VERT_BIT_COLOR1;
-#endif
}
}
/**
* Destructor for this pipeline stage.
*/
-static void dtr( struct gl_pipeline_stage *stage )
+static void dtr( struct tnl_pipeline_stage *stage )
{
struct vp_stage_data *store = VP_STAGE_DATA(stage);
/**
* Public description of this pipeline stage.
*/
-const struct gl_pipeline_stage _tnl_vertex_program_stage =
+const struct tnl_pipeline_stage _tnl_vertex_program_stage =
{
"vertex-program",
_NEW_ALL, /*XXX FIX */ /* recheck */
- _NEW_ALL, /*XXX FIX */ /* recalc -- modelview dependency
- * otherwise not captured by inputs
- * (which may be VERT_BIT_POS) */
+ _NEW_ALL, /*XXX FIX */ /* recalc */
GL_FALSE, /* active */
- /*0*/ VERT_BIT_POS, /* inputs XXX OK? */
- VERT_BIT_CLIP | VERT_BIT_COLOR0, /* outputs XXX OK? */
+ 0, /* inputs - calculated on the fly */
+ _TNL_BITS_PROG_ANY, /* outputs -- could calculate */
0, /* changed_inputs */
NULL, /* private_data */
dtr, /* destroy */
static GLboolean run_render( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
do
{
- GLuint i, length, flags = 0;
- for (i = VB->FirstPrimitive ; !(flags & PRIM_LAST) ; i += length)
+ GLint i;
+
+ for (i = 0 ; i < VB->PrimitiveCount ; i++)
{
- flags = VB->Primitive[i];
- length= VB->PrimitiveLength[i];
- ASSERT(length || (flags & PRIM_LAST));
- ASSERT((flags & PRIM_MODE_MASK) <= GL_POLYGON+1);
+ GLuint prim = VB->Primitive[i].mode;
+ GLuint start = VB->Primitive[i].start;
+ GLuint length = VB->Primitive[i].count;
+
+ assert((prim & PRIM_MODE_MASK) < GL_POLYGON+1);
- if (MESA_VERBOSE & VERBOSE_PRIMS)
+ if (MESA_VERBOSE & VERBOSE_PRIMS)
_mesa_debug(NULL, "MESA prim %s %d..%d\n",
- _mesa_lookup_enum_by_nr(flags & PRIM_MODE_MASK),
- i, i+length);
+ _mesa_lookup_enum_by_nr(prim & PRIM_MODE_MASK),
+ start, start+length);
if (length)
- tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags );
+ tab[prim & PRIM_MODE_MASK]( ctx, start, start + length, prim );
}
} while (tnl->Driver.Render.Multipass &&
tnl->Driver.Render.Multipass( ctx, ++pass ));
-
tnl->Driver.Render.Finish( ctx );
-/* _swrast_flush(ctx); */
-/* usleep(1000000); */
+
return GL_FALSE; /* finished the pipe */
}
/* Quite a bit of work involved in finding out the inputs for the
* render stage.
*/
-static void check_render( GLcontext *ctx, struct gl_pipeline_stage *stage )
+static void check_render( GLcontext *ctx, struct tnl_pipeline_stage *stage )
{
- GLuint inputs = VERT_BIT_CLIP;
+ GLuint inputs = _TNL_BIT_POS;
GLuint i;
if (ctx->Visual.rgbMode) {
- inputs |= VERT_BIT_COLOR0;
+ inputs |= _TNL_BIT_COLOR0;
if (NEED_SECONDARY_COLOR(ctx))
- inputs |= VERT_BIT_COLOR1;
+ inputs |= _TNL_BIT_COLOR1;
if (ctx->Texture._EnabledCoordUnits) {
for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
if (ctx->Texture._EnabledCoordUnits & (1 << i))
- inputs |= VERT_BIT_TEX(i);
+ inputs |= _TNL_BIT_TEX(i);
}
}
}
else {
- inputs |= VERT_BIT_INDEX;
+ inputs |= _TNL_BIT_INDEX;
}
- if (ctx->Point._Attenuated)
- inputs |= VERT_BIT_POINT_SIZE;
-
/* How do drivers turn this off?
*/
if (ctx->Fog.Enabled)
- inputs |= VERT_BIT_FOG;
+ inputs |= _TNL_BIT_FOG;
if (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL)
- inputs |= VERT_BIT_EDGEFLAG;
+ inputs |= _TNL_BIT_EDGEFLAG;
if (ctx->RenderMode==GL_FEEDBACK)
- inputs |= VERT_BITS_TEX_ANY;
+ inputs |= _TNL_BITS_TEX_ANY;
stage->inputs = inputs;
}
-static void dtr( struct gl_pipeline_stage *stage )
+static void dtr( struct tnl_pipeline_stage *stage )
{
}
-const struct gl_pipeline_stage _tnl_render_stage =
+const struct tnl_pipeline_stage _tnl_render_stage =
{
"render", /* name */
(_NEW_BUFFERS |
#ifndef TEST_PRIM_END
#define TEST_PRIM_END(flags) (flags & PRIM_END)
#define TEST_PRIM_BEGIN(flags) (flags & PRIM_BEGIN)
-#define TEST_PRIM_PARITY(flags) (flags & PRIM_PARITY)
#endif
#ifndef ELT
GLuint parity = 0;
LOCAL_VARS;
- if (TEST_PRIM_PARITY(flags))
- parity = 1;
-
INIT(GL_TRIANGLE_STRIP);
if (NEED_EDGEFLAG_SETUP) {
for (j=start+2;j<count;j++,parity^=1) {
GLfloat (*f)[3] = store->tmp_f;
GLfloat *m = store->tmp_m;
-
-/* _mesa_debug(NULL, "%s normstride %d eyestride %d\n", */
-/* __FUNCTION__, VB->NormalPtr->stride, */
-/* VB->EyePtr->stride); */
-
(build_m_tab[VB->EyePtr->size])( store->tmp_f,
store->tmp_m,
VB->NormalPtr,
static GLboolean run_texgen_stage( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
struct texgen_stage_data *store = TEXGEN_STAGE_DATA( stage );
for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
if (ctx->Texture._TexGenEnabled & ENABLE_TEXGEN(i)) {
- if (stage->changed_inputs & (VERT_BIT_EYE | VERT_BIT_NORMAL | VERT_BIT_TEX(i)))
+ if (stage->changed_inputs & (_TNL_BIT_POS | _TNL_BIT_NORMAL | _TNL_BIT_TEX(i)))
store->TexgenFunc[i]( ctx, store, i );
VB->TexCoordPtr[i] = &store->texcoord[i];
static GLboolean run_validate_texgen_stage( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage);
GLuint i;
}
-static void check_texgen( GLcontext *ctx, struct gl_pipeline_stage *stage )
+static void check_texgen( GLcontext *ctx, struct tnl_pipeline_stage *stage )
{
GLuint i;
stage->active = 0;
GLuint inputs = 0;
GLuint outputs = 0;
- if (ctx->Texture._GenFlags & TEXGEN_OBJ_LINEAR)
- inputs |= VERT_BIT_POS;
-
- if (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD)
- inputs |= VERT_BIT_EYE;
+ if (ctx->Texture._GenFlags & (TEXGEN_OBJ_LINEAR | TEXGEN_NEED_EYE_COORD))
+ inputs |= _TNL_BIT_POS;
if (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS)
- inputs |= VERT_BIT_NORMAL;
+ inputs |= _TNL_BIT_NORMAL;
for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
if (ctx->Texture._TexGenEnabled & ENABLE_TEXGEN(i))
{
- outputs |= VERT_BIT_TEX(i);
+ outputs |= _TNL_BIT_TEX(i);
/* Need the original input in case it contains a Q coord:
* (sigh)
*/
- inputs |= VERT_BIT_TEX(i);
+ inputs |= _TNL_BIT_TEX(i);
/* Something for Feedback? */
}
/* Called the first time stage->run() is invoked.
*/
static GLboolean alloc_texgen_data( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
struct texgen_stage_data *store;
}
-static void free_texgen_data( struct gl_pipeline_stage *stage )
+static void free_texgen_data( struct tnl_pipeline_stage *stage )
{
struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage);
-const struct gl_pipeline_stage _tnl_texgen_stage =
+const struct tnl_pipeline_stage _tnl_texgen_stage =
{
"texgen", /* name */
_NEW_TEXTURE, /* when to call check() */
#define TEXMAT_STAGE_DATA(stage) ((struct texmat_stage_data *)stage->privatePtr)
-static void check_texmat( GLcontext *ctx, struct gl_pipeline_stage *stage )
+static void check_texmat( GLcontext *ctx, struct tnl_pipeline_stage *stage )
{
GLuint i;
stage->active = 0;
for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
if (ctx->Texture._TexMatEnabled & ENABLE_TEXMAT(i))
- flags |= VERT_BIT_TEX(i);
+ flags |= _TNL_BIT_TEX(i);
stage->active = 1;
stage->inputs = flags;
}
static GLboolean run_texmat_stage( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
struct texmat_stage_data *store = TEXMAT_STAGE_DATA(stage);
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
*/
for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
if (ctx->Texture._TexMatEnabled & ENABLE_TEXMAT(i)) {
- if (stage->changed_inputs & VERT_BIT_TEX(i))
+ if (stage->changed_inputs & _TNL_BIT_TEX(i))
(void) TransformRaw( &store->texcoord[i],
ctx->TextureMatrixStack[i].Top,
VB->TexCoordPtr[i]);
/* Called the first time stage->run() is invoked.
*/
static GLboolean alloc_texmat_data( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
struct texmat_stage_data *store;
}
-static void free_texmat_data( struct gl_pipeline_stage *stage )
+static void free_texmat_data( struct tnl_pipeline_stage *stage )
{
struct texmat_stage_data *store = TEXMAT_STAGE_DATA(stage);
GLuint i;
-const struct gl_pipeline_stage _tnl_texture_transform_stage =
+const struct tnl_pipeline_stage _tnl_texture_transform_stage =
{
"texture transform", /* name */
_NEW_TEXTURE|_NEW_TEXTURE_MATRIX, /* check_state */
static GLboolean run_vertex_stage( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
struct vertex_stage_data *store = (struct vertex_stage_data *)stage->privatePtr;
TNLcontext *tnl = TNL_CONTEXT(ctx);
VB->EyePtr = TransformRaw( &store->eye,
ctx->ModelviewMatrixStack.Top,
VB->ObjPtr);
-
- if (ctx->ProjectionMatrixStack.Top->type == MATRIX_IDENTITY)
- VB->ClipPtr = VB->EyePtr;
- else
- VB->ClipPtr = TransformRaw( &store->clip,
- &ctx->_ModelProjectMatrix,
- VB->ObjPtr );
- }
- else {
- /* Combined modelviewproject transform:
- */
- if (ctx->_ModelProjectMatrix.type == MATRIX_IDENTITY)
- VB->ClipPtr = VB->ObjPtr;
- else
- VB->ClipPtr = TransformRaw( &store->clip,
- &ctx->_ModelProjectMatrix,
- VB->ObjPtr );
}
+ VB->ClipPtr = TransformRaw( &store->clip,
+ &ctx->_ModelProjectMatrix,
+ VB->ObjPtr );
+
/* Drivers expect this to be clean to element 4...
*/
- if (VB->ClipPtr->size < 4) {
- if (VB->ClipPtr->flags & VEC_NOT_WRITEABLE) {
- ASSERT(VB->ClipPtr == VB->ObjPtr);
- VB->import_data( ctx, VERT_BIT_POS, VEC_NOT_WRITEABLE );
- VB->ClipPtr = VB->ObjPtr;
- }
- if (VB->ClipPtr->size == 2)
- _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 );
+ switch (VB->ClipPtr->size) {
+ case 1:
+ /* impossible */
+ case 2:
+ _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 );
+ case 3:
_mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 );
+ case 4:
+ break;
}
/* Cliptest and perspective divide. Clip functions must clear
VB->ClipOrMask = store->ormask;
VB->ClipMask = store->clipmask;
- if (VB->ClipPtr == VB->ObjPtr && (VB->importable_data & VERT_BIT_POS))
- VB->importable_data |= VERT_BIT_CLIP;
-
store->save_eyeptr = VB->EyePtr;
store->save_clipptr = VB->ClipPtr;
store->save_ndcptr = VB->NdcPtr;
VB->NdcPtr = store->save_ndcptr;
VB->ClipMask = store->clipmask;
VB->ClipOrMask = store->ormask;
- if (VB->ClipPtr == VB->ObjPtr && (VB->importable_data & VERT_BIT_POS))
- VB->importable_data |= VERT_BIT_CLIP;
if (store->andmask)
return GL_FALSE;
}
}
-static void check_vertex( GLcontext *ctx, struct gl_pipeline_stage *stage )
+static void check_vertex( GLcontext *ctx, struct tnl_pipeline_stage *stage )
{
stage->active = !ctx->VertexProgram.Enabled;
}
static GLboolean init_vertex_stage( GLcontext *ctx,
- struct gl_pipeline_stage *stage )
+ struct tnl_pipeline_stage *stage )
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
struct vertex_stage_data *store;
return stage->run( ctx, stage );
}
-static void dtr( struct gl_pipeline_stage *stage )
+static void dtr( struct tnl_pipeline_stage *stage )
{
struct vertex_stage_data *store = VERTEX_STAGE_DATA(stage);
}
-const struct gl_pipeline_stage _tnl_vertex_transform_stage =
+const struct tnl_pipeline_stage _tnl_vertex_transform_stage =
{
"modelview/project/cliptest/divide",
_NEW_PROGRAM, /* check_state: only care about vertex prog */
_NEW_PROGRAM|
_NEW_TRANSFORM,
GL_TRUE, /* active */
- VERT_BIT_POS, /* inputs */
- VERT_BIT_EYE|VERT_BIT_CLIP, /* outputs */
+ _TNL_BIT_POS, /* inputs */
+ _TNL_BIT_POS, /* outputs */
0, /* changed_inputs */
NULL, /* private data */
dtr, /* destructor */
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
-#include "mtypes.h"
+
#include "context.h"
-#include "colormac.h"
-#include "simple_list.h"
+#include "macros.h"
+#include "vtxfmt.h"
+#include "dlist.h"
+#include "state.h"
+#include "light.h"
#include "api_arrayelt.h"
-
-#include "t_context.h"
+#include "api_noop.h"
#include "t_vtx_api.h"
+static void init_attrfv( TNLcontext *tnl );
+
+
+/* Close off the last primitive, execute the buffer, restart the
+ * primitive.
+ */
+static void _tnl_wrap_buffers( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+ if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) {
+ GLint i = tnl->vtx.prim_count - 1;
+ assert(i >= 0);
+ tnl->vtx.prim[i].count = ((tnl->vtx.initial_counter - tnl->vtx.counter) -
+ tnl->vtx.prim[i].start);
+ }
+
+ /* Execute the buffer and save copied vertices.
+ */
+ _tnl_flush_vtx( ctx );
+
+ /* Emit a glBegin to start the new list.
+ */
+ assert(tnl->vtx.prim_count == 0);
+
+ if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) {
+ tnl->vtx.prim[0].mode = ctx->Driver.CurrentExecPrimitive;
+ tnl->vtx.prim[0].start = 0;
+ tnl->vtx.prim[0].count = 0;
+ tnl->vtx.prim_count++;
+ }
+}
+
+
+static void _tnl_wrap_filled_vertex( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLfloat *data = tnl->vtx.copied.buffer;
+ int i;
+
+ /* Run pipeline on current vertices, copy wrapped vertices
+ * to tnl->copied.
+ */
+ _tnl_wrap_buffers( ctx );
+
+ /* Copy stored stored vertices to start of new list.
+ */
+ assert(tnl->vtx.counter > tnl->vtx.copied.nr);
+
+ for (i = 0 ; i < tnl->vtx.copied.nr ; i++) {
+ memcpy( tnl->vtx.vbptr, data, tnl->vtx.vertex_size * sizeof(GLfloat));
+ tnl->vtx.vbptr += tnl->vtx.vertex_size;
+ data += tnl->vtx.vertex_size;
+ tnl->vtx.counter--;
+ }
+
+ tnl->vtx.copied.nr = 0;
+}
+
+static void _tnl_copy_to_current( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLuint i;
+
+ for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_INDEX ; i++)
+ if (tnl->vtx.attrsz[i]) {
+ ASSIGN_4V( tnl->vtx.current[i], 0, 0, 0, 1 );
+ COPY_SZ_4V(tnl->vtx.current[i],
+ tnl->vtx.attrsz[i],
+ tnl->vtx.attrptr[i]);
+ }
+
+ /* Edgeflag requires special treatment:
+ */
+ if (tnl->vtx.attrsz[_TNL_ATTRIB_EDGEFLAG])
+ ctx->Current.EdgeFlag =
+ (tnl->vtx.attrptr[_TNL_ATTRIB_EDGEFLAG][0] == 1.0);
+
+
+ /* Colormaterial -- this kindof sucks.
+ */
+ if (ctx->Light.ColorMaterialEnabled) {
+ _mesa_update_color_material(ctx, ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
+ }
+
+ ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT;
+}
+
+
+static void _tnl_copy_from_current( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLint i;
+
+ for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_INDEX ; i++)
+ switch (tnl->vtx.attrsz[i]) {
+ case 4: tnl->vtx.attrptr[i][3] = tnl->vtx.current[i][3];
+ case 3: tnl->vtx.attrptr[i][2] = tnl->vtx.current[i][2];
+ case 2: tnl->vtx.attrptr[i][1] = tnl->vtx.current[i][1];
+ case 1: tnl->vtx.attrptr[i][0] = tnl->vtx.current[i][0];
+ break;
+ }
+
+ /* Edgeflag requires special treatment:
+ */
+ if (tnl->vtx.attrsz[_TNL_ATTRIB_EDGEFLAG])
+ tnl->vtx.attrptr[_TNL_ATTRIB_EDGEFLAG][0] =
+ (GLfloat)ctx->Current.EdgeFlag;
+
+
+ ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;
+}
+
+
+
+
+
+/* Flush existing data, set new attrib size, replay copied vertices.
+ */
+static void _tnl_wrap_upgrade_vertex( GLcontext *ctx,
+ GLuint attr,
+ GLuint newsz )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLuint oldsz;
+ GLint i;
+ GLfloat *tmp;
+ GLint lastcount = tnl->vtx.initial_counter - tnl->vtx.counter;
+
+
+ /* Run pipeline on current vertices, copy wrapped vertices
+ * to tnl->vtx.copied.
+ */
+ _tnl_wrap_buffers( ctx );
+
+ /* Do a COPY_TO_CURRENT to ensure back-copying works for the case
+ * when the attribute already exists in the vertex and is having
+ * its size increased.
+ */
+ _tnl_copy_to_current( ctx );
+
+
+ /* Heuristic: Attempt to isolate attributes received outside
+ * begin/end so that they don't bloat the vertices.
+ */
+#if 1
+ if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END &&
+ tnl->vtx.attrsz[attr] == 0
+ && lastcount > 8
+ ) {
+ init_attrfv( tnl );
+ }
+#endif
+
+
+ /* Fix up sizes:
+ */
+ oldsz = tnl->vtx.attrsz[attr];
+ tnl->vtx.attrsz[attr] = newsz;
+
+ tnl->vtx.vertex_size += newsz - oldsz;
+ tnl->vtx.counter = MIN2( VERT_BUFFER_SIZE / tnl->vtx.vertex_size,
+ ctx->Const.MaxArrayLockSize );
+ tnl->vtx.initial_counter = tnl->vtx.counter;
+ tnl->vtx.vbptr = tnl->vtx.buffer;
+
+
+ /* Recalculate all the attrptr[] values
+ */
+ for (i = 0, tmp = tnl->vtx.vertex ; i < _TNL_ATTRIB_MAX ; i++) {
+ if (tnl->vtx.attrsz[i]) {
+ tnl->vtx.attrptr[i] = tmp;
+ tmp += tnl->vtx.attrsz[i];
+ }
+ else
+ tnl->vtx.attrptr[i] = 0; /* will not be dereferenced */
+ }
+
+ /* Copy from current to repopulate the vertex with correct values.
+ */
+ _tnl_copy_from_current( ctx );
+
+ /* Replay stored vertices to translate them
+ * to new format here.
+ *
+ * -- No need to replay - just copy piecewise
+ */
+ if (tnl->vtx.copied.nr)
+ {
+ GLfloat *data = tnl->vtx.copied.buffer;
+ GLfloat *dest = tnl->vtx.buffer;
+ GLuint j;
+
+ for (i = 0 ; i < tnl->vtx.copied.nr ; i++) {
+ for (j = 0 ; j < _TNL_ATTRIB_MAX ; j++) {
+ if (tnl->vtx.attrsz[j]) {
+ if (j == attr) {
+ COPY_SZ_4V( dest, newsz, tnl->vtx.current[j] );
+ COPY_SZ_4V( dest, oldsz, data );
+ data += oldsz;
+ dest += newsz;
+ }
+ else {
+ GLuint sz = tnl->vtx.attrsz[j];
+ COPY_SZ_4V( dest, sz, data );
+ dest += sz;
+ data += sz;
+ }
+ }
+ }
+ }
+
+ tnl->vtx.vbptr = dest;
+ tnl->vtx.counter -= tnl->vtx.copied.nr;
+ tnl->vtx.copied.nr = 0;
+ }
+}
+
+
+static void _tnl_fixup_vertex( GLcontext *ctx, GLuint attr, GLuint sz )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ static float id[4] = { 0, 0, 0, 1 };
+ int i;
+
+ if (tnl->vtx.attrsz[attr] < sz) {
+ /* New size is larger. Need to flush existing vertices and get
+ * an enlarged vertex format.
+ */
+ _tnl_wrap_upgrade_vertex( ctx, attr, sz );
+ }
+ else if (tnl->vtx.attrsz[attr] > sz) {
+ /* New size is smaller - just need to fill in some
+ * zeros. Don't need to flush or wrap.
+ */
+ for (i = sz ; i <= tnl->vtx.attrsz[attr] ; i++)
+ tnl->vtx.attrptr[attr][i-1] = id[i-1];
+ }
+}
+
+
+
+
+/* Helper function for 'CHOOSE' macro. Do what's necessary when an
+ * entrypoint is called for the first time.
+ */
+static void do_choose( GLuint attr, GLuint sz,
+ void (*fallback_attr_func)( const GLfloat *),
+ void (*choose1)( const GLfloat *),
+ void (*choose2)( const GLfloat *),
+ void (*choose3)( const GLfloat *),
+ void (*choose4)( const GLfloat *),
+ const GLfloat *v )
+{
+ GET_CURRENT_CONTEXT( ctx );
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+ if (tnl->vtx.attrsz[attr] != sz)
+ _tnl_fixup_vertex( ctx, attr, sz );
+
+ /* Does this belong here? Necessitates resetting vtxfmt on each
+ * flush (otherwise flags won't get reset afterwards).
+ */
+ if (attr == 0)
+ ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
+ else
+ ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;
+
+ /* Reset any active pointers for this attribute
+ */
+ tnl->vtx.tabfv[attr][0] = choose1;
+ tnl->vtx.tabfv[attr][1] = choose2;
+ tnl->vtx.tabfv[attr][2] = choose3;
+ tnl->vtx.tabfv[attr][3] = choose4;
+
+ /* Update the secondary dispatch table with the new function
+ */
+ tnl->vtx.tabfv[attr][sz-1] = fallback_attr_func;
+
+ (*fallback_attr_func)(v);
+}
+
+
/* Versions of all the entrypoints for situations where codegen isn't
- * available. This is slowed significantly by all the gumph necessary
- * to get to the tnl pointer, which can be avoided with codegen.
+ * available.
*
* Note: Only one size for each attribute may be active at once.
* Eg. if Color3f is installed/active, then Color4f may not be, even
* is the job of the chooser function when switching between Color4f
* and Color3f.
*/
-#define ATTRF( ATTR, N, A, B, C, D ) \
+#define ATTRFV( ATTR, N ) \
+static void choose_##ATTR##_##N( const GLfloat *v ); \
+ \
+static void attrib_##ATTR##_##N( const GLfloat *v ) \
{ \
GET_CURRENT_CONTEXT( ctx ); \
TNLcontext *tnl = TNL_CONTEXT(ctx); \
if ((ATTR) == 0) { \
int i; \
\
- if (N>0) tnl->vtx.vbptr[0].f = A; \
- if (N>1) tnl->vtx.vbptr[1].f = B; \
- if (N>2) tnl->vtx.vbptr[2].f = C; \
- if (N>3) tnl->vtx.vbptr[3].f = D; \
+ if (N>0) tnl->vtx.vbptr[0] = v[0]; \
+ if (N>1) tnl->vtx.vbptr[1] = v[1]; \
+ if (N>2) tnl->vtx.vbptr[2] = v[2]; \
+ if (N>3) tnl->vtx.vbptr[3] = v[3]; \
\
for (i = N; i < tnl->vtx.vertex_size; i++) \
- tnl->vtx.vbptr[i].ui = tnl->vtx.vertex[i].ui; \
+ tnl->vtx.vbptr[i] = tnl->vtx.vertex[i]; \
\
tnl->vtx.vbptr += tnl->vtx.vertex_size; \
\
if (--tnl->vtx.counter == 0) \
- _tnl_FlushVertices( ctx, FLUSH_STORED_VERTICES ); \
+ _tnl_wrap_filled_vertex( ctx ); \
} \
else { \
- union uif *dest = tnl->vtx.attrptr[ATTR]; \
- if (N>0) dest[0].f = A; \
- if (N>1) dest[1].f = B; \
- if (N>2) dest[2].f = C; \
- if (N>3) dest[3].f = D; \
+ GLfloat *dest = tnl->vtx.attrptr[ATTR]; \
+ if (N>0) dest[0] = v[0]; \
+ if (N>1) dest[1] = v[1]; \
+ if (N>2) dest[2] = v[2]; \
+ if (N>3) dest[3] = v[3]; \
} \
}
-#define ATTR4F( ATTR, A, B, C, D ) ATTRF( ATTR, 4, A, B, C, D )
-#define ATTR3F( ATTR, A, B, C ) ATTRF( ATTR, 3, A, B, C, 1 )
-#define ATTR2F( ATTR, A, B ) ATTRF( ATTR, 2, A, B, 0, 1 )
-#define ATTR1F( ATTR, A ) ATTRF( ATTR, 1, A, 0, 0, 1 )
-
-#define ATTRS( ATTRIB ) \
-static void attrib_##ATTRIB##_1_0( GLfloat s ) \
-{ \
- ATTR1F( ATTRIB, s ); \
-} \
- \
-static void attrib_##ATTRIB##_1_1( const GLfloat *v ) \
-{ \
- ATTR1F( ATTRIB, v[0] ); \
-} \
- \
-static void attrib_##ATTRIB##_2_0( GLfloat s, GLfloat t ) \
-{ \
- ATTR2F( ATTRIB, s, t ); \
-} \
- \
-static void attrib_##ATTRIB##_2_1( const GLfloat *v ) \
-{ \
- ATTR2F( ATTRIB, v[0], v[1] ); \
-} \
- \
-static void attrib_##ATTRIB##_3_0( GLfloat s, GLfloat t, \
- GLfloat r ) \
-{ \
- ATTR3F( ATTRIB, s, t, r ); \
-} \
- \
-static void attrib_##ATTRIB##_3_1( const GLfloat *v ) \
-{ \
- ATTR3F( ATTRIB, v[0], v[1], v[2] ); \
-} \
- \
-static void attrib_##ATTRIB##_4_0( GLfloat s, GLfloat t, \
- GLfloat r, GLfloat q ) \
-{ \
- ATTR4F( ATTRIB, s, t, r, q ); \
-} \
- \
-static void attrib_##ATTRIB##_4_1( const GLfloat *v ) \
-{ \
- ATTR4F( ATTRIB, v[0], v[1], v[2], v[3] ); \
+#define CHOOSE( ATTR, N ) \
+static void choose_##ATTR##_##N( const GLfloat *v ) \
+{ \
+ do_choose(ATTR, N, \
+ attrib_##ATTR##_##N, \
+ choose_##ATTR##_1, \
+ choose_##ATTR##_2, \
+ choose_##ATTR##_3, \
+ choose_##ATTR##_4, \
+ v ); \
+}
+
+#define INIT(ATTR) \
+static void init_##ATTR( TNLcontext *tnl ) \
+{ \
+ tnl->vtx.tabfv[ATTR][0] = choose_##ATTR##_1; \
+ tnl->vtx.tabfv[ATTR][1] = choose_##ATTR##_2; \
+ tnl->vtx.tabfv[ATTR][2] = choose_##ATTR##_3; \
+ tnl->vtx.tabfv[ATTR][3] = choose_##ATTR##_4; \
}
+
+
+#define ATTRS( ATTRIB ) \
+ ATTRFV( ATTRIB, 1 ) \
+ ATTRFV( ATTRIB, 2 ) \
+ ATTRFV( ATTRIB, 3 ) \
+ ATTRFV( ATTRIB, 4 ) \
+ CHOOSE( ATTRIB, 1 ) \
+ CHOOSE( ATTRIB, 2 ) \
+ CHOOSE( ATTRIB, 3 ) \
+ CHOOSE( ATTRIB, 4 ) \
+ INIT( ATTRIB ) \
+
/* Generate a lot of functions. These are the actual worker
* functions, which are equivalent to those generated via codegen
ATTRS( 14 )
ATTRS( 15 )
-/* Flush existing data, set new attrib size, replay copied vertices.
- */
-static void _tnl_upgrade_vertex( GLcontext *ctx,
- GLuint attr,
- GLuint newsz )
+static void init_attrfv( TNLcontext *tnl )
{
- GLuint oldsz = tnl->vtx.attrib[attr].sz;
-
- _tnl_flush_immediate( ctx );
-
- tnl->vtx.attrib[attr].sz = newsz;
- /* What else to do here?
- */
-
- /* Replay stored vertices to translate them to new format: Use
- * bitmap and ffs() to speed inner loop:
- */
- for (i = 0 ; i < tnl->copied_verts.nr ; i++) {
- GLfloat *data = old_data + tnl->copied_verts.offset[i];
-
- for (j = 1 ; j < MAX_ATTRIB ; j++) {
- if (tnl->vtx.attrib[j].sz) {
- if (j == attr) {
- GLfloat tmp[4];
- COPY_4FV( tmp, id );
- COPY_SZ_4V( tmp, oldsz, data );
- data += oldsz;
- tnl->vtx.attrib[attr].fv( tmp );
- }
- else {
- GLfloat *tmp = data;
- data += tnl->vtx.attrib[j].sz;
- tnl->vtx.attrib[j].fv( tmp );
- }
- }
- }
- }
-}
-
-static void _tnl_wrap_buffers( GLcontext *ctx )
-{
- _tnl_flush_immediate( ctx );
-
- /* Replay stored vertices - don't really need to do this, memcpy
- * would be fine.
- */
- for (i = 0 ; i < tnl->copied_verts.nr ; i++) {
- for (j = 1 ; j < MAX_ATTRIB ; j++) {
- GLfloat *tmp = data;
- data += tnl->vtx.attrib[j].sz;
- tnl->vtx.attrib[j].fv( tmp );
- }
- }
-}
-
-
-
-/* The functions defined below (CHOOSERS) are the initial state for
- * dispatch entries for all entrypoints except those requiring
- * double-dispatch (multitexcoord, material, vertexattrib).
- *
- * These may provoke a vertex-upgrade where the existing vertex buffer
- * is flushed and a new element is added to the active vertex layout.
- * This can happen between begin/end pairs.
- */
-
-/* An active attribute has changed size.
- */
-static void _tnl_fixup_vertex( GLcontext *ctx, GLuint attr, GLuint sz )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
-
- if (tnl->vtx.attrib_sz[attr] < sz) {
- /* New size is larger. Need to flush existing vertices and get
- * an enlarged vertex format.
- */
- _tnl_upgrade_vertex( tnl, attr, sz );
- }
- else {
- static float id[4] = { 0, 0, 0, 1 };
- int i;
-
- /* New size is smaller - just need to fill in some zeros.
- */
- for (i = sz ; i < tnl->vtx.attrib_sz[attr] ; i++)
- tnl->vtx.attrptr[attr][i].f = id[i];
- }
+ if (0) fprintf(stderr, "%s %d\n", __FUNCTION__, tnl->vtx.vertex_size);
- /* Reset the dispatch table - aliasing entrypoints are invalidated.
- */
- _tnl_reset_attr_dispatch_tab( ctx );
-}
-
-static int dispatch_offset[TNL_ATTRIB_MAX][4][2];
-
-
-static void *lookup_or_generate( GLuint attr, GLuint sz, GLuint v,
- void *fallback_attr_func )
-{
- GET_CURRENT_CONTEXT( ctx );
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- void *ptr = 0;
- struct dynfn *dfn;
- int key;
-
- /* This will remove any installed handlers for attr with different
- * sz, will flush, copy and expand the copied vertices if sz won't
- * fit in the current vertex, or will clean the current vertex if
- * it already has this attribute in a larger size.
- */
- if (tnl->vtx.attrib_sz[attr] != sz)
- _tnl_fixup_vertex( ctx, attr, sz );
-
-
- if (attr == 0)
- key = tnl->vtx.vertex_size;
- else
- key = (GLuint)tnl->vtx.attrptr[attr];
-
- for (dfn = tnl->vtx.generated[sz-1][v][isvertex]; dfn; dfn = dfn->next) {
- if (dfn->key == key) {
- ptr = dfn->code;
- break;
- }
- }
-
- if (ptr == 0) {
- dfn = tnl->vtx.codegen[sz-1][v][isvertex]( ctx, key );
- if (dfn) {
- ptr = dfn->code;
- dfn->next = tnl->vtx.generated[sz-1][v][isvertex];
- tnl->vtx.generated[sz-1][v][isvertex] = dfn;
- }
- }
+ if (tnl->vtx.vertex_size) {
+ GLuint i;
- if (ptr == 0)
- ptr = fallback_attr_func;
-
- ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;
-
- /* Need to set all the aliases to this function, too
- */
- if (dispatch_offset[attr][sz-1][v])
- ((void **)tnl->Exec)[dispatch_offset[attr][sz-1][v]] = ptr;
-
- return ptr;
+ init_0( tnl );
+ init_1( tnl );
+ init_2( tnl );
+ init_3( tnl );
+ init_4( tnl );
+ init_5( tnl );
+ init_6( tnl );
+ init_7( tnl );
+ init_8( tnl );
+ init_9( tnl );
+ init_10( tnl );
+ init_11( tnl );
+ init_12( tnl );
+ init_13( tnl );
+ init_14( tnl );
+ init_15( tnl );
+
+ for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++)
+ tnl->vtx.attrsz[i] = 0;
+
+ tnl->vtx.vertex_size = 0;
+ }
}
-
-/* These functions choose one of the ATTR's generated above (or from
- * codegen). Like the ATTR functions, they live in the GL dispatch
- * table and in the second-level dispatch table for MultiTexCoord,
- * AttribNV, etc.
- *
- * Need ATTR1 for use in constructing name of 'attrib_x_y_z' function.
- */
-#define CHOOSE( ATTR1, ATTR2, SZ, V, FNTYPE, ARGS1, ARGS2 ) \
-static void choose_##ATTR2##_##SZ##_##V ARGS1 \
-{ \
- void *ptr = lookup_or_generate(ATTR1, SZ, V, \
- (void *)attrib_##ATTR1##_##SZ##_##V ); \
- \
- assert(ATTR1 == ATTR2); \
- ((FNTYPE) ptr) ARGS2; \
-}
-
-#define afv (const GLfloat *v)
-#define a1f (GLfloat a)
-#define a2f (GLfloat a, GLfloat b)
-#define a3f (GLfloat a, GLfloat b, GLfloat c)
-#define a4f (GLfloat a, GLfloat b, GLfloat c, GLfloat d)
-
-/* Not that many entrypoints when it all boils down:
- */
-CHOOSE( 0, VERT_ATTRIB_POS, 2, 1, pfv, afv, (v) )
-CHOOSE( 0, VERT_ATTRIB_POS, 2, 0, p2f, a2f, (a,b) )
-CHOOSE( 0, VERT_ATTRIB_POS, 3, 1, pfv, afv, (v) )
-CHOOSE( 0, VERT_ATTRIB_POS, 3, 0, p3f, a3f, (a,b,c) )
-CHOOSE( 0, VERT_ATTRIB_POS, 4, 1, pfv, afv, (v) )
-CHOOSE( 0, VERT_ATTRIB_POS, 4, 0, p4f, a4f, (a,b,c,d) )
-CHOOSE( 2, VERT_ATTRIB_NORMAL, 3, 1, pfv, afv, (v) )
-CHOOSE( 2, VERT_ATTRIB_NORMAL, 3, 0, p3f, a3f, (a,b,c) )
-CHOOSE( 3, VERT_ATTRIB_COLOR0, 3, 1, pfv, afv, (v) )
-CHOOSE( 3, VERT_ATTRIB_COLOR0, 3, 0, p3f, a3f, (a,b,c) )
-CHOOSE( 3, VERT_ATTRIB_COLOR0, 4, 1, pfv, afv, (v) )
-CHOOSE( 3, VERT_ATTRIB_COLOR0, 4, 0, p4f, a4f, (a,b,c,d) )
-CHOOSE( 4, VERT_ATTRIB_COLOR1, 3, 1, pfv, afv, (v) )
-CHOOSE( 4, VERT_ATTRIB_COLOR1, 3, 0, p3f, a3f, (a,b,c) )
-CHOOSE( 5, VERT_ATTRIB_FOG, 1, 1, pfv, afv, (v) )
-CHOOSE( 5, VERT_ATTRIB_FOG, 1, 0, p1f, a1f, (a) )
-CHOOSE( 8, VERT_ATTRIB_TEX0, 1, 1, pfv, afv, (v) )
-CHOOSE( 8, VERT_ATTRIB_TEX0, 1, 0, p1f, a1f, (a) )
-CHOOSE( 8, VERT_ATTRIB_TEX0, 2, 1, pfv, afv, (v) )
-CHOOSE( 8, VERT_ATTRIB_TEX0, 2, 0, p2f, a2f, (a,b) )
-CHOOSE( 8, VERT_ATTRIB_TEX0, 3, 1, pfv, afv, (v) )
-CHOOSE( 8, VERT_ATTRIB_TEX0, 3, 0, p3f, a3f, (a,b,c) )
-CHOOSE( 8, VERT_ATTRIB_TEX0, 4, 1, pfv, afv, (v) )
-CHOOSE( 8, VERT_ATTRIB_TEX0, 4, 0, p4f, a4f, (a,b,c,d) )
-
-
-/* Gack. Need to do this without going through the
- * GET_CURRENT_CONTEXT hoohah. Could codegen this, I suppose...
+/* These can be made efficient with codegen. Further, by adding more
+ * logic to do_choose(), the double-dispatch for legacy entrypoints
+ * like glVertex3f() can be removed.
*/
#define DISPATCH_ATTRFV( ATTR, COUNT, P ) \
do { \
GET_CURRENT_CONTEXT( ctx ); \
TNLcontext *tnl = TNL_CONTEXT(ctx); \
- tnl->vtx.tabfv[COUNT-1][ATTR]( P ); \
+ tnl->vtx.tabfv[ATTR][COUNT-1]( P ); \
} while (0)
#define DISPATCH_ATTR1FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 1, V )
#define DISPATCH_ATTR4FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 4, V )
#define DISPATCH_ATTR1F( ATTR, S ) DISPATCH_ATTRFV( ATTR, 1, &(S) )
-#ifdef USE_X86_ASM
-/* Naughty cheat:
- */
-#define DISPATCH_ATTR2F( ATTR, S,T ) DISPATCH_ATTRFV( ATTR, 2, &(S) )
-#define DISPATCH_ATTR3F( ATTR, S,T,R ) DISPATCH_ATTRFV( ATTR, 3, &(S) )
-#define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) DISPATCH_ATTRFV( ATTR, 4, &(S) )
-#else
-/* Safe:
- */
+
#define DISPATCH_ATTR2F( ATTR, S,T ) \
do { \
GLfloat v[2]; \
v[0] = S; v[1] = T; v[2] = R; v[3] = Q; \
DISPATCH_ATTR4FV( ATTR, v ); \
} while (0)
-#endif
-
static void enum_error( void )
_mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ );
}
-static void op_error( void )
+static void _tnl_Vertex2f( GLfloat x, GLfloat y )
{
- GET_CURRENT_CONTEXT( ctx );
- _mesa_error( ctx, GL_INVALID_OPERATION, __FUNCTION__ );
+ DISPATCH_ATTR2F( _TNL_ATTRIB_POS, x, y );
}
+static void _tnl_Vertex2fv( const GLfloat *v )
+{
+ DISPATCH_ATTR2FV( _TNL_ATTRIB_POS, v );
+}
-/* First level for MultiTexcoord: Send through second level dispatch.
- * These are permanently installed in the toplevel dispatch.
- *
- * Assembly can optimize the generation of arrays by using &s instead
- * of building 'v'.
- */
-static void _tnl_MultiTexCoord1f( GLenum target, GLfloat s )
+static void _tnl_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
+{
+ DISPATCH_ATTR3F( _TNL_ATTRIB_POS, x, y, z );
+}
+
+static void _tnl_Vertex3fv( const GLfloat *v )
+{
+ DISPATCH_ATTR3FV( _TNL_ATTRIB_POS, v );
+}
+
+static void _tnl_Vertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
+{
+ DISPATCH_ATTR4F( _TNL_ATTRIB_POS, x, y, z, w );
+}
+
+static void _tnl_Vertex4fv( const GLfloat *v )
+{
+ DISPATCH_ATTR4FV( _TNL_ATTRIB_POS, v );
+}
+
+static void _tnl_TexCoord1f( GLfloat x )
+{
+ DISPATCH_ATTR1F( _TNL_ATTRIB_TEX0, x );
+}
+
+static void _tnl_TexCoord1fv( const GLfloat *v )
+{
+ DISPATCH_ATTR1FV( _TNL_ATTRIB_TEX0, v );
+}
+
+static void _tnl_TexCoord2f( GLfloat x, GLfloat y )
+{
+ DISPATCH_ATTR2F( _TNL_ATTRIB_TEX0, x, y );
+}
+
+static void _tnl_TexCoord2fv( const GLfloat *v )
+{
+ DISPATCH_ATTR2FV( _TNL_ATTRIB_TEX0, v );
+}
+
+static void _tnl_TexCoord3f( GLfloat x, GLfloat y, GLfloat z )
+{
+ DISPATCH_ATTR3F( _TNL_ATTRIB_TEX0, x, y, z );
+}
+
+static void _tnl_TexCoord3fv( const GLfloat *v )
{
- GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
- DISPATCH_ATTR1FV( attr, &s );
+ DISPATCH_ATTR3FV( _TNL_ATTRIB_TEX0, v );
+}
+
+static void _tnl_TexCoord4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
+{
+ DISPATCH_ATTR4F( _TNL_ATTRIB_TEX0, x, y, z, w );
+}
+
+static void _tnl_TexCoord4fv( const GLfloat *v )
+{
+ DISPATCH_ATTR4FV( _TNL_ATTRIB_TEX0, v );
+}
+
+static void _tnl_Normal3f( GLfloat x, GLfloat y, GLfloat z )
+{
+ DISPATCH_ATTR3F( _TNL_ATTRIB_NORMAL, x, y, z );
+}
+
+static void _tnl_Normal3fv( const GLfloat *v )
+{
+ DISPATCH_ATTR3FV( _TNL_ATTRIB_NORMAL, v );
+}
+
+static void _tnl_FogCoordfEXT( GLfloat x )
+{
+ DISPATCH_ATTR1F( _TNL_ATTRIB_FOG, x );
+}
+
+static void _tnl_FogCoordfvEXT( const GLfloat *v )
+{
+ DISPATCH_ATTR1FV( _TNL_ATTRIB_FOG, v );
+}
+
+static void _tnl_Color3f( GLfloat x, GLfloat y, GLfloat z )
+{
+ DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR0, x, y, z );
+}
+
+static void _tnl_Color3fv( const GLfloat *v )
+{
+ DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR0, v );
+}
+
+static void _tnl_Color4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
+{
+ DISPATCH_ATTR4F( _TNL_ATTRIB_COLOR0, x, y, z, w );
+}
+
+static void _tnl_Color4fv( const GLfloat *v )
+{
+ DISPATCH_ATTR4FV( _TNL_ATTRIB_COLOR0, v );
+}
+
+static void _tnl_SecondaryColor3fEXT( GLfloat x, GLfloat y, GLfloat z )
+{
+ DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR1, x, y, z );
+}
+
+static void _tnl_SecondaryColor3fvEXT( const GLfloat *v )
+{
+ DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR1, v );
+}
+
+static void _tnl_MultiTexCoord1f( GLenum target, GLfloat x )
+{
+ GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
+ DISPATCH_ATTR1F( attr, x );
}
static void _tnl_MultiTexCoord1fv( GLenum target, const GLfloat *v )
{
- GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
+ GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
DISPATCH_ATTR1FV( attr, v );
}
-static void _tnl_MultiTexCoord2f( GLenum target, GLfloat s, GLfloat t )
+static void _tnl_MultiTexCoord2f( GLenum target, GLfloat x, GLfloat y )
{
- GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
- DISPATCH_ATTR2F( attr, s, t );
+ GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
+ DISPATCH_ATTR2F( attr, x, y );
}
static void _tnl_MultiTexCoord2fv( GLenum target, const GLfloat *v )
{
- GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
+ GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
DISPATCH_ATTR2FV( attr, v );
}
-static void _tnl_MultiTexCoord3f( GLenum target, GLfloat s, GLfloat t,
- GLfloat r)
+static void _tnl_MultiTexCoord3f( GLenum target, GLfloat x, GLfloat y,
+ GLfloat z)
{
- GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
- DISPATCH_ATTR3F( attr, s, t, r );
+ GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
+ DISPATCH_ATTR3F( attr, x, y, z );
}
static void _tnl_MultiTexCoord3fv( GLenum target, const GLfloat *v )
{
- GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
+ GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
DISPATCH_ATTR3FV( attr, v );
}
-static void _tnl_MultiTexCoord4f( GLenum target, GLfloat s, GLfloat t,
- GLfloat r, GLfloat q )
+static void _tnl_MultiTexCoord4f( GLenum target, GLfloat x, GLfloat y,
+ GLfloat z, GLfloat w )
{
- GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
- DISPATCH_ATTR4F( attr, s, t, r, q );
+ GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
+ DISPATCH_ATTR4F( attr, x, y, z, w );
}
static void _tnl_MultiTexCoord4fv( GLenum target, const GLfloat *v )
{
- GLuint attr = (target & 0x7) + VERT_ATTRIB_TEX0;
+ GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
DISPATCH_ATTR4FV( attr, v );
}
-
-/* First level for NV_vertex_program:
- *
- * Check for errors & reroute through second dispatch layer to get
- * size tracking per-attribute.
- */
-static void _tnl_VertexAttrib1fNV( GLuint index, GLfloat s )
+static void _tnl_VertexAttrib1fNV( GLuint index, GLfloat x )
{
- if (index < TNL_ATTRIB_MAX)
- DISPATCH_ATTR1F( index, s );
+ if (index >= VERT_ATTRIB_POS && index < VERT_ATTRIB_MAX)
+ DISPATCH_ATTR1F( index, x );
else
enum_error();
}
static void _tnl_VertexAttrib1fvNV( GLuint index, const GLfloat *v )
{
- if (index < TNL_ATTRIB_MAX)
+ if (index >= VERT_ATTRIB_POS && index < VERT_ATTRIB_MAX)
DISPATCH_ATTR1FV( index, v );
else
enum_error();
}
-static void _tnl_VertexAttrib2fNV( GLuint index, GLfloat s, GLfloat t )
+static void _tnl_VertexAttrib2fNV( GLuint index, GLfloat x, GLfloat y )
{
- if (index < TNL_ATTRIB_MAX)
- DISPATCH_ATTR2F( index, s, t );
+ if (index >= VERT_ATTRIB_POS && index < VERT_ATTRIB_MAX)
+ DISPATCH_ATTR2F( index, x, y );
else
enum_error();
}
static void _tnl_VertexAttrib2fvNV( GLuint index, const GLfloat *v )
{
- if (index < TNL_ATTRIB_MAX)
+ if (index >= VERT_ATTRIB_POS && index < VERT_ATTRIB_MAX)
DISPATCH_ATTR2FV( index, v );
else
enum_error();
}
-static void _tnl_VertexAttrib3fNV( GLuint index, GLfloat s, GLfloat t,
- GLfloat r )
+static void _tnl_VertexAttrib3fNV( GLuint index, GLfloat x, GLfloat y,
+ GLfloat z )
{
- if (index < TNL_ATTRIB_MAX)
- DISPATCH_ATTR3F( index, s, t, r );
+ if (index >= VERT_ATTRIB_POS && index < VERT_ATTRIB_MAX)
+ DISPATCH_ATTR3F( index, x, y, z );
else
enum_error();
}
static void _tnl_VertexAttrib3fvNV( GLuint index, const GLfloat *v )
{
- if (index < TNL_ATTRIB_MAX)
+ if (index >= VERT_ATTRIB_POS && index < VERT_ATTRIB_MAX)
DISPATCH_ATTR3FV( index, v );
else
enum_error();
}
-static void _tnl_VertexAttrib4fNV( GLuint index, GLfloat s, GLfloat t,
- GLfloat r, GLfloat q )
+static void _tnl_VertexAttrib4fNV( GLuint index, GLfloat x, GLfloat y,
+ GLfloat z, GLfloat w )
{
- if (index < TNL_ATTRIB_MAX)
- DISPATCH_ATTR4F( index, s, t, r, q );
+ if (index >= VERT_ATTRIB_POS && index < VERT_ATTRIB_MAX)
+ DISPATCH_ATTR4F( index, x, y, z, w );
else
enum_error();
}
static void _tnl_VertexAttrib4fvNV( GLuint index, const GLfloat *v )
{
- if (index < TNL_ATTRIB_MAX)
+ if (index >= VERT_ATTRIB_POS && index < VERT_ATTRIB_MAX)
DISPATCH_ATTR4FV( index, v );
else
enum_error();
* just to cope with this, so I unroll the 'C' varients of CHOOSE and
* ATTRF into this function, and dispense with codegen and
* second-level dispatch.
+ *
+ * There is no aliasing of material attributes with other entrypoints.
*/
#define MAT_ATTR( A, N, params ) \
do { \
- if (tnl->vtx.attrib_sz[A] != N) { \
- tnl_fixup_vertex( ctx, A, N ); \
+ if (tnl->vtx.attrsz[A] != N) { \
+ _tnl_fixup_vertex( ctx, A, N ); \
} \
\
{ \
- union uif *dest = tnl->vtx.attrptr[A]; \
- if (N>0) dest[0].f = params[0]; \
- if (N>1) dest[1].f = params[1]; \
- if (N>2) dest[2].f = params[2]; \
- if (N>3) dest[3].f = params[3]; \
+ GLfloat *dest = tnl->vtx.attrptr[A]; \
+ if (N>0) dest[0] = params[0]; \
+ if (N>1) dest[1] = params[1]; \
+ if (N>2) dest[2] = params[2]; \
+ if (N>3) dest[3] = params[3]; \
ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
} \
} while (0)
GET_CURRENT_CONTEXT( ctx );
TNLcontext *tnl = TNL_CONTEXT(ctx);
+ switch (face) {
+ case GL_FRONT:
+ case GL_BACK:
+ case GL_FRONT_AND_BACK:
+ break;
+
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__);
+ return;
+ }
+
switch (pname) {
case GL_EMISSION:
- MAT( VERT_ATTRIB_MAT_FRONT_EMISSION, 4, face, params );
+ MAT( _TNL_ATTRIB_MAT_FRONT_EMISSION, 4, face, params );
break;
case GL_AMBIENT:
- MAT( VERT_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params );
+ MAT( _TNL_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params );
break;
case GL_DIFFUSE:
- MAT( VERT_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params );
+ MAT( _TNL_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params );
break;
case GL_SPECULAR:
- MAT( VERT_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params );
+ MAT( _TNL_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params );
break;
case GL_SHININESS:
- MAT( VERT_ATTRIB_MAT_FRONT_SHININESS, 1, face, params );
+ MAT( _TNL_ATTRIB_MAT_FRONT_SHININESS, 1, face, params );
break;
case GL_COLOR_INDEXES:
- MAT( VERT_ATTRIB_MAT_FRONT_INDEXES, 3, face, params );
+ MAT( _TNL_ATTRIB_MAT_FRONT_INDEXES, 3, face, params );
break;
case GL_AMBIENT_AND_DIFFUSE:
- MAT( VERT_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params );
- MAT( VERT_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params );
+ MAT( _TNL_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params );
+ MAT( _TNL_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params );
break;
default:
_mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ );
GET_CURRENT_CONTEXT( ctx ); \
TNLcontext *tnl = TNL_CONTEXT(ctx); \
\
- if (tnl->vtx.attrib_sz[A] != 1) { \
- tnl_fixup_vertex( ctx, A, 1 ); \
+ if (tnl->vtx.attrsz[A] != 1) { \
+ _tnl_fixup_vertex( ctx, A, 1 ); \
} \
\
{ \
- union uif *dest = tnl->vtx.attrptr[A]; \
- dest[0].ui = IDX; \
+ GLfloat *dest = tnl->vtx.attrptr[A]; \
+ dest[0] = IDX; \
ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \
} \
} while (0)
-static void _tnl_EdgeFlag( GLboolean f )
+static void _tnl_EdgeFlag( GLboolean b )
{
- IDX_ATTR( VERT_ATTRIB_EDGEFLAG, f );
+ IDX_ATTR( _TNL_ATTRIB_EDGEFLAG, (GLfloat)b );
}
-static void _tnl_EdgeFlagv( const GLboolean *f )
+static void _tnl_EdgeFlagv( const GLboolean *v )
{
- IDX_ATTR( VERT_ATTRIB_EDGEFLAG, f[0] );
+ IDX_ATTR( _TNL_ATTRIB_EDGEFLAG, (GLfloat)v[0] );
}
-static void _tnl_Indexi( GLint i )
+static void _tnl_Indexf( GLfloat f )
{
- IDX_ATTR( VERT_ATTRIB_INDEX, i );
+ IDX_ATTR( _TNL_ATTRIB_INDEX, f );
}
-static void _tnl_Indexiv( const GLint *i )
+static void _tnl_Indexfv( const GLfloat *v )
{
- IDX_ATTR( VERT_ATTRIB_INDEX, i[0] );
+ IDX_ATTR( _TNL_ATTRIB_INDEX, v[0] );
}
-
-
-/* EvalCoord needs special treatment as ususal:
+/* Eval
*/
-static void evalcoord( GLfloat a, GLfloat b, GLuint type )
+static void _tnl_EvalCoord1f( GLfloat u )
{
-#if 0
- GET_CURRENT_CONTEXT( ctx );
- TNLcontext *tnl = TNL_CONTEXT(ctx);
-
- /* Initialize the list of eval fixups:
- */
- if (!tnl->evalptr) {
- init_eval_ptr( ctx );
+ GET_CURRENT_CONTEXT( ctx );
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+ /* TODO: use a CHOOSE() function for this: */
+ {
+ GLint i;
+ if (tnl->vtx.eval.new_state)
+ _tnl_update_eval( ctx );
+
+ for (i = 0 ; i <= _TNL_ATTRIB_INDEX ; i++) {
+ if (tnl->vtx.eval.map1[i].map)
+ if (tnl->vtx.attrsz[i] < tnl->vtx.eval.map1[i].sz)
+ _tnl_fixup_vertex( ctx, i, tnl->vtx.eval.map1[i].sz );
+ }
}
- /* Note that this vertex will need to be fixed up:
- */
- tnl->evalptr[0].vert = tnl->initial_counter - tnl->counter;
- tnl->evalptr[0].type = type;
- /* Now emit the vertex with eval data in obj coordinates:
- */
- ATTRF( 0, 2, a, b, 0, 1 );
-#endif
-}
+ memcpy( tnl->vtx.copied.buffer, tnl->vtx.vertex,
+ tnl->vtx.vertex_size * sizeof(GLfloat));
+ _tnl_do_EvalCoord1f( ctx, u );
-static void _tnl_EvalCoord1f( GLfloat u )
-{
- evalcoord( u, 0, TNL_EVAL_COORD1 );
+ memcpy( tnl->vtx.vertex, tnl->vtx.copied.buffer,
+ tnl->vtx.vertex_size * sizeof(GLfloat));
}
-static void _tnl_EvalCoord1fv( const GLfloat *v )
+static void _tnl_EvalCoord2f( GLfloat u, GLfloat v )
{
- evalcoord( v[0], 0, TNL_EVAL_COORD1 );
+ GET_CURRENT_CONTEXT( ctx );
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+ /* TODO: use a CHOOSE() function for this: */
+ {
+ GLint i;
+ if (tnl->vtx.eval.new_state)
+ _tnl_update_eval( ctx );
+
+ for (i = 0 ; i <= _TNL_ATTRIB_INDEX ; i++) {
+ if (tnl->vtx.eval.map2[i].map)
+ if (tnl->vtx.attrsz[i] < tnl->vtx.eval.map2[i].sz)
+ _tnl_fixup_vertex( ctx, i, tnl->vtx.eval.map2[i].sz );
+ }
+
+ if (ctx->Eval.AutoNormal)
+ if (tnl->vtx.attrsz[_TNL_ATTRIB_NORMAL] < 3)
+ _tnl_fixup_vertex( ctx, _TNL_ATTRIB_NORMAL, 3 );
+ }
+
+ memcpy( tnl->vtx.copied.buffer, tnl->vtx.vertex,
+ tnl->vtx.vertex_size * sizeof(GLfloat));
+
+ _tnl_do_EvalCoord2f( ctx, u, v );
+
+ memcpy( tnl->vtx.vertex, tnl->vtx.copied.buffer,
+ tnl->vtx.vertex_size * sizeof(GLfloat));
}
-static void _tnl_EvalCoord2f( GLfloat u, GLfloat v )
+static void _tnl_EvalCoord1fv( const GLfloat *u )
{
- evalcoord( u, v, TNL_EVAL_COORD2 );
+ _tnl_EvalCoord1f( u[0] );
}
-static void _tnl_EvalCoord2fv( const GLfloat *v )
+static void _tnl_EvalCoord2fv( const GLfloat *u )
{
- evalcoord( v[0], v[1], TNL_EVAL_COORD2 );
+ _tnl_EvalCoord2f( u[0], u[1] );
}
static void _tnl_EvalPoint1( GLint i )
{
- evalcoord( (GLfloat)i, 0, TNL_EVAL_POINT1 );
+ GET_CURRENT_CONTEXT( ctx );
+ GLfloat du = ((ctx->Eval.MapGrid1u2 - ctx->Eval.MapGrid1u1) /
+ (GLfloat) ctx->Eval.MapGrid1un);
+ GLfloat u = i * du + ctx->Eval.MapGrid1u1;
+
+ _tnl_EvalCoord1f( u );
}
+
static void _tnl_EvalPoint2( GLint i, GLint j )
{
- evalcoord( (GLfloat)i, (GLfloat)j, TNL_EVAL_POINT2 );
+ GET_CURRENT_CONTEXT( ctx );
+ GLfloat du = ((ctx->Eval.MapGrid2u2 - ctx->Eval.MapGrid2u1) /
+ (GLfloat) ctx->Eval.MapGrid2un);
+ GLfloat dv = ((ctx->Eval.MapGrid2v2 - ctx->Eval.MapGrid2v1) /
+ (GLfloat) ctx->Eval.MapGrid2vn);
+ GLfloat u = i * du + ctx->Eval.MapGrid2u1;
+ GLfloat v = j * dv + ctx->Eval.MapGrid2v1;
+
+ _tnl_EvalCoord2f( u, v );
}
-/* Don't do a lot of processing here - errors are raised when this
- * list is scanned later on (perhaps in display list playback) to
- * build tnl_prim structs.
+
+/* Build a list of primitives on the fly. Keep
+ * ctx->Driver.CurrentExecPrimitive uptodate as well.
*/
static void _tnl_Begin( GLenum mode )
{
GET_CURRENT_CONTEXT( ctx );
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- int i;
- i = tnl->vtx.be_count++;
- tnl->vtx.be[i].type = TNL_BEGIN;
- tnl->vtx.be[i].idx = tnl->vtx.initial_counter - tnl->vtx.counter;
- tnl->vtx.be[i].mode = mode;
+ if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) {
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ int i;
+
+ if (ctx->NewState) {
+ _mesa_update_state( ctx );
+ ctx->Exec->Begin(mode);
+ return;
+ }
+
+#if 1
+ /* Heuristic: attempt to isolate attributes occuring outside
+ * begin/end pairs.
+ */
+ if (tnl->vtx.vertex_size && !tnl->vtx.attrsz[0])
+ _tnl_FlushVertices( ctx, ~0 );
+#endif
+
+ i = tnl->vtx.prim_count++;
+ tnl->vtx.prim[i].mode = mode | PRIM_BEGIN;
+ tnl->vtx.prim[i].start = tnl->vtx.initial_counter - tnl->vtx.counter;
+ tnl->vtx.prim[i].count = 0;
- if (tnl->vtx.be_count == TNL_BE_MAX)
- _tnl_FlushVertices( ctx, FLUSH_STORED_VERTICES );
+ ctx->Driver.CurrentExecPrimitive = mode;
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_OPERATION, __FUNCTION__ );
+
}
static void _tnl_End( void )
{
GET_CURRENT_CONTEXT( ctx );
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- int i;
- i = tnl->vtx.be_count++;
- tnl->vtx.be[i].type = TNL_END;
- tnl->vtx.be[i].idx = tnl->vtx.initial_counter - tnl->vtx.counter;
- tnl->vtx.be[i].mode = 0;
+ if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) {
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ int idx = tnl->vtx.initial_counter - tnl->vtx.counter;
+ int i = tnl->vtx.prim_count - 1;
- if (tnl->vtx.be_count == TNL_BE_MAX)
- _tnl_FlushVertices( ctx, FLUSH_STORED_VERTICES );
-}
+ tnl->vtx.prim[i].mode |= PRIM_END;
+ tnl->vtx.prim[i].count = idx - tnl->vtx.prim[i].start;
+
+ ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1;
+
+#if 0
+ if (tnl->vtx.counter * 2 > tnl->vtx.initial_counter)
+ _tnl_FlushVertices( ctx, ~0 );
+#endif
+ if (tnl->vtx.prim_count == TNL_MAX_PRIM) {
+#if 0
+ _tnl_FlushVertices( ctx, ~0 );
+#else
+ _tnl_flush_vtx( ctx );
+#endif
+ }
+ }
+ else
+ _mesa_error( ctx, GL_INVALID_OPERATION, __FUNCTION__ );
+}
+static void _tnl_exec_vtxfmt_init( GLcontext *ctx )
+{
+ GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->exec_vtxfmt);
+ vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */
+ vfmt->Begin = _tnl_Begin;
+ vfmt->CallList = _mesa_CallList;
+ vfmt->CallLists = _mesa_CallLists;
+ vfmt->Color3f = _tnl_Color3f;
+ vfmt->Color3fv = _tnl_Color3fv;
+ vfmt->Color4f = _tnl_Color4f;
+ vfmt->Color4fv = _tnl_Color4fv;
+ vfmt->EdgeFlag = _tnl_EdgeFlag;
+ vfmt->EdgeFlagv = _tnl_EdgeFlagv;
+ vfmt->End = _tnl_End;
+ vfmt->EvalCoord1f = _tnl_EvalCoord1f;
+ vfmt->EvalCoord1fv = _tnl_EvalCoord1fv;
+ vfmt->EvalCoord2f = _tnl_EvalCoord2f;
+ vfmt->EvalCoord2fv = _tnl_EvalCoord2fv;
+ vfmt->EvalPoint1 = _tnl_EvalPoint1;
+ vfmt->EvalPoint2 = _tnl_EvalPoint2;
+ vfmt->FogCoordfEXT = _tnl_FogCoordfEXT;
+ vfmt->FogCoordfvEXT = _tnl_FogCoordfvEXT;
+ vfmt->Indexf = _tnl_Indexf;
+ vfmt->Indexfv = _tnl_Indexfv;
+ vfmt->Materialfv = _tnl_Materialfv;
+ vfmt->MultiTexCoord1fARB = _tnl_MultiTexCoord1f;
+ vfmt->MultiTexCoord1fvARB = _tnl_MultiTexCoord1fv;
+ vfmt->MultiTexCoord2fARB = _tnl_MultiTexCoord2f;
+ vfmt->MultiTexCoord2fvARB = _tnl_MultiTexCoord2fv;
+ vfmt->MultiTexCoord3fARB = _tnl_MultiTexCoord3f;
+ vfmt->MultiTexCoord3fvARB = _tnl_MultiTexCoord3fv;
+ vfmt->MultiTexCoord4fARB = _tnl_MultiTexCoord4f;
+ vfmt->MultiTexCoord4fvARB = _tnl_MultiTexCoord4fv;
+ vfmt->Normal3f = _tnl_Normal3f;
+ vfmt->Normal3fv = _tnl_Normal3fv;
+ vfmt->SecondaryColor3fEXT = _tnl_SecondaryColor3fEXT;
+ vfmt->SecondaryColor3fvEXT = _tnl_SecondaryColor3fvEXT;
+ vfmt->TexCoord1f = _tnl_TexCoord1f;
+ vfmt->TexCoord1fv = _tnl_TexCoord1fv;
+ vfmt->TexCoord2f = _tnl_TexCoord2f;
+ vfmt->TexCoord2fv = _tnl_TexCoord2fv;
+ vfmt->TexCoord3f = _tnl_TexCoord3f;
+ vfmt->TexCoord3fv = _tnl_TexCoord3fv;
+ vfmt->TexCoord4f = _tnl_TexCoord4f;
+ vfmt->TexCoord4fv = _tnl_TexCoord4fv;
+ vfmt->Vertex2f = _tnl_Vertex2f;
+ vfmt->Vertex2fv = _tnl_Vertex2fv;
+ vfmt->Vertex3f = _tnl_Vertex3f;
+ vfmt->Vertex3fv = _tnl_Vertex3fv;
+ vfmt->Vertex4f = _tnl_Vertex4f;
+ vfmt->Vertex4fv = _tnl_Vertex4fv;
+ vfmt->VertexAttrib1fNV = _tnl_VertexAttrib1fNV;
+ vfmt->VertexAttrib1fvNV = _tnl_VertexAttrib1fvNV;
+ vfmt->VertexAttrib2fNV = _tnl_VertexAttrib2fNV;
+ vfmt->VertexAttrib2fvNV = _tnl_VertexAttrib2fvNV;
+ vfmt->VertexAttrib3fNV = _tnl_VertexAttrib3fNV;
+ vfmt->VertexAttrib3fvNV = _tnl_VertexAttrib3fvNV;
+ vfmt->VertexAttrib4fNV = _tnl_VertexAttrib4fNV;
+ vfmt->VertexAttrib4fvNV = _tnl_VertexAttrib4fvNV;
+
+ vfmt->Rectf = _mesa_noop_Rectf;
+ vfmt->EvalMesh1 = _mesa_noop_EvalMesh1;
+ vfmt->EvalMesh2 = _mesa_noop_EvalMesh2;
+}
-static void _tnl_InitDispatch( struct _glapi_table *tab )
+void _tnl_FlushVertices( GLcontext *ctx, GLuint flags )
{
- GLint i;
-
- /* Most operations boil down to error/transition behaviour.
- * However if we transition eagerly, all that's needed is a single
- * 'error' operation. This will do for now, but requires that the
- * old 'flush' stuff lives on in the state functions, and is
- * wasteful if swapping is expensive (threads?).
- */
- for (i = 0 ; i < sizeof(tab)/sizeof(void*) ; i++)
- ((void **)tab)[i] = (void *)op_error;
-
- tab->Begin = _tnl_Begin;
- tab->End = _tnl_End;
- tab->Color3f = choose_VERT_ATTRIB_COLOR0_3_0;
- tab->Color3fv = choose_VERT_ATTRIB_COLOR0_3_1;
- tab->Color4f = choose_VERT_ATTRIB_COLOR0_4_0;
- tab->Color4fv = choose_VERT_ATTRIB_COLOR0_4_1;
- tab->SecondaryColor3fEXT = choose_VERT_ATTRIB_COLOR1_3_0;
- tab->SecondaryColor3fvEXT = choose_VERT_ATTRIB_COLOR1_3_1;
- tab->MultiTexCoord1fARB = _tnl_MultiTexCoord1f;
- tab->MultiTexCoord1fvARB = _tnl_MultiTexCoord1fv;
- tab->MultiTexCoord2fARB = _tnl_MultiTexCoord2f;
- tab->MultiTexCoord2fvARB = _tnl_MultiTexCoord2fv;
- tab->MultiTexCoord3fARB = _tnl_MultiTexCoord3f;
- tab->MultiTexCoord3fvARB = _tnl_MultiTexCoord3fv;
- tab->MultiTexCoord4fARB = _tnl_MultiTexCoord4f;
- tab->MultiTexCoord4fvARB = _tnl_MultiTexCoord4fv;
- tab->Normal3f = choose_VERT_ATTRIB_NORMAL_3_0;
- tab->Normal3fv = choose_VERT_ATTRIB_NORMAL_3_1;
- tab->TexCoord1f = choose_VERT_ATTRIB_TEX0_1_0;
- tab->TexCoord1fv = choose_VERT_ATTRIB_TEX0_1_1;
- tab->TexCoord2f = choose_VERT_ATTRIB_TEX0_2_0;
- tab->TexCoord2fv = choose_VERT_ATTRIB_TEX0_2_1;
- tab->TexCoord3f = choose_VERT_ATTRIB_TEX0_3_0;
- tab->TexCoord3fv = choose_VERT_ATTRIB_TEX0_3_1;
- tab->TexCoord4f = choose_VERT_ATTRIB_TEX0_4_0;
- tab->TexCoord4fv = choose_VERT_ATTRIB_TEX0_4_1;
- tab->Vertex2f = choose_VERT_ATTRIB_POS_2_0;
- tab->Vertex2fv = choose_VERT_ATTRIB_POS_2_1;
- tab->Vertex3f = choose_VERT_ATTRIB_POS_3_0;
- tab->Vertex3fv = choose_VERT_ATTRIB_POS_3_1;
- tab->Vertex4f = choose_VERT_ATTRIB_POS_4_0;
- tab->Vertex4fv = choose_VERT_ATTRIB_POS_4_1;
- tab->FogCoordfEXT = choose_VERT_ATTRIB_FOG_1_0;
- tab->FogCoordfvEXT = choose_VERT_ATTRIB_FOG_1_1;
- tab->EdgeFlag = _tnl_EdgeFlag;
- tab->EdgeFlagv = _tnl_EdgeFlagv;
- tab->Indexi = _tnl_Indexi;
- tab->Indexiv = _tnl_Indexiv;
- tab->EvalCoord1f = _tnl_EvalCoord1f;
- tab->EvalCoord1fv = _tnl_EvalCoord1fv;
- tab->EvalCoord2f = _tnl_EvalCoord2f;
- tab->EvalCoord2fv = _tnl_EvalCoord2fv;
- tab->Materialfv = _tnl_Materialfv;
- tab->ArrayElement = _ae_loopback_array_elt; /* generic helper */
-}
-
-
-
-static struct dynfn *codegen_noop( GLcontext *ctx, int key )
-{
- (void) ctx; (void) key;
- return 0;
-}
-
-static void _tnl_InitCodegen( GLcontext *ctx )
-{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- int sz, v, z;
-
- /* attr[n][v]
- * vertex[n][v]
- *
- * Generated functions parameterized by:
- * nr 1..4
- * v y/n
- * vertex y/n
- *
- * Vertex functions also parameterized by:
- * vertex_size
- *
- * Attr functions also parameterized by:
- * pointer (destination to receive data)
- */
- for (sz = 1 ; sz < 5 ; sz++) {
- for (v = 0 ; v < 2 ; v++) {
- for (z = 0 ; z < 2 ; z++) {
- tnl->vtx.codegen[sz-1][v][z] = codegen_noop;
- tnl->vtx.generated[sz-1][v][z] = 0;
- }
- }
- }
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
-#if 0
- if (!getenv("MESA_NO_CODEGEN")) {
-#if defined(USE_X86_ASM)
- _tnl_InitX86Codegen( gen );
-#endif
+ if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END)
+ return;
-#if defined(USE_SSE_ASM)
- _tnl_InitSSECodegen( gen );
+ if (tnl->vtx.counter != tnl->vtx.initial_counter) {
+ _tnl_flush_vtx( ctx );
+#if 0
+ init_0(tnl);
#endif
+ }
-#if defined(USE_3DNOW_ASM)
+#if 0
+ if (flags & FLUSH_UPDATE_CURRENT)
#endif
+ {
+ _tnl_copy_to_current( ctx );
-#if defined(USE_SPARC_ASM)
-#endif
+ /* reset attrfv table
+ */
+ init_attrfv( tnl );
+ flags |= FLUSH_UPDATE_CURRENT;
}
-#endif
+
+ ctx->Driver.NeedFlush = 0;
+}
+
+static void _tnl_current_init( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLint i;
+
+ for (i = 0; i < VERT_ATTRIB_MAX; i++)
+ tnl->vtx.current[i] = ctx->Current.Attrib[i];
+
+ for (i = 0; i < MAT_ATTRIB_MAX; i++)
+ tnl->vtx.current[_TNL_ATTRIB_MAT_FRONT_AMBIENT + i] =
+ ctx->Light.Material.Attrib[i];
+
+ tnl->vtx.current[_TNL_ATTRIB_INDEX] = &ctx->Current.Index;
}
void _tnl_vtx_init( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
- _tnl_InitDispatch( tnl->Exec );
- _tnl_InitCodegen( ctx );
+ struct tnl_vertex_arrays *tmp = &tnl->vtx_inputs;
+ GLuint i;
+
+ for (i = 0; i < _TNL_ATTRIB_INDEX; i++)
+ _mesa_vector4f_init( &tmp->Attribs[i], 0, 0);
+
+ _tnl_current_init( ctx );
+ _tnl_exec_vtxfmt_init( ctx );
+
+ _mesa_install_exec_vtxfmt( ctx, &tnl->exec_vtxfmt );
+ tnl->vtx.vertex_size = 1; init_attrfv( tnl );
}
void _tnl_vtx_destroy( GLcontext *ctx )
{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- int sz, v, z;
- struct dynfn *dfn, *next;
-
- for (sz = 1 ; sz <= 4 ; sz++) {
- for (v = 0 ; v <= 1 ; v++) {
- for (z = 0 ; z <= 1 ; z++) {
- dfn = tnl->vtx.generated[sz-1][v][z];
- while (dfn) {
- next = dfn->next;
- FREE(dfn);
- dfn = next;
- }
- }
- }
- }
}
*
*/
-#ifndef __RADEON_VTXFMT_H__
-#define __RADEON_VTXFMT_H__
+#ifndef __T_VTX_API_H__
+#define __T_VTX_API_H__
-#ifdef GLX_DIRECT_RENDERING
+#include "t_context.h"
-#include "_tnl__context.h"
+extern void _tnl_vtx_init( GLcontext *ctx );
+extern void _tnl_vtx_destroy( GLcontext *ctx );
-extern void _tnl_UpdateVtxfmt( GLcontext *ctx );
-extern void _tnl_InitVtxfmt( GLcontext *ctx );
-extern void _tnl_InvalidateVtxfmt( GLcontext *ctx );
-extern void _tnl_DestroyVtxfmt( GLcontext *ctx );
+extern void _tnl_FlushVertices( GLcontext *ctx, GLuint flags );
+extern void _tnl_flush_vtx( GLcontext *ctx );
-typedef void (*p4f)( GLfloat, GLfloat, GLfloat, GLfloat );
-typedef void (*p3f)( GLfloat, GLfloat, GLfloat );
-typedef void (*p2f)( GLfloat, GLfloat );
-typedef void (*p1f)( GLfloat );
-typedef void (*pe2f)( GLenum, GLfloat, GLfloat );
-typedef void (*pe1f)( GLenum, GLfloat );
-typedef void (*p4ub)( GLubyte, GLubyte, GLubyte, GLubyte );
-typedef void (*p3ub)( GLubyte, GLubyte, GLubyte );
-typedef void (*pfv)( const GLfloat * );
-typedef void (*pefv)( GLenum, const GLfloat * );
-typedef void (*pubv)( const GLubyte * );
+extern void _tnl_do_EvalCoord2f( GLcontext* ctx, GLfloat u, GLfloat v );
+extern void _tnl_do_EvalCoord1f(GLcontext* ctx, GLfloat u);
+extern void _tnl_update_eval( GLcontext *ctx );
-/* Want to keep a cache of these around. Each is parameterized by
- * only a single value which has only a small range. Only expect a
- * few, so just rescan the list each time?
- */
-struct dynfn {
- struct dynfn *next, *prev;
- int key;
- char *code;
-};
-
-struct dfn_lists {
- struct dynfn Vertex2f;
- struct dynfn Vertex2fv;
- struct dynfn Vertex3f;
- struct dynfn Vertex3fv;
- struct dynfn Color4ub;
- struct dynfn Color4ubv;
- struct dynfn Color3ub;
- struct dynfn Color3ubv;
- struct dynfn Color4f;
- struct dynfn Color4fv;
- struct dynfn Color3f;
- struct dynfn Color3fv;
- struct dynfn SecondaryColor3ubEXT;
- struct dynfn SecondaryColor3ubvEXT;
- struct dynfn SecondaryColor3fEXT;
- struct dynfn SecondaryColor3fvEXT;
- struct dynfn Normal3f;
- struct dynfn Normal3fv;
- struct dynfn TexCoord2f;
- struct dynfn TexCoord2fv;
- struct dynfn TexCoord1f;
- struct dynfn TexCoord1fv;
- struct dynfn MultiTexCoord2fARB;
- struct dynfn MultiTexCoord2fvARB;
- struct dynfn MultiTexCoord1fARB;
- struct dynfn MultiTexCoord1fvARB;
-};
-
-struct _vb;
-
-struct dfn_generators {
- struct dynfn *(*Vertex2f)( struct _vb *, int );
- struct dynfn *(*Vertex2fv)( struct _vb *, int );
- struct dynfn *(*Vertex3f)( struct _vb *, int );
- struct dynfn *(*Vertex3fv)( struct _vb *, int );
- struct dynfn *(*Color4ub)( struct _vb *, int );
- struct dynfn *(*Color4ubv)( struct _vb *, int );
- struct dynfn *(*Color3ub)( struct _vb *, int );
- struct dynfn *(*Color3ubv)( struct _vb *, int );
- struct dynfn *(*Color4f)( struct _vb *, int );
- struct dynfn *(*Color4fv)( struct _vb *, int );
- struct dynfn *(*Color3f)( struct _vb *, int );
- struct dynfn *(*Color3fv)( struct _vb *, int );
- struct dynfn *(*SecondaryColor3ubEXT)( struct _vb *, int );
- struct dynfn *(*SecondaryColor3ubvEXT)( struct _vb *, int );
- struct dynfn *(*SecondaryColor3fEXT)( struct _vb *, int );
- struct dynfn *(*SecondaryColor3fvEXT)( struct _vb *, int );
- struct dynfn *(*Normal3f)( struct _vb *, int );
- struct dynfn *(*Normal3fv)( struct _vb *, int );
- struct dynfn *(*TexCoord2f)( struct _vb *, int );
- struct dynfn *(*TexCoord2fv)( struct _vb *, int );
- struct dynfn *(*TexCoord1f)( struct _vb *, int );
- struct dynfn *(*TexCoord1fv)( struct _vb *, int );
- struct dynfn *(*MultiTexCoord2fARB)( struct _vb *, int );
- struct dynfn *(*MultiTexCoord2fvARB)( struct _vb *, int );
- struct dynfn *(*MultiTexCoord1fARB)( struct _vb *, int );
- struct dynfn *(*MultiTexCoord1fvARB)( struct _vb *, int );
-};
-
-struct prim {
- GLuint start;
- GLuint end;
- GLuint prim;
-};
-
-#define _TNL__MAX_PRIMS 64
-
-
-
-struct tnl_vbinfo {
- /* Keep these first: referenced from codegen templates:
- */
- GLint counter;
- GLint *dmaptr;
- void (*notify)( void );
- union { float f; int i; GLubyte ub4[4]; } vertex[16*4];
-
- GLfloat *attrptr[16];
- GLuint size[16];
-
- GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */
- GLuint primflags;
-
- GLboolean installed;
- GLboolean recheck;
-
- GLint vertex_size;
- GLint initial_counter;
- GLint nrverts;
- GLuint vertex_format;
-
- GLuint installed_vertex_format;
-
- struct prim primlist[RADEON_MAX_PRIMS];
- int nrprims;
+extern GLboolean *_tnl_translate_edgeflag( GLcontext *ctx,
+ const GLfloat *data,
+ GLuint count,
+ GLuint stride );
- struct dfn_lists dfn_cache;
- struct dfn_generators codegen;
- GLvertexformat vtxfmt;
-};
+extern GLboolean *_tnl_import_current_edgeflag( GLcontext *ctx,
+ GLuint count );
-
-extern void _tnl_InitVtxfmtChoosers( GLvertexformat *vfmt );
-
-
-#define FIXUP( CODE, OFFSET, CHECKVAL, NEWVAL ) \
-do { \
- int *icode = (int *)(CODE+OFFSET); \
- assert (*icode == CHECKVAL); \
- *icode = (int)NEWVAL; \
-} while (0)
-
-
-/* Useful for figuring out the offsets:
- */
-#define FIXUP2( CODE, OFFSET, CHECKVAL, NEWVAL ) \
-do { \
- while (*(int *)(CODE+OFFSET) != CHECKVAL) OFFSET++; \
- fprintf(stderr, "%s/%d CVAL %x OFFSET %d\n", __FUNCTION__, \
- __LINE__, CHECKVAL, OFFSET); \
- *(int *)(CODE+OFFSET) = (int)NEWVAL; \
- OFFSET += 4; \
-} while (0)
-
-/*
- */
-void _tnl_InitCodegen( struct dfn_generators *gen );
-void _tnl_InitX86Codegen( struct dfn_generators *gen );
-void _tnl_InitSSECodegen( struct dfn_generators *gen );
-
-void _tnl_copy_to_current( GLcontext *ctx );
-
-
-/* Defined in tnl_vtxfmt_c.c.
- */
-struct dynfn *tnl_makeX86Vertex2f( TNLcontext *, int );
-struct dynfn *tnl_makeX86Vertex2fv( TNLcontext *, int );
-struct dynfn *tnl_makeX86Vertex3f( TNLcontext *, int );
-struct dynfn *tnl_makeX86Vertex3fv( TNLcontext *, int );
-struct dynfn *tnl_makeX86Color4ub( TNLcontext *, int );
-struct dynfn *tnl_makeX86Color4ubv( TNLcontext *, int );
-struct dynfn *tnl_makeX86Color3ub( TNLcontext *, int );
-struct dynfn *tnl_makeX86Color3ubv( TNLcontext *, int );
-struct dynfn *tnl_makeX86Color4f( TNLcontext *, int );
-struct dynfn *tnl_makeX86Color4fv( TNLcontext *, int );
-struct dynfn *tnl_makeX86Color3f( TNLcontext *, int );
-struct dynfn *tnl_makeX86Color3fv( TNLcontext *, int );
-struct dynfn *tnl_makeX86SecondaryColor3ubEXT( TNLcontext *, int );
-struct dynfn *tnl_makeX86SecondaryColor3ubvEXT( TNLcontext *, int );
-struct dynfn *tnl_makeX86SecondaryColor3fEXT( TNLcontext *, int );
-struct dynfn *tnl_makeX86SecondaryColor3fvEXT( TNLcontext *, int );
-struct dynfn *tnl_makeX86Normal3f( TNLcontext *, int );
-struct dynfn *tnl_makeX86Normal3fv( TNLcontext *, int );
-struct dynfn *tnl_makeX86TexCoord2f( TNLcontext *, int );
-struct dynfn *tnl_makeX86TexCoord2fv( TNLcontext *, int );
-struct dynfn *tnl_makeX86TexCoord1f( TNLcontext *, int );
-struct dynfn *tnl_makeX86TexCoord1fv( TNLcontext *, int );
-struct dynfn *tnl_makeX86MultiTexCoord2fARB( TNLcontext *, int );
-struct dynfn *tnl_makeX86MultiTexCoord2fvARB( TNLcontext *, int );
-struct dynfn *tnl_makeX86MultiTexCoord1fARB( TNLcontext *, int );
-struct dynfn *tnl_makeX86MultiTexCoord1fvARB( TNLcontext *, int );
-
-
-#endif
#endif
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 5.1
+ *
+ * Copyright (C) 1999-2003 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 <keith@tungstengraphics.com>
+ */
+
+#include "glheader.h"
+#include "api_eval.h"
+#include "context.h"
+#include "macros.h"
+#include "math/m_eval.h"
+#include "t_vtx_api.h"
+
+
+static void clear_active_eval1( TNLcontext *tnl, GLuint attr )
+{
+ tnl->vtx.eval.map1[attr].map = 0;
+}
+
+static void clear_active_eval2( TNLcontext *tnl, GLuint attr )
+{
+ tnl->vtx.eval.map2[attr].map = 0;
+}
+
+static void set_active_eval1( TNLcontext *tnl, GLuint attr, GLuint dim,
+ struct gl_1d_map *map )
+{
+ if (!tnl->vtx.eval.map1[attr].map) {
+ tnl->vtx.eval.map1[attr].map = map;
+ tnl->vtx.eval.map1[attr].sz = dim;
+ }
+}
+
+static void set_active_eval2( TNLcontext *tnl, GLuint attr, GLuint dim,
+ struct gl_2d_map *map )
+{
+ if (!tnl->vtx.eval.map2[attr].map) {
+ tnl->vtx.eval.map2[attr].map = map;
+ tnl->vtx.eval.map2[attr].sz = dim;
+ }
+}
+
+void _tnl_update_eval( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLuint attr;
+
+ /* Vertex program maps have priority over conventional attribs */
+
+ for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
+ clear_active_eval1( tnl, attr );
+ clear_active_eval2( tnl, attr );
+ }
+
+ if (ctx->VertexProgram.Enabled) {
+ for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
+ if (ctx->Eval.Map1Attrib[attr])
+ set_active_eval1( tnl, attr, 4, &ctx->EvalMap.Map1Attrib[attr] );
+
+ if (ctx->Eval.Map2Attrib[attr])
+ set_active_eval2( tnl, attr, 4, &ctx->EvalMap.Map2Attrib[attr] );
+ }
+ }
+
+ if (ctx->Eval.Map1Color4)
+ set_active_eval1( tnl, VERT_ATTRIB_COLOR0, 4, &ctx->EvalMap.Map1Color4 );
+
+ if (ctx->Eval.Map2Color4)
+ set_active_eval2( tnl, VERT_ATTRIB_COLOR0, 4, &ctx->EvalMap.Map2Color4 );
+
+ if (ctx->Eval.Map1TextureCoord4)
+ set_active_eval1( tnl, VERT_ATTRIB_TEX0, 4, &ctx->EvalMap.Map1Texture4 );
+ else if (ctx->Eval.Map1TextureCoord3)
+ set_active_eval1( tnl, VERT_ATTRIB_TEX0, 3, &ctx->EvalMap.Map1Texture3 );
+ else if (ctx->Eval.Map1TextureCoord2)
+ set_active_eval1( tnl, VERT_ATTRIB_TEX0, 2, &ctx->EvalMap.Map1Texture2 );
+ else if (ctx->Eval.Map1TextureCoord1)
+ set_active_eval1( tnl, VERT_ATTRIB_TEX0, 1, &ctx->EvalMap.Map1Texture1 );
+
+ if (ctx->Eval.Map2TextureCoord4)
+ set_active_eval2( tnl, VERT_ATTRIB_TEX0, 4, &ctx->EvalMap.Map2Texture4 );
+ else if (ctx->Eval.Map2TextureCoord3)
+ set_active_eval2( tnl, VERT_ATTRIB_TEX0, 3, &ctx->EvalMap.Map2Texture3 );
+ else if (ctx->Eval.Map2TextureCoord2)
+ set_active_eval2( tnl, VERT_ATTRIB_TEX0, 2, &ctx->EvalMap.Map2Texture2 );
+ else if (ctx->Eval.Map2TextureCoord1)
+ set_active_eval2( tnl, VERT_ATTRIB_TEX0, 1, &ctx->EvalMap.Map2Texture1 );
+
+ if (ctx->Eval.Map1Normal)
+ set_active_eval1( tnl, VERT_ATTRIB_NORMAL, 3, &ctx->EvalMap.Map1Normal );
+
+ if (ctx->Eval.Map2Normal)
+ set_active_eval2( tnl, VERT_ATTRIB_NORMAL, 3, &ctx->EvalMap.Map2Normal );
+
+ if (ctx->Eval.Map1Vertex4)
+ set_active_eval1( tnl, VERT_ATTRIB_POS, 4, &ctx->EvalMap.Map1Vertex4 );
+ else if (ctx->Eval.Map1Vertex3)
+ set_active_eval1( tnl, VERT_ATTRIB_POS, 3, &ctx->EvalMap.Map1Vertex3 );
+
+ if (ctx->Eval.Map2Vertex4)
+ set_active_eval2( tnl, VERT_ATTRIB_POS, 4, &ctx->EvalMap.Map2Vertex4 );
+ else if (ctx->Eval.Map2Vertex3)
+ set_active_eval2( tnl, VERT_ATTRIB_POS, 3, &ctx->EvalMap.Map2Vertex3 );
+
+ tnl->vtx.eval.new_state = 0;
+}
+
+
+
+void _tnl_do_EvalCoord1f(GLcontext* ctx, GLfloat u)
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLuint attr;
+
+ for (attr = 1; attr <= _TNL_ATTRIB_INDEX; attr++) {
+ struct gl_1d_map *map = tnl->vtx.eval.map1[attr].map;
+ if (map) {
+ GLfloat uu = (u - map->u1) * map->du;
+ GLfloat data[4];
+
+ ASSIGN_4V(data, 0, 0, 0, 1);
+
+ _math_horner_bezier_curve(map->Points, data, uu,
+ tnl->vtx.eval.map1[attr].sz,
+ map->Order);
+
+ COPY_SZ_4V( tnl->vtx.attrptr[attr],
+ tnl->vtx.attrsz[attr],
+ data );
+ }
+ }
+
+ /** Vertex -- EvalCoord1f is a noop if this map not enabled:
+ **/
+ if (tnl->vtx.eval.map1[0].map) {
+ struct gl_1d_map *map = tnl->vtx.eval.map1[0].map;
+ GLfloat uu = (u - map->u1) * map->du;
+ GLfloat vertex[4];
+
+ ASSIGN_4V(vertex, 0, 0, 0, 1);
+
+ _math_horner_bezier_curve(map->Points, vertex, uu,
+ tnl->vtx.eval.map1[0].sz,
+ map->Order);
+
+ if (tnl->vtx.eval.map1[0].sz == 4)
+ glVertex4fv( vertex );
+ else
+ glVertex3fv( vertex );
+ }
+}
+
+
+
+void _tnl_do_EvalCoord2f( GLcontext* ctx, GLfloat u, GLfloat v )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLuint attr;
+
+ for (attr = 1; attr <= _TNL_ATTRIB_INDEX; attr++) {
+ struct gl_2d_map *map = tnl->vtx.eval.map2[attr].map;
+ if (map) {
+ GLfloat uu = (u - map->u1) * map->du;
+ GLfloat vv = (v - map->v1) * map->dv;
+ GLfloat data[4];
+
+ ASSIGN_4V(data, 0, 0, 0, 1);
+
+ _math_horner_bezier_surf(map->Points,
+ data,
+ uu, vv,
+ tnl->vtx.eval.map2[attr].sz,
+ map->Uorder, map->Vorder);
+
+ COPY_SZ_4V( tnl->vtx.attrptr[attr],
+ tnl->vtx.attrsz[attr],
+ data );
+ }
+ }
+
+ /** Vertex -- EvalCoord2f is a noop if this map not enabled:
+ **/
+ if (tnl->vtx.eval.map2[0].map) {
+ struct gl_2d_map *map = tnl->vtx.eval.map2[0].map;
+ GLfloat uu = (u - map->u1) * map->du;
+ GLfloat vv = (v - map->v1) * map->dv;
+ GLfloat vertex[4];
+
+ ASSIGN_4V(vertex, 0, 0, 0, 1);
+
+ if (ctx->Eval.AutoNormal) {
+ GLfloat normal[3];
+ GLfloat du[4], dv[4];
+
+ _math_de_casteljau_surf(map->Points, vertex, du, dv, uu, vv,
+ tnl->vtx.eval.map2[0].sz,
+ map->Uorder, map->Vorder);
+
+ if (tnl->vtx.eval.map2[0].sz == 4) {
+ du[0] = du[0]*vertex[3] - du[3]*vertex[0];
+ du[1] = du[1]*vertex[3] - du[3]*vertex[1];
+ du[2] = du[2]*vertex[3] - du[3]*vertex[2];
+
+ dv[0] = dv[0]*vertex[3] - dv[3]*vertex[0];
+ dv[1] = dv[1]*vertex[3] - dv[3]*vertex[1];
+ dv[2] = dv[2]*vertex[3] - dv[3]*vertex[2];
+ }
+
+
+ CROSS3(normal, du, dv);
+ NORMALIZE_3FV(normal);
+ normal[3] = 1.0;
+
+ COPY_SZ_4V( tnl->vtx.attrptr[_TNL_ATTRIB_NORMAL],
+ tnl->vtx.attrsz[_TNL_ATTRIB_NORMAL],
+ normal );
+
+ }
+ else {
+ _math_horner_bezier_surf(map->Points, vertex, uu, vv,
+ tnl->vtx.eval.map2[0].sz,
+ map->Uorder, map->Vorder);
+ }
+
+ if (tnl->vtx.attrsz[0] == 4)
+ glVertex4fv( vertex );
+ else
+ glVertex3fv( vertex );
+ }
+}
+
+
-/* $XFree86$ */
-/**************************************************************************
-
-Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas.
-
-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
-on the rights to use, copy, modify, merge, publish, distribute, sub
-license, 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 (including the next
-paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
-TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS 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 <keith@tungstengraphics.com>
+ * Mesa 3-D graphics library
+ * Version: 5.1
+ *
+ * Copyright (C) 1999-2003 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 <keith@tungstengraphics.com>
*/
-#include "api_noop.h"
-#include "api_arrayelt.h"
+
+#include "glheader.h"
+#include "api_eval.h"
#include "context.h"
-#include "imports.h"
-#include "mtypes.h"
-#include "enums.h"
-#include "glapi.h"
-#include "colormac.h"
-#include "light.h"
#include "state.h"
-#include "vtxfmt.h"
-
-#include "tnl/tnl.h"
-#include "tnl/t_context.h"
-#include "tnl/t_array_api.h"
+#include "macros.h"
+#include "math/m_eval.h"
+#include "t_vtx_api.h"
+#include "t_pipeline.h"
-static void _tnl_FlushVertices( GLcontext *, GLuint );
+static void _tnl_print_vtx( GLcontext *ctx )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLuint count = tnl->vtx.initial_counter - tnl->vtx.counter;
+ GLuint i;
+ _mesa_debug(0, "%s: %u vertices %d primitives, %d vertsize\n",
+ __FUNCTION__,
+ count,
+ tnl->vtx.prim_count,
+ tnl->vtx.vertex_size);
+
+ for (i = 0 ; i < tnl->vtx.prim_count ; i++) {
+ struct tnl_prim *prim = &tnl->vtx.prim[i];
+ _mesa_debug(0, " prim %d: %s %d..%d %s %s\n",
+ i,
+ _mesa_lookup_enum_by_nr(prim->mode & PRIM_MODE_MASK),
+ prim->start,
+ prim->start + prim->count,
+ (prim->mode & PRIM_BEGIN) ? "BEGIN" : "(wrap)",
+ (prim->mode & PRIM_END) ? "END" : "(wrap)");
+ }
+}
-void tnl_copy_to_current( GLcontext *ctx )
+GLboolean *_tnl_translate_edgeflag( GLcontext *ctx, const GLfloat *data,
+ GLuint count, GLuint stride )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
- GLuint flag = tnl->vertex_format;
- GLint i;
-
- assert(ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT);
+ GLboolean *ef = tnl->vtx.edgeflag_tmp;
+ GLuint i;
- for (i = 0 ; i < 16 ; i++)
- if (flag & (1<<i))
- COPY_4FV( ctx->Current.Attrib[i], tnl->attribptr[i] );
+ if (!ef)
+ ef = tnl->vtx.edgeflag_tmp = MALLOC( tnl->vb.Size );
+
+ for (i = 0 ; i < count ; i++, data += stride)
+ ef[i] = (data[0] == 1.0);
- if (flag & VERT_BIT_INDEX)
- ctx->Current.Index = tnl->indexptr[0];
+ return ef;
+}
- if (flag & VERT_BIT_EDGEFLAG)
- ctx->Current.EdgeFlag = tnl->edgeflagptr[0];
- if (flag & VERT_BIT_MATERIAL) {
- _mesa_update_material( ctx,
- IM->Material[IM->LastMaterial],
- IM->MaterialOrMask );
+GLboolean *_tnl_import_current_edgeflag( GLcontext *ctx,
+ GLuint count )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLboolean *ef = tnl->vtx.edgeflag_tmp;
+ GLboolean tmp = ctx->Current.EdgeFlag;
+ GLuint i;
- tnl->Driver.NotifyMaterialChange( ctx );
- }
+ if (!ef)
+ ef = tnl->vtx.edgeflag_tmp = MALLOC( tnl->vb.Size );
+ for (i = 0 ; i < count ; i++)
+ ef[i] = tmp;
- ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT;
+ return ef;
}
-static GLboolean discreet_gl_prim[GL_POLYGON+1] = {
- 1, /* 0 points */
- 1, /* 1 lines */
- 0, /* 2 line_strip */
- 0, /* 3 line_loop */
- 1, /* 4 tris */
- 0, /* 5 tri_fan */
- 0, /* 6 tri_strip */
- 1, /* 7 quads */
- 0, /* 8 quadstrip */
- 0, /* 9 poly */
-};
-
-/* Optimize the primitive list: ONLY FOR EXECUTE ATM
- */
-static void optimize_prims( TNLcontext *tnl )
+static GLint get_size( const GLfloat *f )
{
- int i, j;
-
- if (tnl->nrprims <= 1)
- return;
-
- for (j = 0, i = 1 ; i < tnl->nrprims; i++) {
- int pj = tnl->primlist[j].prim & 0xf;
- int pi = tnl->primlist[i].prim & 0xf;
-
- if (pj == pi && discreet_gl_prim[pj] &&
- tnl->primlist[i].start == tnl->primlist[j].end) {
- tnl->primlist[j].end = tnl->primlist[i].end;
- }
- else {
- j++;
- if (j != i) tnl->primlist[j] = tnl->primlist[i];
- }
- }
-
- tnl->nrprims = j+1;
+ if (f[3] != 1.0) return 4;
+ if (f[2] != 0.0) return 3;
+ return 2;
}
-
-/* Bind vertex buffer pointers, run pipeline:
+/* Some nasty stuff still hanging on here.
+ *
+ * TODO - remove VB->NormalPtr, etc and just use the AttrPtr's.
*/
-static void flush_prims( TNLcontext *tnl )
+static void _tnl_vb_bind_vtx( GLcontext *ctx )
{
- int i,j;
-
- tnl->dma.current.ptr = tnl->dma.current.start +=
- (tnl->initial_counter - tnl->counter) * tnl->vertex_size * 4;
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct vertex_buffer *VB = &tnl->vb;
+ struct tnl_vertex_arrays *tmp = &tnl->vtx_inputs;
+ GLfloat *data = tnl->vtx.buffer;
+ GLuint count = tnl->vtx.initial_counter - tnl->vtx.counter;
+ GLuint attr, i;
- tnl->tcl.vertex_format = tnl->vertex_format;
- tnl->tcl.aos_components[0] = &tmp;
- tnl->tcl.nr_aos_components = 1;
- tnl->dma.flush = 0;
+ if (0) fprintf(stderr, "%s: %d verts %d vertsize\n",
+ __FUNCTION__, count, tnl->vtx.vertex_size);
- tnl->Driver.RunPipeline( ... );
-
- tnl->nrprims = 0;
-}
+ /* Setup constant data in the VB.
+ */
+ VB->Count = count;
+ VB->Primitive = tnl->vtx.prim;
+ VB->PrimitiveCount = tnl->vtx.prim_count;
+ VB->Elts = NULL;
+ VB->NormalLengthPtr = NULL;
+
+ for (attr = 0; attr <= _TNL_ATTRIB_INDEX ; attr++) {
+ if (tnl->vtx.attrsz[attr]) {
+ tmp->Attribs[attr].count = count;
+ tmp->Attribs[attr].data = (GLfloat (*)[4]) data;
+ tmp->Attribs[attr].start = data;
+ tmp->Attribs[attr].size = tnl->vtx.attrsz[attr];
+ tmp->Attribs[attr].stride = tnl->vtx.vertex_size * sizeof(GLfloat);
+ VB->AttribPtr[attr] = &tmp->Attribs[attr];
+ data += tnl->vtx.attrsz[attr];
+ }
+ else {
+/* VB->AttribPtr[attr] = &tnl->current.Attribs[attr]; */
-static void start_prim( TNLcontext *tnl, GLuint mode )
-{
- if (MESA_VERBOSE & DEBUG_VFMT)
- _mesa_debug(NULL, "%s %d\n", __FUNCTION__,
- tnl->initial_counter - tnl->counter);
-
- tnl->primlist[tnl->nrprims].start = tnl->initial_counter - tnl->counter;
- tnl->primlist[tnl->nrprims].prim = mode;
-}
-static void note_last_prim( TNLcontext *tnl, GLuint flags )
-{
- if (MESA_VERBOSE & DEBUG_VFMT)
- _mesa_debug(NULL, "%s %d\n", __FUNCTION__,
- tnl->initial_counter - tnl->counter);
+ tmp->Attribs[attr].count = count;
+ tmp->Attribs[attr].data = (GLfloat (*)[4]) tnl->vtx.current[attr];
+ tmp->Attribs[attr].start = tnl->vtx.current[attr];
+ tmp->Attribs[attr].size = get_size( tnl->vtx.current[attr] );
+ tmp->Attribs[attr].stride = 0;
+ VB->AttribPtr[attr] = &tmp->Attribs[attr];
+ }
+ }
- if (tnl->prim[0] != GL_POLYGON+1) {
- tnl->primlist[tnl->nrprims].prim |= flags;
- tnl->primlist[tnl->nrprims].end = tnl->initial_counter - tnl->counter;
+
+ /* Copy and translate EdgeFlag to a contiguous array of GLbooleans
+ */
+ if (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL) {
+ if (tnl->vtx.attrsz[_TNL_ATTRIB_EDGEFLAG]) {
+ VB->EdgeFlag = _tnl_translate_edgeflag( ctx, data, count,
+ tnl->vtx.vertex_size );
+ data++;
+ }
+ else
+ VB->EdgeFlag = _tnl_import_current_edgeflag( ctx, count );
+ }
- if (++tnl->nrprims == TNL_MAX_PRIMS)
- flush_prims( tnl );
+ /* Legacy pointers -- remove one day.
+ */
+ VB->ObjPtr = VB->AttribPtr[_TNL_ATTRIB_POS];
+ VB->NormalPtr = VB->AttribPtr[_TNL_ATTRIB_NORMAL];
+ VB->ColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR0];
+ VB->ColorPtr[1] = 0;
+ VB->IndexPtr[0] = VB->AttribPtr[_TNL_ATTRIB_INDEX];
+ VB->IndexPtr[1] = 0;
+ VB->SecondaryColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR1];
+ VB->SecondaryColorPtr[1] = 0;
+
+ for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
+ VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i];
}
}
-static void copy_vertex( TNLcontext *tnl, GLuint n, GLfloat *dst )
-{
- GLuint i;
- GLfloat *src = (GLfloat *)(tnl->dma.current.address +
- tnl->dma.current.ptr +
- (tnl->primlist[tnl->nrprims].start + n) *
- tnl->vertex_size * 4);
- if (MESA_VERBOSE & DEBUG_VFMT)
- _mesa_debug(NULL, "copy_vertex %d\n",
- tnl->primlist[tnl->nrprims].start + n);
- for (i = 0 ; i < tnl->vertex_size; i++) {
- dst[i] = src[i];
- }
-}
-static GLuint copy_wrapped_verts( TNLcontext *tnl, GLfloat (*tmp)[15] )
+/*
+ * NOTE: Need to have calculated primitives by this point -- do it on the fly.
+ * NOTE: Old 'parity' issue is gone.
+ */
+static GLuint _tnl_copy_vertices( GLcontext *ctx )
{
+ TNLcontext *tnl = TNL_CONTEXT( ctx );
+ GLuint nr = tnl->vtx.prim[tnl->vtx.prim_count-1].count;
GLuint ovf, i;
- GLuint nr = (tnl->initial_counter - tnl->counter) - tnl->primlist[tnl->nrprims].start;
+ GLuint sz = tnl->vtx.vertex_size;
+ GLfloat *dst = tnl->vtx.copied.buffer;
+ GLfloat *src = (tnl->vtx.buffer +
+ tnl->vtx.prim[tnl->vtx.prim_count-1].start *
+ tnl->vtx.vertex_size);
- if (MESA_VERBOSE & DEBUG_VFMT)
- _mesa_debug(NULL, "%s %d verts\n", __FUNCTION__, nr);
- switch( tnl->prim[0] )
+ switch( ctx->Driver.CurrentExecPrimitive )
{
case GL_POINTS:
return 0;
case GL_LINES:
ovf = nr&1;
for (i = 0 ; i < ovf ; i++)
- copy_vertex( tnl, nr-ovf+i, tmp[i] );
+ memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) );
return i;
case GL_TRIANGLES:
ovf = nr%3;
for (i = 0 ; i < ovf ; i++)
- copy_vertex( tnl, nr-ovf+i, tmp[i] );
+ memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) );
return i;
case GL_QUADS:
ovf = nr&3;
for (i = 0 ; i < ovf ; i++)
- copy_vertex( tnl, nr-ovf+i, tmp[i] );
+ memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) );
return i;
case GL_LINE_STRIP:
if (nr == 0)
return 0;
- copy_vertex( tnl, nr-1, tmp[0] );
- return 1;
+ else {
+ memcpy( dst, src+(nr-1)*sz, sz * sizeof(GLfloat) );
+ return 1;
+ }
case GL_LINE_LOOP:
case GL_TRIANGLE_FAN:
case GL_POLYGON:
if (nr == 0)
return 0;
else if (nr == 1) {
- copy_vertex( tnl, 0, tmp[0] );
+ memcpy( dst, src+0, sz * sizeof(GLfloat) );
return 1;
} else {
- copy_vertex( tnl, 0, tmp[0] );
- copy_vertex( tnl, nr-1, tmp[1] );
+ memcpy( dst, src+0, sz * sizeof(GLfloat) );
+ memcpy( dst+sz, src+(nr-1)*sz, sz * sizeof(GLfloat) );
return 2;
}
case GL_TRIANGLE_STRIP:
- ovf = MIN2( nr-1, 2 );
- for (i = 0 ; i < ovf ; i++)
- copy_vertex( tnl, nr-ovf+i, tmp[i] );
- return i;
case GL_QUAD_STRIP:
- ovf = MIN2( nr-1, 2 );
- if (nr > 2) ovf += nr&1;
+ switch (nr) {
+ case 0: ovf = 0; break;
+ case 1: ovf = 1; break;
+ default: ovf = 2 + (nr&1); break;
+ }
for (i = 0 ; i < ovf ; i++)
- copy_vertex( tnl, nr-ovf+i, tmp[i] );
+ memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) );
return i;
+ case GL_POLYGON+1:
+ return 0;
default:
assert(0);
return 0;
-/* Extend for vertex-format changes on wrap:
- */
-static void wrap_buffer( void )
-{
- TNLcontext *tnl = tnl->tnl;
- GLfloat tmp[3][15];
- GLuint i, nrverts;
-
- if (MESA_VERBOSE & (DEBUG_VFMT|DEBUG_PRIMS))
- _mesa_debug(NULL, "%s %d\n", __FUNCTION__,
- tnl->initial_counter - tnl->counter);
-
- /* Don't deal with parity. *** WONT WORK FOR COMPILE
- */
- if ((((tnl->initial_counter - tnl->counter) -
- tnl->primlist[tnl->nrprims].start) & 1)) {
- tnl->counter++;
- tnl->initial_counter++;
- return;
- }
-
- /* Copy vertices out of dma:
- */
- nrverts = copy_dma_verts( tnl, tmp );
-
- if (MESA_VERBOSE & DEBUG_VFMT)
- _mesa_debug(NULL, "%d vertices to copy\n", nrverts);
-
-
- /* Finish the prim at this point:
- */
- note_last_prim( tnl, 0 );
- flush_prims( tnl );
-
- /* Reset counter, dmaptr
- */
- tnl->dmaptr = (int *)(tnl->dma.current.ptr + tnl->dma.current.address);
- tnl->counter = (tnl->dma.current.end - tnl->dma.current.ptr) /
- (tnl->vertex_size * 4);
- tnl->counter--;
- tnl->initial_counter = tnl->counter;
- tnl->notify = wrap_buffer;
- tnl->dma.flush = flush_prims;
- start_prim( tnl, tnl->prim[0] );
- /* Reemit saved vertices
- * *** POSSIBLY IN NEW FORMAT
- * --> Can't always extend at end of vertex?
- */
- for (i = 0 ; i < nrverts; i++) {
- if (MESA_VERBOSE & DEBUG_VERTS) {
- int j;
- _mesa_debug(NULL, "re-emit vertex %d to %p\n", i, tnl->dmaptr);
- if (MESA_VERBOSE & DEBUG_VERBOSE)
- for (j = 0 ; j < tnl->vertex_size; j++)
- _mesa_debug(NULL, "\t%08x/%f\n", *(int*)&tmp[i][j], tmp[i][j]);
- }
-
- memcpy( tnl->dmaptr, tmp[i], tnl->vertex_size * 4 );
- tnl->dmaptr += tnl->vertex_size;
- tnl->counter--;
- }
-}
-
-
-
-/* Always follow data, don't try to predict what's necessary.
+/**
+ * Execute the buffer and save copied verts.
*/
-static GLboolean check_vtx_fmt( GLcontext *ctx )
+void _tnl_flush_vtx( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
- if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT)
- ctx->Driver.FlushVertices( ctx, FLUSH_UPDATE_CURRENT );
-
-
- TNL_NEWPRIM(tnl);
- tnl->vertex_format = VERT_BIT_POS;
- tnl->prim = &ctx->Driver.CurrentExecPrimitive;
-
-
- /* Currently allow the full 4 components per attrib. Can use the
- * mechanism from radeon driver color handling to reduce this (and
- * also to store ubyte colors where these are incoming). This
- * won't work for compile mode.
- *
- * Only adding components when they are first received eliminates
- * the need for displaylist fixup, as there are no 'empty' slots
- * at the start of buffers.
- */
- for (i = 0 ; i < 16 ; i++) {
- if (ind & (1<<i)) {
- tnl->attribptr[i] = &tnl->vertex[tnl->vertex_size].f;
- tnl->vertex_size += 4;
- tnl->attribptr[i][0] = ctx->Current.Attrib[i][0];
- tnl->attribptr[i][1] = ctx->Current.Attrib[i][1];
- tnl->attribptr[i][2] = ctx->Current.Attrib[i][2];
- tnl->attribptr[i][3] = ctx->Current.Attrib[i][3];
- }
- else
- tnl->attribptr[i] = ctx->Current.Attrib[i];
- }
-
- /* Edgeflag, Index:
- */
- for (i = 16 ; i < 18 ; i++)
- ;
-
- /* Materials:
- */
- for (i = 18 ; i < 28 ; i++)
- ;
-
- /* Eval:
- */
- for (i = 28 ; i < 29 ; i++)
- ;
-
-
- if (tnl->installed_vertex_format != tnl->vertex_format) {
- if (MESA_VERBOSE & DEBUG_VFMT)
- _mesa_debug(NULL, "reinstall on vertex_format change\n");
- _mesa_install_exec_vtxfmt( ctx, &tnl->vtxfmt );
- tnl->installed_vertex_format = tnl->vertex_format;
- }
-
- return GL_TRUE;
-}
-
-
-void _tnl_InvalidateVtxfmt( GLcontext *ctx )
-{
- tnl->recheck = GL_TRUE;
- tnl->fell_back = GL_FALSE;
-}
-
-
-
-
-static void _tnl_ValidateVtxfmt( GLcontext *ctx )
-{
- if (MESA_VERBOSE & DEBUG_VFMT)
- _mesa_debug(NULL, "%s\n", __FUNCTION__);
-
- if (ctx->Driver.NeedFlush)
- ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush );
-
- tnl->recheck = GL_FALSE;
-
- if (check_vtx_fmt( ctx )) {
- if (!tnl->installed) {
- if (MESA_VERBOSE & DEBUG_VFMT)
- _mesa_debug(NULL, "reinstall (new install)\n");
-
- _mesa_install_exec_vtxfmt( ctx, &tnl->vtxfmt );
- ctx->Driver.FlushVertices = _tnl_FlushVertices;
- tnl->installed = GL_TRUE;
- }
- else
- _mesa_debug(NULL, "%s: already installed", __FUNCTION__);
- }
- else {
- if (MESA_VERBOSE & DEBUG_VFMT)
- _mesa_debug(NULL, "%s: failed\n", __FUNCTION__);
-
- if (tnl->installed) {
- if (tnl->tnl->dma.flush)
- tnl->tnl->dma.flush( tnl->tnl );
- _tnl_wakeup_exec( ctx );
- tnl->installed = GL_FALSE;
- }
- }
-}
-
-
-
-
-
-/* Begin/End
- */
-static void _tnl_Begin( GLenum mode )
-{
- GLcontext *ctx = tnl->context;
- TNLcontext *tnl = tnl->tnl;
-
- if (MESA_VERBOSE & DEBUG_VFMT)
- _mesa_debug(NULL, "%s\n", __FUNCTION__);
-
- if (mode > GL_POLYGON) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" );
- return;
- }
-
- if (tnl->prim[0] != GL_POLYGON+1) {
- _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" );
- return;
- }
-
- if (ctx->NewState)
- _mesa_update_state( ctx );
-
- if (tnl->recheck)
- _tnl_ValidateVtxfmt( ctx );
-
- if (tnl->dma.flush && tnl->counter < 12) {
- if (MESA_VERBOSE & DEBUG_VFMT)
- _mesa_debug(NULL, "%s: flush almost-empty buffers\n", __FUNCTION__);
- flush_prims( tnl );
- }
-
- if (!tnl->dma.flush) {
- if (tnl->dma.current.ptr + 12*tnl->vertex_size*4 >
- tnl->dma.current.end) {
- TNL_NEWPRIM( tnl );
- _tnl_RefillCurrentDmaRegion( tnl );
- }
-
- tnl->dmaptr = (int *)(tnl->dma.current.address + tnl->dma.current.ptr);
- tnl->counter = (tnl->dma.current.end - tnl->dma.current.ptr) /
- (tnl->vertex_size * 4);
- tnl->counter--;
- tnl->initial_counter = tnl->counter;
- tnl->notify = wrap_buffer;
- tnl->dma.flush = flush_prims;
- tnl->context->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
- }
-
-
- tnl->prim[0] = mode;
- start_prim( tnl, mode | PRIM_BEGIN );
-}
-
-
-
+ if (0)
+ _tnl_print_vtx( ctx );
+ if (tnl->vtx.prim_count &&
+ tnl->vtx.counter != tnl->vtx.initial_counter) {
-static void _tnl_End( void )
-{
- TNLcontext *tnl = tnl->tnl;
- GLcontext *ctx = tnl->context;
-
- if (MESA_VERBOSE & DEBUG_VFMT)
- _mesa_debug(NULL, "%s\n", __FUNCTION__);
-
- if (tnl->prim[0] == GL_POLYGON+1) {
- _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" );
- return;
- }
-
- note_last_prim( tnl, PRIM_END );
- tnl->prim[0] = GL_POLYGON+1;
-}
-
+ tnl->vtx.copied.nr = _tnl_copy_vertices( ctx );
-static void _tnl_FlushVertices( GLcontext *ctx, GLuint flags )
-{
- if (MESA_VERBOSE & DEBUG_VFMT)
- _mesa_debug(NULL, "%s\n", __FUNCTION__);
+ if (ctx->NewState)
+ _mesa_update_state( ctx );
+
+ if (tnl->pipeline.build_state_changes)
+ _tnl_validate_pipeline( ctx );
- assert(tnl->installed);
+ _tnl_vb_bind_vtx( ctx );
- if (flags & FLUSH_UPDATE_CURRENT) {
- _tnl_copy_to_current( ctx );
- if (MESA_VERBOSE & DEBUG_VFMT)
- _mesa_debug(NULL, "reinstall on update_current\n");
- _mesa_install_exec_vtxfmt( ctx, &tnl->vtxfmt );
- ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT;
+ /* Invalidate all stored data before and after run:
+ */
+ tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
+ tnl->Driver.RunPipeline( ctx );
+ tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
}
- if (flags & FLUSH_STORED_VERTICES) {
- TNLcontext *tnl = TNL_CONTEXT( ctx );
- assert (tnl->dma.flush == 0 ||
- tnl->dma.flush == flush_prims);
- if (tnl->dma.flush == flush_prims)
- flush_prims( TNL_CONTEXT( ctx ) );
- ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES;
- }
+ tnl->vtx.prim_count = 0;
+ tnl->vtx.counter = tnl->vtx.initial_counter;
+ tnl->vtx.vbptr = tnl->vtx.buffer;
}
-/* At this point, don't expect very many versions of each function to
- * be generated, so not concerned about freeing them?
- */
-
-
-static void _tnl_InitVtxfmt( GLcontext *ctx )
-{
- GLvertexformat *vfmt = &(tnl->vtxfmt);
-
- MEMSET( vfmt, 0, sizeof(GLvertexformat) );
-
- /* Hook in chooser functions for codegen, etc:
- */
- _tnl_InitVtxfmtChoosers( vfmt );
-
- /* Handled fully in supported states, but no codegen:
- */
- vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */
- vfmt->Rectf = _mesa_noop_Rectf; /* generic helper */
- vfmt->Begin = _tnl_Begin;
- vfmt->End = _tnl_End;
-
- tnl->context = ctx;
- tnl->tnl = TNL_CONTEXT(ctx);
- tnl->prim = &ctx->Driver.CurrentExecPrimitive;
- tnl->primflags = 0;
-
- make_empty_list( &tnl->dfn_cache.Vertex2f );
- make_empty_list( &tnl->dfn_cache.Vertex2fv );
- make_empty_list( &tnl->dfn_cache.Vertex3f );
- make_empty_list( &tnl->dfn_cache.Vertex3fv );
- make_empty_list( &tnl->dfn_cache.Color4ub );
- make_empty_list( &tnl->dfn_cache.Color4ubv );
- make_empty_list( &tnl->dfn_cache.Color3ub );
- make_empty_list( &tnl->dfn_cache.Color3ubv );
- make_empty_list( &tnl->dfn_cache.Color4f );
- make_empty_list( &tnl->dfn_cache.Color4fv );
- make_empty_list( &tnl->dfn_cache.Color3f );
- make_empty_list( &tnl->dfn_cache.Color3fv );
- make_empty_list( &tnl->dfn_cache.SecondaryColor3fEXT );
- make_empty_list( &tnl->dfn_cache.SecondaryColor3fvEXT );
- make_empty_list( &tnl->dfn_cache.SecondaryColor3ubEXT );
- make_empty_list( &tnl->dfn_cache.SecondaryColor3ubvEXT );
- make_empty_list( &tnl->dfn_cache.Normal3f );
- make_empty_list( &tnl->dfn_cache.Normal3fv );
- make_empty_list( &tnl->dfn_cache.TexCoord2f );
- make_empty_list( &tnl->dfn_cache.TexCoord2fv );
- make_empty_list( &tnl->dfn_cache.TexCoord1f );
- make_empty_list( &tnl->dfn_cache.TexCoord1fv );
- make_empty_list( &tnl->dfn_cache.MultiTexCoord2fARB );
- make_empty_list( &tnl->dfn_cache.MultiTexCoord2fvARB );
- make_empty_list( &tnl->dfn_cache.MultiTexCoord1fARB );
- make_empty_list( &tnl->dfn_cache.MultiTexCoord1fvARB );
-
- _tnl_InitCodegen( &tnl->codegen );
-}
-static void free_funcs( struct dynfn *l )
-{
- struct dynfn *f, *tmp;
- foreach_s (f, tmp, l) {
- remove_from_list( f );
- ALIGN_FREE( f->code );
- FREE( f );
- }
-}
-
-
-static void _tnl_DestroyVtxfmt( GLcontext *ctx )
-{
- count_funcs();
- free_funcs( &tnl->dfn_cache.Vertex2f );
- free_funcs( &tnl->dfn_cache.Vertex2fv );
- free_funcs( &tnl->dfn_cache.Vertex3f );
- free_funcs( &tnl->dfn_cache.Vertex3fv );
- free_funcs( &tnl->dfn_cache.Color4ub );
- free_funcs( &tnl->dfn_cache.Color4ubv );
- free_funcs( &tnl->dfn_cache.Color3ub );
- free_funcs( &tnl->dfn_cache.Color3ubv );
- free_funcs( &tnl->dfn_cache.Color4f );
- free_funcs( &tnl->dfn_cache.Color4fv );
- free_funcs( &tnl->dfn_cache.Color3f );
- free_funcs( &tnl->dfn_cache.Color3fv );
- free_funcs( &tnl->dfn_cache.SecondaryColor3ubEXT );
- free_funcs( &tnl->dfn_cache.SecondaryColor3ubvEXT );
- free_funcs( &tnl->dfn_cache.SecondaryColor3fEXT );
- free_funcs( &tnl->dfn_cache.SecondaryColor3fvEXT );
- free_funcs( &tnl->dfn_cache.Normal3f );
- free_funcs( &tnl->dfn_cache.Normal3fv );
- free_funcs( &tnl->dfn_cache.TexCoord2f );
- free_funcs( &tnl->dfn_cache.TexCoord2fv );
- free_funcs( &tnl->dfn_cache.TexCoord1f );
- free_funcs( &tnl->dfn_cache.TexCoord1fv );
- free_funcs( &tnl->dfn_cache.MultiTexCoord2fARB );
- free_funcs( &tnl->dfn_cache.MultiTexCoord2fvARB );
- free_funcs( &tnl->dfn_cache.MultiTexCoord1fARB );
- free_funcs( &tnl->dfn_cache.MultiTexCoord1fvARB );
-}
+++ /dev/null
-/* $XFree86$ */
-/**************************************************************************
-
-Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas.
-
-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
-on the rights to use, copy, modify, merge, publish, distribute, sub
-license, 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 (including the next
-paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
-TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS 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 <keith@tungstengraphics.com>
- */
-
-#include "imports.h"
-#include "simple_list.h"
-#include "t_vtx_api.h"
-
-#if defined(USE_SSE_ASM)
-
-/* Build specialized versions of the immediate calls on the fly for
- * the current state. ???P4 SSE2 versions???
- */
-
-
-static struct dynfn *makeSSENormal3fv( struct _vb *vb, int key )
-{
- /* Requires P4 (sse2?)
- */
- static unsigned char temp[] = {
- 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
- 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $0x12345678,%edx */
- 0xf3, 0x0f, 0x7e, 0x00, /* movq (%eax),%xmm0 */
- 0x66, 0x0f, 0x6e, 0x48, 0x08, /* movd 0x8(%eax),%xmm1 */
- 0x66, 0x0f, 0xd6, 0x42, 0x0c, /* movq %xmm0,0xc(%edx) */
- 0x66, 0x0f, 0x7e, 0x4a, 0x14, /* movd %xmm1,0x14(%edx) */
- 0xc3, /* ret */
- };
-
-
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
- insert_at_head( &vb->dfn_cache.Normal3fv, dfn );
- dfn->key = key;
-
- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
- memcpy (dfn->code, temp, sizeof(temp));
- FIXUP(dfn->code, 5, 0x0, (int)vb->normalptr);
- return dfn;
-}
-
-void _tnl_InitSSECodegen( struct dfn_generators *gen )
-{
- /* Need to:
- * - check kernel sse support
- * - check p4/sse2
- */
- (void) makeSSENormal3fv;
-}
-
-
-#else
-
-void _tnl_InitSSECodegen( struct dfn_generators *gen )
-{
- (void) gen;
-}
-
-#endif
-
-
-
-
+++ /dev/null
-/* $XFree86$ */
-/**************************************************************************
-
-Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas.
-
-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
-on the rights to use, copy, modify, merge, publish, distribute, sub
-license, 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 (including the next
-paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
-TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS 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 <keith@tungstengraphics.com>
- */
-
-#include "imports.h"
-#include "simple_list.h"
-#include "tnl_vtxfmt.h"
-
-#if defined(USE_X86_ASM)
-
-
-struct dynfn *tnl_makeX86Vertex2f( TNLcontext *tnl, int key )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (RADEON_DEBUG & DEBUG_CODEGEN)
- _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
-
- switch (tnl->vertex_size) {
- default: {
- /* Repz convenient as it's possible to emit code for any size
- * vertex with little tweaking. Might as well read vertsize
- * though, and have only one of these.
- */
- static char temp[] = {
- 0x57, /* push %edi */
- 0x56, /* push %esi */
- 0xbe, 0, 0, 0, 0, /* mov $VERTEX+2,%esi */
- 0x8b, 0x3d, 0, 0, 0, 0, /* mov DMAPTR,%edi */
- 0x8b, 0x44, 0x24, 0x0c, /* mov 0x0c(%esp,1),%eax */
- 0x8b, 0x54, 0x24, 0x10, /* mov 0x10(%esp,1),%edx */
- 0x89, 0x07, /* mov %eax,(%edi) */
- 0x89, 0x57, 0x04, /* mov %edx,0x4(%edi) */
- 0x83, 0xc7, 0x08, /* add $0x8,%edi */
- 0xb9, 0, 0, 0, 0, /* mov $VERTSIZE-2,%ecx */
- 0xf3, 0xa5, /* repz movsl %ds:(%esi),%es:(%edi)*/
- 0xa1, 0, 0, 0, 0, /* mov COUNTER,%eax */
- 0x89, 0x3d, 0, 0, 0, 0, /* mov %edi,DMAPTR */
- 0x48, /* dec %eax */
- 0xa3, 0, 0, 0, 0, /* mov %eax,COUNTER */
- 0x5e, /* pop %esi */
- 0x5f, /* pop %edi */
- 0x74, 0x01, /* je +1 */
- 0xc3, /* ret */
- 0xff, 0x25, 0, 0, 0, 0 /* jmp NOTIFY */
- };
-
- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
- memcpy (dfn->code, temp, sizeof(temp));
- FIXUP(dfn->code, 3, 0x0, (int)&tnl->vertex[2]);
- FIXUP(dfn->code, 9, 0x0, (int)&tnl->dmaptr);
- FIXUP(dfn->code, 37, 0x0, tnl->vertex_size-2);
- FIXUP(dfn->code, 44, 0x0, (int)&tnl->counter);
- FIXUP(dfn->code, 50, 0x0, (int)&tnl->dmaptr);
- FIXUP(dfn->code, 56, 0x0, (int)&tnl->counter);
- FIXUP(dfn->code, 67, 0x0, (int)&tnl->notify);
- break;
- }
- }
-
- insert_at_head( &tnl->dfn_cache.Vertex3f, dfn );
- dfn->key = key;
- return dfn;
-}
-
-/* Build specialized versions of the immediate calls on the fly for
- * the current state. Generic x86 versions.
- */
-
-struct dynfn *tnl_makeX86Vertex3f( TNLcontext *tnl, int key )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (RADEON_DEBUG & DEBUG_CODEGEN)
- _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
-
- switch (tnl->vertex_size) {
- case 4: {
- static char temp[] = {
- 0x8b, 0x0d, 0,0,0,0, /* mov DMAPTR,%ecx */
- 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
- 0x8b, 0x54, 0x24, 0x08, /* mov 0x8(%esp,1),%edx */
- 0x89, 0x01, /* mov %eax,(%ecx) */
- 0x89, 0x51, 0x04, /* mov %edx,0x4(%ecx) */
- 0x8b, 0x44, 0x24, 0x0c, /* mov 0xc(%esp,1),%eax */
- 0x8b, 0x15, 0,0,0,0, /* mov VERTEX[3],%edx */
- 0x89, 0x41, 0x08, /* mov %eax,0x8(%ecx) */
- 0x89, 0x51, 0x0c, /* mov %edx,0xc(%ecx) */
- 0xa1, 0, 0, 0, 0, /* mov COUNTER,%eax */
- 0x83, 0xc1, 0x10, /* add $0x10,%ecx */
- 0x48, /* dec %eax */
- 0x89, 0x0d, 0,0,0,0, /* mov %ecx,DMAPTR */
- 0xa3, 0, 0, 0, 0, /* mov %eax,COUNTER */
- 0x74, 0x01, /* je +1 */
- 0xc3, /* ret */
- 0xff, 0x25, 0,0,0,0 /* jmp *NOTIFY */
- };
-
- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
- memcpy (dfn->code, temp, sizeof(temp));
- FIXUP(dfn->code, 2, 0x0, (int)&tnl->dmaptr);
- FIXUP(dfn->code, 25, 0x0, (int)&tnl->vertex[3]);
- FIXUP(dfn->code, 36, 0x0, (int)&tnl->counter);
- FIXUP(dfn->code, 46, 0x0, (int)&tnl->dmaptr);
- FIXUP(dfn->code, 51, 0x0, (int)&tnl->counter);
- FIXUP(dfn->code, 60, 0x0, (int)&tnl->notify);
- break;
- }
- case 6: {
- static char temp[] = {
- 0x57, /* push %edi */
- 0x8b, 0x3d, 0, 0, 0, 0, /* mov DMAPTR,%edi */
- 0x8b, 0x44, 0x24, 0x8, /* mov 0x8(%esp,1),%eax */
- 0x8b, 0x54, 0x24, 0xc, /* mov 0xc(%esp,1),%edx */
- 0x8b, 0x4c, 0x24, 0x10, /* mov 0x10(%esp,1),%ecx */
- 0x89, 0x07, /* mov %eax,(%edi) */
- 0x89, 0x57, 0x04, /* mov %edx,0x4(%edi) */
- 0x89, 0x4f, 0x08, /* mov %ecx,0x8(%edi) */
- 0xa1, 0, 0, 0, 0, /* mov VERTEX[3],%eax */
- 0x8b, 0x15, 0, 0, 0, 0, /* mov VERTEX[4],%edx */
- 0x8b, 0x0d, 0, 0, 0, 0, /* mov VERTEX[5],%ecx */
- 0x89, 0x47, 0x0c, /* mov %eax,0xc(%edi) */
- 0x89, 0x57, 0x10, /* mov %edx,0x10(%edi) */
- 0x89, 0x4f, 0x14, /* mov %ecx,0x14(%edi) */
- 0x83, 0xc7, 0x18, /* add $0x18,%edi */
- 0xa1, 0, 0, 0, 0, /* mov COUNTER,%eax */
- 0x89, 0x3d, 0, 0, 0, 0, /* mov %edi,DMAPTR */
- 0x48, /* dec %eax */
- 0x5f, /* pop %edi */
- 0xa3, 0, 0, 0, 0, /* mov %eax,COUNTER */
- 0x74, 0x01, /* je +1 */
- 0xc3, /* ret */
- 0xff, 0x25, 0,0,0,0, /* jmp *NOTIFY */
- };
-
- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
- memcpy (dfn->code, temp, sizeof(temp));
- FIXUP(dfn->code, 3, 0x0, (int)&tnl->dmaptr);
- FIXUP(dfn->code, 28, 0x0, (int)&tnl->vertex[3]);
- FIXUP(dfn->code, 34, 0x0, (int)&tnl->vertex[4]);
- FIXUP(dfn->code, 40, 0x0, (int)&tnl->vertex[5]);
- FIXUP(dfn->code, 57, 0x0, (int)&tnl->counter);
- FIXUP(dfn->code, 63, 0x0, (int)&tnl->dmaptr);
- FIXUP(dfn->code, 70, 0x0, (int)&tnl->counter);
- FIXUP(dfn->code, 79, 0x0, (int)&tnl->notify);
- break;
- }
- default: {
- /* Repz convenient as it's possible to emit code for any size
- * vertex with little tweaking. Might as well read vertsize
- * though, and have only one of these.
- */
- static char temp[] = {
- 0x57, /* push %edi */
- 0x56, /* push %esi */
- 0xbe, 0, 0, 0, 0, /* mov $VERTEX+3,%esi */
- 0x8b, 0x3d, 0, 0, 0, 0, /* mov DMAPTR,%edi */
- 0x8b, 0x44, 0x24, 0x0c, /* mov 0x0c(%esp,1),%eax */
- 0x8b, 0x54, 0x24, 0x10, /* mov 0x10(%esp,1),%edx */
- 0x8b, 0x4c, 0x24, 0x14, /* mov 0x14(%esp,1),%ecx */
- 0x89, 0x07, /* mov %eax,(%edi) */
- 0x89, 0x57, 0x04, /* mov %edx,0x4(%edi) */
- 0x89, 0x4f, 0x08, /* mov %ecx,0x8(%edi) */
- 0x83, 0xc7, 0x0c, /* add $0xc,%edi */
- 0xb9, 0, 0, 0, 0, /* mov $VERTSIZE-3,%ecx */
- 0xf3, 0xa5, /* repz movsl %ds:(%esi),%es:(%edi)*/
- 0xa1, 0, 0, 0, 0, /* mov COUNTER,%eax */
- 0x89, 0x3d, 0, 0, 0, 0, /* mov %edi,DMAPTR */
- 0x48, /* dec %eax */
- 0xa3, 0, 0, 0, 0, /* mov %eax,COUNTER */
- 0x5e, /* pop %esi */
- 0x5f, /* pop %edi */
- 0x74, 0x01, /* je +1 */
- 0xc3, /* ret */
- 0xff, 0x25, 0, 0, 0, 0 /* jmp NOTIFY */
- };
-
- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
- memcpy (dfn->code, temp, sizeof(temp));
- FIXUP(dfn->code, 3, 0x0, (int)&tnl->vertex[3]);
- FIXUP(dfn->code, 9, 0x0, (int)&tnl->dmaptr);
- FIXUP(dfn->code, 37, 0x0, tnl->vertex_size-3);
- FIXUP(dfn->code, 44, 0x0, (int)&tnl->counter);
- FIXUP(dfn->code, 50, 0x0, (int)&tnl->dmaptr);
- FIXUP(dfn->code, 56, 0x0, (int)&tnl->counter);
- FIXUP(dfn->code, 67, 0x0, (int)&tnl->notify);
- break;
- }
- }
-
- insert_at_head( &tnl->dfn_cache.Vertex3f, dfn );
- dfn->key = key;
- return dfn;
-}
-
-
-
-struct dynfn *tnl_makeX86Vertex3fv( TNLcontext *tnl, int key )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (TNL_DEBUG & DEBUG_CODEGEN)
- _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
-
- switch (tnl->vertex_size) {
- case 6: {
- static char temp[] = {
- 0xa1, 0x00, 0x00, 0, 0, /* mov 0x0,%eax */
- 0x8b, 0x4c, 0x24, 0x04, /* mov 0x4(%esp,1),%ecx */
- 0x8b, 0x11, /* mov (%ecx),%edx */
- 0x89, 0x10, /* mov %edx,(%eax) */
- 0x8b, 0x51, 0x04, /* mov 0x4(%ecx),%edx */
- 0x8b, 0x49, 0x08, /* mov 0x8(%ecx),%ecx */
- 0x89, 0x50, 0x04, /* mov %edx,0x4(%eax) */
- 0x89, 0x48, 0x08, /* mov %ecx,0x8(%eax) */
- 0x8b, 0x15, 0x1c, 0, 0, 0, /* mov 0x1c,%edx */
- 0x8b, 0x0d, 0x20, 0, 0, 0, /* mov 0x20,%ecx */
- 0x89, 0x50, 0x0c, /* mov %edx,0xc(%eax) */
- 0x89, 0x48, 0x10, /* mov %ecx,0x10(%eax) */
- 0x8b, 0x15, 0x24, 0, 0, 0, /* mov 0x24,%edx */
- 0x89, 0x50, 0x14, /* mov %edx,0x14(%eax) */
- 0x83, 0xc0, 0x18, /* add $0x18,%eax */
- 0xa3, 0x00, 0x00, 0, 0, /* mov %eax,0x0 */
- 0xa1, 0x04, 0x00, 0, 0, /* mov 0x4,%eax */
- 0x48, /* dec %eax */
- 0xa3, 0x04, 0x00, 0, 0, /* mov %eax,0x4 */
- 0x74, 0x01, /* je 2a4 <.f11> */
- 0xc3, /* ret */
- 0xff, 0x25, 0x08, 0, 0, 0, /* jmp *0x8 */
- };
-
- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
- memcpy (dfn->code, temp, sizeof(temp));
- FIXUP(dfn->code, 1, 0x00000000, (int)&tnl->dmaptr);
- FIXUP(dfn->code, 27, 0x0000001c, (int)&tnl->vertex[3]);
- FIXUP(dfn->code, 33, 0x00000020, (int)&tnl->vertex[4]);
- FIXUP(dfn->code, 45, 0x00000024, (int)&tnl->vertex[5]);
- FIXUP(dfn->code, 56, 0x00000000, (int)&tnl->dmaptr);
- FIXUP(dfn->code, 61, 0x00000004, (int)&tnl->counter);
- FIXUP(dfn->code, 67, 0x00000004, (int)&tnl->counter);
- FIXUP(dfn->code, 76, 0x00000008, (int)&tnl->notify);
- break;
- }
-
-
- case 8: {
- static char temp[] = {
- 0xa1, 0x00, 0x00, 0, 0, /* mov 0x0,%eax */
- 0x8b, 0x4c, 0x24, 0x04, /* mov 0x4(%esp,1),%ecx */
- 0x8b, 0x11, /* mov (%ecx),%edx */
- 0x89, 0x10, /* mov %edx,(%eax) */
- 0x8b, 0x51, 0x04, /* mov 0x4(%ecx),%edx */
- 0x8b, 0x49, 0x08, /* mov 0x8(%ecx),%ecx */
- 0x89, 0x50, 0x04, /* mov %edx,0x4(%eax) */
- 0x89, 0x48, 0x08, /* mov %ecx,0x8(%eax) */
- 0x8b, 0x15, 0x1c, 0, 0, 0, /* mov 0x1c,%edx */
- 0x8b, 0x0d, 0x20, 0, 0, 0, /* mov 0x20,%ecx */
- 0x89, 0x50, 0x0c, /* mov %edx,0xc(%eax) */
- 0x89, 0x48, 0x10, /* mov %ecx,0x10(%eax) */
- 0x8b, 0x15, 0x1c, 0, 0, 0, /* mov 0x1c,%edx */
- 0x8b, 0x0d, 0x20, 0, 0, 0, /* mov 0x20,%ecx */
- 0x89, 0x50, 0x14, /* mov %edx,0x14(%eax) */
- 0x89, 0x48, 0x18, /* mov %ecx,0x18(%eax) */
- 0x8b, 0x15, 0x24, 0, 0, 0, /* mov 0x24,%edx */
- 0x89, 0x50, 0x1c, /* mov %edx,0x1c(%eax) */
- 0x83, 0xc0, 0x20, /* add $0x20,%eax */
- 0xa3, 0x00, 0x00, 0, 0, /* mov %eax,0x0 */
- 0xa1, 0x04, 0x00, 0, 0, /* mov 0x4,%eax */
- 0x48, /* dec %eax */
- 0xa3, 0x04, 0x00, 0, 0, /* mov %eax,0x4 */
- 0x74, 0x01, /* je 2a4 <.f11> */
- 0xc3, /* ret */
- 0xff, 0x25, 0x08, 0, 0, 0, /* jmp *0x8 */
- };
-
- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
- memcpy (dfn->code, temp, sizeof(temp));
- FIXUP(dfn->code, 1, 0x00000000, (int)&tnl->dmaptr);
- FIXUP(dfn->code, 27, 0x0000001c, (int)&tnl->vertex[3]);
- FIXUP(dfn->code, 33, 0x00000020, (int)&tnl->vertex[4]);
- FIXUP(dfn->code, 45, 0x0000001c, (int)&tnl->vertex[5]);
- FIXUP(dfn->code, 51, 0x00000020, (int)&tnl->vertex[6]);
- FIXUP(dfn->code, 63, 0x00000024, (int)&tnl->vertex[7]);
- FIXUP(dfn->code, 74, 0x00000000, (int)&tnl->dmaptr);
- FIXUP(dfn->code, 79, 0x00000004, (int)&tnl->counter);
- FIXUP(dfn->code, 85, 0x00000004, (int)&tnl->counter);
- FIXUP(dfn->code, 94, 0x00000008, (int)&tnl->notify);
- break;
- }
-
-
-
- default: {
- /* Repz convenient as it's possible to emit code for any size
- * vertex with little tweaking. Might as well read vertsize
- * though, and have only one of these.
- */
- static char temp[] = {
- 0x8b, 0x54, 0x24, 0x04, /* mov 0x4(%esp,1),%edx */
- 0x57, /* push %edi */
- 0x56, /* push %esi */
- 0x8b, 0x3d, 1,1,1,1, /* mov DMAPTR,%edi */
- 0x8b, 0x02, /* mov (%edx),%eax */
- 0x8b, 0x4a, 0x04, /* mov 0x4(%edx),%ecx */
- 0x8b, 0x72, 0x08, /* mov 0x8(%edx),%esi */
- 0x89, 0x07, /* mov %eax,(%edi) */
- 0x89, 0x4f, 0x04, /* mov %ecx,0x4(%edi) */
- 0x89, 0x77, 0x08, /* mov %esi,0x8(%edi) */
- 0x83, 0xc7, 0x0c, /* add $0xc,%edi */
- 0xb9, 0x06, 0x00, 0x00, 0x00, /* mov $VERTSIZE-3,%ecx */
- 0xbe, 0x58, 0x00, 0x00, 0x00, /* mov $VERTEX[3],%esi */
- 0xf3, 0xa5, /* repz movsl %ds:(%esi),%es:(%edi)*/
- 0x89, 0x3d, 1, 1, 1, 1, /* mov %edi,DMAPTR */
- 0xa1, 2, 2, 2, 2, /* mov COUNTER,%eax */
- 0x5e, /* pop %esi */
- 0x5f, /* pop %edi */
- 0x48, /* dec %eax */
- 0xa3, 2, 2, 2, 2, /* mov %eax,COUNTER */
- 0x74, 0x01, /* je +1 */
- 0xc3, /* ret */
- 0xff, 0x25, 0, 0, 0, 0 /* jmp NOTIFY */
- };
-
- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
- memcpy (dfn->code, temp, sizeof(temp));
- FIXUP(dfn->code, 8, 0x01010101, (int)&tnl->dmaptr);
- FIXUP(dfn->code, 32, 0x00000006, tnl->vertex_size-3);
- FIXUP(dfn->code, 37, 0x00000058, (int)&tnl->vertex[3]);
- FIXUP(dfn->code, 45, 0x01010101, (int)&tnl->dmaptr);
- FIXUP(dfn->code, 50, 0x02020202, (int)&tnl->counter);
- FIXUP(dfn->code, 58, 0x02020202, (int)&tnl->counter);
- FIXUP(dfn->code, 67, 0x0, (int)&tnl->notify);
- break;
- }
- }
-
- insert_at_head( &tnl->dfn_cache.Vertex3fv, dfn );
- dfn->key = key;
- return dfn;
-}
-
-
-struct dynfn *tnl_makeX86Attr4fv( TNLcontext *tnl, int key )
-{
- static char temp[] = {
- 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
- 0xba, 0, 0, 0, 0, /* mov $DEST,%edx */
- 0x8b, 0x08, /* mov (%eax),%ecx */
- 0x89, 0x0a, /* mov %ecx,(%edx) */
- 0x8b, 0x48, 0x04, /* mov 0x4(%eax),%ecx */
- 0x89, 0x4a, 0x04, /* mov %ecx,0x4(%edx) */
- 0x8b, 0x48, 0x08, /* mov 0x8(%eax),%ecx */
- 0x89, 0x4a, 0x08, /* mov %ecx,0x8(%edx) */
- 0x8b, 0x48, 0x0a, /* mov 0xa(%eax),%ecx */
- 0x89, 0x4a, 0x0a, /* mov %ecx,0xa(%edx) */
- 0xc3, /* ret */
- };
-
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (TNL_DEBUG & DEBUG_CODEGEN)
- _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
-
- insert_at_head( &tnl->dfn_cache.Normal3fv, dfn );
- dfn->key = key;
- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
- memcpy (dfn->code, temp, sizeof(temp));
- FIXUP(dfn->code, 5, 0x0, (int)tnl->normalptr);
- return dfn;
-}
-
-struct dynfn *tnl_makeX86Attr4f( TNLcontext *tnl, int key )
-{
- static char temp[] = {
- 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */
- 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
- 0x89, 0x02, /* mov %eax,(%edx) */
- 0x8b, 0x44, 0x24, 0x08, /* mov 0x8(%esp,1),%eax */
- 0x89, 0x42, 0x04, /* mov %eax,0x4(%edx) */
- 0x8b, 0x44, 0x24, 0x0c, /* mov 0xc(%esp,1),%eax */
- 0x89, 0x42, 0x08, /* mov %eax,0x8(%edx) */
- 0x8b, 0x44, 0x24, 0x10, /* mov 0x10(%esp,1),%eax */
- 0x89, 0x42, 0x0a, /* mov %eax,0xa(%edx) */
- 0xc3, /* ret */
- };
-
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (TNL_DEBUG & DEBUG_CODEGEN)
- _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
-
- insert_at_head( &tnl->dfn_cache.Normal3f, dfn );
- dfn->key = key;
- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
- memcpy (dfn->code, temp, sizeof(temp));
- FIXUP(dfn->code, 1, 0x12345678, (int)tnl->normalptr);
- return dfn;
-}
-
-
-struct dynfn *tnl_makeX86Attr3fv( TNLcontext *tnl, int key )
-{
- static char temp[] = {
- 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
- 0xba, 0, 0, 0, 0, /* mov $DEST,%edx */
- 0x8b, 0x08, /* mov (%eax),%ecx */
- 0x89, 0x0a, /* mov %ecx,(%edx) */
- 0x8b, 0x48, 0x04, /* mov 0x4(%eax),%ecx */
- 0x89, 0x4a, 0x04, /* mov %ecx,0x4(%edx) */
- 0x8b, 0x48, 0x08, /* mov 0x8(%eax),%ecx */
- 0x89, 0x4a, 0x08, /* mov %ecx,0x8(%edx) */
- 0xc3, /* ret */
- };
-
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (TNL_DEBUG & DEBUG_CODEGEN)
- _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
-
- insert_at_head( &tnl->dfn_cache.Normal3fv, dfn );
- dfn->key = key;
- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
- memcpy (dfn->code, temp, sizeof(temp));
- FIXUP(dfn->code, 5, 0x0, (int)tnl->normalptr);
- return dfn;
-}
-
-struct dynfn *tnl_makeX86Attr3f( TNLcontext *tnl, int key )
-{
- static char temp[] = {
- 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */
- 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
- 0x89, 0x02, /* mov %eax,(%edx) */
- 0x8b, 0x44, 0x24, 0x08, /* mov 0x8(%esp,1),%eax */
- 0x89, 0x42, 0x04, /* mov %eax,0x4(%edx) */
- 0x8b, 0x44, 0x24, 0x0c, /* mov 0xc(%esp,1),%eax */
- 0x89, 0x42, 0x08, /* mov %eax,0x8(%edx) */
- 0xc3, /* ret */
- };
-
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (TNL_DEBUG & DEBUG_CODEGEN)
- _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
-
- insert_at_head( &tnl->dfn_cache.Normal3f, dfn );
- dfn->key = key;
- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
- memcpy (dfn->code, temp, sizeof(temp));
- FIXUP(dfn->code, 1, 0x12345678, (int)tnl->normalptr);
- return dfn;
-}
-
-struct dynfn *tnl_makeX86Attr4ubv( TNLcontext *tnl, int key )
-{
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
- insert_at_head( &tnl->dfn_cache.Color4ubv, dfn );
- dfn->key = key;
-
- if (TNL_DEBUG & DEBUG_CODEGEN)
- _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
-
- if (key & TNL_CP_VC_FRMT_PKCOLOR) {
- static char temp[] = {
- 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
- 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */
- 0x8b, 0x00, /* mov (%eax),%eax */
- 0x89, 0x02, /* mov %eax,(%edx) */
- 0xc3, /* ret */
- };
-
- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
- memcpy (dfn->code, temp, sizeof(temp));
- FIXUP(dfn->code, 5, 0x12345678, (int)tnl->ubytecolorptr);
- return dfn;
- }
- else {
- static char temp[] = {
- 0x53, /* push %ebx */
- 0xba, 0x00, 0x00, 0x00, 0x00, /* mov $0x0,%edx */
- 0x31, 0xc0, /* xor %eax,%eax */
- 0x31, 0xc9, /* xor %ecx,%ecx */
- 0x8b, 0x5c, 0x24, 0x08, /* mov 0x8(%esp,1), %ebx */
- 0x8b, 0x1b, /* mov (%ebx), %ebx */
- 0x88, 0xd8, /* mov %bl, %al */
- 0x88, 0xf9, /* mov %bh, %cl */
- 0x8b, 0x04, 0x82, /* mov (%edx,%eax,4),%eax */
- 0x8b, 0x0c, 0x8a, /* mov (%edx,%ecx,4),%ecx */
- 0xa3, 0xaf, 0xbe, 0xad, 0xde, /* mov %eax,0xdeadbeaf */
- 0x89, 0x0d, 0xaf, 0xbe, 0xad, 0xde, /* mov %ecx,0xdeadbeaf */
- 0x31, 0xc0, /* xor %eax,%eax */
- 0x31, 0xc9, /* xor %ecx,%ecx */
- 0xc1, 0xeb, 0x10, /* shr $0x10, %ebx */
- 0x88, 0xd8, /* mov %bl, %al */
- 0x88, 0xf9, /* mov %bh, %cl */
- 0x8b, 0x04, 0x82, /* mov (%edx,%eax,4),%eax */
- 0x8b, 0x0c, 0x8a, /* mov (%edx,%ecx,4),%ecx */
- 0xa3, 0xaf, 0xbe, 0xad, 0xde, /* mov %eax,0xdeadbeaf */
- 0x89, 0x0d, 0xaf, 0xbe, 0xad, 0xde, /* mov %ecx,0xdeadbeaf */
- 0x5b, /* pop %ebx */
- 0xc3, /* ret */
- };
-
- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
- memcpy (dfn->code, temp, sizeof(temp));
- FIXUP(dfn->code, 2, 0x00000000, (int)_mesa_ubyte_to_float_color_tab);
- FIXUP(dfn->code, 27, 0xdeadbeaf, (int)tnl->floatcolorptr);
- FIXUP(dfn->code, 33, 0xdeadbeaf, (int)tnl->floatcolorptr+4);
- FIXUP(dfn->code, 55, 0xdeadbeaf, (int)tnl->floatcolorptr+8);
- FIXUP(dfn->code, 61, 0xdeadbeaf, (int)tnl->floatcolorptr+12);
- return dfn;
- }
-}
-
-struct dynfn *tnl_makeX86Attr4ub( TNLcontext *tnl, int key )
-{
- if (TNL_DEBUG & DEBUG_CODEGEN)
- _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
-
- if (key & TNL_CP_VC_FRMT_PKCOLOR) {
- /* XXX push/pop */
- static char temp[] = {
- 0x53, /* push %ebx */
- 0x8b, 0x44, 0x24, 0x08, /* mov 0x8(%esp,1),%eax */
- 0x8b, 0x54, 0x24, 0x0c, /* mov 0xc(%esp,1),%edx */
- 0x8b, 0x4c, 0x24, 0x10, /* mov 0x10(%esp,1),%ecx */
- 0x8b, 0x5c, 0x24, 0x14, /* mov 0x14(%esp,1),%ebx */
- 0xa2, 0, 0, 0, 0, /* mov %al,DEST */
- 0x88, 0x15, 0, 0, 0, 0, /* mov %dl,DEST+1 */
- 0x88, 0x0d, 0, 0, 0, 0, /* mov %cl,DEST+2 */
- 0x88, 0x1d, 0, 0, 0, 0, /* mov %bl,DEST+3 */
- 0x5b, /* pop %ebx */
- 0xc3, /* ret */
- };
-
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
- insert_at_head( &tnl->dfn_cache.Color4ub, dfn );
- dfn->key = key;
-
- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
- memcpy (dfn->code, temp, sizeof(temp));
- FIXUP(dfn->code, 18, 0x0, (int)tnl->ubytecolorptr);
- FIXUP(dfn->code, 24, 0x0, (int)tnl->ubytecolorptr+1);
- FIXUP(dfn->code, 30, 0x0, (int)tnl->ubytecolorptr+2);
- FIXUP(dfn->code, 36, 0x0, (int)tnl->ubytecolorptr+3);
- return dfn;
- }
- else
- return 0;
-}
-
-
-
-struct dynfn *tnl_makeX86Attr2fv( TNLcontext *tnl, int key )
-{
- static char temp[] = {
- 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
- 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */
- 0x8b, 0x08, /* mov (%eax),%ecx */
- 0x8b, 0x40, 0x04, /* mov 0x4(%eax),%eax */
- 0x89, 0x0a, /* mov %ecx,(%edx) */
- 0x89, 0x42, 0x04, /* mov %eax,0x4(%edx) */
- 0xc3, /* ret */
- };
-
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (TNL_DEBUG & DEBUG_CODEGEN)
- _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
-
- insert_at_head( &tnl->dfn_cache.TexCoord2fv, dfn );
- dfn->key = key;
- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
- memcpy (dfn->code, temp, sizeof(temp));
- FIXUP(dfn->code, 5, 0x12345678, (int)tnl->texcoordptr[0]);
- return dfn;
-}
-
-struct dynfn *tnl_makeX86Attr2f( TNLcontext *tnl, int key )
-{
- static char temp[] = {
- 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */
- 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
- 0x8b, 0x4c, 0x24, 0x08, /* mov 0x8(%esp,1),%ecx */
- 0x89, 0x02, /* mov %eax,(%edx) */
- 0x89, 0x4a, 0x04, /* mov %ecx,0x4(%edx) */
- 0xc3, /* ret */
- };
-
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (TNL_DEBUG & DEBUG_CODEGEN)
- _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
-
- insert_at_head( &tnl->dfn_cache.TexCoord2f, dfn );
- dfn->key = key;
- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
- memcpy (dfn->code, temp, sizeof(temp));
- FIXUP(dfn->code, 1, 0x12345678, (int)tnl->texcoordptr[0]);
- return dfn;
-}
-
-
-struct dynfn *tnl_makeX86Attr1fv( TNLcontext *tnl, int key )
-{
- static char temp[] = {
- 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
- 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */
- 0x8b, 0x08, /* mov (%eax),%ecx */
- 0x89, 0x0a, /* mov %ecx,(%edx) */
- 0xc3, /* ret */
- };
-
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (TNL_DEBUG & DEBUG_CODEGEN)
- _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
-
- insert_at_head( &tnl->dfn_cache.TexCoord2fv, dfn );
- dfn->key = key;
- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
- memcpy (dfn->code, temp, sizeof(temp));
- FIXUP(dfn->code, 5, 0x12345678, (int)tnl->texcoordptr[0]);
- return dfn;
-}
-
-struct dynfn *tnl_makeX86Attr1f( TNLcontext *tnl, int key )
-{
- static char temp[] = {
- 0xba, 0x78, 0x56, 0x34, 0x12, /* mov $DEST,%edx */
- 0x8b, 0x44, 0x24, 0x04, /* mov 0x4(%esp,1),%eax */
- 0x89, 0x02, /* mov %eax,(%edx) */
- 0xc3, /* ret */
- };
-
- struct dynfn *dfn = MALLOC_STRUCT( dynfn );
-
- if (TNL_DEBUG & DEBUG_CODEGEN)
- _mesa_debug(NULL, "%s 0x%08x\n", __FUNCTION__, key );
-
- insert_at_head( &tnl->dfn_cache.TexCoord2f, dfn );
- dfn->key = key;
- dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
- memcpy (dfn->code, temp, sizeof(temp));
- FIXUP(dfn->code, 1, 0x12345678, (int)tnl->texcoordptr[0]);
- return dfn;
-}
-
-
-
-void _tnl_InitX86Codegen( struct dfn_generators *gen )
-{
- gen->Attr1f = tnl_makeX86Attr1f;
- gen->Attr1fv = tnl_makeX86Attr1fv;
- gen->Attr2f = tnl_makeX86Attr2f;
- gen->Attr2fv = tnl_makeX86Attr2fv;
- gen->Attr3f = tnl_makeX86Attr3f;
- gen->Attr3fv = tnl_makeX86Attr3fv;
- gen->Attr4f = tnl_makeX86Attr4f;
- gen->Attr4fv = tnl_makeX86Attr4fv;
- gen->Attr4ub = tnl_makeX86Attr4ub;
- gen->Attr4ubv = tnl_makeX86Attr4ubv;
- gen->Vertex3f = tnl_makeX86Vertex3f;
- gen->Vertex3fv = tnl_makeX86Vertex3fv;
-}
-
-
-#else
-
-void _tnl_InitX86Codegen( struct dfn_generators *gen )
-{
- (void) gen;
-}
-
-#endif
currentsz = dmasz;
}
- if ((flags & PRIM_PARITY) && count - start > 2) {
- if (HAVE_TRI_STRIP_1 && 0) {
- } else {
- EMIT_VERTS( ctx, start, 1 );
- currentsz--;
- }
- }
-
/* From here on emit even numbers of tris when wrapping over buffers:
*/
dmasz -= (dmasz & 1);
currentsz = dmasz;
}
- if ((flags & PRIM_PARITY) && count - start > 2) {
- TAG(emit_elts)( ctx, elts+start, 1 );
- }
-
/* Keep the same winding over multiple buffers:
*/
dmasz -= (dmasz & 1);
ELT_INIT( GL_TRIANGLES, HW_TRIANGLES );
- if (flags & PRIM_PARITY)
- parity = 1;
-
/* Emit even number of tris in each full buffer.
*/
dmasz = dmasz/3;
CLOSE_ELTS();
}
}
- else if ((flags & PRIM_PARITY) == 0)
- EMIT_PRIM( ctx, GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_0, start, count );
else if (HAVE_TRI_STRIP_1)
EMIT_PRIM( ctx, GL_TRIANGLE_STRIP, HW_TRIANGLE_STRIP_1, start, count );
else {
for (j = start ; j + 2 < count; j += nr - 2 ) {
nr = MIN2( dmasz, count - j );
- if (flags & PRIM_PARITY) {
- dest = ALLOC_ELTS( nr );
- dest = TAG(emit_elts)( ctx, dest, elts+j, 1 );
- dest = TAG(emit_elts)( ctx, dest, elts+j, nr-1 );
- nr--; flags &= ~PRIM_PARITY;
- CLOSE_ELTS();
- }
- else {
- dest = ALLOC_ELTS( nr );
- dest = TAG(emit_elts)( ctx, dest, elts+j, nr );
- CLOSE_ELTS();
- }
+ dest = ALLOC_ELTS( nr );
+ dest = TAG(emit_elts)( ctx, dest, elts+j, nr );
+ CLOSE_ELTS();
}
}
}
}
else {
- GLchan (*vbcolor)[4] = (GLchan (*)[4])VB->ColorPtr[1]->Ptr;
- ASSERT(VB->ColorPtr[1]->Type == CHAN_TYPE);
- ASSERT(VB->ColorPtr[1]->StrideB == 4*sizeof(GLchan));
+ GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
+ ASSERT(VB->ColorPtr[1]->stride == 4*sizeof(GLfloat));
(void) vbcolor;
if (!DO_FLAT) {
VERT_SET_RGBA( v[2], vbcolor[e2] );
if (HAVE_SPEC && VB->SecondaryColorPtr[1]) {
- GLchan (*vbspec)[4] = (GLchan (*)[4])VB->SecondaryColorPtr[1]->Ptr;
+ GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
if (!DO_FLAT) {
VERT_SAVE_SPEC( 0 );
}
}
else {
- GLuint *vbindex = VB->IndexPtr[1]->data;
+ GLfloat (*vbindex) = (GLfloat *)VB->IndexPtr[1]->data;
if (!DO_FLAT) {
+ VERT_SAVE_IND( 0 );
+ VERT_SAVE_IND( 1 );
VERT_SET_IND( v[0], vbindex[e0] );
VERT_SET_IND( v[1], vbindex[e1] );
}
+ VERT_SAVE_IND( 2 );
VERT_SET_IND( v[2], vbindex[e2] );
}
}
}
}
else {
- GLuint *vbindex = VB->IndexPtr[0]->data;
if (!DO_FLAT) {
- VERT_SET_IND( v[0], vbindex[e0] );
- VERT_SET_IND( v[1], vbindex[e1] );
+ VERT_RESTORE_IND( 0 );
+ VERT_RESTORE_IND( 1 );
}
- VERT_SET_IND( v[2], vbindex[e2] );
+ VERT_RESTORE_IND( 2 );
}
}
if (DO_TWOSIDE && facing == 1)
{
if (HAVE_RGBA) {
- GLchan (*vbcolor)[4] = (GLchan (*)[4])VB->ColorPtr[1]->Ptr;
+ GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
(void)vbcolor;
if (HAVE_BACK_COLORS) {
VERT_SET_RGBA( v[3], vbcolor[e3] );
if (HAVE_SPEC && VB->SecondaryColorPtr[1]) {
- GLchan (*vbspec)[4] = (GLchan (*)[4])VB->SecondaryColorPtr[1]->Ptr;
- ASSERT(VB->SecondaryColorPtr[1]->StrideB==4*sizeof(GLchan));
+ GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
+ ASSERT(VB->SecondaryColorPtr[1]->stride==4*sizeof(GLfloat));
if (!DO_FLAT) {
VERT_SAVE_SPEC( 0 );
}
}
else {
- GLuint *vbindex = VB->IndexPtr[1]->data;
+ GLfloat *vbindex = (GLfloat *)VB->IndexPtr[1]->data;
if (!DO_FLAT) {
+ VERT_SAVE_IND( 0 );
+ VERT_SAVE_IND( 1 );
+ VERT_SAVE_IND( 2 );
VERT_SET_IND( v[0], vbindex[e0] );
VERT_SET_IND( v[1], vbindex[e1] );
VERT_SET_IND( v[2], vbindex[e2] );
}
+ VERT_SAVE_IND( 3 );
VERT_SET_IND( v[3], vbindex[e3] );
}
}
}
}
else {
- GLuint *vbindex = VB->IndexPtr[0]->data;
if (!DO_FLAT) {
- VERT_SET_IND( v[0], vbindex[e0] );
- VERT_SET_IND( v[1], vbindex[e1] );
- VERT_SET_IND( v[2], vbindex[e2] );
+ VERT_RESTORE_IND( 0 );
+ VERT_RESTORE_IND( 1 );
+ VERT_RESTORE_IND( 2 );
}
- VERT_SET_IND( v[3], vbindex[e3] );
+ VERT_RESTORE_IND( 3 );
}
}
#if DO_LINE
static void TAG(line)( GLcontext *ctx, GLuint e0, GLuint e1 )
{
- TNLvertexbuffer *VB = &TNL_CONTEXT(ctx)->vb;
+ struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
VERTEX *v[2];
LOCAL_VARS(2);
fprintf(stderr, "\n");
}
-static void do_import( struct vertex_buffer *VB,
- struct gl_client_array *to,
- struct gl_client_array *from )
-{
- GLuint count = VB->Count;
-
- if (!to->Ptr) {
- to->Ptr = ALIGN_MALLOC( VB->Size * 4 * sizeof(GLubyte), 32 );
- to->Type = GL_UNSIGNED_BYTE;
- }
-
- /* No need to transform the same value 3000 times.
- */
- if (!from->StrideB) {
- to->StrideB = 0;
- count = 1;
- }
- else
- to->StrideB = 4 * sizeof(GLubyte);
-
- _math_trans_4ub( (GLubyte (*)[4]) to->Ptr,
- from->Ptr,
- from->StrideB,
- from->Type,
- from->Size,
- 0,
- count);
-}
-
-#ifndef IMPORT_QUALIFIER
-#define IMPORT_QUALIFIER static
-#endif
-
-IMPORT_QUALIFIER void TAG(import_float_colors)( GLcontext *ctx )
-{
- LOCALVARS
- struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
- struct gl_client_array *to = GET_UBYTE_COLOR_STORE();
- do_import( VB, to, VB->ColorPtr[0] );
- VB->ColorPtr[0] = to;
-}
-IMPORT_QUALIFIER void TAG(import_float_spec_colors)( GLcontext *ctx )
-{
- LOCALVARS
- struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
- struct gl_client_array *to = GET_UBYTE_SPEC_COLOR_STORE();
- do_import( VB, to, VB->SecondaryColorPtr[0] );
- VB->SecondaryColorPtr[0] = to;
-}
/* Interpolate the elements of the VB not included in typical hardware
* vertices.
#define INTERP_QUALIFIER static
#endif
-#define GET_COLOR(ptr, idx) (((GLchan (*)[4])((ptr)->Ptr))[idx])
+#define GET_COLOR(ptr, idx) ((ptr)->data[idx])
INTERP_QUALIFIER void TAG(interp_extras)( GLcontext *ctx,
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
if (VB->ColorPtr[1]) {
- INTERP_4CHAN( t,
+ assert(VB->ColorPtr[1]->stride == 4 * sizeof(GLfloat));
+
+ INTERP_4F( t,
GET_COLOR(VB->ColorPtr[1], dst),
GET_COLOR(VB->ColorPtr[1], out),
GET_COLOR(VB->ColorPtr[1], in) );
if (VB->SecondaryColorPtr[1]) {
- INTERP_3CHAN( t,
+ INTERP_3F( t,
GET_COLOR(VB->SecondaryColorPtr[1], dst),
GET_COLOR(VB->SecondaryColorPtr[1], out),
GET_COLOR(VB->SecondaryColorPtr[1], in) );
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
if (VB->ColorPtr[1]) {
- COPY_CHAN4( GET_COLOR(VB->ColorPtr[1], dst),
- GET_COLOR(VB->ColorPtr[1], src) );
+ COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst),
+ GET_COLOR(VB->ColorPtr[1], src) );
if (VB->SecondaryColorPtr[1]) {
- COPY_CHAN4( GET_COLOR(VB->SecondaryColorPtr[1], dst),
- GET_COLOR(VB->SecondaryColorPtr[1], src) );
+ COPY_4FV( GET_COLOR(VB->SecondaryColorPtr[1], dst),
+ GET_COLOR(VB->SecondaryColorPtr[1], src) );
}
}
#undef INTERP_QUALIFIER
-#undef IMPORT_QUALIFIER
#undef GET_COLOR
#undef IND
GLuint stride )
{
LOCALVARS
- struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+ struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLfloat (*tc0)[4], (*tc1)[4], (*fog)[4];
GLfloat (*tc2)[4], (*tc3)[4];
- GLubyte (*col)[4], (*spec)[4];
+ GLfloat (*col)[4], (*spec)[4];
GLuint tc0_stride, tc1_stride, col_stride, spec_stride, fog_stride;
GLuint tc2_stride, tc3_stride;
GLuint tc0_size, tc1_size;
}
if (DO_RGBA) {
- if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE)
- IMPORT_FLOAT_COLORS( ctx );
- col = (GLubyte (*)[4])VB->ColorPtr[0]->Ptr;
- col_stride = VB->ColorPtr[0]->StrideB;
+ col_stride = VB->ColorPtr[0]->stride;
+ col = VB->ColorPtr[0]->data;
}
if (DO_SPEC) {
if (VB->SecondaryColorPtr[0]) {
- if (VB->SecondaryColorPtr[0]->Type != GL_UNSIGNED_BYTE)
- IMPORT_FLOAT_SPEC_COLORS( ctx );
- spec = (GLubyte (*)[4])VB->SecondaryColorPtr[0]->Ptr;
- spec_stride = VB->SecondaryColorPtr[0]->StrideB;
+ spec_stride = VB->SecondaryColorPtr[0]->stride;
+ spec = VB->SecondaryColorPtr[0]->data;
} else {
- GLubyte tmp[4];
- spec = &tmp;
+ spec = (GLfloat (*)[4])ctx->Current.Attrib[VERT_ATTRIB_COLOR1];
spec_stride = 0;
}
}
}
}
- if (VB->importable_data || (DO_SPEC && !spec_stride) || (DO_FOG && !fog_stride)) {
- /* May have nonstandard strides:
- */
- if (start) {
- coord = (GLfloat (*)[4])((GLubyte *)coord + start * coord_stride);
- if (DO_TEX0)
- tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + start * tc0_stride);
- if (DO_TEX1)
- tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + start * tc1_stride);
- if (DO_TEX2)
- tc2 = (GLfloat (*)[4])((GLubyte *)tc2 + start * tc2_stride);
- if (DO_TEX3)
- tc3 = (GLfloat (*)[4])((GLubyte *)tc3 + start * tc3_stride);
- if (DO_RGBA)
- STRIDE_4UB(col, start * col_stride);
- if (DO_SPEC)
- STRIDE_4UB(spec, start * spec_stride);
- if (DO_FOG)
- /*STRIDE_F(fog, start * fog_stride);*/
- fog = (GLfloat (*)[4])((GLubyte *)fog + start * fog_stride);
- }
+ /* May have nonstandard strides:
+ */
+ if (start) {
+ STRIDE_4F(coord, start * coord_stride);
+ if (DO_TEX0)
+ STRIDE_4F(tc0, start * tc0_stride);
+ if (DO_TEX1)
+ STRIDE_4F(tc1, start * tc1_stride);
+ if (DO_TEX2)
+ STRIDE_4F(tc2, start * tc2_stride);
+ if (DO_TEX3)
+ STRIDE_4F(tc3, start * tc3_stride);
+ if (DO_RGBA)
+ STRIDE_4F(col, start * col_stride);
+ if (DO_SPEC)
+ STRIDE_4F(spec, start * spec_stride);
+ if (DO_FOG)
+ STRIDE_4F(fog, start * fog_stride);
+ }
- for (i=start; i < end; i++, v = (VERTEX *)((GLubyte *)v + stride)) {
- if (DO_XYZW) {
- if (HAVE_HW_VIEWPORT || mask[i] == 0) {
- VIEWPORT_X(v->v.x, coord[0][0]);
- VIEWPORT_Y(v->v.y, coord[0][1]);
- VIEWPORT_Z(v->v.z, coord[0][2]);
- v->v.w = coord[0][3];
- }
-/* fprintf(stderr, "vert %d: %.2f %.2f %.2f %.2f\n", */
-/* i, v->v.x, v->v.y, v->v.z, v->v.w); */
- coord = (GLfloat (*)[4])((GLubyte *)coord + coord_stride);
- }
- if (DO_RGBA) {
- if (HAVE_RGBA_COLOR) {
- *(GLuint *)&v->v.color = LE32_TO_CPU(*(GLuint *)&col[0]);
- STRIDE_4UB(col, col_stride);
- } else {
- v->v.color.blue = col[0][2];
- v->v.color.green = col[0][1];
- v->v.color.red = col[0][0];
- v->v.color.alpha = col[0][3];
- STRIDE_4UB(col, col_stride);
- }
- }
- if (DO_SPEC) {
- v->v.specular.red = spec[0][0];
- v->v.specular.green = spec[0][1];
- v->v.specular.blue = spec[0][2];
- STRIDE_4UB(spec, spec_stride);
- }
- if (DO_FOG) {
- v->v.specular.alpha = fog[0][0] * 255.0;
- /*STRIDE_F(fog, fog_stride);*/
- fog = (GLfloat (*)[4])((GLubyte *)fog + fog_stride);
- }
- if (DO_TEX0) {
- v->v.u0 = tc0[0][0];
- v->v.v0 = tc0[0][1];
- if (DO_PTEX) {
- if (HAVE_PTEX_VERTICES) {
- if (tc0_size == 4)
- v->pv.q0 = tc0[0][3];
- else
- v->pv.q0 = 1.0;
- }
- else if (tc0_size == 4) {
- float rhw = 1.0 / tc0[0][3];
- v->v.w *= tc0[0][3];
- v->v.u0 *= rhw;
- v->v.v0 *= rhw;
- }
- }
- tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + tc0_stride);
- }
- if (DO_TEX1) {
- if (DO_PTEX) {
- v->pv.u1 = tc1[0][0];
- v->pv.v1 = tc1[0][1];
- if (tc1_size == 4)
- v->pv.q1 = tc1[0][3];
- else
- v->pv.q1 = 1.0;
- }
- else {
- v->v.u1 = tc1[0][0];
- v->v.v1 = tc1[0][1];
- }
- tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + tc1_stride);
- }
- else if (DO_PTEX) {
- *(GLuint *)&v->pv.q1 = 0; /* avoid culling on radeon */
+ for (i=start; i < end; i++, v = (VERTEX *)((GLubyte *)v + stride)) {
+ if (DO_XYZW) {
+ if (HAVE_HW_VIEWPORT || mask[i] == 0) {
+ VIEWPORT_X(v->v.x, coord[0][0]);
+ VIEWPORT_Y(v->v.y, coord[0][1]);
+ VIEWPORT_Z(v->v.z, coord[0][2]);
+ v->v.w = coord[0][3];
}
- if (DO_TEX2) {
- if (DO_PTEX) {
- v->pv.u2 = tc2[0][0];
- v->pv.v2 = tc2[0][1];
- if (tc2_size == 4)
- v->pv.q2 = tc2[0][3];
+ STRIDE_4F(coord, coord_stride);
+ }
+ if (DO_RGBA) {
+ UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.red, col[0][0]);
+ UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.green, col[0][1]);
+ UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.blue, col[0][2]);
+ UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.alpha, col[0][3]);
+ STRIDE_4F(col, col_stride);
+ }
+ if (DO_SPEC) {
+ UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.red, spec[0][0]);
+ UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.green, spec[0][1]);
+ UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.blue, spec[0][2]);
+ STRIDE_4F(spec, spec_stride);
+ }
+ if (DO_FOG) {
+ UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.alpha, fog[0][0]);
+ STRIDE_4F(fog, fog_stride);
+ }
+ if (DO_TEX0) {
+ v->v.u0 = tc0[0][0];
+ v->v.v0 = tc0[0][1];
+ if (DO_PTEX) {
+ if (HAVE_PTEX_VERTICES) {
+ if (tc0_size == 4)
+ v->pv.q0 = tc0[0][3];
else
- v->pv.q2 = 1.0;
+ v->pv.q0 = 1.0;
}
- else {
- v->v.u2 = tc2[0][0];
- v->v.v2 = tc2[0][1];
- }
- tc2 = (GLfloat (*)[4])((GLubyte *)tc2 + tc2_stride);
- }
- if (DO_TEX3) {
- if (DO_PTEX) {
- v->pv.u3 = tc3[0][0];
- v->pv.v3 = tc3[0][1];
- if (tc3_size == 4)
- v->pv.q3 = tc3[0][3];
- else
- v->pv.q3 = 1.0;
+ else if (tc0_size == 4) {
+ float rhw = 1.0 / tc0[0][3];
+ v->v.w *= tc0[0][3];
+ v->v.u0 *= rhw;
+ v->v.v0 *= rhw;
}
- else {
- v->v.u3 = tc3[0][0];
- v->v.v3 = tc3[0][1];
- }
- tc3 = (GLfloat (*)[4])((GLubyte *)tc3 + tc3_stride);
}
+ STRIDE_4F(tc0, tc0_stride);
}
- }
- else {
- for (i=start; i < end; i++, v = (VERTEX *)((GLubyte *)v + stride)) {
- if (DO_XYZW) {
- if (HAVE_HW_VIEWPORT || mask[i] == 0) {
- VIEWPORT_X(v->v.x, coord[i][0]);
- VIEWPORT_Y(v->v.y, coord[i][1]);
- VIEWPORT_Z(v->v.z, coord[i][2]);
- v->v.w = coord[i][3];
- }
- }
- if (DO_RGBA) {
- if (HAVE_RGBA_COLOR) {
- *(GLuint *)&v->v.color = LE32_TO_CPU(*(GLuint *)&col[i]);
- }
- else {
- v->v.color.blue = col[i][2];
- v->v.color.green = col[i][1];
- v->v.color.red = col[i][0];
- v->v.color.alpha = col[i][3];
- }
- }
- if (DO_SPEC) {
- v->v.specular.red = spec[i][0];
- v->v.specular.green = spec[i][1];
- v->v.specular.blue = spec[i][2];
- }
- if (DO_FOG) {
- v->v.specular.alpha = fog[i][0] * 255.0;
+ if (DO_TEX1) {
+ if (DO_PTEX) {
+ v->pv.u1 = tc1[0][0];
+ v->pv.v1 = tc1[0][1];
+ if (tc1_size == 4)
+ v->pv.q1 = tc1[0][3];
+ else
+ v->pv.q1 = 1.0;
+ }
+ else {
+ v->v.u1 = tc1[0][0];
+ v->v.v1 = tc1[0][1];
}
- if (DO_TEX0) {
- v->v.u0 = tc0[i][0];
- v->v.v0 = tc0[i][1];
- if (DO_PTEX) {
- if (HAVE_PTEX_VERTICES) {
- if (tc0_size == 4)
- v->pv.q0 = tc0[i][3];
- else
- v->pv.q0 = 1.0;
-
- v->pv.q1 = 0; /* radeon */
- }
- else if (tc0_size == 4) {
- float rhw = 1.0 / tc0[i][3];
- v->v.w *= tc0[i][3];
- v->v.u0 *= rhw;
- v->v.v0 *= rhw;
- }
- }
+ STRIDE_4F(tc1, tc1_stride);
+ }
+ else if (DO_PTEX) {
+ *(GLuint *)&v->pv.q1 = 0; /* avoid culling on radeon */
+ }
+ if (DO_TEX2) {
+ if (DO_PTEX) {
+ v->pv.u2 = tc2[0][0];
+ v->pv.v2 = tc2[0][1];
+ if (tc2_size == 4)
+ v->pv.q2 = tc2[0][3];
+ else
+ v->pv.q2 = 1.0;
+ }
+ else {
+ v->v.u2 = tc2[0][0];
+ v->v.v2 = tc2[0][1];
}
- if (DO_TEX1) {
- if (DO_PTEX) {
- v->pv.u1 = tc1[i][0];
- v->pv.v1 = tc1[i][1];
- if (tc1_size == 4)
- v->pv.q1 = tc1[i][3];
- else
- v->pv.q1 = 1.0;
- }
- else {
- v->v.u1 = tc1[i][0];
- v->v.v1 = tc1[i][1];
- }
+ STRIDE_4F(tc2, tc2_stride);
+ }
+ if (DO_TEX3) {
+ if (DO_PTEX) {
+ v->pv.u3 = tc3[0][0];
+ v->pv.v3 = tc3[0][1];
+ if (tc3_size == 4)
+ v->pv.q3 = tc3[0][3];
+ else
+ v->pv.q3 = 1.0;
+ }
+ else {
+ v->v.u3 = tc3[0][0];
+ v->v.v3 = tc3[0][1];
}
- }
+ STRIDE_4F(tc3, tc3_stride);
+ }
}
+
}
#else
-#if DO_XYZW
#if HAVE_HW_DIVIDE
#error "cannot use tiny vertices with hw perspective divide"
void *dest, GLuint stride )
{
LOCALVARS
- struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
- GLubyte (*col)[4];
+ struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+ GLfloat (*col)[4];
GLuint col_stride;
GLfloat (*coord)[4] = VB->NdcPtr->data;
GLuint coord_stride = VB->NdcPtr->stride;
ASSERT(stride == 4);
- if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE)
- IMPORT_FLOAT_COLORS( ctx );
-
- col = (GLubyte (*)[4])VB->ColorPtr[0]->Ptr;
- col_stride = VB->ColorPtr[0]->StrideB;
- ASSERT(VB->ColorPtr[0]->Type == GL_UNSIGNED_BYTE);
+ col = VB->ColorPtr[0]->data;
+ col_stride = VB->ColorPtr[0]->stride;
/* fprintf(stderr, "%s(small) importable %x\n", */
/* __FUNCTION__, VB->importable_data); */
/* Pack what's left into a 4-dword vertex. Color is in a different
* place, and there is no 'w' coordinate.
*/
- if (VB->importable_data) {
- if (start) {
- coord = (GLfloat (*)[4])((GLubyte *)coord + start * coord_stride);
- STRIDE_4UB(col, start * col_stride);
- }
+ if (start) {
+ STRIDE_4F(coord, start * coord_stride);
+ STRIDE_4F(col, start * col_stride);
+ }
- for (i=start; i < end; i++, v+=4) {
+ for (i=start; i < end; i++, v+=4) {
+ if (DO_XYZW) {
if (HAVE_HW_VIEWPORT || mask[i] == 0) {
VIEWPORT_X(v[0], coord[0][0]);
VIEWPORT_Y(v[1], coord[0][1]);
VIEWPORT_Z(v[2], coord[0][2]);
}
- coord = (GLfloat (*)[4])((GLubyte *)coord + coord_stride);
- if (DO_RGBA) {
- if (HAVE_RGBA_COLOR) {
- *(GLuint *)&v[3] = LE32_TO_CPU(*(GLuint *)col);
- }
- else {
- VERTEX_COLOR *c = (VERTEX_COLOR *)&v[3];
- c->blue = col[0][2];
- c->green = col[0][1];
- c->red = col[0][0];
- c->alpha = col[0][3];
- }
- STRIDE_4UB( col, col_stride );
- }
-/* fprintf(stderr, "vert %d: %.2f %.2f %.2f %x\n", */
-/* i, v[0], v[1], v[2], *(int *)&v[3]); */
+ STRIDE_4F( coord, coord_stride );
+ }
+ if (DO_RGBA) {
+ VERTEX_COLOR *c = (VERTEX_COLOR *)&v[3];
+ UNCLAMPED_FLOAT_TO_UBYTE(c->red, col[0][0]);
+ UNCLAMPED_FLOAT_TO_UBYTE(c->green, col[0][1]);
+ UNCLAMPED_FLOAT_TO_UBYTE(c->blue, col[0][2]);
+ UNCLAMPED_FLOAT_TO_UBYTE(c->alpha, col[0][3]);
+ STRIDE_4F( col, col_stride );
}
- }
- else {
- for (i=start; i < end; i++, v+=4) {
- if (HAVE_HW_VIEWPORT || mask[i] == 0) {
- VIEWPORT_X(v[0], coord[i][0]);
- VIEWPORT_Y(v[1], coord[i][1]);
- VIEWPORT_Z(v[2], coord[i][2]);
- }
- if (DO_RGBA) {
- if (HAVE_RGBA_COLOR) {
- *(GLuint *)&v[3] = LE32_TO_CPU(*(GLuint *)&col[i]);
- }
- else {
- VERTEX_COLOR *c = (VERTEX_COLOR *)&v[3];
- c->blue = col[i][2];
- c->green = col[i][1];
- c->red = col[i][0];
- c->alpha = col[i][3];
- }
- }
/* fprintf(stderr, "vert %d: %.2f %.2f %.2f %x\n", */
/* i, v[0], v[1], v[2], *(int *)&v[3]); */
-
- }
}
}
-#else
-static void TAG(emit)( GLcontext *ctx, GLuint start, GLuint end,
- void *dest, GLuint stride )
-{
- LOCALVARS
- struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
- GLubyte (*col)[4];
- GLuint col_stride;
- GLfloat *v = (GLfloat *)dest;
- int i;
- if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE)
- IMPORT_FLOAT_COLORS( ctx );
-
- col = VB->ColorPtr[0]->Ptr;
- col_stride = VB->ColorPtr[0]->StrideB;
-
- if (start)
- STRIDE_4UB(col, col_stride * start);
-
- /* Need to figure out where color is:
- */
- if (GET_VERTEX_FORMAT() == TINY_VERTEX_FORMAT)
- v += 3;
- else
- v += 4;
-
- for (i=start; i < end; i++, STRIDE_F(v, stride)) {
- if (HAVE_RGBA_COLOR) {
- *(GLuint *)v = LE32_TO_CPU(*(GLuint *)col[0]);
- }
- else {
- VERTEX_COLOR *c = (VERTEX_COLOR *)v;
- c->blue = col[0][2];
- c->green = col[0][1];
- c->red = col[0][0];
- c->alpha = col[0][3];
- }
- STRIDE_4UB( col, col_stride );
- }
-}
-#endif /* emit */
#endif /* emit */
#if (DO_XYZW) && (DO_RGBA)
-/* $Id: assyntax.h,v 1.23 2003/10/21 08:33:10 dborca Exp $ */
#ifndef __ASSYNTAX_H__
#define __ASSYNTAX_H__
-/* $Id: common_x86.c,v 1.24 2003/10/21 23:53:34 kendallb Exp $ */
/*
* Mesa 3-D graphics library
DEFINE( "VERT_BIT_END_VB ", VERT_BIT_END_VB );
DEFINE( "VERT_BIT_POINT_SIZE ", VERT_BIT_POINT_SIZE );
DEFINE( "VERT_BIT_EYE ", VERT_BIT_EYE );
- DEFINE( "VERT_BIT_CLIP ", VERT_BIT_CLIP );
printf( "\n" );
DEFINE( "VERT_BIT_OBJ_23 ", VERT_BIT_OBJ_3 );
DEFINE( "VERT_BIT_OBJ_234 ", VERT_BIT_OBJ_4 );
-/* $Id: sse.c,v 1.4 2003/10/21 23:53:34 kendallb Exp $ */
/*
* Mesa 3-D graphics library