#include "glheader.h"
#include "context.h"
#include "dlist.h"
#include "enums.h"
#include "light.h"
#include "imports.h"
#include "state.h"
#include "colormac.h"
#include "macros.h"
#include "vtxfmt.h"
#include "t_context.h"
#include "t_imm_api.h"
#include "t_imm_elt.h"
#include "t_imm_exec.h"
#include "t_imm_dlist.h"
void _tnl_flush_immediate( GLcontext *ctx, struct immediate *IM )
{
if (!ctx) {
GET_CURRENT_CONTEXT(context);
ctx = context;
}
if (MESA_VERBOSE & VERBOSE_IMMEDIATE)
_mesa_debug(ctx, "_tnl_flush_immediate IM: %d compiling: %d\n",
IM->id, ctx->CompileFlag);
if (IM->FlushElt == FLUSH_ELT_EAGER) {
_tnl_translate_array_elts( ctx, IM, IM->LastPrimitive, IM->Count );
}
IM->PrimitiveLength[IM->LastPrimitive] = IM->Count - IM->LastPrimitive;
IM->Primitive[IM->LastPrimitive] |= PRIM_LAST;
if (ctx->CompileFlag)
_tnl_compile_cassette( ctx, IM );
else
_tnl_execute_cassette( ctx, IM );
}
void _tnl_flush_vertices( GLcontext *ctx, GLuint flags )
{
struct immediate *IM = TNL_CURRENT_IM(ctx);
if (MESA_VERBOSE & VERBOSE_IMMEDIATE)
_mesa_debug(ctx,
"_tnl_flush_vertices flags %x IM(%d) %d..%d Flag[%d]: %x\n",
flags, IM->id, IM->Start, IM->Count, IM->Start,
IM->Flag[IM->Start]);
if (IM->Flag[IM->Start]) {
if ((flags & FLUSH_UPDATE_CURRENT) ||
IM->Count > IM->Start ||
(IM->Flag[IM->Start] & (VERT_BIT_BEGIN | VERT_BIT_END))) {
_tnl_flush_immediate( ctx, IM );
}
}
}
void
_tnl_save_Begin( GLenum mode )
{
GET_CURRENT_CONTEXT(ctx);
struct immediate *IM = TNL_CURRENT_IM(ctx);
GLuint inflags, state;
if (mode > GL_POLYGON) {
_mesa_compile_error( ctx, GL_INVALID_ENUM, "_tnl_Begin" );
return;
}
if (ctx->NewState)
_mesa_update_state(ctx);
#if 000
if (IM->Count > IMM_MAXDATA-8) {
_tnl_flush_immediate( ctx, IM );
IM = TNL_CURRENT_IM(ctx);
}
#endif
if (IM->Count > IMM_MAXDATA-8) {
_tnl_flush_immediate( ctx, IM );
IM = TNL_CURRENT_IM(ctx);
}
if (IM->SavedBeginState) {
_tnl_flush_immediate( ctx, IM );
IM = TNL_CURRENT_IM(ctx);
IM->BeginState = IM->SavedBeginState;
IM->SavedBeginState = 0;
}
state = IM->BeginState;
inflags = state & (VERT_BEGIN_0|VERT_BEGIN_1);
state |= inflags << 2;
if (inflags != (VERT_BEGIN_0|VERT_BEGIN_1))
{
GLuint count = IM->Count;
GLuint last = IM->LastPrimitive;
state |= (VERT_BEGIN_0|VERT_BEGIN_1);
IM->Flag[count] |= VERT_BIT_BEGIN;
IM->Primitive[count] = mode | PRIM_BEGIN;
IM->PrimitiveLength[IM->LastPrimitive] = count - IM->LastPrimitive;
IM->LastPrimitive = count;
if (IM->FlushElt == FLUSH_ELT_EAGER) {
_tnl_translate_array_elts( ctx, IM, last, count );
}
}
ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
IM->BeginState = state;
if (ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN)
ctx->Driver.CurrentSavePrimitive = PRIM_INSIDE_UNKNOWN_PRIM;
else if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END)
ctx->Driver.CurrentSavePrimitive = mode;
}
void
_tnl_Begin( GLenum mode )
{
GET_CURRENT_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
ASSERT (!ctx->CompileFlag);
if (mode > GL_POLYGON) {
_mesa_error( ctx, GL_INVALID_ENUM, "_tnl_Begin(0x%x)", mode );
return;
}
if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) {
_mesa_error( ctx, GL_INVALID_OPERATION, "_tnl_Begin" );
return;
}
if (ctx->NewState)
_mesa_update_state(ctx);
{
struct immediate *IM = TNL_CURRENT_IM(ctx);
if (IM->Count > IMM_MAXDATA-8) {
_tnl_flush_immediate( ctx, IM );
IM = TNL_CURRENT_IM(ctx);
}
}
{
struct immediate *IM = TNL_CURRENT_IM(ctx);
GLuint count = IM->Count;
GLuint last = IM->LastPrimitive;
if (IM->Start == IM->Count &&
tnl->Driver.NotifyBegin &&
tnl->Driver.NotifyBegin( ctx, mode )) {
return;
}
assert( (IM->SavedBeginState & (VERT_BEGIN_0|VERT_BEGIN_1)) == 0 );
assert( (IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1)) == 0 );
if (IM->FlushElt == FLUSH_ELT_EAGER) {
_tnl_translate_array_elts( ctx, IM, last, count );
}
IM->Flag[count] |= VERT_BIT_BEGIN;
IM->Primitive[count] = mode | PRIM_BEGIN;
IM->PrimitiveLength[last] = count - last;
IM->LastPrimitive = count;
IM->BeginState = (VERT_BEGIN_0|VERT_BEGIN_1);
ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
ctx->Driver.CurrentExecPrimitive = mode;
}
}
GLboolean
_tnl_hard_begin( GLcontext *ctx, GLenum p )
{
if (!ctx->CompileFlag) {
glBegin( p );
return GL_TRUE;
}
else {
struct immediate *IM = TNL_CURRENT_IM(ctx);
if (ctx->NewState)
_mesa_update_state(ctx);
if (IM->Count > IMM_MAXDATA-8) {
_tnl_flush_immediate( ctx, IM );
IM = TNL_CURRENT_IM(ctx);
}
switch (IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1)) {
case VERT_BEGIN_0|VERT_BEGIN_1:
ASSERT(ctx->Driver.CurrentSavePrimitive <= GL_POLYGON);
IM->BeginState |= (VERT_ERROR_1|VERT_ERROR_0);
return GL_FALSE;
case VERT_BEGIN_0:
case VERT_BEGIN_1:
ASSERT(IM->SavedBeginState == 0);
ASSERT(ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN);
IM->SavedBeginState = IM->BeginState;
case 0:
ASSERT(ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN ||
ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END);
ASSERT (IM->FlushElt != FLUSH_ELT_EAGER);
IM->BeginState |= VERT_BEGIN_0|VERT_BEGIN_1;
IM->Flag[IM->Count] |= VERT_BIT_BEGIN;
IM->Primitive[IM->Count] = p | PRIM_BEGIN;
IM->PrimitiveLength[IM->LastPrimitive] = IM->Count - IM->LastPrimitive;
IM->LastPrimitive = IM->Count;
ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
return GL_TRUE;
default:
assert (0);
return GL_TRUE;
}
}
}
void
_tnl_end( GLcontext *ctx )
{
struct immediate *IM = TNL_CURRENT_IM(ctx);
GLuint state = IM->BeginState;
GLuint inflags = (~state) & (VERT_BEGIN_0|VERT_BEGIN_1);
state |= inflags << 2;
if (inflags != (VERT_BEGIN_0|VERT_BEGIN_1))
{
GLuint count = IM->Count;
GLuint last = IM->LastPrimitive;
state &= ~(VERT_BEGIN_0|VERT_BEGIN_1);
IM->Flag[count] |= VERT_BIT_END;
IM->Primitive[last] |= PRIM_END;
IM->PrimitiveLength[last] = count - last;
IM->Primitive[count] = PRIM_OUTSIDE_BEGIN_END;
IM->LastPrimitive = count;
if (IM->FlushElt == FLUSH_ELT_EAGER) {
_tnl_translate_array_elts( ctx, IM, last, count );
}
}
IM->BeginState = state;
if (!ctx->CompileFlag) {
if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END)
_mesa_error( ctx, GL_INVALID_OPERATION, "_tnl_End" );
else
ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
}
if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
_tnl_flush_immediate( ctx, IM );
}
void
_tnl_End(void)
{
GET_CURRENT_CONTEXT(ctx);
_tnl_end( ctx );
if (ctx->CompileFlag)
ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
}
#define COLOR( r, g, b, a ) \
{ \
GET_IMMEDIATE; \
GLuint count = IM->Count; \
GLfloat *color = IM->Attrib[VERT_ATTRIB_COLOR0][count]; \
IM->Flag[count] |= VERT_BIT_COLOR0; \
color[0] = r; \
color[1] = g; \
color[2] = b; \
color[3] = a; \
}
static void
_tnl_Color3f( GLfloat red, GLfloat green, GLfloat blue )
{
COLOR( red, green, blue, 1.0 );
}
static void
_tnl_Color3ub( GLubyte red, GLubyte green, GLubyte blue )
{
COLOR(UBYTE_TO_FLOAT(red),
UBYTE_TO_FLOAT(green),
UBYTE_TO_FLOAT(blue),
1.0);
}
static void
_tnl_Color4f( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
{
COLOR( red, green, blue, alpha );
}
static void
_tnl_Color4ub( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha )
{
COLOR(UBYTE_TO_FLOAT(red),
UBYTE_TO_FLOAT(green),
UBYTE_TO_FLOAT(blue),
UBYTE_TO_FLOAT(alpha));
}
static void
_tnl_Color3fv( const GLfloat *v )
{
COLOR( v[0], v[1], v[2], 1.0 );
}
static void
_tnl_Color3ubv( const GLubyte *v )
{
COLOR(UBYTE_TO_FLOAT(v[0]),
UBYTE_TO_FLOAT(v[1]),
UBYTE_TO_FLOAT(v[2]),
1.0 );
}
static void
_tnl_Color4fv( const GLfloat *v )
{
COLOR( v[0], v[1], v[2], v[3] );
}
static void
_tnl_Color4ubv( const GLubyte *v)
{
COLOR(UBYTE_TO_FLOAT(v[0]),
UBYTE_TO_FLOAT(v[1]),
UBYTE_TO_FLOAT(v[2]),
UBYTE_TO_FLOAT(v[3]));
}
#define SECONDARY_COLOR( r, g, b ) \
{ \
GLuint count; \
GET_IMMEDIATE; \
count = IM->Count; \
IM->Flag[count] |= VERT_BIT_COLOR1; \
IM->Attrib[VERT_ATTRIB_COLOR1][count][0] = r; \
IM->Attrib[VERT_ATTRIB_COLOR1][count][1] = g; \
IM->Attrib[VERT_ATTRIB_COLOR1][count][2] = b; \
}
static void
_tnl_SecondaryColor3fEXT( GLfloat red, GLfloat green, GLfloat blue )
{
SECONDARY_COLOR( red, green, blue );
}
static void
_tnl_SecondaryColor3ubEXT( GLubyte red, GLubyte green, GLubyte blue )
{
SECONDARY_COLOR(UBYTE_TO_FLOAT(red),
UBYTE_TO_FLOAT(green),
UBYTE_TO_FLOAT(blue));
}
static void
_tnl_SecondaryColor3fvEXT( const GLfloat *v )
{
SECONDARY_COLOR( v[0], v[1], v[2] );
}
static void
_tnl_SecondaryColor3ubvEXT( const GLubyte *v )
{
SECONDARY_COLOR(UBYTE_TO_FLOAT(v[0]),
UBYTE_TO_FLOAT(v[1]),
UBYTE_TO_FLOAT(v[2]));
}
static void
_tnl_EdgeFlag( GLboolean flag )
{
GLuint count;
GET_IMMEDIATE;
count = IM->Count;
IM->EdgeFlag[count] = flag;
IM->Flag[count] |= VERT_BIT_EDGEFLAG;
}
static void
_tnl_EdgeFlagv( const GLboolean *flag )
{
GLuint count;
GET_IMMEDIATE;
count = IM->Count;
IM->EdgeFlag[count] = *flag;
IM->Flag[count] |= VERT_BIT_EDGEFLAG;
}
static void
_tnl_FogCoordfEXT( GLfloat f )
{
GLuint count;
GET_IMMEDIATE;
count = IM->Count;
IM->Attrib[VERT_ATTRIB_FOG][count][0] = f;
IM->Flag[count] |= VERT_BIT_FOG;
}
static void
_tnl_FogCoordfvEXT( const GLfloat *v )
{
GLuint count;
GET_IMMEDIATE;
count = IM->Count;
IM->Attrib[VERT_ATTRIB_FOG][count][0] = v[0];
IM->Flag[count] |= VERT_BIT_FOG;
}
static void
_tnl_Indexi( GLint c )
{
GLuint count;
GET_IMMEDIATE;
count = IM->Count;
IM->Index[count] = c;
IM->Flag[count] |= VERT_BIT_INDEX;
}
static void
_tnl_Indexiv( const GLint *c )
{
GLuint count;
GET_IMMEDIATE;
count = IM->Count;
IM->Index[count] = *c;
IM->Flag[count] |= VERT_BIT_INDEX;
}
#define NORMAL( x, y, z ) \
{ \
GLuint count; \
GLfloat *normal; \
GET_IMMEDIATE; \
count = IM->Count; \
IM->Flag[count] |= VERT_BIT_NORMAL; \
normal = IM->Attrib[VERT_ATTRIB_NORMAL][count]; \
ASSIGN_3V(normal, x,y,z); \
}
#if defined(USE_IEEE)
#define NORMALF( x, y, z ) \
{ \
GLuint count; \
fi_type *normal; \
GET_IMMEDIATE; \
count = IM->Count; \
IM->Flag[count] |= VERT_BIT_NORMAL; \
normal = (fi_type *)IM->Attrib[VERT_ATTRIB_NORMAL][count]; \
normal[0].i = ((fi_type *)&(x))->i; \
normal[1].i = ((fi_type *)&(y))->i; \
normal[2].i = ((fi_type *)&(z))->i; \
}
#else
#define NORMALF NORMAL
#endif
static void
_tnl_Normal3f( GLfloat nx, GLfloat ny, GLfloat nz )
{
NORMALF(nx, ny, nz);
}
static void
_tnl_Normal3fv( const GLfloat *v )
{
NORMALF( v[0], v[1], v[2] );
}
#define TEXCOORD1(s) \
{ \
GLuint count; \
GLfloat *tc; \
GET_IMMEDIATE; \
count = IM->Count; \
IM->Flag[count] |= VERT_BIT_TEX0; \
tc = IM->Attrib[VERT_ATTRIB_TEX0][count]; \
ASSIGN_4V(tc,s,0,0,1); \
}
#define TEXCOORD2(s, t) \
{ \
GLuint count; \
GLfloat *tc; \
GET_IMMEDIATE; \
count = IM->Count; \
IM->Flag[count] |= VERT_BIT_TEX0; \
tc = IM->Attrib[VERT_ATTRIB_TEX0][count]; \
ASSIGN_4V(tc, s, t, 0, 1); \
}
#define TEXCOORD3(s, t, u) \
{ \
GLuint count; \
GLfloat *tc; \
GET_IMMEDIATE; \
count = IM->Count; \
IM->Flag[count] |= VERT_BIT_TEX0; \
IM->TexSize |= TEX_0_SIZE_3; \
tc = IM->Attrib[VERT_ATTRIB_TEX0][count]; \
ASSIGN_4V(tc, s, t, u, 1); \
}
#define TEXCOORD4(s, t, u, v) \
{ \
GLuint count; \
GLfloat *tc; \
GET_IMMEDIATE; \
count = IM->Count; \
IM->Flag[count] |= VERT_BIT_TEX0; \
IM->TexSize |= TEX_0_SIZE_4; \
tc = IM->Attrib[VERT_ATTRIB_TEX0][count]; \
ASSIGN_4V(tc, s, t, u, v); \
}
#if defined(USE_IEEE)
#define TEXCOORD2F(s, t) \
{ \
GLuint count; \
fi_type *tc; \
GET_IMMEDIATE; \
count = IM->Count; \
IM->Flag[count] |= VERT_BIT_TEX0; \
tc = (fi_type *)IM->Attrib[VERT_ATTRIB_TEX0][count]; \
tc[0].i = ((fi_type *)&(s))->i; \
tc[1].i = ((fi_type *)&(t))->i; \
tc[2].i = 0; \
tc[3].i = IEEE_ONE; \
}
#else
#define TEXCOORD2F TEXCOORD2
#endif
static void
_tnl_TexCoord1f( GLfloat s )
{
TEXCOORD1(s);
}
static void
_tnl_TexCoord2f( GLfloat s, GLfloat t )
{
TEXCOORD2F(s, t);
}
static void
_tnl_TexCoord3f( GLfloat s, GLfloat t, GLfloat r )
{
TEXCOORD3(s, t, r);
}
static void
_tnl_TexCoord4f( GLfloat s, GLfloat t, GLfloat r, GLfloat q )
{
TEXCOORD4(s, t, r, q)
}
static void
_tnl_TexCoord1fv( const GLfloat *v )
{
TEXCOORD1(v[0]);
}
static void
_tnl_TexCoord2fv( const GLfloat *v )
{
TEXCOORD2F(v[0], v[1]);
}
static void
_tnl_TexCoord3fv( const GLfloat *v )
{
TEXCOORD3(v[0], v[1], v[2]);
}
static void
_tnl_TexCoord4fv( const GLfloat *v )
{
TEXCOORD4(v[0], v[1], v[2], v[3]);
}
#define VERTEX2(IM, x,y) \
{ \
GLuint count = IM->Count++; \
GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
IM->Flag[count] |= VERT_BIT_POS; \
ASSIGN_4V(dest, x, y, 0, 1); \
\
if (count == IMM_MAXDATA - 1) \
_tnl_flush_immediate( NULL, IM ); \
}
#define VERTEX3(IM,x,y,z) \
{ \
GLuint count = IM->Count++; \
GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
IM->Flag[count] |= VERT_BITS_OBJ_23; \
ASSIGN_4V(dest, x, y, z, 1); \
\
if (count == IMM_MAXDATA - 1) \
_tnl_flush_immediate( NULL, IM ); \
}
#define VERTEX4(IM, x,y,z,w) \
{ \
GLuint count = IM->Count++; \
GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
IM->Flag[count] |= VERT_BITS_OBJ_234; \
ASSIGN_4V(dest, x, y, z, w); \
if (count == IMM_MAXDATA - 1) \
_tnl_flush_immediate( NULL, IM ); \
}
#if defined(USE_IEEE)
#define VERTEX2F(IM, x, y) \
{ \
GLuint count = IM->Count++; \
fi_type *dest = (fi_type *)IM->Attrib[VERT_ATTRIB_POS][count]; \
IM->Flag[count] |= VERT_BIT_POS; \
dest[0].i = ((fi_type *)&(x))->i; \
dest[1].i = ((fi_type *)&(y))->i; \
dest[2].i = 0; \
dest[3].i = IEEE_ONE; \
\
if (count == IMM_MAXDATA - 1) \
_tnl_flush_immediate( NULL, IM ); \
}
#else
#define VERTEX2F VERTEX2
#endif
#if defined(USE_IEEE)
#define VERTEX3F(IM, x, y, z) \
{ \
GLuint count = IM->Count++; \
fi_type *dest = (fi_type *)IM->Attrib[VERT_ATTRIB_POS][count]; \
IM->Flag[count] |= VERT_BITS_OBJ_23; \
dest[0].i = ((fi_type *)&(x))->i; \
dest[1].i = ((fi_type *)&(y))->i; \
dest[2].i = ((fi_type *)&(z))->i; \
dest[3].i = IEEE_ONE; \
\
if (count == IMM_MAXDATA - 1) \
_tnl_flush_immediate( NULL, IM ); \
}
#else
#define VERTEX3F VERTEX3
#endif
#if defined(USE_IEEE)
#define VERTEX4F(IM, x, y, z, w) \
{ \
GLuint count = IM->Count++; \
fi_type *dest = (fi_type *)IM->Attrib[VERT_ATTRIB_POS][count]; \
IM->Flag[count] |= VERT_BITS_OBJ_234; \
dest[0].i = ((fi_type *)&(x))->i; \
dest[1].i = ((fi_type *)&(y))->i; \
dest[2].i = ((fi_type *)&(z))->i; \
dest[3].i = ((fi_type *)&(w))->i; \
if (count == IMM_MAXDATA - 1) \
_tnl_flush_immediate( NULL, IM ); \
}
#else
#define VERTEX4F VERTEX4
#endif
static void
_tnl_Vertex2f( GLfloat x, GLfloat y )
{
GET_IMMEDIATE;
VERTEX2F( IM, x, y );
}
static void
_tnl_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
{
GET_IMMEDIATE;
VERTEX3F( IM, x, y, z );
}
static void
_tnl_Vertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
{
GET_IMMEDIATE;
VERTEX4F( IM, x, y, z, w );
}
static void
_tnl_Vertex2fv( const GLfloat *v )
{
GET_IMMEDIATE;
VERTEX2F( IM, v[0], v[1] );
}
static void
_tnl_Vertex3fv( const GLfloat *v )
{
GET_IMMEDIATE;
VERTEX3F( IM, v[0], v[1], v[2] );
}
static void
_tnl_Vertex4fv( const GLfloat *v )
{
GET_IMMEDIATE;
VERTEX4F( IM, v[0], v[1], v[2], v[3] );
}
#define MAX_TARGET (GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS)
#define MULTI_TEXCOORD1(target, s) \
{ \
GET_IMMEDIATE; \
GLuint texunit = target - GL_TEXTURE0_ARB; \
if (texunit < IM->MaxTextureUnits) { \
GLuint count = IM->Count; \
GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \
ASSIGN_4V(tc, s, 0.0F, 0.0F, 1.0F); \
IM->Flag[count] |= VERT_BIT_TEX(texunit); \
} \
}
#define MULTI_TEXCOORD2(target, s, t) \
{ \
GET_IMMEDIATE; \
GLuint texunit = target - GL_TEXTURE0_ARB; \
if (texunit < IM->MaxTextureUnits) { \
GLuint count = IM->Count; \
GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \
ASSIGN_4V(tc, s, t, 0.0F, 1.0F); \
IM->Flag[count] |= VERT_BIT_TEX(texunit); \
} \
}
#define MULTI_TEXCOORD3(target, s, t, u) \
{ \
GET_IMMEDIATE; \
GLuint texunit = target - GL_TEXTURE0_ARB; \
if (texunit < IM->MaxTextureUnits) { \
GLuint count = IM->Count; \
GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \
ASSIGN_4V(tc, s, t, u, 1.0F); \
IM->Flag[count] |= VERT_BIT_TEX(texunit); \
IM->TexSize |= TEX_SIZE_3(texunit); \
} \
}
#define MULTI_TEXCOORD4(target, s, t, u, v) \
{ \
GET_IMMEDIATE; \
GLuint texunit = target - GL_TEXTURE0_ARB; \
if (texunit < IM->MaxTextureUnits) { \
GLuint count = IM->Count; \
GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \
ASSIGN_4V(tc, s, t, u, v); \
IM->Flag[count] |= VERT_BIT_TEX(texunit); \
IM->TexSize |= TEX_SIZE_4(texunit); \
} \
}
#if defined(USE_IEEE)
#define MULTI_TEXCOORD2F(target, s, t) \
{ \
GET_IMMEDIATE; \
GLuint texunit = target - GL_TEXTURE0_ARB; \
if (texunit < IM->MaxTextureUnits) { \
GLuint count = IM->Count; \
fi_type *tc = (fi_type *)IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count];\
IM->Flag[count] |= VERT_BIT_TEX(texunit); \
tc[0].i = ((fi_type *)&(s))->i; \
tc[1].i = ((fi_type *)&(t))->i; \
tc[2].i = 0; \
tc[3].i = IEEE_ONE; \
} \
}
#else
#define MULTI_TEXCOORD2F MULTI_TEXCOORD2
#endif
static void
_tnl_MultiTexCoord1fARB(GLenum target, GLfloat s)
{
MULTI_TEXCOORD1( target, s );
}
static void
_tnl_MultiTexCoord1fvARB(GLenum target, const GLfloat *v)
{
MULTI_TEXCOORD1( target, v[0] );
}
static void
_tnl_MultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t)
{
MULTI_TEXCOORD2F( target, s, t );
}
static void
_tnl_MultiTexCoord2fvARB(GLenum target, const GLfloat *v)
{
MULTI_TEXCOORD2F( target, v[0], v[1] );
}
static void
_tnl_MultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r)
{
MULTI_TEXCOORD3( target, s, t, r );
}
static void
_tnl_MultiTexCoord3fvARB(GLenum target, const GLfloat *v)
{
MULTI_TEXCOORD3( target, v[0], v[1], v[2] );
}
static void
_tnl_MultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
{
MULTI_TEXCOORD4( target, s, t, r, q );
}
static void
_tnl_MultiTexCoord4fvARB(GLenum target, const GLfloat *v)
{
MULTI_TEXCOORD4( target, v[0], v[1], v[2], v[3] );
}
#define EVALCOORD1(IM, x) \
{ \
GLuint count = IM->Count++; \
GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
IM->Flag[count] |= VERT_BIT_EVAL_C1; \
ASSIGN_4V(dest, x, 0, 0, 1); \
if (count == IMM_MAXDATA-1) \
_tnl_flush_immediate( NULL, IM ); \
}
#define EVALCOORD2(IM, x, y) \
{ \
GLuint count = IM->Count++; \
GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
IM->Flag[count] |= VERT_BIT_EVAL_C2; \
ASSIGN_4V(dest, x, y, 0, 1); \
if (count == IMM_MAXDATA-1) \
_tnl_flush_immediate( NULL, IM ); \
}
#define EVALPOINT1(IM, x) \
{ \
GLuint count = IM->Count++; \
GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
IM->Flag[count] |= VERT_BIT_EVAL_P1; \
ASSIGN_4V(dest, x, 0, 0, 1); \
if (count == IMM_MAXDATA-1) \
_tnl_flush_immediate( NULL, IM ); \
}
#define EVALPOINT2(IM, x, y) \
{ \
GLuint count = IM->Count++; \
GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
IM->Flag[count] |= VERT_BIT_EVAL_P2; \
ASSIGN_4V(dest, x, y, 0, 1); \
if (count == IMM_MAXDATA-1) \
_tnl_flush_immediate( NULL, IM ); \
}
static void
_tnl_EvalCoord1f( GLfloat u )
{
GET_IMMEDIATE;
EVALCOORD1( IM, u );
}
static void
_tnl_EvalCoord1fv( const GLfloat *u )
{
GET_IMMEDIATE;
EVALCOORD1( IM, (GLfloat) *u );
}
static void
_tnl_EvalCoord2f( GLfloat u, GLfloat v )
{
GET_IMMEDIATE;
EVALCOORD2( IM, u, v );
}
static void
_tnl_EvalCoord2fv( const GLfloat *u )
{
GET_IMMEDIATE;
EVALCOORD2( IM, u[0], u[1] );
}
static void
_tnl_EvalPoint1( GLint i )
{
GET_IMMEDIATE;
EVALPOINT1( IM, (GLfloat) i );
}
static void
_tnl_EvalPoint2( GLint i, GLint j )
{
GET_IMMEDIATE;
EVALPOINT2( IM, (GLfloat) i, (GLfloat) j );
}
#define ARRAY_ELT( IM, i ) \
{ \
GLuint count = IM->Count; \
IM->Elt[count] = i; \
IM->Flag[count] &= IM->ArrayEltFlags; \
IM->Flag[count] |= VERT_BIT_ELT; \
IM->FlushElt = IM->ArrayEltFlush; \
IM->Count += IM->ArrayEltIncr; \
if (IM->Count == IMM_MAXDATA) \
_tnl_flush_immediate( NULL, IM ); \
}
static void
_tnl_ArrayElement( GLint i )
{
GET_IMMEDIATE;
ARRAY_ELT( IM, i );
}
void
_tnl_eval_coord1f( GLcontext *CC, GLfloat u )
{
struct immediate *i = TNL_CURRENT_IM(CC);
EVALCOORD1( i, u );
}
void
_tnl_eval_coord2f( GLcontext *CC, GLfloat u, GLfloat v )
{
struct immediate *i = TNL_CURRENT_IM(CC);
EVALCOORD2( i, u, v );
}
static void
_tnl_VertexAttrib4fNV( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w )
{
if (index < 16) {
GET_IMMEDIATE;
const GLuint count = IM->Count;
GLfloat *attrib = IM->Attrib[index][count];
ASSIGN_4V(attrib, x, y, z, w);
IM->Flag[count] |= (1 << index);
if (index == 0) {
IM->Count++;
if (count == IMM_MAXDATA - 1)
_tnl_flush_immediate( NULL, IM );
}
}
else {
GET_CURRENT_CONTEXT(ctx);
_mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribNV(index > 15)");
}
}
static void
_tnl_VertexAttrib4fvNV( GLuint index, const GLfloat *v )
{
if (index < 16) {
GET_IMMEDIATE;
const GLuint count = IM->Count;
GLfloat *attrib = IM->Attrib[index][count];
COPY_4V(attrib, v);
IM->Flag[count] |= (1 << index);
if (index == 0) {
IM->Count++;
if (count == IMM_MAXDATA - 1)
_tnl_flush_immediate( NULL, IM );
}
}
else {
GET_CURRENT_CONTEXT(ctx);
_mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribNV(index > 15)");
}
}
static void
_tnl_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
{
GET_CURRENT_CONTEXT(ctx);
if (_tnl_hard_begin( ctx, GL_QUADS )) {
glVertex2f( x1, y1 );
glVertex2f( x2, y1 );
glVertex2f( x2, y2 );
glVertex2f( x1, y2 );
glEnd();
}
}
static void
_tnl_Materialfv( GLenum face, GLenum pname, const GLfloat *params )
{
GET_CURRENT_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct immediate *IM = TNL_CURRENT_IM(ctx);
GLuint count = IM->Count;
struct gl_material *mat;
GLuint bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, "Materialfv");
if (bitmask == 0)
return;
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "_tnl_Materialfv\n");
if (tnl->IsolateMaterials &&
!(IM->BeginState & VERT_BEGIN_1))
{
_tnl_flush_immediate( ctx, IM );
IM = TNL_CURRENT_IM(ctx);
count = IM->Count;
}
if (!(IM->Flag[count] & VERT_BIT_MATERIAL)) {
if (!IM->Material) {
IM->Material = (struct gl_material (*)[2])
MALLOC( sizeof(struct gl_material) * IMM_SIZE * 2 );
IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * IMM_SIZE );
IM->MaterialMask[IM->LastMaterial] = 0;
}
else if (IM->MaterialOrMask & ~bitmask) {
_mesa_copy_material_pairs( IM->Material[count],
IM->Material[IM->LastMaterial],
IM->MaterialOrMask & ~bitmask );
}
IM->Flag[count] |= VERT_BIT_MATERIAL;
IM->MaterialMask[count] = 0;
IM->MaterialAndMask &= IM->MaterialMask[IM->LastMaterial];
IM->LastMaterial = count;
}
IM->MaterialOrMask |= bitmask;
IM->MaterialMask[count] |= bitmask;
mat = IM->Material[count];
if (bitmask & FRONT_AMBIENT_BIT) {
COPY_4FV( mat[0].Ambient, params );
}
if (bitmask & BACK_AMBIENT_BIT) {
COPY_4FV( mat[1].Ambient, params );
}
if (bitmask & FRONT_DIFFUSE_BIT) {
COPY_4FV( mat[0].Diffuse, params );
}
if (bitmask & BACK_DIFFUSE_BIT) {
COPY_4FV( mat[1].Diffuse, params );
}
if (bitmask & FRONT_SPECULAR_BIT) {
COPY_4FV( mat[0].Specular, params );
}
if (bitmask & BACK_SPECULAR_BIT) {
COPY_4FV( mat[1].Specular, params );
}
if (bitmask & FRONT_EMISSION_BIT) {
COPY_4FV( mat[0].Emission, params );
}
if (bitmask & BACK_EMISSION_BIT) {
COPY_4FV( mat[1].Emission, params );
}
if (bitmask & FRONT_SHININESS_BIT) {
GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
mat[0].Shininess = shininess;
}
if (bitmask & BACK_SHININESS_BIT) {
GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
mat[1].Shininess = shininess;
}
if (bitmask & FRONT_INDEXES_BIT) {
mat[0].AmbientIndex = params[0];
mat[0].DiffuseIndex = params[1];
mat[0].SpecularIndex = params[2];
}
if (bitmask & BACK_INDEXES_BIT) {
mat[1].AmbientIndex = params[0];
mat[1].DiffuseIndex = params[1];
mat[1].SpecularIndex = params[2];
}
if (tnl->IsolateMaterials &&
!(IM->BeginState & VERT_BEGIN_1))
{
_tnl_flush_immediate( ctx, IM );
}
}
void _tnl_imm_vtxfmt_init( GLcontext *ctx )
{
GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->vtxfmt);
vfmt->ArrayElement = _tnl_ArrayElement;
vfmt->Begin = _tnl_Begin;
vfmt->Color3f = _tnl_Color3f;
vfmt->Color3fv = _tnl_Color3fv;
vfmt->Color3ub = _tnl_Color3ub;
vfmt->Color3ubv = _tnl_Color3ubv;
vfmt->Color4f = _tnl_Color4f;
vfmt->Color4fv = _tnl_Color4fv;
vfmt->Color4ub = _tnl_Color4ub;
vfmt->Color4ubv = _tnl_Color4ubv;
vfmt->EdgeFlag = _tnl_EdgeFlag;
vfmt->EdgeFlagv = _tnl_EdgeFlagv;
vfmt->End = _tnl_End;
vfmt->EvalCoord1f = _tnl_EvalCoord1f;
vfmt->EvalCoord1fv = _tnl_EvalCoord1fv;
vfmt->EvalCoord2f = _tnl_EvalCoord2f;
vfmt->EvalCoord2fv = _tnl_EvalCoord2fv;
vfmt->EvalPoint1 = _tnl_EvalPoint1;
vfmt->EvalPoint2 = _tnl_EvalPoint2;
vfmt->FogCoordfEXT = _tnl_FogCoordfEXT;
vfmt->FogCoordfvEXT = _tnl_FogCoordfvEXT;
vfmt->Indexi = _tnl_Indexi;
vfmt->Indexiv = _tnl_Indexiv;
vfmt->Materialfv = _tnl_Materialfv;
vfmt->MultiTexCoord1fARB = _tnl_MultiTexCoord1fARB;
vfmt->MultiTexCoord1fvARB = _tnl_MultiTexCoord1fvARB;
vfmt->MultiTexCoord2fARB = _tnl_MultiTexCoord2fARB;
vfmt->MultiTexCoord2fvARB = _tnl_MultiTexCoord2fvARB;
vfmt->MultiTexCoord3fARB = _tnl_MultiTexCoord3fARB;
vfmt->MultiTexCoord3fvARB = _tnl_MultiTexCoord3fvARB;
vfmt->MultiTexCoord4fARB = _tnl_MultiTexCoord4fARB;
vfmt->MultiTexCoord4fvARB = _tnl_MultiTexCoord4fvARB;
vfmt->Normal3f = _tnl_Normal3f;
vfmt->Normal3fv = _tnl_Normal3fv;
vfmt->SecondaryColor3fEXT = _tnl_SecondaryColor3fEXT;
vfmt->SecondaryColor3fvEXT = _tnl_SecondaryColor3fvEXT;
vfmt->SecondaryColor3ubEXT = _tnl_SecondaryColor3ubEXT;
vfmt->SecondaryColor3ubvEXT = _tnl_SecondaryColor3ubvEXT;
vfmt->TexCoord1f = _tnl_TexCoord1f;
vfmt->TexCoord1fv = _tnl_TexCoord1fv;
vfmt->TexCoord2f = _tnl_TexCoord2f;
vfmt->TexCoord2fv = _tnl_TexCoord2fv;
vfmt->TexCoord3f = _tnl_TexCoord3f;
vfmt->TexCoord3fv = _tnl_TexCoord3fv;
vfmt->TexCoord4f = _tnl_TexCoord4f;
vfmt->TexCoord4fv = _tnl_TexCoord4fv;
vfmt->Vertex2f = _tnl_Vertex2f;
vfmt->Vertex2fv = _tnl_Vertex2fv;
vfmt->Vertex3f = _tnl_Vertex3f;
vfmt->Vertex3fv = _tnl_Vertex3fv;
vfmt->Vertex4f = _tnl_Vertex4f;
vfmt->Vertex4fv = _tnl_Vertex4fv;
vfmt->VertexAttrib4fNV = _tnl_VertexAttrib4fNV;
vfmt->VertexAttrib4fvNV = _tnl_VertexAttrib4fvNV;
vfmt->Rectf = _tnl_Rectf;
vfmt->CallList = _mesa_CallList;
vfmt->prefer_float_colors = GL_FALSE;
}