#include "glheader.h"
#include "context.h"
#include "macros.h"
#include "imports.h"
#include "mtypes.h"
#include "tnl/t_context.h"
#include "gamma_context.h"
#include "gamma_tris.h"
#include "gamma_vb.h"
static void gamma_emit( GLcontext *ctx, GLuint start, GLuint end)
{
gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLfloat (*coord)[4];
GLuint coord_stride;
GLubyte (*col)[4];
GLuint col_stride;
int i;
GLuint tc0_stride = 0;
GLfloat (*tc0)[4] = 0;
GLuint tc0_size = 0;
if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE)
gamma_import_float_colors( ctx );
col = VB->ColorPtr[0]->Ptr;
col_stride = VB->ColorPtr[0]->StrideB;
if (ctx->Texture.Unit[0]._ReallyEnabled) {
tc0_stride = VB->TexCoordPtr[0]->stride;
tc0 = VB->TexCoordPtr[0]->data;
tc0_size = VB->TexCoordPtr[0]->size;
coord = VB->ClipPtr->data;
coord_stride = VB->ClipPtr->stride;
} else {
coord = VB->NdcPtr->data;
coord_stride = VB->NdcPtr->stride;
}
if (VB->importable_data) {
if (start) {
coord = (GLfloat (*)[4])((GLubyte *)coord + start * coord_stride);
STRIDE_4UB(col, start * col_stride);
if (ctx->Texture.Unit[0]._ReallyEnabled)
tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + start * tc0_stride);
}
if (ctx->Texture.Unit[0]._ReallyEnabled && tc0_size == 4) {
for (i=start; i < end; i++) {
CHECK_DMA_BUFFER(gmesa, 9);
WRITEF(gmesa->buf, Tq4, tc0[0][3]);
WRITEF(gmesa->buf, Tr4, tc0[0][2]);
WRITEF(gmesa->buf, Tt4, tc0[0][0]);
WRITEF(gmesa->buf, Ts4, tc0[0][1]);
WRITE(gmesa->buf, PackedColor4, *(CARD32*)col[0]);
WRITEF(gmesa->buf, Vw, coord[0][3]);
WRITEF(gmesa->buf, Vz, coord[0][2]);
WRITEF(gmesa->buf, Vy, coord[0][1]);
WRITEF(gmesa->buf, Vx4, coord[0][0]);
STRIDE_4UB(col, col_stride);
tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + tc0_stride);
coord = (GLfloat (*)[4])((GLubyte *)coord + coord_stride);
}
} else if (ctx->Texture.Unit[0]._ReallyEnabled && tc0_size == 2) {
for (i=start; i < end; i++) {
CHECK_DMA_BUFFER(gmesa, 7);
WRITEF(gmesa->buf, Tt2, tc0[0][0]);
WRITEF(gmesa->buf, Ts2, tc0[0][1]);
WRITE(gmesa->buf, PackedColor4, *(CARD32*)col[0]);
WRITEF(gmesa->buf, Vw, coord[0][3]);
WRITEF(gmesa->buf, Vz, coord[0][2]);
WRITEF(gmesa->buf, Vy, coord[0][1]);
WRITEF(gmesa->buf, Vx4, coord[0][0]);
STRIDE_4UB(col, col_stride);
tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + tc0_stride);
coord = (GLfloat (*)[4])((GLubyte *)coord + coord_stride);
}
} else {
for (i=start; i < end; i++) {
CHECK_DMA_BUFFER(gmesa, 4);
WRITE(gmesa->buf, PackedColor4, *(CARD32*)col[0]);
WRITEF(gmesa->buf, Vz, coord[0][2]);
WRITEF(gmesa->buf, Vy, coord[0][1]);
WRITEF(gmesa->buf, Vx3, coord[0][0]);
STRIDE_4UB(col, col_stride);
coord = (GLfloat (*)[4])((GLubyte *)coord + coord_stride);
}
}
} else {
if (ctx->Texture.Unit[0]._ReallyEnabled && tc0_size == 4) {
for (i=start; i < end; i++) {
CHECK_DMA_BUFFER(gmesa, 9);
WRITEF(gmesa->buf, Tq4, tc0[i][3]);
WRITEF(gmesa->buf, Tr4, tc0[i][2]);
WRITEF(gmesa->buf, Tt4, tc0[i][0]);
WRITEF(gmesa->buf, Ts4, tc0[i][1]);
WRITE(gmesa->buf, PackedColor4, *(CARD32*)col[i]);
WRITEF(gmesa->buf, Vw, coord[i][3]);
WRITEF(gmesa->buf, Vz, coord[i][2]);
WRITEF(gmesa->buf, Vy, coord[i][1]);
WRITEF(gmesa->buf, Vx4, coord[i][0]);
}
} else if (ctx->Texture.Unit[0]._ReallyEnabled && tc0_size == 2) {
for (i=start; i < end; i++) {
CHECK_DMA_BUFFER(gmesa, 7);
WRITEF(gmesa->buf, Tt2, tc0[i][0]);
WRITEF(gmesa->buf, Ts2, tc0[i][1]);
WRITE(gmesa->buf, PackedColor4, *(CARD32*)col[i]);
WRITEF(gmesa->buf, Vw, coord[i][3]);
WRITEF(gmesa->buf, Vz, coord[i][2]);
WRITEF(gmesa->buf, Vy, coord[i][1]);
WRITEF(gmesa->buf, Vx4, coord[i][0]);
}
} else {
for (i=start; i < end; i++) {
CHECK_DMA_BUFFER(gmesa, 4);
WRITE(gmesa->buf, PackedColor4, *(CARD32*)col[i]);
WRITEF(gmesa->buf, Vz, coord[i][2]);
WRITEF(gmesa->buf, Vy, coord[i][1]);
WRITEF(gmesa->buf, Vx3, coord[i][0]);
}
}
}
}
#define HAVE_POINTS 1
#define HAVE_LINES 1
#define HAVE_LINE_STRIPS 1
#define HAVE_TRIANGLES 1
#define HAVE_TRI_STRIPS 1
#define HAVE_TRI_STRIP_1 0
#define HAVE_TRI_FANS 1
#define HAVE_QUADS 1
#define HAVE_QUAD_STRIPS 1
#define HAVE_POLYGONS 1
#define HAVE_ELTS 0
static void VERT_FALLBACK( GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
tnl->Driver.Render.PrimitiveNotify( ctx, flags & PRIM_MODE_MASK );
tnl->Driver.Render.BuildVertices( ctx, start, count, ~0 );
tnl->Driver.Render.PrimTabVerts[flags&PRIM_MODE_MASK]( ctx, start, count, flags );
GAMMA_CONTEXT(ctx)->SetupNewInputs = VERT_BIT_CLIP;
}
static const GLuint hw_prim[GL_POLYGON+1] = {
B_PrimType_Points,
B_PrimType_Lines,
B_PrimType_LineLoop,
B_PrimType_LineStrip,
B_PrimType_Triangles,
B_PrimType_TriangleStrip,
B_PrimType_TriangleFan,
B_PrimType_Quads,
B_PrimType_QuadStrip,
B_PrimType_Polygon
};
static __inline void gammaStartPrimitive( gammaContextPtr gmesa, GLenum prim )
{
CHECK_DMA_BUFFER(gmesa, 1);
WRITE(gmesa->buf, Begin, gmesa->Begin | hw_prim[prim]);
}
static __inline void gammaEndPrimitive( gammaContextPtr gmesa )
{
GLcontext *ctx = gmesa->glCtx;
if ( ctx->Line.SmoothFlag ||
ctx->Polygon.SmoothFlag ||
ctx->Point.SmoothFlag ) {
CHECK_DMA_BUFFER(gmesa, 1);
WRITE(gmesa->buf, FlushSpan, 0);
}
CHECK_DMA_BUFFER(gmesa, 1);
WRITE(gmesa->buf, End, 0);
}
#define LOCAL_VARS gammaContextPtr gmesa = GAMMA_CONTEXT(ctx)
#define INIT( prim ) gammaStartPrimitive( gmesa, prim )
#define FINISH gammaEndPrimitive( gmesa )
#define NEW_PRIMITIVE()
#define NEW_BUFFER()
#define GET_CURRENT_VB_MAX_VERTS() \
(gmesa->bufSize - gmesa->bufCount) / 2
#define GET_SUBSEQUENT_VB_MAX_VERTS() \
GAMMA_DMA_BUFFER_SIZE / 2
#define EMIT_VERTS( ctx, j, nr ) gamma_emit(ctx, j, (j)+(nr))
#define TAG(x) gamma_##x
#include "tnl_dd/t_dd_dmatmp.h"
static GLboolean gamma_run_render( GLcontext *ctx,
struct gl_pipeline_stage *stage )
{
gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint i, length, flags = 0;
render_func *tab;
if (VB->ClipOrMask || gmesa->RenderIndex != 0)
return GL_TRUE;
if (VB->Elts)
return GL_TRUE;
tab = TAG(render_tab_verts);
tnl->Driver.Render.Start( ctx );
for (i = VB->FirstPrimitive ; !(flags & PRIM_LAST) ; i += length)
{
flags = VB->Primitive[i];
length = VB->PrimitiveLength[i];
if (length)
tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags );
}
tnl->Driver.Render.Finish( ctx );
return GL_FALSE;
}
static void gamma_check_render( GLcontext *ctx,
struct gl_pipeline_stage *stage )
{
GLuint inputs = VERT_BIT_CLIP | VERT_BIT_COLOR0;
if (ctx->RenderMode == GL_RENDER) {
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
inputs |= VERT_BIT_COLOR1;
if (ctx->Texture.Unit[0]._ReallyEnabled)
inputs |= VERT_BIT_TEX0;
if (ctx->Texture.Unit[1]._ReallyEnabled)
inputs |= VERT_BIT_TEX1;
if (ctx->Fog.Enabled)
inputs |= VERT_BIT_FOG;
}
stage->inputs = inputs;
}
static void dtr( struct gl_pipeline_stage *stage )
{
(void)stage;
}
const struct gl_pipeline_stage _gamma_render_stage =
{
"gamma render",
(_DD_NEW_SEPARATE_SPECULAR |
_NEW_TEXTURE|
_NEW_FOG|
_NEW_RENDERMODE),
0,
GL_TRUE,
0, 0,
0, 0,
dtr,
gamma_check_render,
gamma_run_render
};