Merge vtx-0-2-branch

This commit is contained in:
Keith Whitwell 2003-11-24 15:23:18 +00:00
parent 57c9814b9e
commit ae0eaf93e0
75 changed files with 6087 additions and 8034 deletions

View file

@ -136,16 +136,10 @@ TNL_SOURCES = \
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 \
@ -154,7 +148,11 @@ TNL_SOURCES = \
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 \
@ -230,9 +228,9 @@ CORE_SOURCES = \
$(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:

View file

@ -93,7 +93,7 @@ static void _ac_fallbacks_init( GLcontext *ctx )
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;
@ -217,9 +217,9 @@ static void _ac_cache_init( GLcontext *ctx )
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;

View file

@ -1,6 +1,5 @@
#!/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

View file

@ -1,6 +1,5 @@
#!/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

View file

@ -250,6 +250,9 @@ static void (*fogcoordfuncs[8])( const void * ) = {
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;

View file

@ -1,324 +0,0 @@
/*
* 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] );
}

View file

@ -45,7 +45,6 @@
* 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)
@ -55,7 +54,7 @@
#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)
@ -65,294 +64,15 @@
#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 )
@ -397,6 +117,13 @@ loopback_Color3us_f( GLushort red, GLushort green, GLushort 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 )
@ -439,6 +166,13 @@ loopback_Color3usv_f( const GLushort *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,
@ -484,6 +218,13 @@ loopback_Color4us_f( GLushort red, GLushort green, GLushort blue, GLushort alpha
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 )
@ -529,6 +270,13 @@ loopback_Color4usv_f( const GLushort *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 )
{
@ -545,55 +293,49 @@ loopback_FogCoorddvEXT( const GLdouble *v )
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
@ -1172,114 +914,6 @@ loopback_Rectsv(const GLshort *v1, const GLshort *v2)
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 )
{
@ -1326,6 +960,14 @@ loopback_SecondaryColor3usEXT_f( GLushort red, GLushort green, GLushort 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 )
{
@ -1371,6 +1013,14 @@ loopback_SecondaryColor3usvEXT_f( const GLushort *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
@ -1379,153 +1029,153 @@ loopback_SecondaryColor3usvEXT_f( const GLushort *v )
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]));
}
@ -1642,171 +1292,127 @@ loopback_VertexAttribs4ubvNV(GLuint index, GLsizei n, const GLubyte *v)
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_init_api_table( struct _glapi_table *dest )
{
_mesa_loopback_prefer_float( dest, prefer_float_colors );
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;

View file

@ -32,10 +32,6 @@
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

View file

@ -27,11 +27,13 @@
#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
@ -53,93 +55,56 @@ void _mesa_noop_EdgeFlagv( const GLboolean *b )
ctx->Current.EdgeFlag = *b;
}
void _mesa_noop_Indexf( GLfloat f )
{
GET_CURRENT_CONTEXT(ctx);
ctx->Current.Index = f;
}
void _mesa_noop_Indexfv( const GLfloat *v )
{
GET_CURRENT_CONTEXT(ctx);
ctx->Current.Index = *v;
}
void _mesa_noop_FogCoordfEXT( GLfloat a )
{
GET_CURRENT_CONTEXT(ctx);
ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = a;
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_FogCoordfvEXT( const GLfloat *v )
{
GET_CURRENT_CONTEXT(ctx);
ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = *v;
}
void _mesa_noop_Indexi( GLint i )
{
GET_CURRENT_CONTEXT(ctx);
ctx->Current.Index = i;
}
void _mesa_noop_Indexiv( const GLint *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 )
@ -162,26 +127,6 @@ void _mesa_noop_Color4fv( const GLfloat *v )
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);
@ -212,7 +157,7 @@ void _mesa_noop_MultiTexCoord1fARB( GLenum target, GLfloat a )
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;
@ -229,7 +174,7 @@ void _mesa_noop_MultiTexCoord1fvARB( GLenum target, const GLfloat *v )
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;
@ -246,8 +191,8 @@ void _mesa_noop_MultiTexCoord2fARB( GLenum target, GLfloat a, GLfloat b )
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;
}
@ -263,8 +208,8 @@ void _mesa_noop_MultiTexCoord2fvARB( GLenum target, const GLfloat *v )
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;
}
@ -280,9 +225,9 @@ void _mesa_noop_MultiTexCoord3fARB( GLenum target, GLfloat a, GLfloat b, GLfloat
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;
}
}
@ -297,9 +242,9 @@ void _mesa_noop_MultiTexCoord3fvARB( GLenum target, const GLfloat *v )
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;
}
}
@ -315,9 +260,9 @@ void _mesa_noop_MultiTexCoord4fARB( GLenum target, GLfloat a, GLfloat b,
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;
}
}
@ -332,33 +277,13 @@ void _mesa_noop_MultiTexCoord4fvARB( GLenum target, const GLfloat *v )
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);
@ -383,7 +308,7 @@ void _mesa_noop_TexCoord1f( GLfloat a )
{
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;
@ -393,7 +318,7 @@ void _mesa_noop_TexCoord1fv( const GLfloat *v )
{
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;
@ -403,8 +328,8 @@ void _mesa_noop_TexCoord2f( GLfloat a, GLfloat b )
{
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;
}
@ -413,8 +338,8 @@ void _mesa_noop_TexCoord2fv( 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]);
dest[0] = v[0];
dest[1] = v[1];
dest[2] = 0;
dest[3] = 1;
}
@ -423,9 +348,9 @@ void _mesa_noop_TexCoord3f( GLfloat a, GLfloat b, GLfloat c )
{
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;
}
@ -433,9 +358,9 @@ void _mesa_noop_TexCoord3fv( 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]);
dest[0] = v[0];
dest[1] = v[1];
dest[2] = v[2];
dest[3] = 1;
}
@ -443,23 +368,136 @@ void _mesa_noop_TexCoord4f( GLfloat a, GLfloat b, GLfloat c, GLfloat d )
{
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];
}
/* Useful outside begin/end?
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__ );
}
/* 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 )
{
@ -491,25 +529,54 @@ void _mesa_noop_Vertex4f( GLfloat a, GLfloat b, GLfloat c, GLfloat d )
(void) a; (void) b; (void) c; (void) d;
}
void _mesa_noop_VertexAttrib4fNV( GLuint index, GLfloat x,
GLfloat y, GLfloat z, GLfloat w )
/* Similarly, these have no effect outside begin/end:
*/
void _mesa_noop_EvalCoord1f( GLfloat a )
{
GET_CURRENT_CONTEXT(ctx);
if (index < 16) {
ASSIGN_4V(ctx->Current.Attrib[index], x, y, z, w);
}
(void) a;
}
void _mesa_noop_VertexAttrib4fvNV( GLuint index, const GLfloat *v )
void _mesa_noop_EvalCoord1fv( 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_EvalCoord2f( GLfloat a, GLfloat b )
{
(void) a; (void) b;
}
void _mesa_noop_EvalCoord2fv( const GLfloat *v )
{
(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
@ -549,7 +616,7 @@ void _mesa_noop_DrawArrays(GLenum mode, GLint start, GLsizei count)
return;
glBegin(mode);
for (i = start ; i <= count ; i++)
for (i = start ; i < count ; i++)
glArrayElement( i );
glEnd();
}
@ -599,3 +666,199 @@ void _mesa_noop_DrawRangeElements(GLenum mode,
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;
}

View file

@ -46,9 +46,9 @@ extern void _mesa_noop_FogCoordfEXT( GLfloat a );
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 );
@ -127,11 +127,37 @@ extern void _mesa_noop_Vertex3f( 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

View file

@ -1431,15 +1431,13 @@ _mesa_initialize_context( GLcontext *ctx,
#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;

View file

@ -49,6 +49,7 @@
#include "glapi.h"
#include "imports.h"
#include "mtypes.h"
@ -263,6 +264,7 @@ _mesa_Flush( void );
/** \name Macros for contexts/flushing. */
/*@{*/
/**
* Flush vertices.
*
@ -272,8 +274,6 @@ _mesa_Flush( void );
* 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 { \

View file

@ -819,6 +819,7 @@ struct dd_function_table {
* these conditions.
*/
GLuint NeedFlush;
GLuint SaveNeedFlush;
/**
* If inside glBegin()/glEnd(), it should ASSERT(0). Otherwise, if
@ -830,6 +831,14 @@ struct dd_function_table {
* 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
@ -910,12 +919,8 @@ typedef struct {
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 */
@ -926,8 +931,8 @@ typedef struct {
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 * );
@ -941,8 +946,6 @@ typedef struct {
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 );
@ -958,8 +961,15 @@ typedef struct {
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 );
/*@}*/
@ -970,10 +980,6 @@ typedef struct {
/**
* \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 );
@ -999,11 +1005,6 @@ typedef struct {
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;

File diff suppressed because it is too large Load diff

View file

@ -79,6 +79,8 @@ extern void GLAPIENTRY _mesa_save_EvalMesh1( GLenum mode, GLint i1, GLint i2 );
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
@ -94,6 +96,9 @@ extern void _mesa_init_display_list( GLcontext * ctx );
/** No-op */
#define _mesa_init_display_list(c) ((void)0)
/** No-op */
#define _mesa_save_vtxfmt_init(v) ((void)0)
#endif
#endif

View file

@ -295,7 +295,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
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);
@ -499,7 +499,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
*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)
@ -2041,7 +2041,7 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params )
*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)
@ -3578,7 +3578,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
*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)
@ -5092,7 +5092,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
*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)

View file

@ -109,6 +109,8 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256];
#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 */

View file

@ -447,7 +447,7 @@ struct gl_current_attrib {
/*@{*/
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 */
/*@}*/
@ -2027,6 +2027,27 @@ struct gl_tnl_module {
/*@}*/
};
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
@ -2058,9 +2079,6 @@ struct __GLcontextRec {
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 */
@ -2090,15 +2108,10 @@ struct __GLcontextRec {
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;

View file

@ -144,7 +144,7 @@ _mesa_init_exec_table(struct _glapi_table *exec, GLuint tableSize)
_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 */

View file

@ -77,12 +77,8 @@ static void install_vtxfmt( struct _glapi_table *tab, GLvertexformat *vfmt )
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;
@ -93,8 +89,8 @@ static void install_vtxfmt( struct _glapi_table *tab, GLvertexformat *vfmt )
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;
@ -108,8 +104,6 @@ static void install_vtxfmt( struct _glapi_table *tab, GLvertexformat *vfmt )
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;
@ -125,8 +119,15 @@ static void install_vtxfmt( struct _glapi_table *tab, GLvertexformat *vfmt )
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;
@ -150,15 +151,11 @@ void _mesa_install_exec_vtxfmt( GLcontext *ctx, GLvertexformat *vfmt )
{
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 );
}

View file

@ -48,18 +48,6 @@ static void GLAPIENTRY TAG(Color3fv)( const GLfloat *v )
_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 );
@ -72,18 +60,6 @@ static void GLAPIENTRY TAG(Color4fv)( const GLfloat *v )
_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 );
@ -144,16 +120,16 @@ static void GLAPIENTRY TAG(FogCoordfvEXT)( const GLfloat *v )
_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 )
@ -236,18 +212,6 @@ static void GLAPIENTRY TAG(SecondaryColor3fvEXT)( 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 );
@ -338,6 +302,12 @@ static void GLAPIENTRY TAG(CallList)( GLuint i )
_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 );
@ -390,6 +360,42 @@ static void GLAPIENTRY TAG(EvalMesh2)( GLenum mode, GLint i1, GLint i2,
_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 );
@ -407,12 +413,8 @@ static GLvertexformat TAG(vtxfmt) = {
TAG(ArrayElement),
TAG(Color3f),
TAG(Color3fv),
TAG(Color3ub),
TAG(Color3ubv),
TAG(Color4f),
TAG(Color4fv),
TAG(Color4ub),
TAG(Color4ubv),
TAG(EdgeFlag),
TAG(EdgeFlagv),
TAG(EvalCoord1f),
@ -423,8 +425,8 @@ static GLvertexformat TAG(vtxfmt) = {
TAG(EvalPoint2),
TAG(FogCoordfEXT),
TAG(FogCoordfvEXT),
TAG(Indexi),
TAG(Indexiv),
TAG(Indexf),
TAG(Indexfv),
TAG(Materialfv),
TAG(MultiTexCoord1fARB),
TAG(MultiTexCoord1fvARB),
@ -438,8 +440,6 @@ static GLvertexformat TAG(vtxfmt) = {
TAG(Normal3fv),
TAG(SecondaryColor3fEXT),
TAG(SecondaryColor3fvEXT),
TAG(SecondaryColor3ubEXT),
TAG(SecondaryColor3ubvEXT),
TAG(TexCoord1f),
TAG(TexCoord1fv),
TAG(TexCoord2f),
@ -455,8 +455,15 @@ static GLvertexformat TAG(vtxfmt) = {
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),

View file

@ -88,68 +88,7 @@ void _mesa_vector4f_init( GLvector4f *v, GLuint flags, GLfloat (*storage)[4] )
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 ;
}
/*
@ -174,82 +113,6 @@ void _mesa_vector4f_alloc( GLvector4f *v, GLuint flags, GLuint count,
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 ;
}
@ -271,83 +134,6 @@ void _mesa_vector4f_free( GLvector4f *v )
}
}
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
@ -402,28 +188,3 @@ void _mesa_vector4f_print( GLvector4f *v, GLubyte *cullmask, GLboolean culling )
}
/*
* 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]);
}
}

View file

@ -80,132 +80,6 @@ extern void _mesa_vector4f_print( GLvector4f *v, GLubyte *, GLboolean );
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 * );

View file

@ -162,8 +162,8 @@ static void _swsetup_render_point_tri( GLcontext *ctx,
_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)

View file

@ -62,18 +62,18 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
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]);
@ -137,18 +137,18 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint 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]);

View file

@ -39,6 +39,8 @@
#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 )
@ -83,7 +85,7 @@ static void import_float_spec_colors( GLcontext *ctx )
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
@ -226,7 +228,7 @@ static copy_pv_func copy_pv_tab[MAX_SETUPFUNC];
* 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,
@ -236,23 +238,22 @@ static void interp_extras( GLcontext *ctx,
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) {
@ -268,8 +269,8 @@ static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src )
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),
@ -277,7 +278,7 @@ static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src )
}
}
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);

View file

@ -35,9 +35,9 @@ static void TAG(emit)(GLcontext *ctx, GLuint start, GLuint end,
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];
@ -80,21 +80,15 @@ static void TAG(emit)(GLcontext *ctx, GLuint start, GLuint end,
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) {
@ -128,13 +122,13 @@ static void TAG(emit)(GLcontext *ctx, GLuint start, GLuint end,
}
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) {
@ -144,7 +138,7 @@ static void TAG(emit)(GLcontext *ctx, GLuint start, GLuint end,
if (IND & INDEX) {
v->index = index[0];
STRIDE_UI(index, index_stride);
STRIDE_F(index, index_stride);
}
if (IND & POINT) {

View file

@ -40,38 +40,40 @@
#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();
}
@ -81,22 +83,26 @@ static void _tnl_draw_range_elements( GLcontext *ctx, GLenum mode,
{
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 );
@ -108,8 +114,9 @@ static void _tnl_draw_range_elements( GLcontext *ctx, GLenum mode,
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;
}
@ -122,7 +129,6 @@ _tnl_DrawArrays(GLenum mode, GLint start, GLsizei count)
{
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)
@ -136,10 +142,9 @@ _tnl_DrawArrays(GLenum mode, GLint start, GLsizei count)
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).
*/
@ -148,6 +153,8 @@ _tnl_DrawArrays(GLenum mode, GLint start, GLsizei count)
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 );
@ -160,9 +167,13 @@ _tnl_DrawArrays(GLenum mode, GLint start, GLsizei count)
/* 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 {
@ -237,13 +248,25 @@ _tnl_DrawArrays(GLenum mode, GLint start, GLsizei count)
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;
@ -286,12 +309,9 @@ _tnl_DrawRangeElements(GLenum mode,
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.
*/
@ -360,12 +380,9 @@ _tnl_DrawElements(GLenum mode, GLsizei count, GLenum type,
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,
@ -397,8 +414,8 @@ _tnl_DrawElements(GLenum mode, GLsizei count, GLenum type,
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;
@ -410,14 +427,10 @@ void _tnl_array_init( GLcontext *ctx )
_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);
}
@ -427,7 +440,4 @@ void _tnl_array_init( GLcontext *ctx )
*/
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);
}

View file

@ -37,7 +37,6 @@
#include "t_array_import.h"
#include "t_context.h"
#include "t_imm_debug.h"
static void _tnl_import_vertex( GLcontext *ctx,
@ -46,7 +45,7 @@ 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,
@ -56,21 +55,11 @@ static void _tnl_import_vertex( GLcontext *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,
@ -79,73 +68,72 @@ 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;
@ -154,47 +142,29 @@ static void _tnl_import_fogcoord( GLcontext *ctx,
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;
}
@ -203,7 +173,7 @@ static void _tnl_import_texcoord( 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;
@ -214,20 +184,11 @@ static void _tnl_import_texcoord( GLcontext *ctx,
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;
}
@ -235,29 +196,18 @@ static void _tnl_import_edgeflag( 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_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;
}
@ -267,7 +217,7 @@ static void _tnl_import_attrib( 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;
@ -278,98 +228,15 @@ static void _tnl_import_attrib( GLcontext *ctx,
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 */
}
@ -378,28 +245,15 @@ void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLsizei count )
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 );
@ -416,63 +270,92 @@ void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLsizei count )
VB->AttribPtr[index] = &tmp->Attribs[index];
}
}
else {
/*
* Conventional attributes
*/
if (inputs & VERT_BIT_POS) {
_tnl_import_vertex( ctx, 0, 0 );
tmp->Obj.count = VB->Count;
VB->ObjPtr = &tmp->Obj;
}
/*
* 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;
}
if (inputs & VERT_BIT_NORMAL) {
_tnl_import_normal( ctx, 0, 0 );
tmp->Normal.count = VB->Count;
VB->NormalPtr = &tmp->Normal;
}
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_BIT_COLOR0) {
_tnl_import_color( ctx, 0, 0, 0 );
VB->ColorPtr[0] = &tmp->Color;
VB->ColorPtr[1] = 0;
}
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_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_INDEX) {
_tnl_import_index( ctx, 0, 0 );
tmp->Index.count = VB->Count;
VB->AttribPtr[_TNL_ATTRIB_INDEX] = &tmp->Index;
}
if (inputs & _TNL_BIT_FOG) {
_tnl_import_fogcoord( ctx, 0, 0 );
tmp->FogCoord.count = VB->Count;
VB->AttribPtr[_TNL_ATTRIB_FOG] = &tmp->FogCoord;
}
if (inputs & _TNL_BIT_EDGEFLAG) {
_tnl_import_edgeflag( ctx, GL_TRUE, sizeof(GLboolean) );
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 & _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];
}
}
}
}
if (inputs & (VERT_BIT_INDEX | VERT_BIT_FOG |
VERT_BIT_EDGEFLAG | VERT_BIT_COLOR1)) {
if (inputs & VERT_BIT_INDEX) {
_tnl_import_index( ctx, 0, 0 );
tmp->Index.count = VB->Count;
VB->IndexPtr[0] = &tmp->Index;
VB->IndexPtr[1] = 0;
}
if (inputs & VERT_BIT_FOG) {
_tnl_import_fogcoord( ctx, 0, 0 );
tmp->FogCoord.count = VB->Count;
VB->FogCoordPtr = &tmp->FogCoord;
}
if (inputs & VERT_BIT_EDGEFLAG) {
_tnl_import_edgeflag( ctx, GL_TRUE, sizeof(GLboolean) );
VB->EdgeFlag = (GLboolean *) tmp->EdgeFlag.data;
}
if (inputs & VERT_BIT_COLOR1) {
_tnl_import_secondarycolor( ctx, 0, 0, 0 );
VB->SecondaryColorPtr[0] = &tmp->SecondaryColor;
VB->SecondaryColorPtr[1] = 0;
}
/* 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];
}
}

View file

@ -27,6 +27,7 @@
*/
#include "api_arrayelt.h"
#include "glheader.h"
#include "imports.h"
#include "macros.h"
@ -37,17 +38,11 @@
#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
@ -55,9 +50,6 @@ _tnl_MakeCurrent( GLcontext *ctx,
GLframebuffer *drawBuffer,
GLframebuffer *readBuffer )
{
#ifndef THREADS
SET_IMMEDIATE( ctx, TNL_CURRENT_IM(ctx) );
#endif
}
@ -66,7 +58,8 @@ install_driver_callbacks( GLcontext *ctx )
{
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;
@ -89,18 +82,21 @@ _tnl_CreateContext( GLcontext *ctx )
/* 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;
@ -108,29 +104,19 @@ _tnl_CreateContext( GLcontext *ctx )
/* 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;
}
@ -142,9 +128,9 @@ _tnl_DestroyContext( GLcontext *ctx )
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;
@ -157,13 +143,6 @@ _tnl_InvalidateState( GLcontext *ctx, GLuint new_state )
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 */
}
@ -171,7 +150,7 @@ _tnl_InvalidateState( GLcontext *ctx, GLuint new_state )
tnl->pipeline.build_state_changes |= (new_state &
tnl->pipeline.build_state_trigger);
tnl->eval.EvalNewState |= new_state;
tnl->vtx.eval.new_state |= new_state;
}
@ -185,7 +164,7 @@ _tnl_wakeup_exec( GLcontext *ctx )
/* 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.
*/
@ -197,9 +176,9 @@ _tnl_wakeup_exec( GLcontext *ctx )
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] );
}
}

View file

@ -1,5 +1,5 @@
/*
* Mesa 3-D graphics library
* mesa 3-D graphics library
* Version: 5.1
*
* Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
@ -37,9 +37,9 @@
* 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.
*
@ -68,7 +68,6 @@
* into TNLcontext::vb, so that the pipeline can be started.
*/
/* What is ELT? */
#ifndef _T_CONTEXT_H
#define _T_CONTEXT_H
@ -84,256 +83,346 @@
#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)))
/* Values for IM->BeginState
#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
/*
*/
#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 */
/* 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 */
/**
* 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 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))
/* Shorthands.
*/
#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 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.
*/
struct immediate
{
GLuint id, ref_count;
/* 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;
GLuint ArrayEltFlags; /* precalc'ed for glArrayElt */
GLuint ArrayEltIncr;
GLuint ArrayEltFlush;
#define FLUSH_ELT_EAGER 0x1
#define FLUSH_ELT_LAZY 0x2
GLuint FlushElt;
GLuint MaxTextureUnits; /* precalc'ed for glMultiTexCoordARB */
/* Temporary values created when vertices are copied into the
* first 3 slots of the struct:
*/
GLuint CopyOrFlag;
GLuint CopyAndFlag;
GLuint CopyTexSize;
GLuint Evaluated;
/* 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 *NormalLengthPtr; /* length of normal vectors (display list only) */
GLuint Elt[IMM_SIZE];
GLubyte EdgeFlag[IMM_SIZE];
GLuint Index[IMM_SIZE];
struct tnl_prim {
GLuint mode;
GLuint start;
GLuint count;
};
struct vertex_arrays
struct tnl_eval1_map {
struct gl_1d_map *map;
GLuint sz;
};
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];
};
#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.
*/
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;
};
/* 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.
*/
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
/* Storage to be shared among several vertex_lists.
*/
struct tnl_vertex_store {
GLfloat buffer[SAVE_BUFFER_SIZE];
GLuint used;
GLuint refcount;
};
struct tnl_primitive_store {
struct tnl_prim buffer[SAVE_PRIM_SIZE];
GLuint used;
GLuint refcount;
};
struct tnl_save {
GLubyte attrsz[_TNL_ATTRIB_MAX];
GLuint vertex_size;
GLfloat *buffer;
GLuint count;
GLuint wrap_count;
struct tnl_prim *prim;
GLuint prim_count, prim_max;
struct tnl_vertex_store *vertex_store;
struct tnl_primitive_store *prim_store;
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 *current[_TNL_ATTRIB_MAX]; /* points into ctx->ListState */
GLubyte *currentsz[_TNL_ATTRIB_MAX];
void (*tabfv[_TNL_ATTRIB_MAX][4])( const GLfloat * );
};
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
@ -365,12 +454,12 @@ struct gl_pipeline_stage {
/* 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
@ -380,31 +469,23 @@ struct gl_pipeline_stage {
* 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 );
@ -533,50 +614,26 @@ typedef struct {
*/
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;
struct tnl_vertex_arrays vtx_inputs;
struct tnl_vertex_arrays save_inputs;
struct tnl_vertex_arrays current;
struct tnl_vertex_arrays array_inputs;
/* 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;
/* 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:
*/
@ -585,13 +642,8 @@ typedef struct {
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;
@ -599,7 +651,6 @@ typedef struct {
#define TNL_CONTEXT(ctx) ((TNLcontext *)(ctx->swtnl_context))
#define TNL_CURRENT_IM(ctx) ((struct immediate *)(ctx->swtnl_im))
#define TYPE_IDX(t) ((t) & 0xf)
@ -610,21 +661,6 @@ extern void _tnl_MakeCurrent( GLcontext *ctx,
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

View file

@ -1,151 +0,0 @@
/*
* 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;
}
}

View file

@ -1,39 +0,0 @@
/*
* 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

View file

@ -1,182 +0,0 @@
/*
* 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");
}
}

View file

@ -1,38 +0,0 @@
/*
* 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

View file

@ -1,667 +0,0 @@
/*
* 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();
}
}
}

View file

@ -1,44 +0,0 @@
/*
* 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

View file

@ -1,45 +0,0 @@
/*
* 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

View file

@ -1,38 +0,0 @@
/*
* 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

View file

@ -1,586 +0,0 @@
/*
* 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;
}
}

View file

@ -1,68 +0,0 @@
/*
* 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

View file

@ -1,786 +0,0 @@
/*
* 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;
}
}

View file

@ -1,56 +0,0 @@
/*
* 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

View file

@ -40,10 +40,10 @@
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);
@ -82,8 +82,8 @@ void _tnl_destroy_pipeline( GLcontext *ctx )
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;
@ -118,9 +118,8 @@ void _tnl_validate_pipeline( GLcontext *ctx )
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;
@ -153,7 +152,6 @@ void _tnl_run_pipeline( GLcontext *ctx )
running = s->run( ctx, s );
s->changed_inputs = 0;
VB->importable_data &= ~s->outputs;
}
}
@ -184,7 +182,7 @@ void _tnl_run_pipeline( GLcontext *ctx )
*
* - 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 *
@ -193,7 +191,7 @@ void _tnl_run_pipeline( GLcontext *ctx )
* 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,

View file

@ -41,24 +41,24 @@ extern void _tnl_validate_pipeline( GLcontext *ctx );
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:

1580
src/mesa/tnl/t_save_api.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -29,63 +29,30 @@ 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"
#ifndef __T_SAVE_API_H__
#define __T_SAVE_API_H__
#if defined(USE_SSE_ASM)
#include "t_context.h"
/* Build specialized versions of the immediate calls on the fly for
* the current state. ???P4 SSE2 versions???
*/
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 );
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 */
};
extern void _tnl_EndCallList( GLcontext *ctx );
extern void _tnl_BeginCallList( GLcontext *ctx, GLuint list );
extern void _tnl_SaveFlushVertices( GLcontext *ctx );
struct dynfn *dfn = MALLOC_STRUCT( dynfn );
insert_at_head( &vb->dfn_cache.Normal3fv, dfn );
dfn->key = key;
extern void _tnl_save_init( GLcontext *ctx );
extern void _tnl_save_destroy( GLcontext *ctx );
dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
memcpy (dfn->code, temp, sizeof(temp));
FIXUP(dfn->code, 5, 0x0, (int)vb->normalptr);
return dfn;
}
extern void _tnl_loopback_vertex_list( GLcontext *ctx,
struct tnl_vertex_list *list );
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;
}
extern void _tnl_playback_vertex_list( GLcontext *ctx, void *data );
#endif

View file

@ -0,0 +1,301 @@
/*
* 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 );
}
}

View file

@ -0,0 +1,218 @@
/*
* 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 );
}

View file

@ -126,7 +126,7 @@ TAG(clip_line)( GLcontext *ctx, GLuint i, GLuint j, GLubyte mask )
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 );
@ -174,7 +174,7 @@ TAG(clip_tri)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLubyte mask )
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 );
@ -199,7 +199,7 @@ TAG(clip_tri)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLubyte mask )
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 );
}
}
@ -227,7 +227,7 @@ TAG(clip_quad)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3,
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 );
@ -252,7 +252,7 @@ TAG(clip_quad)( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3,
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 );
}
}

View file

@ -127,7 +127,7 @@ static void make_win_fog_coords( GLcontext *ctx, GLvector4f *out,
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);
@ -189,21 +189,21 @@ static GLboolean run_fog_stage( GLcontext *ctx,
}
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;
@ -225,7 +225,7 @@ static GLboolean alloc_fog_data( GLcontext *ctx,
}
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) {
@ -236,14 +236,14 @@ static void free_fog_data( struct gl_pipeline_stage *stage )
}
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 */

View file

@ -38,68 +38,93 @@
#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;
GLuint i;
if (!to->Ptr) {
to->Ptr = (GLubyte *) ALIGN_MALLOC( VB->Size * 4 * sizeof(GLfloat), 32 );
to->Type = GL_FLOAT;
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);
}
/* No need to transform the same value 3000 times.
*/
if (!from->StrideB) {
to->StrideB = 0;
count = 1;
}
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;
_mesa_update_material( ctx, store->mat_bitmask );
_mesa_validate_all_lighting_tables( ctx );
}
static void update_materials( GLcontext *ctx,
const struct gl_material *src,
GLuint bitmask )
static GLuint prepare_materials( GLcontext *ctx,
struct vertex_buffer *VB,
struct light_stage_data *store )
{
_mesa_copy_materials( &ctx->Light.Material, src, bitmask );
_mesa_update_material( ctx, bitmask );
GLuint i;
store->mat_count = 0;
store->mat_bitmask = 0;
/* If ColorMaterial enabled, overwrite affected AttrPtr's with
* the color pointer. This could be done earlier.
*/
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);
}
}
/* FIXME: Is this already done?
*/
_mesa_update_material( ctx, ~0 );
_mesa_validate_all_lighting_tables( ctx );
return store->mat_count;
}
/* Tables for all the shading functions.
@ -114,32 +139,16 @@ static light_func _tnl_light_ci_tab[MAX_LIGHT_FUNC];
#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)
#define TAG(x) x##_material
#define IDX (LIGHT_MATERIAL)
#include "t_vb_lighttmp.h"
#define TAG(x) x##_tw_fl
#define IDX (LIGHT_FLAGS|LIGHT_TWOSIDE)
#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"
@ -149,55 +158,64 @@ static void init_lighting( void )
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);
if (stage->changed_inputs & _TNL_BIT_POS) {
if (input->size <= 2 && input == VB->ObjPtr) {
VB->import_data( ctx, VERT_BIT_POS, VEC_NOT_WRITEABLE );
input = ctx->_NeedEyeCoords ? VB->EyePtr : VB->ObjPtr;
_math_trans_4f( store->Input.data,
VB->ObjPtr->data,
VB->ObjPtr->stride,
GL_FLOAT,
VB->ObjPtr->size,
0,
VB->Count );
ASSERT((input->flags & VEC_NOT_WRITEABLE) == 0);
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;
}
@ -206,9 +224,8 @@ static GLboolean run_lighting( GLcontext *ctx, struct gl_pipeline_stage *stage )
/* 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) {
@ -228,13 +245,8 @@ static GLboolean run_validate_lighting( GLcontext *ctx,
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:
*/
@ -246,23 +258,13 @@ static GLboolean run_validate_lighting( GLcontext *ctx,
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;
@ -277,15 +279,18 @@ static GLboolean run_init_lighting( GLcontext *ctx,
*/
init_lighting();
store->FloatColor.Ptr = 0;
_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 );
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_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...
*/
@ -299,52 +304,49 @@ static GLboolean run_init_lighting( GLcontext *ctx,
* 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 */

View file

@ -29,49 +29,6 @@
*/
#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
@ -79,7 +36,7 @@
#endif
/* define TRACE if to trace lighting code */
/* define TRACE to trace lighting code */
/* #define TRACE 1 */
/*
@ -90,12 +47,12 @@
*/
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;
@ -103,20 +60,13 @@ static void TAG(light_rgba_spec)( GLcontext *ctx,
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;
@ -124,23 +74,14 @@ static void TAG(light_rgba_spec)( GLcontext *ctx,
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?
@ -148,24 +89,15 @@ static void TAG(light_rgba_spec)( GLcontext *ctx,
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]);
@ -288,13 +220,13 @@ static void TAG(light_rgba_spec)( GLcontext *ctx,
}
} /*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];
}
}
@ -303,81 +235,56 @@ static void TAG(light_rgba_spec)( GLcontext *ctx,
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;
GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;
GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
GLfloat (*color[2])[4];
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;
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]);
@ -503,11 +410,11 @@ static void TAG(light_rgba)( GLcontext *ctx,
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];
}
}
@ -520,23 +427,17 @@ static void TAG(light_rgba)( GLcontext *ctx,
*/
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;
@ -545,19 +446,9 @@ static void TAG(light_fast_rgba_single)( GLcontext *ctx,
#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];
@ -565,84 +456,61 @@ static void TAG(light_fast_rgba_single)( GLcontext *ctx,
if (stage->changed_inputs == 0)
return;
do {
if ( CHECK_COLOR_MATERIAL(j) ) {
_mesa_update_color_material( ctx, CMcolor );
}
for (j = 0; j < nr; j++, STRIDE_F(normal,nstride)) {
if ( CHECK_MATERIAL(j) )
update_materials( ctx, &new_material[j], new_material_mask[j] );
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]);
}
}
}
@ -650,44 +518,29 @@ static void TAG(light_fast_rgba_single)( GLcontext *ctx,
*/
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)
@ -696,84 +549,60 @@ static void TAG(light_fast_rgba)( GLcontext *ctx,
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]);
}
COPY_3V(sum[0], ctx->Light._BaseColor[0]);
sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
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;
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);
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]);
}
}
}
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];
}
j++;
CMSTRIDE;
STRIDE_F(normal, NSTRIDE);
} while (DO_ANOTHER_NORMAL(j));
/* 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]);
sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
}
} while (!CHECK_END_VB(j));
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;
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);
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]);
}
}
}
COPY_3V( Fcolor[j], sum[0] );
Fcolor[j][3] = sumA[0];
if (IDX & LIGHT_TWOSIDE) {
COPY_3V( Bcolor[j], sum[1] );
Bcolor[j][3] = sumA[1];
}
}
}
@ -791,7 +620,7 @@ static void TAG(light_fast_rgba)( GLcontext *ctx,
*/
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);
@ -800,19 +629,13 @@ static void TAG(light_ci)( GLcontext *ctx,
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;
@ -823,36 +646,18 @@ static void TAG(light_ci)( GLcontext *ctx,
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;
@ -962,7 +767,6 @@ static void TAG(light_ci)( GLcontext *ctx,
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);
@ -970,7 +774,7 @@ static void TAG(light_ci)( GLcontext *ctx,
index = ind[MAT_INDEX_SPECULAR];
}
}
indexResult[side][j] = (GLuint) (GLint) index;
indexResult[side][j] = index;
}
} /*for vertex*/
}
@ -990,12 +794,3 @@ static void TAG(init_light_tab)( void )
#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

View file

@ -52,7 +52,7 @@ struct normal_stage_data {
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;
@ -83,7 +83,7 @@ static GLboolean run_normal_stage( GLcontext *ctx,
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);
@ -133,7 +133,7 @@ static GLboolean run_validate_normal_stage( GLcontext *ctx,
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));
@ -146,7 +146,7 @@ static void check_normal_transform( GLcontext *ctx,
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;
@ -165,7 +165,7 @@ static GLboolean alloc_normal_data( GLcontext *ctx,
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) {
@ -182,14 +182,14 @@ static void free_normal_data( struct gl_pipeline_stage *stage )
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 */

View file

@ -43,7 +43,7 @@ struct point_stage_data {
* 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;
@ -73,13 +73,13 @@ static GLboolean run_point_stage( GLcontext *ctx,
/* 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;
@ -97,7 +97,7 @@ static GLboolean alloc_point_data( GLcontext *ctx,
}
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) {
@ -107,14 +107,14 @@ static void free_point_data( struct gl_pipeline_stage *stage )
}
}
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 */

View file

@ -49,8 +49,6 @@
#include "t_context.h"
#include "t_pipeline.h"
#include "t_imm_api.h"
#include "t_imm_exec.h"
/**
@ -81,10 +79,6 @@ struct vp_stage_data {
/** 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 */
@ -97,7 +91,7 @@ struct vp_stage_data {
/**
* 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);
@ -129,28 +123,16 @@ static GLboolean run_vp( GLcontext *ctx, struct gl_pipeline_stage *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 */
@ -182,10 +164,10 @@ static GLboolean run_vp( GLcontext *ctx, struct gl_pipeline_stage *stage )
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++)
@ -225,11 +207,6 @@ static GLboolean run_vp( GLcontext *ctx, struct gl_pipeline_stage *stage )
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;
}
@ -238,7 +215,7 @@ static GLboolean run_vp( GLcontext *ctx, struct gl_pipeline_stage *stage )
* 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? */
@ -282,27 +259,13 @@ static GLboolean run_validate_program( GLcontext *ctx,
}
/**
* 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);
@ -321,12 +284,6 @@ static GLboolean run_init_vp( GLcontext *ctx,
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 );
@ -343,31 +300,15 @@ static GLboolean run_init_vp( GLcontext *ctx,
* 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
}
}
@ -375,7 +316,7 @@ static void check_vp( GLcontext *ctx, struct gl_pipeline_stage *stage )
/**
* 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);
@ -398,16 +339,14 @@ static void dtr( struct gl_pipeline_stage *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 */

View file

@ -261,7 +261,7 @@ void _tnl_RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
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;
@ -304,29 +304,29 @@ static GLboolean run_render( GLcontext *ctx,
do
{
GLuint i, length, flags = 0;
for (i = VB->FirstPrimitive ; !(flags & PRIM_LAST) ; i += length)
{
flags = VB->Primitive[i];
length= VB->PrimitiveLength[i];
ASSERT(length || (flags & PRIM_LAST));
ASSERT((flags & PRIM_MODE_MASK) <= GL_POLYGON+1);
GLint i;
if (MESA_VERBOSE & VERBOSE_PRIMS)
for (i = 0 ; i < VB->PrimitiveCount ; i++)
{
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)
_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 */
}
@ -340,41 +340,38 @@ static GLboolean run_render( GLcontext *ctx,
/* 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;
}
@ -382,12 +379,12 @@ static void check_render( GLcontext *ctx, struct gl_pipeline_stage *stage )
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 |

View file

@ -52,7 +52,6 @@
#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
@ -187,9 +186,6 @@ static void TAG(render_tri_strip)( GLcontext *ctx,
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) {

View file

@ -319,11 +319,6 @@ static void texgen_sphere_map( GLcontext *ctx,
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,
@ -518,7 +513,7 @@ static void texgen( GLcontext *ctx,
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 );
@ -526,7 +521,7 @@ static GLboolean run_texgen_stage( GLcontext *ctx,
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];
@ -539,7 +534,7 @@ static GLboolean run_texgen_stage( GLcontext *ctx,
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;
@ -584,7 +579,7 @@ static GLboolean run_validate_texgen_stage( GLcontext *ctx,
}
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;
@ -593,24 +588,21 @@ static void check_texgen( GLcontext *ctx, struct gl_pipeline_stage *stage )
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? */
}
@ -629,7 +621,7 @@ static void check_texgen( GLcontext *ctx, struct gl_pipeline_stage *stage )
/* 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;
@ -653,7 +645,7 @@ static GLboolean alloc_texgen_data( GLcontext *ctx,
}
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);
@ -674,7 +666,7 @@ static void free_texgen_data( struct gl_pipeline_stage *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() */

View file

@ -52,7 +52,7 @@ struct texmat_stage_data {
#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;
@ -62,7 +62,7 @@ static void check_texmat( GLcontext *ctx, struct gl_pipeline_stage *stage )
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;
@ -71,7 +71,7 @@ static void check_texmat( GLcontext *ctx, struct gl_pipeline_stage *stage )
}
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;
@ -82,7 +82,7 @@ static GLboolean run_texmat_stage( GLcontext *ctx,
*/
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]);
@ -96,7 +96,7 @@ static GLboolean run_texmat_stage( GLcontext *ctx,
/* 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;
@ -117,7 +117,7 @@ static GLboolean alloc_texmat_data( GLcontext *ctx,
}
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;
@ -133,7 +133,7 @@ static void free_texmat_data( struct gl_pipeline_stage *stage )
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 */

View file

@ -129,7 +129,7 @@ static void (*(usercliptab[5]))( GLcontext *,
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);
@ -149,36 +149,23 @@ static GLboolean run_vertex_stage( GLcontext *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
@ -225,9 +212,6 @@ static GLboolean run_vertex_stage( GLcontext *ctx,
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;
@ -240,8 +224,6 @@ static GLboolean run_vertex_stage( GLcontext *ctx,
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;
}
@ -250,13 +232,13 @@ static GLboolean run_vertex_stage( GLcontext *ctx,
}
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;
@ -285,7 +267,7 @@ static GLboolean init_vertex_stage( GLcontext *ctx,
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);
@ -301,7 +283,7 @@ static void dtr( struct gl_pipeline_stage *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 */
@ -311,8 +293,8 @@ const struct gl_pipeline_stage _tnl_vertex_transform_stage =
_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 */

File diff suppressed because it is too large Load diff

View file

@ -32,203 +32,27 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#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;
struct dfn_lists dfn_cache;
struct dfn_generators codegen;
GLvertexformat vtxfmt;
};
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 );
extern GLboolean *_tnl_translate_edgeflag( GLcontext *ctx,
const GLfloat *data,
GLuint count,
GLuint stride );
extern GLboolean *_tnl_import_current_edgeflag( GLcontext *ctx,
GLuint count );
#endif
#endif

253
src/mesa/tnl/t_vtx_eval.c Normal file
View file

@ -0,0 +1,253 @@
/*
* 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 );
}
}

View file

@ -1,244 +1,252 @@
/* $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 "macros.h"
#include "math/m_eval.h"
#include "t_vtx_api.h"
#include "t_pipeline.h"
#include "tnl/tnl.h"
#include "tnl/t_context.h"
#include "tnl/t_array_api.h"
static void _tnl_FlushVertices( GLcontext *, GLuint );
void tnl_copy_to_current( GLcontext *ctx )
static void _tnl_print_vtx( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint flag = tnl->vertex_format;
GLint i;
GLuint count = tnl->vtx.initial_counter - tnl->vtx.counter;
GLuint i;
assert(ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT);
_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 < 16 ; i++)
if (flag & (1<<i))
COPY_4FV( ctx->Current.Attrib[i], tnl->attribptr[i] );
if (flag & VERT_BIT_INDEX)
ctx->Current.Index = tnl->indexptr[0];
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 );
tnl->Driver.NotifyMaterialChange( ctx );
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)");
}
ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT;
}
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 )
GLboolean *_tnl_translate_edgeflag( GLcontext *ctx, const GLfloat *data,
GLuint count, GLuint stride )
{
int i, j;
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLboolean *ef = tnl->vtx.edgeflag_tmp;
GLuint i;
if (tnl->nrprims <= 1)
return;
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);
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;
return ef;
}
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;
if (!ef)
ef = tnl->vtx.edgeflag_tmp = MALLOC( tnl->vb.Size );
for (i = 0 ; i < count ; i++)
ef[i] = tmp;
return ef;
}
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->NormalPtr, etc and just use the AttrPtr's.
*/
static void _tnl_vb_bind_vtx( GLcontext *ctx )
{
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;
if (0) fprintf(stderr, "%s: %d verts %d vertsize\n",
__FUNCTION__, count, tnl->vtx.vertex_size);
/* 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 {
j++;
if (j != i) tnl->primlist[j] = tnl->primlist[i];
/* VB->AttribPtr[attr] = &tnl->current.Attribs[attr]; */
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];
}
}
tnl->nrprims = j+1;
}
/* Bind vertex buffer pointers, run pipeline:
*/
static void flush_prims( TNLcontext *tnl )
{
int i,j;
tnl->dma.current.ptr = tnl->dma.current.start +=
(tnl->initial_counter - tnl->counter) * tnl->vertex_size * 4;
tnl->tcl.vertex_format = tnl->vertex_format;
tnl->tcl.aos_components[0] = &tmp;
tnl->tcl.nr_aos_components = 1;
tnl->dma.flush = 0;
tnl->Driver.RunPipeline( ... );
tnl->nrprims = 0;
}
/* 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 );
}
/* 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;
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);
if (tnl->prim[0] != GL_POLYGON+1) {
tnl->primlist[tnl->nrprims].prim |= flags;
tnl->primlist[tnl->nrprims].end = tnl->initial_counter - tnl->counter;
if (++tnl->nrprims == TNL_MAX_PRIMS)
flush_prims( tnl );
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;
@ -247,385 +255,45 @@ static GLuint copy_wrapped_verts( TNLcontext *tnl, GLfloat (*tmp)[15] )
/* Extend for vertex-format changes on wrap:
/**
* Execute the buffer and save copied verts.
*/
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.
*/
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 );
if (0)
_tnl_print_vtx( ctx );
TNL_NEWPRIM(tnl);
tnl->vertex_format = VERT_BIT_POS;
tnl->prim = &ctx->Driver.CurrentExecPrimitive;
if (tnl->vtx.prim_count &&
tnl->vtx.counter != tnl->vtx.initial_counter) {
tnl->vtx.copied.nr = _tnl_copy_vertices( ctx );
/* 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];
if (ctx->NewState)
_mesa_update_state( ctx );
if (tnl->pipeline.build_state_changes)
_tnl_validate_pipeline( ctx );
_tnl_vb_bind_vtx( ctx );
/* 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;
}
/* 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;
}
}
tnl->vtx.prim_count = 0;
tnl->vtx.counter = tnl->vtx.initial_counter;
tnl->vtx.vbptr = tnl->vtx.buffer;
}
/* 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 );
}
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;
}
static void _tnl_FlushVertices( GLcontext *ctx, GLuint flags )
{
if (MESA_VERBOSE & DEBUG_VFMT)
_mesa_debug(NULL, "%s\n", __FUNCTION__);
assert(tnl->installed);
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;
}
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;
}
}
/* 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 );
}

View file

@ -1,704 +0,0 @@
/* $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

View file

@ -318,14 +318,6 @@ static void TAG(render_tri_strip_verts)( GLcontext *ctx,
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);
@ -869,10 +861,6 @@ static void TAG(render_tri_strip_elts)( GLcontext *ctx,
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);

View file

@ -323,9 +323,6 @@ static void TAG(render_tri_strip_verts)( GLcontext *ctx,
ELT_INIT( GL_TRIANGLES, HW_TRIANGLES );
if (flags & PRIM_PARITY)
parity = 1;
/* Emit even number of tris in each full buffer.
*/
dmasz = dmasz/3;
@ -348,8 +345,6 @@ static void TAG(render_tri_strip_verts)( GLcontext *ctx,
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 {
@ -757,18 +752,9 @@ static void TAG(render_tri_strip_elts)( GLcontext *ctx,
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();
}
}

View file

@ -176,9 +176,8 @@ static void TAG(triangle)( GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
}
}
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) {
@ -191,7 +190,7 @@ static void TAG(triangle)( GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
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 );
@ -205,11 +204,14 @@ static void TAG(triangle)( GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 )
}
}
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] );
}
}
@ -308,12 +310,11 @@ static void TAG(triangle)( GLcontext *ctx, GLuint e0, GLuint e1, GLuint 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 );
}
}
@ -384,7 +385,7 @@ static void TAG(quad)( GLcontext *ctx,
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) {
@ -424,8 +425,8 @@ static void TAG(quad)( GLcontext *ctx,
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 );
@ -441,12 +442,16 @@ static void TAG(quad)( GLcontext *ctx,
}
}
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] );
}
}
@ -557,13 +562,12 @@ static void TAG(quad)( GLcontext *ctx,
}
}
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 );
}
}
@ -611,7 +615,7 @@ static void TAG(quad)( GLcontext *ctx, GLuint e0,
#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);

View file

@ -271,56 +271,7 @@ void TAG(print_vertex)( GLcontext *ctx, const VERTEX *v )
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.
@ -332,7 +283,7 @@ IMPORT_QUALIFIER void TAG(import_float_spec_colors)( GLcontext *ctx )
#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,
@ -344,13 +295,15 @@ 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) );
@ -371,12 +324,12 @@ INTERP_QUALIFIER void TAG(copy_pv_extras)( GLcontext *ctx,
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) );
}
}
@ -385,7 +338,6 @@ INTERP_QUALIFIER void TAG(copy_pv_extras)( GLcontext *ctx,
#undef INTERP_QUALIFIER
#undef IMPORT_QUALIFIER
#undef GET_COLOR
#undef IND

View file

@ -123,10 +123,10 @@ static void TAG(emit)( GLcontext *ctx,
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;
@ -184,21 +184,16 @@ static void TAG(emit)( GLcontext *ctx,
}
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;
}
}
@ -215,200 +210,124 @@ static void TAG(emit)( GLcontext *ctx,
}
}
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);
}
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 */
}
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];
}
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 {
v->v.u3 = tc3[0][0];
v->v.v3 = tc3[0][1];
}
tc3 = (GLfloat (*)[4])((GLubyte *)tc3 + tc3_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);
}
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_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;
}
}
}
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];
}
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];
}
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.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;
}
}
STRIDE_4F(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];
}
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];
}
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"
@ -418,8 +337,8 @@ 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];
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;
@ -432,12 +351,8 @@ static void TAG(emit)( GLcontext *ctx, GLuint start, GLuint end,
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); */
@ -445,103 +360,33 @@ static void TAG(emit)( GLcontext *ctx, GLuint start, GLuint end,
/* 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 );
}
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 );
}
/* fprintf(stderr, "vert %d: %.2f %.2f %.2f %x\n", */
/* i, v[0], v[1], v[2], *(int *)&v[3]); */
}
}
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)

View file

@ -1,4 +1,3 @@
/* $Id: assyntax.h,v 1.23 2003/10/21 08:33:10 dborca Exp $ */
#ifndef __ASSYNTAX_H__
#define __ASSYNTAX_H__

View file

@ -1,4 +1,3 @@
/* $Id: common_x86.c,v 1.24 2003/10/21 23:53:34 kendallb Exp $ */
/*
* Mesa 3-D graphics library

View file

@ -178,7 +178,6 @@ int main( int argc, char **argv )
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 );

View file

@ -1,4 +1,3 @@
/* $Id: sse.c,v 1.4 2003/10/21 23:53:34 kendallb Exp $ */
/*
* Mesa 3-D graphics library