summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/glide/fxdd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/glide/fxdd.c')
-rw-r--r--src/mesa/drivers/glide/fxdd.c686
1 files changed, 405 insertions, 281 deletions
diff --git a/src/mesa/drivers/glide/fxdd.c b/src/mesa/drivers/glide/fxdd.c
index 3b58eb0535d..09844a6e2a8 100644
--- a/src/mesa/drivers/glide/fxdd.c
+++ b/src/mesa/drivers/glide/fxdd.c
@@ -2,7 +2,7 @@
* fxDDReadPixels888 does not convert 8A8R8G8B into 5R5G5B
*/
-/* $Id: fxdd.c,v 1.99 2003/08/19 15:52:53 brianp Exp $ */
+/* $Id: fxdd.c,v 1.100 2003/10/02 17:36:44 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -63,8 +63,6 @@
-float gl_ubyte_to_float_255_color_tab[256];
-
/* These lookup table are used to extract RGB values in [0,255] from
* 16-bit pixel values.
*/
@@ -72,6 +70,12 @@ GLubyte FX_PixelToR[0x10000];
GLubyte FX_PixelToG[0x10000];
GLubyte FX_PixelToB[0x10000];
+/* lookup table for scaling 4 bit colors up to 8 bits */
+GLuint FX_rgb_scale_4[16] = {
+ 0, 17, 34, 51, 68, 85, 102, 119,
+ 136, 153, 170, 187, 204, 221, 238, 255
+};
+
/* lookup table for scaling 5 bit colors up to 8 bits */
GLuint FX_rgb_scale_5[32] = {
0, 8, 16, 25, 33, 41, 49, 58,
@@ -80,6 +84,18 @@ GLuint FX_rgb_scale_5[32] = {
197, 206, 214, 222, 230, 239, 247, 255
};
+/* lookup table for scaling 6 bit colors up to 8 bits */
+GLuint FX_rgb_scale_6[64] = {
+ 0, 4, 8, 12, 16, 20, 24, 28,
+ 32, 36, 40, 45, 49, 53, 57, 61,
+ 65, 69, 73, 77, 81, 85, 89, 93,
+ 97, 101, 105, 109, 113, 117, 121, 125,
+ 130, 134, 138, 142, 146, 150, 154, 158,
+ 162, 166, 170, 174, 178, 182, 186, 190,
+ 194, 198, 202, 206, 210, 215, 219, 223,
+ 227, 231, 235, 239, 243, 247, 251, 255
+};
+
/*
* Initialize the FX_PixelTo{RGB} arrays.
@@ -120,22 +136,18 @@ fxInitPixelTables(fxMesaContext fxMesa, GLboolean bgrOrder)
/* Return buffer size information */
static void
-fxDDBufferSize(GLframebuffer *buffer, GLuint * width, GLuint * height)
+fxDDBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
{
GET_CURRENT_CONTEXT(ctx);
- if (ctx && ctx->DriverCtx) {
- fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
+ if (ctx && FX_CONTEXT(ctx)) {
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
- if (MESA_VERBOSE & VERBOSE_DRIVER) {
- fprintf(stderr, "fxmesa: fxDDBufferSize(...) Start\n");
+ if (TDFX_DEBUG & VERBOSE_DRIVER) {
+ fprintf(stderr, "%s(...)\n", __FUNCTION__);
}
*width = fxMesa->width;
*height = fxMesa->height;
-
- if (MESA_VERBOSE & VERBOSE_DRIVER) {
- fprintf(stderr, "fxmesa: fxDDBufferSize(...) End\n");
- }
}
}
@@ -144,11 +156,11 @@ fxDDBufferSize(GLframebuffer *buffer, GLuint * width, GLuint * height)
static void
fxDDClearColor(GLcontext * ctx, const GLfloat color[4])
{
- fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
GLubyte col[4];
- if (MESA_VERBOSE & VERBOSE_DRIVER) {
- fprintf(stderr, "fxmesa: fxDDClearColor(%f,%f,%f,%f)\n",
+ if (TDFX_DEBUG & VERBOSE_DRIVER) {
+ fprintf(stderr, "%s(%f, %f, %f, %f)\n", __FUNCTION__,
color[0], color[1], color[2], color[3]);
}
@@ -163,122 +175,264 @@ fxDDClearColor(GLcontext * ctx, const GLfloat color[4])
/* Clear the color and/or depth buffers */
-static void
-fxDDClear(GLcontext * ctx, GLbitfield mask, GLboolean all,
- GLint x, GLint y, GLint width, GLint height)
+static void fxDDClear( GLcontext *ctx,
+ GLbitfield mask, GLboolean all,
+ GLint x, GLint y, GLint width, GLint height )
{
- fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
- const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask);
- /* [dBorca] should use an adequate scaler for 16 vs 32bit (GR_ZDEPTH_MIN_MAX) */
- const FxU32 clearD = (FxU32) (ctx->Depth.Clear * 0x00ffffff);
- GLbitfield softwareMask = mask & (DD_STENCIL_BIT | DD_ACCUM_BIT);
-
- /* we can't clear stencil or accum buffers */
- mask &= ~(DD_STENCIL_BIT | DD_ACCUM_BIT);
-
- if (MESA_VERBOSE & VERBOSE_DRIVER) {
- fprintf(stderr, "fxmesa: fxDDClear(%d,%d,%d,%d)\n", (int) x, (int) y,
- (int) width, (int) height);
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ GLbitfield softwareMask = mask & (DD_ACCUM_BIT);
+ const GLuint stencil_size = fxMesa->haveHwStencil ? ctx->Visual.stencilBits : 0;
+ const FxU32 clearD = (FxU32) (((1 << ctx->Visual.depthBits) - 1) * ctx->Depth.Clear);
+ const FxU8 clearS = (FxU8) (ctx->Stencil.Clear & 0xff);
+
+ if ( TDFX_DEBUG & MESA_VERBOSE ) {
+ fprintf( stderr, "%s( %d, %d, %d, %d )\n",
+ __FUNCTION__, (int) x, (int) y, (int) width, (int) height );
}
- if (colorMask != 0xffffffff) {
- /* do masked color buffer clears in software */
- softwareMask |= (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT));
- mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT);
+/*jejeje*/
+ /* Need this check to respond to glScissor and clipping updates */
+ if (fxMesa->new_state & FX_NEW_SCISSOR) {
+ extern void fxSetupScissor(GLcontext * ctx);
+ fxSetupScissor(ctx);
}
- /*
- * This could probably be done fancier but doing each possible case
- * explicitly is less error prone.
- */
- switch (mask) {
- case DD_BACK_LEFT_BIT | DD_DEPTH_BIT:
- /* back buffer & depth */
- grDepthMask(FXTRUE);
- grRenderBuffer(GR_BUFFER_BACKBUFFER);
- FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
- if (!ctx->Depth.Mask) {
- grDepthMask(FXFALSE);
+ /* we can't clear accum buffers */
+ mask &= ~(DD_ACCUM_BIT);
+
+ if (mask & DD_STENCIL_BIT) {
+ if (!fxMesa->haveHwStencil || fxMesa->unitsState.stencilWriteMask != 0xff) {
+ /* Napalm seems to have trouble with stencil write masks != 0xff */
+ /* do stencil clear in software */
+ mask &= ~(DD_STENCIL_BIT);
+ softwareMask |= DD_STENCIL_BIT;
}
- break;
- case DD_FRONT_LEFT_BIT | DD_DEPTH_BIT:
- /* XXX it appears that the depth buffer isn't cleared when
- * glRenderBuffer(GR_BUFFER_FRONTBUFFER) is set.
- * This is a work-around/
+ }
+
+ if (ctx->Visual.greenBits != 8 && ctx->Visual.greenBits != 5) {
+ /* can only do color masking if running in 24/32bpp on Napalm */
+ if (ctx->Color.ColorMask[RCOMP] != ctx->Color.ColorMask[GCOMP] ||
+ ctx->Color.ColorMask[GCOMP] != ctx->Color.ColorMask[BCOMP]) {
+ softwareMask |= (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT));
+ mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT);
+ }
+ }
+
+ if (fxMesa->haveHwStencil) {
+ /*
+ * If we want to clear stencil, it must be enabled
+ * in the HW, even if the stencil test is not enabled
+ * in the OGL state.
*/
- /* clear depth */
- grDepthMask(FXTRUE);
- grRenderBuffer(GR_BUFFER_BACKBUFFER);
- grColorMask(FXFALSE, FXFALSE);
- FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
- /* clear front */
- grColorMask(FXTRUE, ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
- grRenderBuffer(GR_BUFFER_FRONTBUFFER);
- FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
- break;
- case DD_BACK_LEFT_BIT:
- /* back buffer only */
- grDepthMask(FXFALSE);
- grRenderBuffer(GR_BUFFER_BACKBUFFER);
- FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
- if (ctx->Depth.Mask) {
- grDepthMask(FXTRUE);
+ BEGIN_BOARD_LOCK();
+ if (mask & DD_STENCIL_BIT) {
+ fxMesa->Glide.grStencilMaskExt(0xff /*fxMesa->unitsState.stencilWriteMask*/);
+ /* set stencil ref value = desired clear value */
+ fxMesa->Glide.grStencilFuncExt(GR_CMP_ALWAYS, clearS, 0xff);
+ fxMesa->Glide.grStencilOpExt(GR_STENCILOP_REPLACE,
+ GR_STENCILOP_REPLACE, GR_STENCILOP_REPLACE);
+ grEnable(GR_STENCIL_MODE_EXT);
}
- break;
- case DD_FRONT_LEFT_BIT:
- /* front buffer only */
- grDepthMask(FXFALSE);
- grRenderBuffer(GR_BUFFER_FRONTBUFFER);
- FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
- if (ctx->Depth.Mask) {
- grDepthMask(FXTRUE);
+ else {
+ grDisable(GR_STENCIL_MODE_EXT);
}
- break;
- case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT:
- /* front and back */
- grDepthMask(FXFALSE);
- grRenderBuffer(GR_BUFFER_BACKBUFFER);
- FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
- grRenderBuffer(GR_BUFFER_FRONTBUFFER);
- FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
- if (ctx->Depth.Mask) {
+ END_BOARD_LOCK();
+ }
+
+ /*
+ * This may be ugly, but it's needed in order to work around a number
+ * of Glide bugs.
+ */
+ BEGIN_CLIP_LOOP();
+ {
+ /*
+ * This could probably be done fancier but doing each possible case
+ * explicitly is less error prone.
+ */
+ switch (mask & ~DD_STENCIL_BIT) {
+ case DD_BACK_LEFT_BIT | DD_DEPTH_BIT:
+ /* back buffer & depth */
+ fxColorMask(fxMesa, GL_TRUE); /* work around Voodoo3 bug */
grDepthMask(FXTRUE);
- }
- break;
- case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT | DD_DEPTH_BIT:
- /* clear front */
- grDepthMask(FXFALSE);
- grRenderBuffer(GR_BUFFER_FRONTBUFFER);
- FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
- /* clear back and depth */
- grDepthMask(FXTRUE);
- grRenderBuffer(GR_BUFFER_BACKBUFFER);
- FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
- if (!ctx->Depth.Mask) {
+ grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ if (stencil_size > 0) {
+ fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD, clearS);
+ }
+ else
+ grBufferClear(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD);
+ if (!ctx->Depth.Mask || !ctx->Depth.Test) {
+ grDepthMask(FXFALSE);
+ }
+ break;
+ case DD_FRONT_LEFT_BIT | DD_DEPTH_BIT:
+ /* XXX it appears that the depth buffer isn't cleared when
+ * glRenderBuffer(GR_BUFFER_FRONTBUFFER) is set.
+ * This is a work-around/
+ */
+ /* clear depth */
+ grDepthMask(FXTRUE);
+ grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ fxColorMask(fxMesa, GL_FALSE);
+ if (stencil_size > 0)
+ fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD, clearS);
+ else
+ grBufferClear(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD);
+ /* clear front */
+ fxColorMask(fxMesa, GL_TRUE);
+ grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+ if (stencil_size > 0)
+ fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD, clearS);
+ else
+ grBufferClear(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD);
+ if (!ctx->Depth.Mask || !ctx->Depth.Test) {
+ grDepthMask(FXFALSE);
+ }
+ break;
+ case DD_BACK_LEFT_BIT:
+ /* back buffer only */
grDepthMask(FXFALSE);
- }
- break;
- case DD_DEPTH_BIT:
- /* just the depth buffer */
- grRenderBuffer(GR_BUFFER_BACKBUFFER);
- grColorMask(FXFALSE, FXFALSE);
- grDepthMask(FXTRUE);
- FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
- grColorMask(FXTRUE, ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
- if (ctx->Color._DrawDestMask & FRONT_LEFT_BIT)
+ grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ if (stencil_size > 0)
+ fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD, clearS);
+ else
+ grBufferClear(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD);
+ if (ctx->Depth.Mask && ctx->Depth.Test) {
+ grDepthMask(FXTRUE);
+ }
+ break;
+ case DD_FRONT_LEFT_BIT:
+ /* front buffer only */
+ grDepthMask(FXFALSE);
+ grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+ if (stencil_size > 0)
+ fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD, clearS);
+ else
+ grBufferClear(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD);
+ if (ctx->Depth.Mask && ctx->Depth.Test) {
+ grDepthMask(FXTRUE);
+ }
+ break;
+ case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT:
+ /* front and back */
+ grDepthMask(FXFALSE);
+ grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ if (stencil_size > 0)
+ fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD, clearS);
+ else
+ grBufferClear(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD);
grRenderBuffer(GR_BUFFER_FRONTBUFFER);
- if (!ctx->Depth.Test || !ctx->Depth.Mask)
+ if (stencil_size > 0)
+ fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD, clearS);
+ else
+ grBufferClear(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD);
+ if (ctx->Depth.Mask && ctx->Depth.Test) {
+ grDepthMask(FXTRUE);
+ }
+ break;
+ case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT | DD_DEPTH_BIT:
+ /* clear front */
grDepthMask(FXFALSE);
- break;
- default:
- /* error */
- ;
+ grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+ if (stencil_size > 0)
+ fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD, clearS);
+ else
+ grBufferClear(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD);
+ /* clear back and depth */
+ grDepthMask(FXTRUE);
+ grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ if (stencil_size > 0)
+ fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD, clearS);
+ else
+ grBufferClear(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD);
+ if (!ctx->Depth.Mask || !ctx->Depth.Mask) {
+ grDepthMask(FXFALSE);
+ }
+ break;
+ case DD_DEPTH_BIT:
+ /* just the depth buffer */
+ grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ fxColorMask(fxMesa, GL_FALSE);
+ grDepthMask(FXTRUE);
+ if (stencil_size > 0)
+ fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD, clearS);
+ else
+ grBufferClear(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD);
+ fxColorMask(fxMesa, GL_TRUE);
+ if (ctx->Color._DrawDestMask & FRONT_LEFT_BIT)
+ grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+ if (!ctx->Depth.Test || !ctx->Depth.Mask)
+ grDepthMask(FXFALSE);
+ break;
+ default:
+ /* clear no color buffers or depth buffer but might clear stencil */
+ if (stencil_size > 0 && (mask & DD_STENCIL_BIT)) {
+ /* XXX need this RenderBuffer call to work around Glide bug */
+ grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ grDepthMask(FXFALSE);
+ fxColorMask(fxMesa, GL_FALSE);
+ fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
+ fxMesa->clearA,
+ clearD, clearS);
+ if (ctx->Depth.Mask && ctx->Depth.Test) {
+ grDepthMask(FXTRUE);
+ }
+ fxColorMask(fxMesa, GL_TRUE);
+ if (ctx->Color._DrawDestMask & FRONT_LEFT_BIT)
+ grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+ }
+ }
+ }
+ END_CLIP_LOOP();
+
+ if (fxMesa->haveHwStencil && (mask & DD_STENCIL_BIT)) {
+ /* We changed the stencil state above. Signal that we need to
+ * upload it again.
+ */
+ fxMesa->new_state |= FX_NEW_STENCIL;
}
- /* Clear any remaining buffers:
- */
if (softwareMask)
- _swrast_Clear(ctx, softwareMask, all, x, y, width, height);
+ _swrast_Clear( ctx, softwareMask, all, x, y, width, height );
}
@@ -287,10 +441,10 @@ fxDDClear(GLcontext * ctx, GLbitfield mask, GLboolean all,
static void
fxDDSetDrawBuffer(GLcontext * ctx, GLenum mode)
{
- fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
- if (MESA_VERBOSE & VERBOSE_DRIVER) {
- fprintf(stderr, "fxmesa: fxDDSetBuffer(%x)\n", (int) mode);
+ if (TDFX_DEBUG & VERBOSE_DRIVER) {
+ fprintf(stderr, "%s(%x)\n", __FUNCTION__, (int)mode);
}
if (mode == GL_FRONT_LEFT) {
@@ -302,7 +456,7 @@ fxDDSetDrawBuffer(GLcontext * ctx, GLenum mode)
grRenderBuffer(fxMesa->currentFB);
}
else if (mode == GL_NONE) {
- grColorMask(FXFALSE, FXFALSE);
+ fxColorMask(fxMesa, GL_FALSE);
}
else {
/* we'll need a software fallback */
@@ -323,7 +477,7 @@ fxDDDrawBitmap(GLcontext * ctx, GLint px, GLint py,
const struct gl_pixelstore_attrib *unpack,
const GLubyte * bitmap)
{
- fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
GrLfbInfo_t info;
FxU16 color;
const struct gl_pixelstore_attrib *finalUnpack;
@@ -409,9 +563,7 @@ fxDDDrawBitmap(GLcontext * ctx, GLint px, GLint py,
fxMesa->currentFB,
GR_LFBWRITEMODE_565,
GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
-#ifndef FX_SILENT
- fprintf(stderr, "fx Driver: error locking the linear frame buffer\n");
-#endif
+ fprintf(stderr, "%s: ERROR: locking the linear frame buffer\n", __FUNCTION__);
return;
}
@@ -493,7 +645,7 @@ fxDDReadPixels(GLcontext * ctx, GLint x, GLint y,
return;
}
else {
- fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
GrLfbInfo_t info;
BEGIN_BOARD_LOCK();
@@ -608,7 +760,7 @@ static void fxDDReadPixels555 (GLcontext * ctx,
return;
}
else {
- fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
GrLfbInfo_t info;
BEGIN_BOARD_LOCK();
@@ -719,7 +871,7 @@ static void fxDDReadPixels888 (GLcontext * ctx,
return;
}
else {
- fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
GrLfbInfo_t info;
BEGIN_BOARD_LOCK();
@@ -798,20 +950,11 @@ fxDDFinish(GLcontext * ctx)
static const GLubyte *
fxDDGetString(GLcontext * ctx, GLenum name)
{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+
switch (name) {
case GL_RENDERER:
- {
- static char buf[80];
- GrVoodooConfig_t *vc = &glbHWConfig.SSTs[glbCurrentBoard].VoodooConfig;
- sprintf(buf, "Mesa %s v0.31 %s %dMB FB, %dMB TM, %d TMU, %s",
- grGetString(GR_RENDERER),
- grGetString(GR_HARDWARE),
- vc->fbRam,
- (vc->tmuConfig[GR_TMU0].tmuRam + ((vc->nTexelfx > 1) ? vc->tmuConfig[GR_TMU1].tmuRam : 0)),
- (vc->nTexelfx * vc->numChips),
- (vc->numChips > 1) ? "SLI" : "NOSLI");
- return (GLubyte *)buf;
- }
+ return (GLubyte *)fxMesa->rendererString;
default:
return NULL;
}
@@ -821,10 +964,10 @@ static const struct gl_pipeline_stage *fx_pipeline[] = {
&_tnl_vertex_transform_stage, /* TODO: Add the fastpath here */
&_tnl_normal_transform_stage,
&_tnl_lighting_stage,
- &_tnl_fog_coordinate_stage, /* TODO: Omit fog stage */
+ /*&_tnl_fog_coordinate_stage,*/ /* TODO: Omit fog stage ZZZ ZZZ ZZZ */
&_tnl_texgen_stage,
&_tnl_texture_transform_stage,
- &_tnl_point_attenuation_stage,
+ /*&_tnl_point_attenuation_stage,*/ /* TODO: For AA primitives ZZZ ZZZ ZZZ */
&_tnl_render_stage,
0,
};
@@ -836,31 +979,10 @@ int
fxDDInitFxMesaContext(fxMesaContext fxMesa)
{
int i;
-
- for (i = 0; i < 256; i++) {
- gl_ubyte_to_float_255_color_tab[i] = (float) i;
- }
+ GLcontext *ctx = fxMesa->glCtx;
FX_setupGrVertexLayout();
- if (getenv("FX_EMULATE_SINGLE_TMU"))
- fxMesa->haveTwoTMUs = GL_FALSE;
-
- if (getenv("FX_GLIDE_SWAPINTERVAL"))
- fxMesa->swapInterval = atoi(getenv("FX_GLIDE_SWAPINTERVAL"));
- else
- fxMesa->swapInterval = 1;
-
- if (getenv("MESA_FX_SWAP_PENDING"))
- fxMesa->maxPendingSwapBuffers = atoi(getenv("MESA_FX_SWAP_PENDING"));
- else
- fxMesa->maxPendingSwapBuffers = 2;
-
- if (getenv("MESA_FX_INFO"))
- fxMesa->verbose = GL_TRUE;
- else
- fxMesa->verbose = GL_FALSE;
-
fxMesa->color = 0xffffffff;
fxMesa->clearC = 0;
fxMesa->clearA = 0;
@@ -877,7 +999,7 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa)
/* FX units setup */
fxMesa->unitsState.alphaTestEnabled = GL_FALSE;
- fxMesa->unitsState.alphaTestFunc = GR_CMP_ALWAYS;
+ fxMesa->unitsState.alphaTestFunc = GL_ALWAYS;
fxMesa->unitsState.alphaTestRefValue = 0.0;
fxMesa->unitsState.blendEnabled = GL_FALSE;
@@ -888,9 +1010,12 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa)
fxMesa->unitsState.depthTestEnabled = GL_FALSE;
fxMesa->unitsState.depthMask = GL_TRUE;
- fxMesa->unitsState.depthTestFunc = GR_CMP_LESS;
+ fxMesa->unitsState.depthTestFunc = GL_LESS;
+ fxMesa->unitsState.depthBias = 0;
- grColorMask(FXTRUE, fxMesa->haveAlphaBuffer ? FXTRUE : FXFALSE);
+ fxMesa->unitsState.stencilWriteMask = 0xff;
+
+ fxColorMask(fxMesa, GL_TRUE);
if (fxMesa->haveDoubleBuffer) {
fxMesa->currentFB = GR_BUFFER_BACKBUFFER;
grRenderBuffer(GR_BUFFER_BACKBUFFER);
@@ -900,15 +1025,15 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa)
grRenderBuffer(GR_BUFFER_FRONTBUFFER);
}
- fxMesa->state = malloc(FX_grGetInteger(GR_GLIDE_STATE_SIZE));
- fxMesa->fogTable = (GrFog_t *) malloc(FX_grGetInteger(GR_FOG_TABLE_ENTRIES) *
+ fxMesa->state = MALLOC(FX_grGetInteger(GR_GLIDE_STATE_SIZE));
+ fxMesa->fogTable = (GrFog_t *) MALLOC(FX_grGetInteger(GR_FOG_TABLE_ENTRIES) *
sizeof(GrFog_t));
if (!fxMesa->state || !fxMesa->fogTable) {
if (fxMesa->state)
- free(fxMesa->state);
+ FREE(fxMesa->state);
if (fxMesa->fogTable)
- free(fxMesa->fogTable);
+ FREE(fxMesa->fogTable);
return 0;
}
@@ -920,42 +1045,50 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa)
fxMesa->textureAlign = FX_grGetInteger(GR_TEXTURE_ALIGN);
/* [koolsmoky] */
{
- int textureSize = ((fxMesa->maxTextureSize > 2048) ? 2048 : fxMesa->maxTextureSize);
- fxMesa->glCtx->Const.MaxTextureLevels = 0;
+ int textureLevels = 0;
+ int textureSize = FX_grGetInteger(GR_MAX_TEXTURE_SIZE);
do {
- fxMesa->glCtx->Const.MaxTextureLevels++;
+ textureLevels++;
} while ((textureSize >>= 0x1) & 0x7ff);
+ ctx->Const.MaxTextureLevels = textureLevels;
}
- fxMesa->glCtx->Const.MaxTextureUnits = fxMesa->haveTwoTMUs ? 2 : 1;
+ ctx->Const.MaxTextureCoordUnits = fxMesa->haveTwoTMUs ? 2 : 1;
+ ctx->Const.MaxTextureImageUnits = fxMesa->haveTwoTMUs ? 2 : 1;
+ ctx->Const.MaxTextureUnits = MAX2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits);
+
fxMesa->new_state = _NEW_ALL;
+ if (!fxMesa->haveHwStencil) {
+ /* don't touch stencil if there is none */
+ fxMesa->new_state &= ~FX_NEW_STENCIL;
+ }
/* Initialize the software rasterizer and helper modules.
*/
- _swrast_CreateContext(fxMesa->glCtx);
- _ac_CreateContext(fxMesa->glCtx);
- _tnl_CreateContext(fxMesa->glCtx);
- _swsetup_CreateContext(fxMesa->glCtx);
+ _swrast_CreateContext(ctx);
+ _ac_CreateContext(ctx);
+ _tnl_CreateContext(ctx);
+ _swsetup_CreateContext(ctx);
/* Install customized pipeline */
- _tnl_destroy_pipeline(fxMesa->glCtx);
- _tnl_install_pipeline(fxMesa->glCtx, fx_pipeline);
+ _tnl_destroy_pipeline(ctx);
+ _tnl_install_pipeline(ctx, fx_pipeline);
- fxAllocVB(fxMesa->glCtx);
+ fxAllocVB(ctx);
- fxSetupDDPointers(fxMesa->glCtx);
- fxDDInitTriFuncs(fxMesa->glCtx);
+ fxSetupDDPointers(ctx);
+ fxDDInitTriFuncs(ctx);
/* Tell the software rasterizer to use pixel fog always.
*/
- _swrast_allow_vertex_fog(fxMesa->glCtx, GL_FALSE);
- _swrast_allow_pixel_fog(fxMesa->glCtx, GL_TRUE);
+ _swrast_allow_vertex_fog(ctx, GL_FALSE);
+ _swrast_allow_pixel_fog(ctx, GL_TRUE);
/* Tell tnl not to calculate or use vertex fog factors. (Needed to
* tell render stage not to clip fog coords).
*/
-/* _tnl_calculate_vertex_fog( fxMesa->glCtx, GL_FALSE ); */
+/* _tnl_calculate_vertex_fog( ctx, GL_FALSE ); */
- fxDDInitExtensions(fxMesa->glCtx);
+ fxDDInitExtensions(ctx);
grGlideGetState((GrState *) fxMesa->state);
@@ -973,9 +1106,9 @@ fxDDDestroyFxMesaContext(fxMesaContext fxMesa)
_swrast_DestroyContext(fxMesa->glCtx);
if (fxMesa->state)
- free(fxMesa->state);
+ FREE(fxMesa->state);
if (fxMesa->fogTable)
- free(fxMesa->fogTable);
+ FREE(fxMesa->fogTable);
fxTMClose(fxMesa);
fxFreeVB(fxMesa->glCtx);
}
@@ -986,7 +1119,7 @@ fxDDDestroyFxMesaContext(fxMesaContext fxMesa)
void
fxDDInitExtensions(GLcontext * ctx)
{
- fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
/*_mesa_add_extension(ctx, GL_TRUE, "3DFX_set_global_palette", 0);*/
_mesa_enable_extension(ctx, "GL_EXT_point_parameters");
@@ -994,11 +1127,32 @@ fxDDInitExtensions(GLcontext * ctx)
_mesa_enable_extension(ctx, "GL_EXT_texture_lod_bias");
_mesa_enable_extension(ctx, "GL_EXT_shared_texture_palette");
- if (fxMesa->haveTwoTMUs)
+ if (fxMesa->haveTwoTMUs) {
_mesa_enable_extension(ctx, "GL_EXT_texture_env_add");
-
- if (fxMesa->haveTwoTMUs)
_mesa_enable_extension(ctx, "GL_ARB_multitexture");
+ }
+
+ if (fxMesa->haveHwStencil) {
+ _mesa_enable_extension( ctx, "GL_EXT_stencil_wrap" );
+ }
+
+#if 0 /* not ready yet */
+ /* banshee/avenger should enable this for NCC */
+ _mesa_enable_extension( ctx, "GL_ARB_texture_compression" );
+#endif
+ if (0/*IS_NAPALM*/) {
+ /* tex_compress: not ready yet */
+ _mesa_enable_extension( ctx, "GL_3DFX_texture_compression_FXT1" );
+ _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
+ /*_mesa_enable_extension( ctx, "GL_S3_s3tc" );*/
+
+ /* env_combine: not ready yet */
+ /*_mesa_enable_extension( ctx, "GL_EXT_texture_env_combine" );*/
+ }
+
+ if (fxMesa->HaveMirExt) {
+ _mesa_enable_extension(ctx, "GL_ARB_texture_mirrored_repeat");
+ }
}
@@ -1010,38 +1164,52 @@ fxDDInitExtensions(GLcontext * ctx)
*
* Performs similar work to fxDDChooseRenderState() - should be merged.
*/
-GLboolean
+GLuint
fx_check_IsInHardware(GLcontext * ctx)
{
- fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
- if (ctx->RenderMode != GL_RENDER)
- return GL_FALSE;
+ if (ctx->RenderMode != GL_RENDER) {
+ return FX_FALLBACK_RENDER_MODE;
+ }
- if (ctx->Stencil.Enabled ||
- (ctx->Color._DrawDestMask != FRONT_LEFT_BIT &&
- ctx->Color._DrawDestMask != BACK_LEFT_BIT) ||
- ((ctx->Color.BlendEnabled)
- && (ctx->Color.BlendEquation != GL_FUNC_ADD_EXT))
- || ((ctx->Color.ColorLogicOpEnabled)
- && (ctx->Color.LogicOp != GL_COPY))
- || (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
+ if (ctx->Stencil.Enabled && !fxMesa->haveHwStencil) {
+ return FX_FALLBACK_STENCIL;
+ }
+
+ if (ctx->Color._DrawDestMask != FRONT_LEFT_BIT && ctx->Color._DrawDestMask != BACK_LEFT_BIT) {
+ return FX_FALLBACK_DRAW_BUFFER;
+ }
+
+ if (ctx->Color.BlendEnabled && (ctx->Color.BlendEquation != GL_FUNC_ADD_EXT)) {
+ return FX_FALLBACK_BLEND;
+ }
+
+ if (ctx->Color.ColorLogicOpEnabled && (ctx->Color.LogicOp != GL_COPY)) {
+ return FX_FALLBACK_LOGICOP;
+ }
+
+ if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) {
+ return FX_FALLBACK_SPECULAR;
+ }
+
+ if ((ctx->Color.ColorMask[RCOMP] != ctx->Color.ColorMask[GCOMP])
||
- (!((ctx->
- Color.ColorMask[RCOMP] == ctx->Color.ColorMask[GCOMP])
- && (ctx->Color.ColorMask[GCOMP] == ctx->Color.ColorMask[BCOMP])
- && (ctx->Color.ColorMask[ACOMP] == ctx->Color.ColorMask[ACOMP])))
+ (ctx->Color.ColorMask[GCOMP] != ctx->Color.ColorMask[BCOMP])
+ ||
+ (ctx->Color.ColorMask[BCOMP] != ctx->Color.ColorMask[ACOMP])
) {
- return GL_FALSE;
+ return FX_FALLBACK_COLORMASK;
}
+
/* Unsupported texture/multitexture cases */
if (fxMesa->haveTwoTMUs) {
/* we can only do 2D textures */
if (ctx->Texture.Unit[0]._ReallyEnabled & ~TEXTURE_2D_BIT)
- return GL_FALSE;
+ return FX_FALLBACK_TEXTURE_1D_3D;
if (ctx->Texture.Unit[1]._ReallyEnabled & ~TEXTURE_2D_BIT)
- return GL_FALSE;
+ return FX_FALLBACK_TEXTURE_1D_3D;
if (ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_2D_BIT) {
if (ctx->Texture.Unit[0].EnvMode == GL_BLEND &&
@@ -1050,21 +1218,21 @@ fx_check_IsInHardware(GLcontext * ctx)
ctx->Texture.Unit[0].EnvColor[1] != 0 ||
ctx->Texture.Unit[0].EnvColor[2] != 0 ||
ctx->Texture.Unit[0].EnvColor[3] != 1)) {
- return GL_FALSE;
+ return FX_FALLBACK_TEXTURE_ENV;
}
if (ctx->Texture.Unit[0]._Current->Image[0]->Border > 0)
- return GL_FALSE;
+ return FX_FALLBACK_TEXTURE_BORDER;
}
if (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_2D_BIT) {
if (ctx->Texture.Unit[1].EnvMode == GL_BLEND)
- return GL_FALSE;
+ return FX_FALLBACK_TEXTURE_ENV;
if (ctx->Texture.Unit[1]._Current->Image[0]->Border > 0)
- return GL_FALSE;
+ return FX_FALLBACK_TEXTURE_BORDER;
}
- if (MESA_VERBOSE & (VERBOSE_DRIVER | VERBOSE_TEXTURE))
- fprintf(stderr, "fxMesa: fxIsInHardware, envmode is %s/%s\n",
+ if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE))
+ fprintf(stderr, "%s: envmode is %s/%s\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(ctx->Texture.Unit[0].EnvMode),
_mesa_lookup_enum_by_nr(ctx->Texture.Unit[1].EnvMode));
@@ -1078,96 +1246,51 @@ fx_check_IsInHardware(GLcontext * ctx)
* back to software.
*/
if (!fxMesa->haveTwoTMUs && ctx->Color.BlendEnabled) {
- return GL_FALSE;
+ return FX_FALLBACK_TEXTURE_MULTI;
}
if ((ctx->Texture.Unit[0].EnvMode != ctx->Texture.Unit[1].EnvMode) &&
(ctx->Texture.Unit[0].EnvMode != GL_MODULATE) &&
(ctx->Texture.Unit[0].EnvMode != GL_REPLACE)) { /* q2, seems ok... */
- if (MESA_VERBOSE & VERBOSE_DRIVER)
- fprintf(stderr, "fxMesa: unsupported multitex env mode\n");
- return GL_FALSE;
+ if (TDFX_DEBUG & VERBOSE_DRIVER)
+ fprintf(stderr, "%s: unsupported multitex env mode\n", __FUNCTION__);
+ return FX_FALLBACK_TEXTURE_MULTI;
}
}
}
else {
/* we have just one texture unit */
if (ctx->Texture._EnabledUnits > 0x1) {
- return GL_FALSE;
+ return FX_FALLBACK_TEXTURE_MULTI;
}
if ((ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_2D_BIT) &&
(ctx->Texture.Unit[0].EnvMode == GL_BLEND)) {
- return GL_FALSE;
+ return FX_FALLBACK_TEXTURE_ENV;
}
}
- return GL_TRUE;
+ return 0;
}
static void
-update_texture_scales(GLcontext * ctx)
-{
- fxMesaContext fxMesa = FX_CONTEXT(ctx);
- struct gl_texture_unit *t0 = &ctx->Texture.Unit[fxMesa->tmu_source[0]];
- struct gl_texture_unit *t1 = &ctx->Texture.Unit[fxMesa->tmu_source[1]];
-
- if (t0 && t0->_Current && FX_TEXTURE_DATA(t0)) {
- fxMesa->s0scale = FX_TEXTURE_DATA(t0)->sScale;
- fxMesa->t0scale = FX_TEXTURE_DATA(t0)->tScale;
- fxMesa->inv_s0scale = 1.0 / fxMesa->s0scale;
- fxMesa->inv_t0scale = 1.0 / fxMesa->t0scale;
- }
-
- if (t1 && t1->_Current && FX_TEXTURE_DATA(t1)) {
- fxMesa->s1scale = FX_TEXTURE_DATA(t1)->sScale;
- fxMesa->t1scale = FX_TEXTURE_DATA(t1)->tScale;
- fxMesa->inv_s1scale = 1.0 / fxMesa->s1scale;
- fxMesa->inv_t1scale = 1.0 / fxMesa->t1scale;
- }
-}
-
-static void
fxDDUpdateDDPointers(GLcontext * ctx, GLuint new_state)
{
/* TNLcontext *tnl = TNL_CONTEXT(ctx);*/
fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ if (TDFX_DEBUG & VERBOSE_DRIVER) {
+ fprintf(stderr, "fxDDUpdateDDPointers(%08x)\n", new_state);
+ }
+
_swrast_InvalidateState(ctx, new_state);
_ac_InvalidateState(ctx, new_state);
_tnl_InvalidateState(ctx, new_state);
_swsetup_InvalidateState(ctx, new_state);
- /* Recalculate fog table on projection matrix changes. This used to
- * be triggered by the NearFar callback.
- */
- if (new_state & _NEW_PROJECTION)
- fxMesa->new_state |= FX_NEW_FOG;
-
- if (new_state & (_FX_NEW_IS_IN_HARDWARE |
- _FX_NEW_RENDERSTATE |
- _FX_NEW_SETUP_FUNCTION |
- _NEW_TEXTURE)) {
-
- if (new_state & _FX_NEW_IS_IN_HARDWARE)
- fxCheckIsInHardware(ctx);
-
- if (fxMesa->new_state)
- fxSetupFXUnits(ctx);
-
- if (fxMesa->is_in_hardware) {
- if (new_state & _FX_NEW_RENDERSTATE)
- fxDDChooseRenderState(ctx);
-
- if (new_state & _FX_NEW_SETUP_FUNCTION)
- fxChooseVertexState(ctx);
- }
-
- if (new_state & _NEW_TEXTURE)
- update_texture_scales(ctx);
- }
+ fxMesa->new_gl_state |= new_state;
}
@@ -1176,10 +1299,11 @@ fxDDUpdateDDPointers(GLcontext * ctx, GLuint new_state)
void
fxSetupDDPointers(GLcontext * ctx)
{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
- if (MESA_VERBOSE & VERBOSE_DRIVER) {
- fprintf(stderr, "fxmesa: fxSetupDDPointers()\n");
+ if (TDFX_DEBUG & VERBOSE_DRIVER) {
+ fprintf(stderr, "%s()\n", __FUNCTION__);
}
ctx->Driver.UpdateState = fxDDUpdateDDPointers;
@@ -1193,8 +1317,6 @@ fxSetupDDPointers(GLcontext * ctx)
ctx->Driver.Bitmap = fxDDDrawBitmap;
ctx->Driver.CopyPixels = _swrast_CopyPixels;
ctx->Driver.DrawPixels = _swrast_DrawPixels;
- {
- fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
switch (fxMesa->colDepth) {
case 15:
ctx->Driver.ReadPixels = fxDDReadPixels555;
@@ -1206,7 +1328,6 @@ fxSetupDDPointers(GLcontext * ctx)
ctx->Driver.ReadPixels = fxDDReadPixels888;
break;
}
- }
ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
ctx->Driver.Finish = fxDDFinish;
ctx->Driver.Flush = NULL;
@@ -1249,8 +1370,11 @@ fxSetupDDPointers(GLcontext * ctx)
ctx->Driver.CullFace = fxDDCullFace;
ctx->Driver.ShadeModel = fxDDShadeModel;
ctx->Driver.Enable = fxDDEnable;
-
- tnl->Driver.RunPipeline = _tnl_run_pipeline;
+ if (fxMesa->haveHwStencil) {
+ ctx->Driver.StencilFunc = fxDDStencilFunc;
+ ctx->Driver.StencilMask = fxDDStencilMask;
+ ctx->Driver.StencilOp = fxDDStencilOp;
+ }
fxSetupDDSpanPointers(ctx);
fxDDUpdateDDPointers(ctx, ~0);