#include "xmlpool.h"
+/* Savage4, ProSavage[DDR], SuperSavage watermarks */
+#define S4_ZRLO 24
+#define S4_ZRHI 24
+#define S4_ZWLO 0
+#define S4_ZWHI 0
+
+#define S4_DRLO 0
+#define S4_DRHI 0
+#define S4_DWLO 0
+#define S4_DWHI 0
+
+#define S4_TR 15
+
+/* Savage3D/MX/IX watermarks */
+#define S3D_ZRLO 8
+#define S3D_ZRHI 24
+#define S3D_ZWLO 0
+#define S3D_ZWHI 24
+
+#define S3D_DRLO 0
+#define S3D_DRHI 0
+#define S3D_DWLO 0
+#define S3D_DWHI 0
+
+#define S3D_TR 15
+
static void savageBlendFunc_s4(GLcontext *);
static void savageBlendFunc_s3d(GLcontext *);
* test, and shading model)
*/
- imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = 0;
+ imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_FALSE;
/*
* blend modes
imesa->regs.s4.zBufCtrl.ni.zCmpFunc = zmode;
imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = ctx->Depth.Mask;
imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_TRUE;
-#if 1
- imesa->regs.s4.zWatermarks.ni.wLow = 0;
-#endif
-
imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_TRUE;
}
else if (imesa->glCtx->Stencil.Enabled && imesa->hw_stencil)
imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_TRUE;
imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = GL_FALSE;
imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE;
- imesa->regs.s4.zWatermarks.ni.wLow = 8;
}
else
{
}
imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = GL_FALSE;
imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE;
- imesa->regs.s4.zWatermarks.ni.wLow = 8;
}
if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui)
imesa->regs.s3d.zBufCtrl.ni.zUpdateEn = ctx->Depth.Mask;
imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE;
-#if 1
- imesa->regs.s3d.zWatermarks.ni.wLow = 0;
-#endif
}
else
{
}
imesa->regs.s3d.zBufCtrl.ni.zUpdateEn = GL_FALSE;
imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_FALSE;
- imesa->regs.s3d.zWatermarks.ni.wLow = 8;
}
if (drawCtrl != imesa->regs.s3d.drawCtrl.ui ||
static void savageDDDepthMask_s4(GLcontext *ctx, GLboolean flag)
{
- savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
- u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui;
-
- if (flag)
- {
- imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_TRUE;
- }
- else
- {
- imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE;
- }
savageDDDepthFunc_s4(ctx,ctx->Depth.Func);
-
- if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui)
- imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
}
static void savageDDDepthMask_s3d(GLcontext *ctx, GLboolean flag)
{
- savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
- u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui;
-
- if (flag)
- {
- imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE;
- }
- else
- {
- imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_FALSE;
- }
savageDDDepthFunc_s3d(ctx,ctx->Depth.Func);
-
- if (drawCtrl != imesa->regs.s3d.drawCtrl.ui)
- imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
}
static void savageDDScissor( GLcontext *ctx, GLint x, GLint y,
GLsizei w, GLsizei h )
-{
+{
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
- imesa->scissor_rect.x1 = MAX2(imesa->drawX+x,imesa->draw_rect.x1);
- imesa->scissor_rect.y1 = MAX2(imesa->drawY+imesa->driDrawable->h -(y+h),
- imesa->draw_rect.y1);
- imesa->scissor_rect.x2 = MIN2(imesa->drawX+x+w,imesa->draw_rect.x2);
- imesa->scissor_rect.y2 = MIN2(imesa->drawY+imesa->driDrawable->h - y,
- imesa->draw_rect.y2);
-
- imesa->scissorChanged=GL_TRUE;
+ /* Emit buffered commands with old scissor state. */
+ FLUSH_BATCH(imesa);
- imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS;
+ /* Mirror scissors in private context. */
+ imesa->scissor.enabled = ctx->Scissor.Enabled;
+ imesa->scissor.x = x;
+ imesa->scissor.y = y;
+ imesa->scissor.w = w;
+ imesa->scissor.h = h;
}
/*
* _DrawDestMask is easier to cope with than <mode>.
*/
- switch ( ctx->Color._DrawDestMask[0] ) {
- case DD_FRONT_LEFT_BIT:
+ switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) {
+ case BUFFER_BIT_FRONT_LEFT:
imesa->IsDouble = GL_FALSE;
-
- imesa->drawMap = (char *)imesa->apertureBase[TARGET_FRONT];
- imesa->readMap = (char *)imesa->apertureBase[TARGET_FRONT];
imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->frontOffset>>11;
+
imesa->NotFirstFrame = GL_FALSE;
savageXMesaSetFrontClipRects( imesa );
FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_FALSE );
break;
- case DD_BACK_LEFT_BIT:
+ case BUFFER_BIT_BACK_LEFT:
imesa->IsDouble = GL_TRUE;
- imesa->drawMap = (char *)imesa->apertureBase[TARGET_BACK];
- imesa->readMap = (char *)imesa->apertureBase[TARGET_BACK];
imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->backOffset>>11;
imesa->NotFirstFrame = GL_FALSE;
savageXMesaSetBackClipRects( imesa );
* Window position and viewport transformation
*/
-static void savageCalcViewport( GLcontext *ctx )
+void savageCalcViewport( GLcontext *ctx )
{
savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
const GLfloat *v = ctx->Viewport._WindowMap.m;
* Color masks
*/
-/* Mesa calls this from the wrong place - it is called a very large
- * number of redundant times.
- *
- * Colormask can be simulated by multipass or multitexture techniques.
+/* Savage4 can disable draw updates when all channels are
+ * masked. Savage3D has a bit called drawUpdateEn, but it doesn't seem
+ * to have any effect. If only some channels are masked we need a
+ * software fallback on all chips.
*/
static void savageDDColorMask_s4(GLcontext *ctx,
GLboolean r, GLboolean g,
GLboolean b, GLboolean a )
{
savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
- GLuint enable;
+ GLboolean passAny, passAll;
- if (ctx->Visual.alphaBits)
- {
- enable = b | g | r | a;
- }
- else
- {
- enable = b | g | r;
+ if (ctx->Visual.alphaBits) {
+ passAny = b || g || r || a;
+ passAll = r && g && b && a;
+ } else {
+ passAny = b || g || r;
+ passAll = r && g && b;
}
- if (enable)
- {
- imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn = GL_TRUE;
- }
- else
- {
+ if (passAny) {
+ if (!imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn) {
+ imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn = GL_TRUE;
+ imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
+ }
+ FALLBACK (ctx, SAVAGE_FALLBACK_COLORMASK, !passAll);
+ } else if (imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn) {
imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn = GL_FALSE;
+ imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
}
- imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
- /* TODO: need a software fallback */
}
static void savageDDColorMask_s3d(GLcontext *ctx,
GLboolean r, GLboolean g,
GLboolean b, GLboolean a )
{
- savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
- GLuint enable;
-
if (ctx->Visual.alphaBits)
- {
- enable = b | g | r | a;
- }
+ FALLBACK (ctx, SAVAGE_FALLBACK_COLORMASK, !(r && g && b && a));
else
- {
- enable = b | g | r;
- }
-
- if (enable)
- {
- imesa->regs.s3d.zBufCtrl.ni.drawUpdateEn = GL_TRUE;
- }
- else
- {
- imesa->regs.s3d.zBufCtrl.ni.drawUpdateEn = GL_FALSE;
- }
- imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
- /* TODO: need a software fallback */
+ FALLBACK (ctx, SAVAGE_FALLBACK_COLORMASK, !(r && g && b));
}
/* Seperate specular not fully implemented in hardware... Needs
savageBlendFunc_s4(ctx);
break;
case GL_BLEND:
- /*Can't find Enable bit in the 3D registers.*/
- /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
- */
- FALLBACK (ctx, SAVAGE_FALLBACK_LOGICOP,
- (ctx->Color.ColorLogicOpEnabled &&
- ctx->Color.LogicOp != GL_COPY));
/*add the savageBlendFunc 2001/11/25
* if call no such function, then glDisable(GL_BLEND) will do noting,
*our chip has no disable bit
*/
savageBlendFunc_s4(ctx);
+ case GL_COLOR_LOGIC_OP:
+ /* Fall through:
+ * For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
+ */
+ FALLBACK (ctx, SAVAGE_FALLBACK_LOGICOP,
+ (ctx->Color.ColorLogicOpEnabled &&
+ ctx->Color.LogicOp != GL_COPY));
break;
case GL_DEPTH_TEST:
savageDDDepthFunc_s4(ctx,ctx->Depth.Func);
break;
case GL_SCISSOR_TEST:
- imesa->scissor = state;
- imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS;
savageDDScissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
ctx->Scissor.Width, ctx->Scissor.Height);
break;
savageBlendFunc_s3d(ctx);
break;
case GL_BLEND:
- /*Can't find Enable bit in the 3D registers.*/
- /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
- */
- FALLBACK (ctx, SAVAGE_FALLBACK_LOGICOP,
- (ctx->Color.ColorLogicOpEnabled &&
- ctx->Color.LogicOp != GL_COPY));
/*add the savageBlendFunc 2001/11/25
* if call no such function, then glDisable(GL_BLEND) will do noting,
*our chip has no disable bit
*/
savageBlendFunc_s3d(ctx);
+ case GL_COLOR_LOGIC_OP:
+ /* Fall through:
+ * For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
+ */
+ FALLBACK (ctx, SAVAGE_FALLBACK_LOGICOP,
+ (ctx->Color.ColorLogicOpEnabled &&
+ ctx->Color.LogicOp != GL_COPY));
break;
case GL_DEPTH_TEST:
savageDDDepthFunc_s3d(ctx,ctx->Depth.Func);
break;
case GL_SCISSOR_TEST:
- imesa->scissor = state;
- imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS;
savageDDScissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
ctx->Scissor.Width, ctx->Scissor.Height);
break;
}
-void savageEmitDrawingRectangle( savageContextPtr imesa )
-{
- __DRIdrawablePrivate *dPriv = imesa->driDrawable;
- savageScreenPrivate *savageScreen = imesa->savageScreen;
- drm_clip_rect_t *pbox;
- int nbox;
-
-
- int x0 = imesa->drawX;
- int y0 = imesa->drawY;
- int x1 = x0 + dPriv->w;
- int y1 = y0 + dPriv->h;
-
- pbox = dPriv->pClipRects;
- nbox = dPriv->numClipRects;
-
-
-
- /* Coordinate origin of the window - may be offscreen.
- */
- /* imesa->BufferSetup[SAVAGE_DESTREG_DR4] = ((y0<<16) |
- (((unsigned)x0)&0xFFFF));*/
-
- /* Clip to screen.
- */
- if (x0 < 0) x0 = 0;
- if (y0 < 0) y0 = 0;
- if (x1 > savageScreen->width) x1 = savageScreen->width;
- if (y1 > savageScreen->height) y1 = savageScreen->height;
-
-
- if(nbox == 1)
- {
- imesa->draw_rect.x1 = MAX2(x0,pbox->x1);
- imesa->draw_rect.y1 = MAX2(y0,pbox->y1);
- imesa->draw_rect.x2 = MIN2(x1,pbox->x2);
- imesa->draw_rect.y2 = MIN2(y1,pbox->y2);
- }
- else
- {
- imesa->draw_rect.x1 = x0;
- imesa->draw_rect.y1 = y0;
- imesa->draw_rect.x2 = x1;
- imesa->draw_rect.y2 = y1;
- }
-
- imesa->scissorChanged = GL_TRUE;
-
- /* imesa->regs.ni.changed.ni.fDrawCtrl0Changed=GL_TRUE;
- imesa->regs.ni.changed.ni.fDrawCtrl1Changed=GL_TRUE;*/
-
- savageCalcViewport (imesa->glCtx);
-}
-
-
static void savageDDPrintDirty( const char *msg, GLuint state )
{
- fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s\n",
+ fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s\n",
msg,
(unsigned int) state,
(state & SAVAGE_UPLOAD_LOCAL) ? "upload-local, " : "",
(state & SAVAGE_UPLOAD_TEX1) ? "upload-tex1, " : "",
(state & SAVAGE_UPLOAD_FOGTBL) ? "upload-fogtbl, " : "",
(state & SAVAGE_UPLOAD_GLOBAL) ? "upload-global, " : "",
- (state & SAVAGE_UPLOAD_TEXGLOBAL) ? "upload-texglobal, " : "",
- (state & SAVAGE_UPLOAD_CLIPRECTS) ? "upload-cliprects, " : ""
+ (state & SAVAGE_UPLOAD_TEXGLOBAL) ? "upload-texglobal, " : ""
);
}
}
static void savageUpdateRegister_s4(savageContextPtr imesa)
{
- /*
- * Scissors updates drawctrl0 and drawctrl 1
- */
- if (imesa->scissorChanged && imesa->savageScreen->driScrnPriv->drmMinor < 1)
- {
- if(imesa->scissor)
- {
- imesa->regs.s4.drawCtrl0.ni.scissorXStart = imesa->scissor_rect.x1;
- imesa->regs.s4.drawCtrl0.ni.scissorYStart = imesa->scissor_rect.y1;
- imesa->regs.s4.drawCtrl1.ni.scissorXEnd = imesa->scissor_rect.x2-1;
- imesa->regs.s4.drawCtrl1.ni.scissorYEnd = imesa->scissor_rect.y2-1;
- }
- else
- {
- imesa->regs.s4.drawCtrl0.ni.scissorXStart = imesa->draw_rect.x1;
- imesa->regs.s4.drawCtrl0.ni.scissorYStart = imesa->draw_rect.y1;
- imesa->regs.s4.drawCtrl1.ni.scissorXEnd = imesa->draw_rect.x2-1;
- imesa->regs.s4.drawCtrl1.ni.scissorYEnd = imesa->draw_rect.y2-1;
- }
- imesa->scissorChanged = GL_FALSE;
- }
+ /* In case the texture image was changed without changing the
+ * texture address as well, we need to force emitting the texture
+ * address in order to flush texture cashes. */
+ if ((imesa->dirty & SAVAGE_UPLOAD_TEX0) &&
+ imesa->oldRegs.s4.texAddr[0].ui == imesa->regs.s4.texAddr[0].ui)
+ imesa->oldRegs.s4.texAddr[0].ui = 0xffffffff;
+ if ((imesa->dirty & SAVAGE_UPLOAD_TEX1) &&
+ imesa->oldRegs.s4.texAddr[1].ui == imesa->regs.s4.texAddr[1].ui)
+ imesa->oldRegs.s4.texAddr[1].ui = 0xffffffff;
+
+ /* Fix up watermarks */
+ if (imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites) {
+ imesa->regs.s4.destTexWatermarks.ni.destWriteLow = 0;
+ imesa->regs.s4.destTexWatermarks.ni.destFlush = 1;
+ } else
+ imesa->regs.s4.destTexWatermarks.ni.destWriteLow = S4_DWLO;
+ if (imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites)
+ imesa->regs.s4.zWatermarks.ni.wLow = 0;
+ else
+ imesa->regs.s4.zWatermarks.ni.wLow = S4_ZWLO;
- /* the savage4 uses the contiguous range of BCI registers 0x1e-0x39
- * 0x1e-0x27 are local, no need to check them for global changes */
savageEmitChangedRegs (imesa, 0x1e, 0x39);
imesa->dirty=0;
}
static void savageUpdateRegister_s3d(savageContextPtr imesa)
{
- if (imesa->scissorChanged && imesa->savageScreen->driScrnPriv->drmMinor < 1)
- {
- if(imesa->scissor)
- {
- imesa->regs.s3d.scissorsStart.ni.scissorXStart =
- imesa->scissor_rect.x1;
- imesa->regs.s3d.scissorsStart.ni.scissorYStart =
- imesa->scissor_rect.y1;
- imesa->regs.s3d.scissorsEnd.ni.scissorXEnd =
- imesa->scissor_rect.x2-1;
- imesa->regs.s3d.scissorsEnd.ni.scissorYEnd =
- imesa->scissor_rect.y2-1;
- }
- else
- {
- imesa->regs.s3d.scissorsStart.ni.scissorXStart =
- imesa->draw_rect.x1;
- imesa->regs.s3d.scissorsStart.ni.scissorYStart =
- imesa->draw_rect.y1;
- imesa->regs.s3d.scissorsEnd.ni.scissorXEnd =
- imesa->draw_rect.x2-1;
- imesa->regs.s3d.scissorsEnd.ni.scissorYEnd =
- imesa->draw_rect.y2-1;
- }
- imesa->scissorChanged = GL_FALSE;
- }
+ /* In case the texture image was changed without changing the
+ * texture address as well, we need to force emitting the texture
+ * address in order to flush texture cashes. */
+ if ((imesa->dirty & SAVAGE_UPLOAD_TEX0) &&
+ imesa->oldRegs.s3d.texAddr.ui == imesa->regs.s3d.texAddr.ui)
+ imesa->oldRegs.s3d.texAddr.ui = 0xffffffff;
+
+ /* Fix up watermarks */
+ if (imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites) {
+ imesa->regs.s3d.destTexWatermarks.ni.destWriteLow = 0;
+ imesa->regs.s3d.destTexWatermarks.ni.destFlush = 1;
+ } else
+ imesa->regs.s3d.destTexWatermarks.ni.destWriteLow = S3D_DWLO;
+ if (imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites)
+ imesa->regs.s3d.zWatermarks.ni.wLow = 0;
+ else
+ imesa->regs.s3d.zWatermarks.ni.wLow = S3D_ZWLO;
- /* Some temporary hacks to workaround lockups. Not sure if they are
- * still needed. But they work for now. */
- imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
- imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE;
/* the savage3d uses two contiguous ranges of BCI registers:
* 0x18-0x1c and 0x20-0x38. Some texture registers need to be
* emitted in one chunk or we get some funky rendering errors. */
- /* FIXME: watermark registers aren't programmed correctly ATM */
savageEmitChangedRegs (imesa, 0x18, 0x19);
savageEmitChangedRegChunk (imesa, 0x1a, 0x1c);
- savageEmitChangedRegs (imesa, 0x20, 0x36);
+ savageEmitChangedRegs (imesa, 0x20, 0x38);
imesa->dirty=0;
}
savageEmitOldRegs (imesa, 0x1e, 0x39, GL_TRUE);
} else {
savageEmitOldRegs (imesa, 0x18, 0x1c, GL_TRUE);
- savageEmitOldRegs (imesa, 0x20, 0x36, GL_FALSE);
+ savageEmitOldRegs (imesa, 0x20, 0x38, GL_FALSE);
}
}
if (SAVAGE_DEBUG & DEBUG_VERBOSE_API)
savageDDPrintDirty( "\n\n\nsavageEmitHwStateLocked", imesa->dirty );
- if (imesa->dirty & ~SAVAGE_UPLOAD_CLIPRECTS)
+ if (imesa->dirty)
{
- if (imesa->dirty & (SAVAGE_UPLOAD_GLOBAL | SAVAGE_UPLOAD_LOCAL |
- SAVAGE_UPLOAD_TEX0 | SAVAGE_UPLOAD_TEX1 |
- SAVAGE_UPLOAD_FOGTBL | SAVAGE_UPLOAD_TEXGLOBAL))
- {
- if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
- fprintf (stderr, "... emitting state\n");
- if (imesa->savageScreen->chipset >= S3_SAVAGE4)
- savageUpdateRegister_s4(imesa);
- else
- savageUpdateRegister_s3d(imesa);
- }
-
- imesa->dirty &= SAVAGE_UPLOAD_CLIPRECTS;
- }
+ if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
+ fprintf (stderr, "... emitting state\n");
+ if (imesa->savageScreen->chipset >= S3_SAVAGE4)
+ savageUpdateRegister_s4(imesa);
+ else
+ savageUpdateRegister_s3d(imesa);
+ }
+
+ imesa->dirty = 0;
}
imesa->regs.s4.zWatermarks.ui = 0x12000C04;
imesa->regs.s4.destTexWatermarks.ui = 0x40200400;
#else
- imesa->regs.s4.zWatermarks.ui = 0x16001808;
- imesa->regs.s4.destTexWatermarks.ui = 0x4f000000;
+ /*imesa->regs.s4.zWatermarks.ui = 0x16001808;*/
+ imesa->regs.s4.zWatermarks.ni.rLow = S4_ZRLO;
+ imesa->regs.s4.zWatermarks.ni.rHigh = S4_ZRHI;
+ imesa->regs.s4.zWatermarks.ni.wLow = S4_ZWLO;
+ imesa->regs.s4.zWatermarks.ni.wHigh = S4_ZWHI;
+ /*imesa->regs.s4.destTexWatermarks.ui = 0x4f000000;*/
+ imesa->regs.s4.destTexWatermarks.ni.destReadLow = S4_DRLO;
+ imesa->regs.s4.destTexWatermarks.ni.destReadHigh = S4_DRHI;
+ imesa->regs.s4.destTexWatermarks.ni.destWriteLow = S4_DWLO;
+ imesa->regs.s4.destTexWatermarks.ni.destWriteHigh = S4_DWHI;
+ imesa->regs.s4.destTexWatermarks.ni.texRead = S4_TR;
+ imesa->regs.s4.destTexWatermarks.ni.destFlush = 1;
#endif
imesa->regs.s4.drawCtrl0.ni.dPerfAccelEn = GL_TRUE;
imesa->regs.s4.texCtrl[1].ni.texXprEn = GL_TRUE;
imesa->regs.s4.texCtrl[0].ni.dMax = 0x0f;
imesa->regs.s4.texCtrl[1].ni.dMax = 0x0f;
+ /* programm a valid tex address, in case texture state is emitted
+ * in wrong order. */
+ if (imesa->lastTexHeap == 2 && imesa->savageScreen->textureSize[1]) {
+ /* AGP textures available */
+ imesa->regs.s4.texAddr[0].ui = imesa->savageScreen->textureOffset[1]|3;
+ imesa->regs.s4.texAddr[1].ui = imesa->savageScreen->textureOffset[1]|3;
+ } else {
+ /* no AGP textures available, use local */
+ imesa->regs.s4.texAddr[0].ui = imesa->savageScreen->textureOffset[0]|2;
+ imesa->regs.s4.texAddr[1].ui = imesa->savageScreen->textureOffset[0]|2;
+ }
imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn = GL_TRUE;
imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_One;
imesa->regs.s4.drawLocalCtrl.ni.wrZafterAlphaTst = GL_FALSE;
imesa->regs.s3d.zWatermarks.ui = 0x12000C04;
imesa->regs.s3d.destTexWatermarks.ui = 0x40200400;
#else
- imesa->regs.s3d.zWatermarks.ui = 0x16001808;
- imesa->regs.s3d.destTexWatermarks.ui = 0x4f000000;
+ /*imesa->regs.s3d.zWatermarks.ui = 0x16001808;*/
+ imesa->regs.s3d.zWatermarks.ni.rLow = S3D_ZRLO;
+ imesa->regs.s3d.zWatermarks.ni.rHigh = S3D_ZRHI;
+ imesa->regs.s3d.zWatermarks.ni.wLow = S3D_ZWLO;
+ imesa->regs.s3d.zWatermarks.ni.wHigh = S3D_ZWHI;
+ /*imesa->regs.s3d.destTexWatermarks.ui = 0x4f000000;*/
+ imesa->regs.s3d.destTexWatermarks.ni.destReadLow = S3D_DRLO;
+ imesa->regs.s3d.destTexWatermarks.ni.destReadHigh = S3D_DRHI;
+ imesa->regs.s3d.destTexWatermarks.ni.destWriteLow = S3D_DWLO;
+ imesa->regs.s3d.destTexWatermarks.ni.destWriteHigh = S3D_DWHI;
+ imesa->regs.s3d.destTexWatermarks.ni.texRead = S3D_TR;
+ imesa->regs.s3d.destTexWatermarks.ni.destFlush = 1;
#endif
- /* clrCmpAlphaBlendCtrl is needed to get alphatest and
- * alpha blending working properly
- */
-
imesa->regs.s3d.texCtrl.ni.dBias = 0x08;
imesa->regs.s3d.texCtrl.ni.texXprEn = GL_TRUE;
+ /* texXprEn is needed to get alphatest and alpha blending working
+ * properly. However, this makes texels with color texXprClr
+ * completely transparent in some texture environment modes. I
+ * couldn't find a way to disable this. So choose an arbitrary and
+ * improbable color. (0 is a bad choice, makes all black texels
+ * transparent.) */
+ imesa->regs.s3d.texXprClr.ui = 0x26ae26ae;
+ /* programm a valid tex address, in case texture state is emitted
+ * in wrong order. */
+ if (imesa->lastTexHeap == 2 && imesa->savageScreen->textureSize[1]) {
+ /* AGP textures available */
+ imesa->regs.s3d.texAddr.ui = imesa->savageScreen->textureOffset[1]|3;
+ } else {
+ /* no AGP textures available, use local */
+ imesa->regs.s3d.texAddr.ui = imesa->savageScreen->textureOffset[0]|2;
+ }
imesa->regs.s3d.zBufCtrl.ni.drawUpdateEn = GL_TRUE;
imesa->regs.s3d.zBufCtrl.ni.wrZafterAlphaTst = GL_FALSE;
/*fprintf(stderr,"DBflag:%d\n",imesa->glCtx->Visual->DBflag);*/
/* zbufoffset and destctrl have the same position and layout on
* savage4 and savage3d. */
- imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->backOffset>>11;
- if(imesa->savageScreen->cpp == 2)
- {
+ if (imesa->glCtx->Visual.doubleBufferMode) {
+ imesa->IsDouble = GL_TRUE;
+ imesa->toggle = TARGET_BACK;
+ imesa->regs.s4.destCtrl.ni.offset =
+ imesa->savageScreen->backOffset>>11;
+ } else {
+ imesa->IsDouble = GL_FALSE;
+ imesa->toggle = TARGET_FRONT;
+ imesa->regs.s4.destCtrl.ni.offset =
+ imesa->savageScreen->frontOffset>>11;
+ }
+ if(imesa->savageScreen->cpp == 2) {
imesa->regs.s4.destCtrl.ni.dstPixFmt = 0;
imesa->regs.s4.destCtrl.ni.dstWidthInTile =
(imesa->savageScreen->width+63)>>6;
- }
- else
- {
+ } else {
imesa->regs.s4.destCtrl.ni.dstPixFmt = 1;
imesa->regs.s4.destCtrl.ni.dstWidthInTile =
(imesa->savageScreen->width+31)>>5;
}
-
- imesa->IsDouble = GL_TRUE;
-
+ imesa->drawMap = imesa->apertureBase[imesa->toggle];
+ imesa->readMap = imesa->apertureBase[imesa->toggle];
imesa->NotFirstFrame = GL_FALSE;
+
imesa->regs.s4.zBufOffset.ni.offset=imesa->savageScreen->depthOffset>>11;
- if(imesa->savageScreen->zpp == 2)
- {
+ if(imesa->savageScreen->zpp == 2) {
imesa->regs.s4.zBufOffset.ni.zBufWidthInTiles =
(imesa->savageScreen->width+63)>>6;
imesa->regs.s4.zBufOffset.ni.zDepthSelect = 0;
- }
- else
- {
+ } else {
imesa->regs.s4.zBufOffset.ni.zBufWidthInTiles =
(imesa->savageScreen->width+31)>>5;
imesa->regs.s4.zBufOffset.ni.zDepthSelect = 1;
}
-
- if (imesa->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) {
- if(imesa->IsFullScreen)
- {
- imesa->toggle = TARGET_BACK;
-
- imesa->drawMap = (char *)imesa->apertureBase[imesa->toggle];
- imesa->readMap = (char *)imesa->apertureBase[imesa->toggle];
- }
- else
- {
- imesa->drawMap = (char *)imesa->apertureBase[TARGET_BACK];
- imesa->readMap = (char *)imesa->apertureBase[TARGET_BACK];
- }
-
- } else {
-
- if(imesa->IsFullScreen)
- {
- imesa->toggle = TARGET_BACK;
-
- imesa->drawMap = (char *)imesa->apertureBase[imesa->toggle];
- imesa->readMap = (char *)imesa->apertureBase[imesa->toggle];
- }
- else
- {
- imesa->drawMap = (char *)imesa->apertureBase[TARGET_BACK];
- imesa->readMap = (char *)imesa->apertureBase[TARGET_BACK];
- }
- }
memcpy (imesa->oldRegs.ui, imesa->regs.ui, SAVAGE_NR_REGS*sizeof(u_int32_t));