summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Borca <dborca@users.sourceforge.net>2003-10-21 08:31:02 +0000
committerDaniel Borca <dborca@users.sourceforge.net>2003-10-21 08:31:02 +0000
commitf03cb2e4eea23fd82e9837e05f0ab3a83cb474c7 (patch)
tree1ca2ed8c4e5ad9e23862a5d9f7d12cd5e1856de8
parent3f60e4f21b9ff5bf3a83734d38ee90aff8a67fa0 (diff)
Napalm total immersion
-rw-r--r--src/mesa/drivers/glide/fxapi.c3
-rw-r--r--src/mesa/drivers/glide/fxdd.c467
-rw-r--r--src/mesa/drivers/glide/fxddspan.c395
-rw-r--r--src/mesa/drivers/glide/fxddtex.c19
-rw-r--r--src/mesa/drivers/glide/fxdrv.h16
-rw-r--r--src/mesa/drivers/glide/fxg.c8
-rw-r--r--src/mesa/drivers/glide/fxglidew.c3
-rw-r--r--src/mesa/drivers/glide/fxglidew.h3
-rw-r--r--src/mesa/drivers/glide/fxsetup.c380
-rw-r--r--src/mesa/drivers/glide/fxsetup.h1128
-rw-r--r--src/mesa/drivers/glide/fxtexman.c49
-rw-r--r--src/mesa/drivers/glide/fxtris.c21
-rw-r--r--src/mesa/drivers/glide/fxvb.c2
-rw-r--r--src/mesa/drivers/glide/fxvbtmp.h2
-rw-r--r--src/mesa/drivers/glide/fxwgl.c4
15 files changed, 2098 insertions, 402 deletions
diff --git a/src/mesa/drivers/glide/fxapi.c b/src/mesa/drivers/glide/fxapi.c
index 02b00a84c9..2ebb451b2d 100644
--- a/src/mesa/drivers/glide/fxapi.c
+++ b/src/mesa/drivers/glide/fxapi.c
@@ -1,5 +1,3 @@
-/* $Id: fxapi.c,v 1.40 2003/10/13 11:14:58 dborca Exp $ */
-
/*
* Mesa 3-D graphics library
* Version: 4.0
@@ -324,6 +322,7 @@ fxMesaCreateContext(GLuint win,
fxMesa->HaveTexFmt = voodoo->HaveTexFmt;
fxMesa->HaveCmbExt = voodoo->HaveCmbExt;
fxMesa->HaveMirExt = voodoo->HaveMirExt;
+ fxMesa->HaveTexUma = voodoo->HaveTexUma;
fxMesa->HaveTexus2 = voodoo->HaveTexus2;
fxMesa->Glide = glbHWConfig.Glide;
Glide = &fxMesa->Glide;
diff --git a/src/mesa/drivers/glide/fxdd.c b/src/mesa/drivers/glide/fxdd.c
index 7087c30b66..fec2ee9d72 100644
--- a/src/mesa/drivers/glide/fxdd.c
+++ b/src/mesa/drivers/glide/fxdd.c
@@ -1,9 +1,3 @@
-/* Hack alert:
- * fxDDReadPixels888 does not convert 8A8R8G8B into 5R5G5B
- */
-
-/* $Id: fxdd.c,v 1.103 2003/10/14 14:56:45 dborca Exp $ */
-
/*
* Mesa 3-D graphics library
* Version: 5.1
@@ -55,6 +49,7 @@
#include "texstore.h"
#include "teximage.h"
#include "swrast/swrast.h"
+#include "swrast/s_context.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
#include "tnl/t_context.h"
@@ -200,6 +195,12 @@ static void fxDDClear( GLcontext *ctx,
const FxU32 clearD = (FxU32) (((1 << ctx->Visual.depthBits) - 1) * ctx->Depth.Clear);
const FxU8 clearS = (FxU8) (ctx->Stencil.Clear & 0xff);
+ /* [dBorca] Hack alert:
+ * if we set Mesa for 32bit depth, we'll get
+ * clearD == 0
+ * due to 32bit integer overflow!
+ */
+
if ( TDFX_DEBUG & MESA_VERBOSE ) {
fprintf( stderr, "%s( %d, %d, %d, %d )\n",
__FUNCTION__, (int) x, (int) y, (int) width, (int) height );
@@ -492,44 +493,48 @@ fxDDSetDrawBuffer(GLcontext * ctx, GLenum mode)
}
-
-
-
static void
-fxDDDrawBitmap(GLcontext * ctx, GLint px, GLint py,
- GLsizei width, GLsizei height,
- const struct gl_pixelstore_attrib *unpack,
- const GLubyte * bitmap)
+fxDDDrawBitmap2 (GLcontext *ctx, GLint px, GLint py,
+ GLsizei width, GLsizei height,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLubyte *bitmap)
{
fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
GrLfbInfo_t info;
+ GrLfbWriteMode_t mode;
FxU16 color;
const struct gl_pixelstore_attrib *finalUnpack;
struct gl_pixelstore_attrib scissoredUnpack;
/* check if there's any raster operations enabled which we can't handle */
- if (ctx->Color.AlphaEnabled ||
- ctx->Color.BlendEnabled ||
- ctx->Depth.Test ||
- ctx->Fog.Enabled ||
- ctx->Color.ColorLogicOpEnabled ||
- ctx->Stencil.Enabled ||
- ctx->Scissor.Enabled ||
- (ctx->DrawBuffer->UseSoftwareAlphaBuffers &&
- ctx->Color.ColorMask[ACOMP]) ||
- (ctx->Color._DrawDestMask != FRONT_LEFT_BIT &&
- ctx->Color._DrawDestMask != BACK_LEFT_BIT)) {
+ if ((swrast->_RasterMask & (ALPHATEST_BIT |
+ /*BLEND_BIT |*/ /* blending ok, through pixpipe */
+ DEPTH_BIT | /* could be done with RGB:DEPTH */
+ FOG_BIT | /* could be done with RGB:DEPTH */
+ LOGIC_OP_BIT |
+ /*CLIP_BIT |*/ /* clipping ok, below */
+ STENCIL_BIT |
+ /*MASKING_BIT |*/ /* masking ok, test follows */
+ ALPHABUF_BIT | /* nope! see 565 span kludge */
+ MULTI_DRAW_BIT |
+ OCCLUSION_BIT | /* nope! at least not yet */
+ TEXTURE_BIT |
+ FRAGPROG_BIT))
+ ||
+ ((swrast->_RasterMask & MASKING_BIT) /*&& (ctx->Visual.greenBits != 8)*/ && (ctx->Visual.greenBits != 5))
+ ) {
_swrast_Bitmap(ctx, px, py, width, height, unpack, bitmap);
return;
}
+ /* make sure the pixelpipe is configured correctly */
+ fxSetupFXUnits(ctx);
if (ctx->Scissor.Enabled) {
/* This is a bit tricky, but by carefully adjusting the px, py,
* width, height, skipPixels and skipRows values we can do
* scissoring without special code in the rendering loop.
- *
- * KW: This code is never reached, see the test above.
*/
/* we'll construct a new pixelstore struct */
@@ -568,10 +573,14 @@ fxDDDrawBitmap(GLcontext * ctx, GLint px, GLint py,
/* compute pixel value */
{
- GLint r = (GLint) (ctx->Current.RasterColor[0] * 255.0f);
- GLint g = (GLint) (ctx->Current.RasterColor[1] * 255.0f);
- GLint b = (GLint) (ctx->Current.RasterColor[2] * 255.0f);
- /*GLint a = (GLint)(ctx->Current.RasterColor[3]*255.0f); */
+ GLint r = (GLint) (ctx->Current.RasterColor[RCOMP] * 255.0f);
+ GLint g = (GLint) (ctx->Current.RasterColor[GCOMP] * 255.0f);
+ GLint b = (GLint) (ctx->Current.RasterColor[BCOMP] * 255.0f);
+ GLint a = (GLint) (ctx->Current.RasterColor[ACOMP] * 255.0f);
+#if 0
+ /* [dBorca]
+ * who uses bgr, anyway? Expecting the V2 from HM... :D
+ */
if (fxMesa->bgrOrder)
color = (FxU16)
(((FxU16) 0xf8 & b) << (11 - 3)) |
@@ -580,14 +589,23 @@ fxDDDrawBitmap(GLcontext * ctx, GLint px, GLint py,
color = (FxU16)
(((FxU16) 0xf8 & r) << (11 - 3)) |
(((FxU16) 0xfc & g) << (5 - 3 + 1)) | (((FxU16) 0xf8 & b) >> 3);
+#else
+ if (fxMesa->colDepth == 15) {
+ color = TDFXPACKCOLOR1555(b, g, r, a);
+ mode = GR_LFBWRITEMODE_1555;
+ } else {
+ color = TDFXPACKCOLOR565(b, g, r);
+ mode = GR_LFBWRITEMODE_565;
+ }
+#endif
}
info.size = sizeof(info);
if (!grLfbLock(GR_LFB_WRITE_ONLY,
fxMesa->currentFB,
- GR_LFBWRITEMODE_565,
- GR_ORIGIN_UPPER_LEFT, FXFALSE, &info)) {
- fprintf(stderr, "%s: ERROR: locking the linear frame buffer\n", __FUNCTION__);
+ mode,
+ GR_ORIGIN_UPPER_LEFT, FXTRUE, &info)) {
+ _swrast_Bitmap(ctx, px, py, width, height, unpack, bitmap);
return;
}
@@ -656,14 +674,188 @@ fxDDDrawBitmap(GLcontext * ctx, GLint px, GLint py,
grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB);
}
+static void
+fxDDDrawBitmap4 (GLcontext *ctx, GLint px, GLint py,
+ GLsizei width, GLsizei height,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLubyte *bitmap)
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ GrLfbInfo_t info;
+ FxU32 color;
+ const struct gl_pixelstore_attrib *finalUnpack;
+ struct gl_pixelstore_attrib scissoredUnpack;
+
+ /* check if there's any raster operations enabled which we can't handle */
+ if ((swrast->_RasterMask & (ALPHATEST_BIT |
+ /*BLEND_BIT |*/ /* blending ok, through pixpipe */
+ DEPTH_BIT | /* could be done with RGB:DEPTH */
+ FOG_BIT | /* could be done with RGB:DEPTH */
+ LOGIC_OP_BIT |
+ /*CLIP_BIT |*/ /* clipping ok, below */
+ STENCIL_BIT |
+ /*MASKING_BIT |*/ /* masking ok, we're in 32bpp */
+ /*ALPHABUF_BIT |*//* alpha ok, we're in 32bpp */
+ MULTI_DRAW_BIT |
+ OCCLUSION_BIT | /* nope! at least not yet */
+ TEXTURE_BIT |
+ FRAGPROG_BIT))
+ ) {
+ _swrast_Bitmap(ctx, px, py, width, height, unpack, bitmap);
+ return;
+ }
+
+ /* make sure the pixelpipe is configured correctly */
+ fxSetupFXUnits(ctx);
+
+ if (ctx->Scissor.Enabled) {
+ /* This is a bit tricky, but by carefully adjusting the px, py,
+ * width, height, skipPixels and skipRows values we can do
+ * scissoring without special code in the rendering loop.
+ */
+
+ /* we'll construct a new pixelstore struct */
+ finalUnpack = &scissoredUnpack;
+ scissoredUnpack = *unpack;
+ if (scissoredUnpack.RowLength == 0)
+ scissoredUnpack.RowLength = width;
+
+ /* clip left */
+ if (px < ctx->Scissor.X) {
+ scissoredUnpack.SkipPixels += (ctx->Scissor.X - px);
+ width -= (ctx->Scissor.X - px);
+ px = ctx->Scissor.X;
+ }
+ /* clip right */
+ if (px + width >= ctx->Scissor.X + ctx->Scissor.Width) {
+ width -= (px + width - (ctx->Scissor.X + ctx->Scissor.Width));
+ }
+ /* clip bottom */
+ if (py < ctx->Scissor.Y) {
+ scissoredUnpack.SkipRows += (ctx->Scissor.Y - py);
+ height -= (ctx->Scissor.Y - py);
+ py = ctx->Scissor.Y;
+ }
+ /* clip top */
+ if (py + height >= ctx->Scissor.Y + ctx->Scissor.Height) {
+ height -= (py + height - (ctx->Scissor.Y + ctx->Scissor.Height));
+ }
+
+ if (width <= 0 || height <= 0)
+ return;
+ }
+ else {
+ finalUnpack = unpack;
+ }
+
+ /* compute pixel value */
+ {
+ GLint r = (GLint) (ctx->Current.RasterColor[RCOMP] * 255.0f);
+ GLint g = (GLint) (ctx->Current.RasterColor[GCOMP] * 255.0f);
+ GLint b = (GLint) (ctx->Current.RasterColor[BCOMP] * 255.0f);
+ GLint a = (GLint) (ctx->Current.RasterColor[ACOMP] * 255.0f);
+#if 0
+ /* [dBorca]
+ * who uses bgr, anyway? Expecting the V2 from HM... :D
+ */
+ if (fxMesa->bgrOrder)
+ color = (FxU16)
+ (((FxU16) 0xf8 & b) << (11 - 3)) |
+ (((FxU16) 0xfc & g) << (5 - 3 + 1)) | (((FxU16) 0xf8 & r) >> 3);
+ else
+ color = (FxU16)
+ (((FxU16) 0xf8 & r) << (11 - 3)) |
+ (((FxU16) 0xfc & g) << (5 - 3 + 1)) | (((FxU16) 0xf8 & b) >> 3);
+#else
+ color = TDFXPACKCOLOR8888(b, g, r, a);
+#endif
+ }
+
+ info.size = sizeof(info);
+ if (!grLfbLock(GR_LFB_WRITE_ONLY,
+ fxMesa->currentFB,
+ GR_LFBWRITEMODE_8888,
+ GR_ORIGIN_UPPER_LEFT, FXTRUE, &info)) {
+ _swrast_Bitmap(ctx, px, py, width, height, unpack, bitmap);
+ return;
+ }
+
+ {
+ const GLint winX = 0;
+ const GLint winY = fxMesa->height - 1;
+ /* The dest stride depends on the hardware and whether we're drawing
+ * to the front or back buffer. This compile-time test seems to do
+ * the job for now.
+ */
+ const GLint dstStride = info.strideInBytes / 4; /* stride in GLuints */
+
+ GLint row;
+ /* compute dest address of bottom-left pixel in bitmap */
+ GLuint *dst = (GLuint *) info.lfbPtr
+ + (winY - py) * dstStride + (winX + px);
+
+ for (row = 0; row < height; row++) {
+ const GLubyte *src =
+ (const GLubyte *) _mesa_image_address(finalUnpack,
+ bitmap, width, height,
+ GL_COLOR_INDEX, GL_BITMAP,
+ 0, row, 0);
+ if (finalUnpack->LsbFirst) {
+ /* least significan bit first */
+ GLubyte mask = 1U << (finalUnpack->SkipPixels & 0x7);
+ GLint col;
+ for (col = 0; col < width; col++) {
+ if (*src & mask) {
+ dst[col] = color;
+ }
+ if (mask == 128U) {
+ src++;
+ mask = 1U;
+ }
+ else {
+ mask = mask << 1;
+ }
+ }
+ if (mask != 1)
+ src++;
+ }
+ else {
+ /* most significan bit first */
+ GLubyte mask = 128U >> (finalUnpack->SkipPixels & 0x7);
+ GLint col;
+ for (col = 0; col < width; col++) {
+ if (*src & mask) {
+ dst[col] = color;
+ }
+ if (mask == 1U) {
+ src++;
+ mask = 128U;
+ }
+ else {
+ mask = mask >> 1;
+ }
+ }
+ if (mask != 128)
+ src++;
+ }
+ dst -= dstStride;
+ }
+ }
+
+ grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB);
+}
+
static void
-fxDDReadPixels(GLcontext * ctx, GLint x, GLint y,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const struct gl_pixelstore_attrib *packing, GLvoid * dstImage)
+fxDDReadPixels565 (GLcontext * ctx,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *packing,
+ GLvoid *dstImage)
{
- if (ctx->_ImageTransferState) {
+ if (ctx->_ImageTransferState/* & (IMAGE_SCALE_BIAS_BIT|IMAGE_MAP_COLOR_BIT)*/) {
_swrast_ReadPixels(ctx, x, y, width, height, format, type,
packing, dstImage);
return;
@@ -771,14 +963,15 @@ fxDDReadPixels(GLcontext * ctx, GLint x, GLint y,
}
}
-static void fxDDReadPixels555 (GLcontext * ctx,
- GLint x, GLint y,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const struct gl_pixelstore_attrib *packing,
- GLvoid *dstImage)
+static void
+fxDDReadPixels555 (GLcontext * ctx,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *packing,
+ GLvoid *dstImage)
{
- if (ctx->_ImageTransferState) {
+ if (ctx->_ImageTransferState/* & (IMAGE_SCALE_BIAS_BIT|IMAGE_MAP_COLOR_BIT)*/) {
_swrast_ReadPixels(ctx, x, y, width, height, format, type,
packing, dstImage);
return;
@@ -839,7 +1032,7 @@ static void fxDDReadPixels555 (GLcontext * ctx,
for (col = 0; col < halfWidth; col++) {
const GLuint pixel = ((const GLuint *) src)[col];
*d++ = FX_rgb_scale_5[ pixel & 0x1f];
- *d++ = FX_rgb_scale_5[(pixel >> 5) & 0x1f];
+ *d++ = FX_rgb_scale_5[(pixel >> 5) & 0x1f];
*d++ = FX_rgb_scale_5[(pixel >> 10) & 0x1f];
*d++ = (pixel & 0x8000) ? 255 : 0;
*d++ = FX_rgb_scale_5[(pixel >> 16) & 0x1f];
@@ -850,7 +1043,7 @@ static void fxDDReadPixels555 (GLcontext * ctx,
if (extraPixel) {
const GLushort pixel = src[width - 1];
*d++ = FX_rgb_scale_5[ pixel & 0x1f];
- *d++ = FX_rgb_scale_5[(pixel >> 5) & 0x1f];
+ *d++ = FX_rgb_scale_5[(pixel >> 5) & 0x1f];
*d++ = FX_rgb_scale_5[(pixel >> 10) & 0x1f];
*d++ = (pixel & 0x8000) ? 255 : 0;
}
@@ -882,14 +1075,15 @@ static void fxDDReadPixels555 (GLcontext * ctx,
}
}
-static void fxDDReadPixels888 (GLcontext * ctx,
- GLint x, GLint y,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const struct gl_pixelstore_attrib *packing,
- GLvoid *dstImage)
+static void
+fxDDReadPixels8888 (GLcontext * ctx,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *packing,
+ GLvoid *dstImage)
{
- if (ctx->_ImageTransferState) {
+ if (ctx->_ImageTransferState/* & (IMAGE_SCALE_BIAS_BIT|IMAGE_MAP_COLOR_BIT)*/) {
_swrast_ReadPixels(ctx, x, y, width, height, format, type,
packing, dstImage);
return;
@@ -930,17 +1124,35 @@ static void fxDDReadPixels888 (GLcontext * ctx,
}
}
else if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
- /* directly memcpy 8A8R8G8B pixels into client's buffer */
- const GLint widthInBytes = width * 4;
- GLint row;
+ /* 8A8R8G8B pixels into client's buffer */
+ GLint row, col;
for (row = 0; row < height; row++) {
- MEMCPY(dst, src, widthInBytes);
+ GLubyte *d = dst;
+ for (col = 0; col < width; col++) {
+ const GLuint pixel = ((const GLuint *) src)[col];
+ *d++ = pixel >> 16;
+ *d++ = pixel >> 8;
+ *d++ = pixel;
+ *d++ = pixel >> 24;
+ }
dst += dstStride;
src -= srcStride;
}
}
else if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) {
- /* convert 8A8R8G8B into 5R5G5B */
+ /* convert 8A8R8G8B into 5R6G5B */
+ GLint row, col;
+ for (row = 0; row < height; row++) {
+ GLushort *d = (GLushort *)dst;
+ for (col = 0; col < width; col++) {
+ const GLuint pixel = ((const GLuint *) src)[col];
+ *d++ = (((pixel >> 16) & 0xf8) << 8) |
+ (((pixel >> 8) & 0xfc) << 3) |
+ ((pixel & 0xf8) >> 3);
+ }
+ dst += dstStride;
+ src -= srcStride;
+ }
}
else {
grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
@@ -957,6 +1169,105 @@ static void fxDDReadPixels888 (GLcontext * ctx,
}
+/* [dBorca] Hack alert:
+ * not finished!!!
+ * revise fallback tests and fix scissor; implement new formats
+ * also write its siblings: 565 and 1555
+ */
+void
+fxDDDrawPixels8888 (GLcontext * ctx, GLint x, GLint y,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLvoid * pixels)
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ GrLfbInfo_t info;
+
+ if (ctx->Pixel.ZoomX != 1.0F ||
+ ctx->Pixel.ZoomY != 1.0F ||
+ (ctx->_ImageTransferState & (IMAGE_SCALE_BIAS_BIT|
+ IMAGE_MAP_COLOR_BIT)) ||
+ ctx->Color.AlphaEnabled ||
+ ctx->Depth.Test ||
+ ctx->Fog.Enabled ||
+ ctx->Scissor.Enabled ||
+ ctx->Stencil.Enabled ||
+ !ctx->Color.ColorMask[0] ||
+ !ctx->Color.ColorMask[1] ||
+ !ctx->Color.ColorMask[2] ||
+ !ctx->Color.ColorMask[3] ||
+ ctx->Color.ColorLogicOpEnabled ||
+ ctx->Texture._EnabledUnits ||
+ ctx->Depth.OcclusionTest ||
+ fxMesa->fallback)
+ {
+ _swrast_DrawPixels( ctx, x, y, width, height, format, type,
+ unpack, pixels );
+ return;
+ }
+
+ /* lock early to make sure cliprects are right */
+ BEGIN_BOARD_LOCK();
+
+ /* make sure the pixelpipe is configured correctly */
+ fxSetupFXUnits(ctx);
+
+ /* look for clipmasks, giveup if region obscured */
+#if 0
+ if (ctx->Color.DrawBuffer == GL_FRONT) {
+ if (!inClipRects_Region(fxMesa, scrX, scrY, width, height)) {
+ END_BOARD_LOCK(fxMesa);
+ _swrast_DrawPixels(ctx, x, y, width, height, format, type, unpack, pixels);
+ return;
+ }
+ }
+#endif
+
+ info.size = sizeof(info);
+ if (!grLfbLock(GR_LFB_WRITE_ONLY,
+ fxMesa->currentFB,
+ GR_LFBWRITEMODE_8888,
+ GR_ORIGIN_UPPER_LEFT, FXTRUE, &info)) {
+ _swrast_DrawPixels(ctx, x, y, width, height, format, type, unpack, pixels);
+ return;
+ }
+
+ {
+ const GLint winX = 0;
+ const GLint winY = fxMesa->height - 1;
+
+ const GLint dstStride = info.strideInBytes / 4; /* stride in GLuints */
+ GLuint *dst = (GLuint *) info.lfbPtr + (winY - y) * dstStride + (winX + x);
+ const GLubyte *src = (GLubyte *)_mesa_image_address(unpack, pixels,
+ width, height, format,
+ type, 0, 0, 0);
+ const GLint srcStride = _mesa_image_row_stride(unpack, width, format, type);
+
+ if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
+ /* directly memcpy 8A8R8G8B pixels to screen */
+ const GLint widthInBytes = width * 4;
+ GLint row;
+ for (row = 0; row < height; row++) {
+ MEMCPY(dst, src, widthInBytes);
+ dst -= dstStride;
+ src += srcStride;
+ }
+ }
+ else {
+ grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB);
+ END_BOARD_LOCK();
+ _swrast_DrawPixels(ctx, x, y, width, height, format, type, unpack, pixels);
+ return;
+ }
+
+ }
+
+ grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB);
+ END_BOARD_LOCK();
+}
+
+
static void
fxDDFinish(GLcontext * ctx)
{
@@ -1031,6 +1342,7 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa)
fxMesa->unitsState.blendDstFuncRGB = GR_BLEND_ZERO;
fxMesa->unitsState.blendSrcFuncAlpha = GR_BLEND_ONE;
fxMesa->unitsState.blendDstFuncAlpha = GR_BLEND_ZERO;
+ fxMesa->unitsState.blendEq = GR_BLEND_OP_ADD;
fxMesa->unitsState.depthTestEnabled = GL_FALSE;
fxMesa->unitsState.depthMask = GL_TRUE;
@@ -1151,6 +1463,7 @@ fxDDInitExtensions(GLcontext * ctx)
_mesa_enable_extension(ctx, "GL_EXT_paletted_texture");
_mesa_enable_extension(ctx, "GL_EXT_texture_lod_bias");
_mesa_enable_extension(ctx, "GL_EXT_shared_texture_palette");
+ _mesa_enable_extension(ctx, "GL_EXT_blend_func_separate");
if (fxMesa->haveTwoTMUs) {
_mesa_enable_extension(ctx, "GL_EXT_texture_env_add");
@@ -1170,9 +1483,14 @@ fxDDInitExtensions(GLcontext * ctx)
_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" );*/
+ }
+
+ if (fxMesa->HaveCmbExt) {
+ _mesa_enable_extension(ctx, "GL_EXT_texture_env_combine");
+ }
- /* env_combine: not ready yet */
- /*_mesa_enable_extension( ctx, "GL_EXT_texture_env_combine" );*/
+ if (fxMesa->HavePixExt) {
+ _mesa_enable_extension(ctx, "GL_EXT_blend_subtract");
}
if (fxMesa->HaveMirExt) {
@@ -1206,8 +1524,17 @@ fx_check_IsInHardware(GLcontext * ctx)
return FX_FALLBACK_DRAW_BUFFER;
}
- if (ctx->Color.BlendEnabled && (ctx->Color.BlendEquation != GL_FUNC_ADD_EXT)) {
- return FX_FALLBACK_BLEND;
+ if (ctx->Color.BlendEnabled) {
+ if (ctx->Color.BlendEquation != GL_FUNC_ADD_EXT) {
+ if (fxMesa->HavePixExt) {
+ if ((ctx->Color.BlendEquation != GL_FUNC_SUBTRACT_EXT) &&
+ (ctx->Color.BlendEquation != GL_FUNC_REVERSE_SUBTRACT_EXT)) {
+ return FX_FALLBACK_BLEND;
+ }
+ } else {
+ return FX_FALLBACK_BLEND;
+ }
+ }
}
if (ctx->Color.ColorLogicOpEnabled && (ctx->Color.LogicOp != GL_COPY)) {
@@ -1237,6 +1564,7 @@ fx_check_IsInHardware(GLcontext * ctx)
return FX_FALLBACK_TEXTURE_1D_3D;
if (ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_2D_BIT) {
+ if (fxMesa->type < GR_SSTTYPE_Voodoo2)
if (ctx->Texture.Unit[0].EnvMode == GL_BLEND &&
(ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_2D_BIT ||
ctx->Texture.Unit[0].EnvColor[0] != 0 ||
@@ -1250,6 +1578,7 @@ fx_check_IsInHardware(GLcontext * ctx)
}
if (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_2D_BIT) {
+ if (fxMesa->type < GR_SSTTYPE_Voodoo2)
if (ctx->Texture.Unit[1].EnvMode == GL_BLEND)
return FX_FALLBACK_TEXTURE_ENV;
if (ctx->Texture.Unit[1]._Current->Image[0]->Border > 0)
@@ -1289,6 +1618,7 @@ fx_check_IsInHardware(GLcontext * ctx)
return FX_FALLBACK_TEXTURE_MULTI;
}
+ if (fxMesa->type < GR_SSTTYPE_Voodoo2)
if ((ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_2D_BIT) &&
(ctx->Texture.Unit[0].EnvMode == GL_BLEND)) {
return FX_FALLBACK_TEXTURE_ENV;
@@ -1339,18 +1669,21 @@ fxSetupDDPointers(GLcontext * ctx)
ctx->Driver.DrawBuffer = fxDDSetDrawBuffer;
ctx->Driver.GetBufferSize = fxDDBufferSize;
ctx->Driver.Accum = _swrast_Accum;
- ctx->Driver.Bitmap = fxDDDrawBitmap;
ctx->Driver.CopyPixels = _swrast_CopyPixels;
ctx->Driver.DrawPixels = _swrast_DrawPixels;
switch (fxMesa->colDepth) {
case 15:
ctx->Driver.ReadPixels = fxDDReadPixels555;
+ ctx->Driver.Bitmap = fxDDDrawBitmap2;
break;
case 16:
- ctx->Driver.ReadPixels = fxDDReadPixels;
+ ctx->Driver.ReadPixels = fxDDReadPixels565;
+ ctx->Driver.Bitmap = fxDDDrawBitmap2;
break;
case 32:
- ctx->Driver.ReadPixels = fxDDReadPixels888;
+ ctx->Driver.DrawPixels = fxDDDrawPixels8888;
+ ctx->Driver.ReadPixels = fxDDReadPixels8888;
+ ctx->Driver.Bitmap = fxDDDrawBitmap4;
break;
}
ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
@@ -1387,6 +1720,8 @@ fxSetupDDPointers(GLcontext * ctx)
ctx->Driver.UpdateTexturePalette = fxDDTexPalette;
ctx->Driver.AlphaFunc = fxDDAlphaFunc;
ctx->Driver.BlendFunc = fxDDBlendFunc;
+ ctx->Driver.BlendFuncSeparate = fxDDBlendFuncSeparate;
+ ctx->Driver.BlendEquation = fxDDBlendEquation;
ctx->Driver.DepthFunc = fxDDDepthFunc;
ctx->Driver.DepthMask = fxDDDepthMask;
ctx->Driver.ColorMask = fxDDColorMask;
diff --git a/src/mesa/drivers/glide/fxddspan.c b/src/mesa/drivers/glide/fxddspan.c
index c7d5021923..3e242f9bd7 100644
--- a/src/mesa/drivers/glide/fxddspan.c
+++ b/src/mesa/drivers/glide/fxddspan.c
@@ -1,5 +1,3 @@
-/* $Id: fxddspan.c,v 1.26 2003/10/09 15:12:21 dborca Exp $ */
-
/*
* Mesa 3-D graphics library
* Version: 4.0
@@ -48,41 +46,9 @@
#include "swrast/swrast.h"
-#define writeRegionClipped(fxm,dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data) \
- FX_grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data)
-
-
-
-/* KW: Rearranged the args in the call to grLfbWriteRegion().
- */
-#define LFB_WRITE_SPAN_MESA(dst_buffer, \
- dst_x, \
- dst_y, \
- src_width, \
- src_stride, \
- src_data) \
- writeRegionClipped(fxMesa, dst_buffer, \
- dst_x, \
- dst_y, \
- GR_LFB_SRC_FMT_8888, \
- src_width, \
- 1, \
- src_stride, \
- src_data) \
-
-
/************************************************************************/
/***** Span functions *****/
/************************************************************************/
-#define TDFXPACKCOLOR1555( r, g, b, a ) \
- ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
- ((a) ? 0x8000 : 0))
-#define TDFXPACKCOLOR565( r, g, b ) \
- ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
-#define TDFXPACKCOLOR8888( r, g, b, a ) \
- (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
-/************************************************************************/
-
#define DBG 0
@@ -135,20 +101,26 @@
#define HW_WRITE_CLIPLOOP() \
do { \
int _nc = 1; /* numcliprects */ \
+ /* [dBorca] Hack alert: */ \
+ /* remember, we need to flip the scissor, too */ \
+ /* is it better to do it inside fxDDScissor? */ \
while (_nc--) { \
const int minx = fxMesa->clipMinX; \
- const int miny = fxMesa->clipMinY; \
+ const int maxy = Y_FLIP(fxMesa->clipMinY); \
const int maxx = fxMesa->clipMaxX; \
- const int maxy = fxMesa->clipMaxY;
+ const int miny = Y_FLIP(fxMesa->clipMaxY);
#define HW_READ_CLIPLOOP() \
do { \
int _nc = 1; /* numcliprects */ \
+ /* [dBorca] Hack alert: */ \
+ /* remember, we need to flip the scissor, too */ \
+ /* is it better to do it inside fxDDScissor? */ \
while (_nc--) { \
const int minx = fxMesa->clipMinX; \
- const int miny = fxMesa->clipMinY; \
+ const int maxy = Y_FLIP(fxMesa->clipMinY); \
const int maxx = fxMesa->clipMaxX; \
- const int maxy = fxMesa->clipMaxY;
+ const int miny = Y_FLIP(fxMesa->clipMaxY);
#define HW_ENDCLIPLOOP() \
} \
@@ -188,6 +160,13 @@
/* 16 bit, RGB565 color spanline and pixel functions */
+/* [dBorca] Hack alert:
+ * This is wrong. The alpha value is lost, even when we provide
+ * HW alpha (565 w/o depth buffering). To really update alpha buffer,
+ * we would need to do the 565 writings via 8888 colorformat and rely
+ * on the Voodoo to perform color scaling. In which case our 565 span
+ * would look nicer! But this violates FSAA rules...
+ */
#undef LFB_MODE
#define LFB_MODE GR_LFBWRITEMODE_565
@@ -252,6 +231,105 @@
/************************************************************************/
+/***** Depth functions *****/
+/************************************************************************/
+
+#define DBG 0
+
+#undef HW_WRITE_LOCK
+#undef HW_WRITE_UNLOCK
+#undef HW_READ_LOCK
+#undef HW_READ_UNLOCK
+
+#define HW_CLIPLOOP HW_WRITE_CLIPLOOP
+
+#define LOCAL_DEPTH_VARS \
+ GLuint pitch = info.strideInBytes; \
+ GLuint height = fxMesa->height; \
+ char *buf = (char *)((char *)info.lfbPtr + 0 /* x, y offset */); \
+ (void) buf;
+
+#define HW_WRITE_LOCK() \
+ fxMesaContext fxMesa = FX_CONTEXT(ctx); \
+ GrLfbInfo_t info; \
+ info.size = sizeof(GrLfbInfo_t); \
+ if ( grLfbLock( GR_LFB_WRITE_ONLY, \
+ GR_BUFFER_AUXBUFFER, LFB_MODE, \
+ GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) {
+
+#define HW_WRITE_UNLOCK() \
+ grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_AUXBUFFER); \
+ }
+
+#define HW_READ_LOCK() \
+ fxMesaContext fxMesa = FX_CONTEXT(ctx); \
+ GrLfbInfo_t info; \
+ info.size = sizeof(GrLfbInfo_t); \
+ if ( grLfbLock( GR_LFB_READ_ONLY, GR_BUFFER_AUXBUFFER, \
+ LFB_MODE, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) {
+
+#define HW_READ_UNLOCK() \
+ grLfbUnlock( GR_LFB_READ_ONLY, GR_BUFFER_AUXBUFFER); \
+ }
+
+
+/* 16 bit, depth spanline and pixel functions */
+
+#undef LFB_MODE
+#define LFB_MODE GR_LFBWRITEMODE_ZA16
+
+#undef BYTESPERPIXEL
+#define BYTESPERPIXEL 2
+
+#define WRITE_DEPTH( _x, _y, d ) \
+ *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch) = d
+
+#define READ_DEPTH( d, _x, _y ) \
+ d = *(GLushort *)(buf + _x*BYTESPERPIXEL + _y*pitch)
+
+#define TAG(x) tdfx##x##_Z16
+#include "../dri/common/depthtmp.h"
+
+
+/* 24 bit, depth spanline and pixel functions (for use w/ stencil) */
+/* [dBorca] Hack alert:
+ * This is evil. The incoming Mesa's 24bit depth value
+ * is shifted left 8 bits, to obtain a full 32bit value,
+ * which will be thrown into the framebuffer. We rely on
+ * the fact that Voodoo hardware transforms a 32bit value
+ * into 24bit value automatically and, MOST IMPORTANT, won't
+ * alter the upper 8bits of the value already existing in the
+ * framebuffer (where stencil resides).
+ */
+
+#undef LFB_MODE
+#define LFB_MODE GR_LFBWRITEMODE_Z32
+
+#undef BYTESPERPIXEL
+#define BYTESPERPIXEL 4
+
+#define WRITE_DEPTH( _x, _y, d ) \
+ *(GLuint *)(buf + _x*BYTESPERPIXEL + _y*pitch) = d << 8
+
+#define READ_DEPTH( d, _x, _y ) \
+ d = (*(GLuint *)(buf + _x*BYTESPERPIXEL + _y*pitch)) & 0xffffff
+
+#define TAG(x) tdfx##x##_Z24
+#include "../dri/common/depthtmp.h"
+
+
+/* 32 bit, depth spanline and pixel functions (for use w/o stencil) */
+/* [dBorca] Hack alert:
+ * This is more evil. We make Mesa run in 32bit depth, but
+ * tha Voodoo HW can only handle 24bit depth. Well, exploiting
+ * the pixel pipeline, we can achieve 24:8 format for greater
+ * precision...
+ * If anyone tells me how to really store 32bit values into the
+ * depth buffer, I'll write the *_Z32 routines. Howver, bear in
+ * mind that means running without stencil!
+ */
+
+/************************************************************************/
/***** Span functions (optimized) *****/
/************************************************************************/
@@ -378,88 +456,24 @@ static void fxReadRGBASpan_ARGB8888 (const GLcontext * ctx,
GLint x, GLint y,
GLubyte rgba[][4])
{
- /* Hack alert: WRONG! */
fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ GLuint i;
grLfbReadRegion(fxMesa->currentFB, x, fxMesa->height - 1 - y, n, 1, n * 4, rgba);
+ for (i = 0; i < n; i++) {
+ GLubyte c = rgba[i][0];
+ rgba[i][0] = rgba[i][2];
+ rgba[i][2] = c;
+ }
}
/************************************************************************/
-/***** Depth functions *****/
+/***** Depth functions (optimized) *****/
/************************************************************************/
void
-fxDDWriteDepthSpan(GLcontext * ctx,
- GLuint n, GLint x, GLint y, const GLdepth depth[],
- const GLubyte mask[])
-{
- fxMesaContext fxMesa = FX_CONTEXT(ctx);
- GLint bottom = fxMesa->height - 1;
-
- if (TDFX_DEBUG & VERBOSE_DRIVER) {
- fprintf(stderr, "%s(...)\n", __FUNCTION__);
- }
-
-
- if (mask) {
- GLint i;
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- GLshort d = depth[i];
- writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x + i, bottom - y,
- GR_LFB_SRC_FMT_ZA16, 1, 1, 0, (void *) &d);
- }
- }
- }
- else {
- GLushort depth16[MAX_WIDTH];
- GLint i;
- for (i = 0; i < n; i++) {
- depth16[i] = depth[i];
- }
- writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x, bottom - y,
- GR_LFB_SRC_FMT_ZA16, n, 1, 0, (void *) depth16);
- }
-}
-
-
-void
-fxDDWriteDepth32Span(GLcontext * ctx,
- GLuint n, GLint x, GLint y, const GLdepth depth[],
- const GLubyte mask[])
-{
- fxMesaContext fxMesa = FX_CONTEXT(ctx);
- GLint bottom = fxMesa->height - 1;
- GLint i;
-
- if (TDFX_DEBUG & VERBOSE_DRIVER) {
- fprintf(stderr, "%s(...)\n", __FUNCTION__);
- }
-
-
- if (mask) {
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- GLuint d = depth[i] << 8;
- writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x + i, bottom - y,
- GR_LFBWRITEMODE_Z32, 1, 1, 0, (void *) &d);
- }
- }
- }
- else {
- GLuint depth32[MAX_WIDTH];
- for (i = 0; i < n; i++) {
- depth32[i] = depth[i] << 8;
- }
- writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x, bottom - y,
- GR_LFBWRITEMODE_Z32, n, 1, 0, (void *) depth32);
- }
-}
-
-
-void
-fxDDReadDepthSpan(GLcontext * ctx,
- GLuint n, GLint x, GLint y, GLdepth depth[])
+fxReadDepthSpan_Z16(GLcontext * ctx,
+ GLuint n, GLint x, GLint y, GLdepth depth[])
{
fxMesaContext fxMesa = FX_CONTEXT(ctx);
GLint bottom = fxMesa->height - 1;
@@ -478,116 +492,81 @@ fxDDReadDepthSpan(GLcontext * ctx,
void
-fxDDReadDepth32Span(GLcontext * ctx,
- GLuint n, GLint x, GLint y, GLdepth depth[])
+fxReadDepthSpan_Z24(GLcontext * ctx,
+ GLuint n, GLint x, GLint y, GLdepth depth[])
{
fxMesaContext fxMesa = FX_CONTEXT(ctx);
GLint bottom = fxMesa->height - 1;
+ GLuint i;
if (TDFX_DEBUG & VERBOSE_DRIVER) {
fprintf(stderr, "%s(...)\n", __FUNCTION__);
}
grLfbReadRegion(GR_BUFFER_AUXBUFFER, x, bottom - y, n, 1, 0, depth);
+ for (i = 0; i < n; i++) {
+ depth[i] &= 0xffffff;
+ }
}
+/************************************************************************/
+/***** Stencil functions (optimized) *****/
+/************************************************************************/
-void
-fxDDWriteDepthPixels(GLcontext * ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth depth[], const GLubyte mask[])
+void fxWriteStencilSpan (GLcontext *ctx, GLuint n, GLint x, GLint y,
+ const GLstencil stencil[], const GLubyte mask[])
{
- fxMesaContext fxMesa = FX_CONTEXT(ctx);
- GLint bottom = fxMesa->height - 1;
- GLuint i;
-
- if (TDFX_DEBUG & VERBOSE_DRIVER) {
- fprintf(stderr, "%s(...)\n", __FUNCTION__);
- }
-
- for (i = 0; i < n; i++) {
- if (mask[i]) {
- int xpos = x[i];
- int ypos = bottom - y[i];
- GLushort d = depth[i];
- writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, xpos, ypos,
- GR_LFB_SRC_FMT_ZA16, 1, 1, 0, (void *) &d);
- }
- }
+ /*
+ * XXX todo
+ */
}
-
void
-fxDDWriteDepth32Pixels(GLcontext * ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth depth[], const GLubyte mask[])
+fxReadStencilSpan(GLcontext * ctx,
+ GLuint n, GLint x, GLint y, GLstencil stencil[])
{
fxMesaContext fxMesa = FX_CONTEXT(ctx);
GLint bottom = fxMesa->height - 1;
+ GLuint zs32[MAX_WIDTH];
GLuint i;
if (TDFX_DEBUG & VERBOSE_DRIVER) {
fprintf(stderr, "%s(...)\n", __FUNCTION__);
}
+ grLfbReadRegion(GR_BUFFER_AUXBUFFER, x, bottom - y, n, 1, 0, zs32);
for (i = 0; i < n; i++) {
- if (mask[i]) {
- int xpos = x[i];
- int ypos = bottom - y[i];
- GLuint d = depth[i] << 8;
- writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, xpos, ypos,
- GR_LFBWRITEMODE_Z32, 1, 1, 0, (void *) &d);
- }
+ stencil[i] = zs32[i] >> 24;
}
}
-
-void
-fxDDReadDepthPixels(GLcontext * ctx, GLuint n,
- const GLint x[], const GLint y[], GLdepth depth[])
+void fxWriteStencilPixels (GLcontext *ctx, GLuint n,
+ const GLint x[], const GLint y[],
+ const GLstencil stencil[],
+ const GLubyte mask[])
{
- fxMesaContext fxMesa = FX_CONTEXT(ctx);
- GLint bottom = fxMesa->height - 1;
- GLuint i;
-
- if (TDFX_DEBUG & VERBOSE_DRIVER) {
- fprintf(stderr, "%s(...)\n", __FUNCTION__);
- }
-
- for (i = 0; i < n; i++) {
- int xpos = x[i];
- int ypos = bottom - y[i];
- GLushort d;
- grLfbReadRegion(GR_BUFFER_AUXBUFFER, xpos, ypos, 1, 1, 0, &d);
- depth[i] = d;
- }
+ /*
+ * XXX todo
+ */
}
-
-void
-fxDDReadDepth32Pixels(GLcontext * ctx, GLuint n,
- const GLint x[], const GLint y[], GLdepth depth[])
+void fxReadStencilPixels (GLcontext *ctx, GLuint n,
+ const GLint x[], const GLint y[],
+ GLstencil stencil[])
{
- fxMesaContext fxMesa = FX_CONTEXT(ctx);
- GLint bottom = fxMesa->height - 1;
- GLuint i;
-
- if (TDFX_DEBUG & VERBOSE_DRIVER) {
- fprintf(stderr, "%s(...)\n", __FUNCTION__);
- }
-
- for (i = 0; i < n; i++) {
- int xpos = x[i];
- int ypos = bottom - y[i];
- grLfbReadRegion(GR_BUFFER_AUXBUFFER, xpos, ypos, 1, 1, 0, &depth[i]);
- }
+ /*
+ * XXX todo
+ */
}
-/* Set the buffer used for reading */
-/* XXX support for separate read/draw buffers hasn't been tested */
+/*
+ * This function is called to specify which buffer to read and write
+ * for software rasterization (swrast) fallbacks. This doesn't necessarily
+ * correspond to glDrawBuffer() or glReadBuffer() calls.
+ */
static void
fxDDSetBuffer(GLcontext * ctx, GLframebuffer * buffer, GLuint bufferBit)
{
@@ -631,10 +610,10 @@ fxSetupDDSpanPointers(GLcontext * ctx)
swdd->ReadRGBASpan = /*td*/fxReadRGBASpan_ARGB1555;
swdd->ReadRGBAPixels = tdfxReadRGBAPixels_ARGB1555;
- swdd->WriteDepthSpan = fxDDWriteDepthSpan;
- swdd->WriteDepthPixels = fxDDWriteDepthPixels;
- swdd->ReadDepthSpan = fxDDReadDepthSpan;
- swdd->ReadDepthPixels = fxDDReadDepthPixels;
+ swdd->WriteDepthSpan = tdfxWriteDepthSpan_Z16;
+ swdd->WriteDepthPixels = tdfxWriteDepthPixels_Z16;
+ swdd->ReadDepthSpan = /*td*/fxReadDepthSpan_Z16;
+ swdd->ReadDepthPixels = tdfxReadDepthPixels_Z16;
break;
case 16:
swdd->WriteRGBASpan = tdfxWriteRGBASpan_RGB565;
@@ -644,11 +623,11 @@ fxSetupDDSpanPointers(GLcontext * ctx)
swdd->WriteMonoRGBAPixels = tdfxWriteMonoRGBAPixels_RGB565;
swdd->ReadRGBASpan = /*td*/fxReadRGBASpan_RGB565;
swdd->ReadRGBAPixels = tdfxReadRGBAPixels_RGB565;
-
- swdd->WriteDepthSpan = fxDDWriteDepthSpan;
- swdd->WriteDepthPixels = fxDDWriteDepthPixels;
- swdd->ReadDepthSpan = fxDDReadDepthSpan;
- swdd->ReadDepthPixels = fxDDReadDepthPixels;
+
+ swdd->WriteDepthSpan = tdfxWriteDepthSpan_Z16;
+ swdd->WriteDepthPixels = tdfxWriteDepthPixels_Z16;
+ swdd->ReadDepthSpan = /*td*/fxReadDepthSpan_Z16;
+ swdd->ReadDepthPixels = tdfxReadDepthPixels_Z16;
break;
case 32:
swdd->WriteRGBASpan = tdfxWriteRGBASpan_ARGB8888;
@@ -656,29 +635,23 @@ fxSetupDDSpanPointers(GLcontext * ctx)
swdd->WriteRGBAPixels = tdfxWriteRGBAPixels_ARGB8888;
swdd->WriteMonoRGBASpan = tdfxWriteMonoRGBASpan_ARGB8888;
swdd->WriteMonoRGBAPixels = tdfxWriteMonoRGBAPixels_ARGB8888;
- swdd->ReadRGBASpan = tdfxReadRGBASpan_ARGB8888;
+ swdd->ReadRGBASpan = /*td*/fxReadRGBASpan_ARGB8888;
swdd->ReadRGBAPixels = tdfxReadRGBAPixels_ARGB8888;
- swdd->WriteDepthSpan = fxDDWriteDepth32Span;
- swdd->WriteDepthPixels = fxDDWriteDepth32Pixels;
- swdd->ReadDepthSpan = fxDDReadDepth32Span;
- swdd->ReadDepthPixels = fxDDReadDepth32Pixels;
+ swdd->WriteDepthSpan = tdfxWriteDepthSpan_Z24;
+ swdd->WriteDepthPixels = tdfxWriteDepthPixels_Z24;
+ swdd->ReadDepthSpan = /*td*/fxReadDepthSpan_Z24;
+ swdd->ReadDepthPixels = tdfxReadDepthPixels_Z24;
break;
}
-#if 0
- if ( fxMesa->haveHwStencil ) {
- swdd->WriteStencilSpan = write_stencil_span;
- swdd->ReadStencilSpan = read_stencil_span;
- swdd->WriteStencilPixels = write_stencil_pixels;
- swdd->ReadStencilPixels = read_stencil_pixels;
+ if (fxMesa->haveHwStencil) {
+ swdd->WriteStencilSpan = fxWriteStencilSpan;
+ swdd->ReadStencilSpan = fxReadStencilSpan;
+ swdd->WriteStencilPixels = fxWriteStencilPixels;
+ swdd->ReadStencilPixels = fxReadStencilPixels;
}
-
- swdd->WriteDepthSpan = tdfxDDWriteDepthSpan;
- swdd->WriteDepthPixels = tdfxDDWriteDepthPixels;
- swdd->ReadDepthSpan = tdfxDDReadDepthSpan;
- swdd->ReadDepthPixels = tdfxDDReadDepthPixels;
-
+#if 0
swdd->WriteCI8Span = NULL;
swdd->WriteCI32Span = NULL;
swdd->WriteMonoCISpan = NULL;
@@ -687,8 +660,8 @@ fxSetupDDSpanPointers(GLcontext * ctx)
swdd->ReadCI32Span = NULL;
swdd->ReadCI32Pixels = NULL;
- swdd->SpanRenderStart = tdfxSpanRenderStart; /* BEGIN_BOARD_LOCK */
- swdd->SpanRenderFinish = tdfxSpanRenderFinish; /* END_BOARD_LOCK */
+ swdd->SpanRenderStart = tdfxSpanRenderStart; /* BEGIN_BOARD_LOCK */
+ swdd->SpanRenderFinish = tdfxSpanRenderFinish; /* END_BOARD_LOCK */
#endif
}
diff --git a/src/mesa/drivers/glide/fxddtex.c b/src/mesa/drivers/glide/fxddtex.c
index 346d3625b0..8b64a8e2c6 100644
--- a/src/mesa/drivers/glide/fxddtex.c
+++ b/src/mesa/drivers/glide/fxddtex.c
@@ -1,5 +1,3 @@
-/* $Id: fxddtex.c,v 1.51 2003/10/14 14:56:45 dborca Exp $ */
-
/*
* Mesa 3-D graphics library
* Version: 4.0
@@ -715,6 +713,7 @@ fetch_alpha8(const struct gl_texture_image *texImage,
i = i * mml->wScale;
j = j * mml->hScale;
+ /* [dBorca] why, oh... why? */
i = i * mml->width / texImage->Width;
j = j * mml->height / texImage->Height;
@@ -736,6 +735,7 @@ fetch_index8(const struct gl_texture_image *texImage,
i = i * mml->wScale;
j = j * mml->hScale;
+ /* [dBorca] why, oh... why? */
i = i * mml->width / texImage->Width;
j = j * mml->height / texImage->Height;
@@ -863,6 +863,21 @@ fxDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
fxMesaContext fxMesa = FX_CONTEXT(ctx);
GLboolean allow32bpt = fxMesa->HaveTexFmt;
+ /* [dBorca] Hack alert:
+ * There is something wrong with this!!! Take an example:
+ * 1) start HW rendering
+ * 2) create a texture like this:
+ * glTexImage2D(GL_TEXTURE_2D, 0, 3, 16, 16, 0,
+ * GL_RGB, GL_UNSIGNED_BYTE, floorTexture);
+ * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ * 3) we get here with internalFormat==3 and return either
+ * _mesa_texformat_argb565 or _mesa_texformat_argb8888
+ * 4) at some point, we encounter total rasterization fallback
+ * 5) displaying a polygon with the above textures yield garbage on areas
+ * where pixel is larger than a texel, because our already set texel
+ * function doesn't match the real _mesa_texformat_argb888
+ */
+
if (TDFX_DEBUG & VERBOSE_TEXTURE) {
fprintf(stderr, "fxDDChooseTextureFormat(...)\n");
}
diff --git a/src/mesa/drivers/glide/fxdrv.h b/src/mesa/drivers/glide/fxdrv.h
index 204fef78ce..996c1be2bb 100644
--- a/src/mesa/drivers/glide/fxdrv.h
+++ b/src/mesa/drivers/glide/fxdrv.h
@@ -1,5 +1,3 @@
-/* $Id: fxdrv.h,v 1.61 2003/10/14 14:56:45 dborca Exp $ */
-
/*
* Mesa 3-D graphics library
* Version: 4.0
@@ -86,6 +84,14 @@
( (unsigned int)(c[0])) )
#endif
+#define TDFXPACKCOLOR1555( r, g, b, a ) \
+ ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \
+ ((a) ? 0x8000 : 0))
+#define TDFXPACKCOLOR565( r, g, b ) \
+ ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
+#define TDFXPACKCOLOR8888( r, g, b, a ) \
+ (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
+
/* fastpath flags first
@@ -313,6 +319,7 @@ typedef struct
GrAlphaBlendFnc_t blendDstFuncRGB;
GrAlphaBlendFnc_t blendSrcFuncAlpha;
GrAlphaBlendFnc_t blendDstFuncAlpha;
+ GrAlphaBlendOp_t blendEq;
/* Depth test */
@@ -531,6 +538,7 @@ struct tfxMesaContext
FxBool HaveTexFmt; /* TEXFMT */
FxBool HaveCmbExt; /* COMBINE */
FxBool HaveMirExt; /* TEXMIRROR */
+ FxBool HaveTexUma; /* TEXUMA */
FxBool HaveTexus2; /* Texus 2 - FXT1 */
struct tdfx_glide Glide;
char rendererString[100];
@@ -597,6 +605,8 @@ extern void fxDDTexUseGlbPalette(GLcontext *, GLboolean);
extern void fxDDEnable(GLcontext *, GLenum, GLboolean);
extern void fxDDAlphaFunc(GLcontext *, GLenum, GLfloat);
extern void fxDDBlendFunc(GLcontext *, GLenum, GLenum);
+extern void fxDDBlendFuncSeparate(GLcontext *, GLenum, GLenum, GLenum, GLenum);
+extern void fxDDBlendEquation(GLcontext *, GLenum);
extern void fxDDDepthMask(GLcontext *, GLboolean);
extern void fxDDDepthFunc(GLcontext *, GLenum);
extern void fxDDStencilFunc (GLcontext *ctx, GLenum func, GLint ref, GLuint mask);
@@ -617,6 +627,7 @@ extern void fxTMReloadMipMapLevel(fxMesaContext, struct gl_texture_object *,
extern void fxTMReloadSubMipMapLevel(fxMesaContext,
struct gl_texture_object *, GLint, GLint,
GLint);
+extern int fxTMCheckStartAddr (fxMesaContext fxMesa, GLint tmu, tfxTexInfo *ti);
extern void fxTexGetFormat(GLcontext *, GLenum, GrTextureFormat_t *, GLint *); /* [koolsmoky] */
@@ -665,6 +676,7 @@ extern void fxCheckIsInHardware(GLcontext *ctx);
/* fxsetup:
* semi-private functions
*/
+void fxSetupCull (GLcontext * ctx);
void fxSetupScissor (GLcontext * ctx);
void fxSetupColorMask (GLcontext * ctx);
diff --git a/src/mesa/drivers/glide/fxg.c b/src/mesa/drivers/glide/fxg.c
index 25b2bb6b9c..99c2066af1 100644
--- a/src/mesa/drivers/glide/fxg.c
+++ b/src/mesa/drivers/glide/fxg.c
@@ -30,8 +30,6 @@
* Web : http://www.geocities.com/dborca
*/
-#ifdef FX
-
#include <stdio.h>
#include <stdarg.h>
@@ -243,6 +241,8 @@ const char *TRP_BLEND (GrAlphaBlendFnc_t func)
TRAP_CASE_STRING(GR_BLEND_RESERVED_E);
TRAP_CASE_STRING(GR_BLEND_ALPHA_SATURATE);
/*TRAP_CASE_STRING(GR_BLEND_PREFOG_COLOR); ==GR_BLEND_ALPHA_SATURATE*/
+ TRAP_CASE_STRING(GR_BLEND_SAME_COLOR_EXT);
+ TRAP_CASE_STRING(GR_BLEND_ONE_MINUS_SAME_COLOR_EXT);
TRAP_NODEFAULT;
}
}
@@ -733,8 +733,6 @@ const char *TRP_BLENDOP (GrAlphaBlendOp_t op)
TRAP_CASE_STRING(GR_BLEND_OP_ADD);
TRAP_CASE_STRING(GR_BLEND_OP_SUB);
TRAP_CASE_STRING(GR_BLEND_OP_REVSUB);
- TRAP_CASE_STRING(GR_BLEND_SAME_COLOR_EXT);
- TRAP_CASE_STRING(GR_BLEND_ONE_MINUS_SAME_COLOR_EXT);
TRAP_NODEFAULT;
}
}
@@ -2135,5 +2133,3 @@ void tdfx_hook_glide (struct tdfx_glide *Glide)
#undef GET_EXT_ADDR
}
-
-#endif /* FX */
diff --git a/src/mesa/drivers/glide/fxglidew.c b/src/mesa/drivers/glide/fxglidew.c
index e20949e062..0e6ff6a530 100644
--- a/src/mesa/drivers/glide/fxglidew.c
+++ b/src/mesa/drivers/glide/fxglidew.c
@@ -1,5 +1,3 @@
-/* $Id: fxglidew.c,v 1.23 2003/10/13 11:14:58 dborca Exp $ */
-
/*
* Mesa 3-D graphics library
* Version: 4.0
@@ -230,6 +228,7 @@ FX_grSstQueryHardware(GrHwConfiguration * config)
config->SSTs[i].HaveTexFmt = (strstr(extension, " TEXFMT ") != NULL);
config->SSTs[i].HaveCmbExt = (strstr(extension, " COMBINE ") != NULL);
config->SSTs[i].HaveMirExt = (strstr(extension, " TEXMIRROR ") != NULL);
+ config->SSTs[i].HaveTexUma = (strstr(extension, " TEXUMA ") != NULL);
config->SSTs[i].HaveTexus2 = GL_FALSE;
/* number of Voodoo chips */
diff --git a/src/mesa/drivers/glide/fxglidew.h b/src/mesa/drivers/glide/fxglidew.h
index fb354ffd6f..7f7bd692ee 100644
--- a/src/mesa/drivers/glide/fxglidew.h
+++ b/src/mesa/drivers/glide/fxglidew.h
@@ -1,5 +1,3 @@
-/* $Id: fxglidew.h,v 1.18 2003/10/13 11:14:58 dborca Exp $ */
-
/*
* Mesa 3-D graphics library
* Version: 4.0
@@ -78,6 +76,7 @@ typedef struct {
FxBool HaveTexFmt; /* TEXFMT */
FxBool HaveCmbExt; /* COMBINE */
FxBool HaveMirExt; /* TEXMIRROR */
+ FxBool HaveTexUma; /* TEXUMA */
FxBool HaveTexus2; /* Texus 2 - FXT1 */
}
SSTs[MAX_NUM_SST]; /* configuration for each board */
diff --git a/src/mesa/drivers/glide/fxsetup.c b/src/mesa/drivers/glide/fxsetup.c
index d9c42dd088..40fd4a5f9c 100644
--- a/src/mesa/drivers/glide/fxsetup.c
+++ b/src/mesa/drivers/glide/fxsetup.c
@@ -1,5 +1,3 @@
-/* $Id: fxsetup.c,v 1.42 2003/10/13 11:14:58 dborca Exp $ */
-
/*
* Mesa 3-D graphics library
* Version: 4.0
@@ -315,13 +313,8 @@ fxSetupSingleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj)
if (ti->LODblend)
fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU_SPLIT);
else {
- /* XXX putting textures into the second memory bank when the
- * first bank is full is not working at this time.
- */
- if (/*[dBorca]: fixme*/0 && fxMesa->haveTwoTMUs) {
- if (fxMesa->freeTexMem[FX_TMU0] >
- grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH,
- &(ti->info))) {
+ if (fxMesa->haveTwoTMUs) {
+ if (fxTMCheckStartAddr(fxMesa, FX_TMU0, ti)) {
fxTMMoveInTM_NoLock(fxMesa, tObj, FX_TMU0);
}
else {
@@ -431,8 +424,10 @@ fxSelectSingleTMUSrc_NoLock(fxMesaContext fxMesa, GLint tmu, FxBool LODblend)
tex1.FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL;
tex1.FactorAlpha = GR_COMBINE_FACTOR_NONE;
- /* GR_COMBINE_FUNCTION_SCALE_OTHER doesn't work ?!? */
-
+ /* [dBorca] Hack alert:
+ * don't use GR_COMBINE_FUNCTION_SCALE_OTHER
+ * such that Glide recognizes TMU0 in passthrough mode
+ */
tex0.FunctionRGB = GR_COMBINE_FUNCTION_BLEND;
tex0.FactorRGB = GR_COMBINE_FACTOR_ONE;
tex0.FunctionAlpha = GR_COMBINE_FUNCTION_BLEND;
@@ -549,49 +544,49 @@ fxSetupTextureSingleTMU_NoLock(GLcontext * ctx, GLuint textureset)
}
break;
case GL_BLEND:
-#if 1
- if (TDFX_DEBUG & VERBOSE_DRIVER) {
- fprintf(stderr, "%s: GL_BLEND not quite supported\n", __FUNCTION__);
- }
- return;
-#else
- /*
- * XXX we can't do real GL_BLEND mode. These settings assume that
- * the TexEnv color is black and incoming fragment color is white.
- */
if (ifmt == GL_LUMINANCE || ifmt == GL_RGB) {
/* Av = Af */
alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
- alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
- alphaComb.Other = GR_COMBINE_OTHER_NONE;
+ alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
+ alphaComb.Other = GR_COMBINE_OTHER_NONE;
}
else if (ifmt == GL_INTENSITY) {
/* Av = Af * (1 - It) + Ac * It */
- /* XXX this is wrong */
- alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
- alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
- alphaComb.Other = GR_COMBINE_OTHER_NONE;
+ alphaComb.Function = GR_COMBINE_FUNCTION_BLEND;
+ alphaComb.Factor = GR_COMBINE_FACTOR_TEXTURE_ALPHA;
+ alphaComb.Other = GR_COMBINE_OTHER_CONSTANT;
}
else {
/* Av = Af * At */
alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
- alphaComb.Factor = GR_COMBINE_FACTOR_LOCAL;
- alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
+ alphaComb.Factor = GR_COMBINE_FACTOR_LOCAL;
+ alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
}
+
if (ifmt == GL_ALPHA) {
colorComb.Function = GR_COMBINE_FUNCTION_LOCAL;
- colorComb.Factor = GR_COMBINE_FACTOR_NONE;
- colorComb.Other = GR_COMBINE_OTHER_NONE;
- }
- else {
- colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
- colorComb.Factor = GR_COMBINE_FACTOR_ONE;
- colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
- colorComb.Invert = FXTRUE;
+ colorComb.Factor = GR_COMBINE_FACTOR_NONE;
+ colorComb.Other = GR_COMBINE_OTHER_NONE;
+ } else {
+ /* [dBorca] Hack alert:
+ * only Voodoo^2 can GL_BLEND (GR_COMBINE_FACTOR_TEXTURE_RGB)
+ */
+ if (fxMesa->type >= GR_SSTTYPE_Voodoo2) {
+ colorComb.Function = GR_COMBINE_FUNCTION_BLEND;
+ colorComb.Factor = GR_COMBINE_FACTOR_TEXTURE_RGB;
+ colorComb.Other = GR_COMBINE_OTHER_CONSTANT;
+ } else {
+ _mesa_problem(NULL, "can't GL_BLEND with SST1");
+ return;
+ }
}
- /* XXX return GL_FALSE for modes we don't support */
+
+ grConstantColorValue(
+ ((GLuint)((ctx->Texture.Unit[textureset].EnvColor[0] * 255.0f)) ) |
+ ((GLuint)((ctx->Texture.Unit[textureset].EnvColor[1] * 255.0f)) << 8) |
+ ((GLuint)((ctx->Texture.Unit[textureset].EnvColor[2] * 255.0f)) << 16) |
+ ((GLuint)((ctx->Texture.Unit[textureset].EnvColor[3] * 255.0f)) << 24));
break;
-#endif
case GL_REPLACE:
if ((ifmt == GL_RGB) || (ifmt == GL_LUMINANCE)) {
alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
@@ -613,6 +608,41 @@ fxSetupTextureSingleTMU_NoLock(GLcontext * ctx, GLuint textureset)
colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
}
break;
+ case GL_ADD:
+ if (ifmt == GL_ALPHA ||
+ ifmt == GL_LUMINANCE_ALPHA ||
+ ifmt == GL_RGBA) {
+ /* product of texel and fragment alpha */
+ alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER;
+ alphaComb.Factor = GR_COMBINE_FACTOR_LOCAL;
+ alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
+ }
+ else if (ifmt == GL_LUMINANCE || ifmt == GL_RGB) {
+ /* fragment alpha is unchanged */
+ alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL;
+ alphaComb.Factor = GR_COMBINE_FACTOR_NONE;
+ alphaComb.Other = GR_COMBINE_OTHER_NONE;
+ }
+ else {
+ /* sum of texel and fragment alpha */
+ alphaComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,
+ alphaComb.Factor = GR_COMBINE_FACTOR_ONE;
+ alphaComb.Other = GR_COMBINE_OTHER_TEXTURE;
+ }
+
+ if (ifmt == GL_ALPHA) {
+ /* rgb unchanged */
+ colorComb.Function = GR_COMBINE_FUNCTION_LOCAL;
+ colorComb.Factor = GR_COMBINE_FACTOR_NONE;
+ colorComb.Other = GR_COMBINE_OTHER_NONE;
+ }
+ else {
+ /* sum of texel and fragment rgb */
+ colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL,
+ colorComb.Factor = GR_COMBINE_FACTOR_ONE;
+ colorComb.Other = GR_COMBINE_OTHER_TEXTURE;
+ }
+ break;
default:
if (TDFX_DEBUG & VERBOSE_DRIVER) {
fprintf(stderr, "%s: %x Texture.EnvMode not yet supported\n", __FUNCTION__,
@@ -1083,6 +1113,8 @@ fxSetupTextureNone_NoLock(GLcontext * ctx)
fxMesa->lastUnitsMode = FX_UM_NONE;
}
+#include "fxsetup.h"
+
/************************************************************************/
/************************** Texture Mode SetUp **************************/
/************************************************************************/
@@ -1096,20 +1128,38 @@ fxSetupTexture_NoLock(GLcontext * ctx)
fprintf(stderr, "%s(...)\n", __FUNCTION__);
}
- /* Texture Combine, Color Combine and Alpha Combine. */
- if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT &&
- ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT &&
- fxMesa->haveTwoTMUs) {
- fxSetupTextureDoubleTMU_NoLock(ctx);
- }
- else if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) {
- fxSetupTextureSingleTMU_NoLock(ctx, 0);
- }
- else if (ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT) {
- fxSetupTextureSingleTMU_NoLock(ctx, 1);
- }
- else {
- fxSetupTextureNone_NoLock(ctx);
+ if (fxMesa->HaveCmbExt) {
+ /* Texture Combine, Color Combine and Alpha Combine. */
+ if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT &&
+ ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT &&
+ fxMesa->haveTwoTMUs) {
+ fxSetupTextureDoubleTMUNapalm_NoLock(ctx);
+ }
+ else if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) {
+ fxSetupTextureSingleTMUNapalm_NoLock(ctx, 0);
+ }
+ else if (ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT) {
+ fxSetupTextureSingleTMUNapalm_NoLock(ctx, 1);
+ }
+ else {
+ fxSetupTextureNoneNapalm_NoLock(ctx);
+ }
+ } else {
+ /* Texture Combine, Color Combine and Alpha Combine. */
+ if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT &&
+ ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT &&
+ fxMesa->haveTwoTMUs) {
+ fxSetupTextureDoubleTMU_NoLock(ctx);
+ }
+ else if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) {
+ fxSetupTextureSingleTMU_NoLock(ctx, 0);
+ }
+ else if (ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT) {
+ fxSetupTextureSingleTMU_NoLock(ctx, 1);
+ }
+ else {
+ fxSetupTextureNone_NoLock(ctx);
+ }
}
}
@@ -1125,117 +1175,211 @@ fxSetupTexture(GLcontext * ctx)
/**************************** Blend SetUp *******************************/
/************************************************************************/
-/* XXX consider supporting GL_INGR_blend_func_separate */
void
-fxDDBlendFunc(GLcontext * ctx, GLenum sfactor, GLenum dfactor)
+fxDDBlendFuncSeparate(GLcontext * ctx, GLenum sfactor, GLenum dfactor, GLenum asfactor, GLenum adfactor)
{
fxMesaContext fxMesa = FX_CONTEXT(ctx);
tfxUnitsState *us = &fxMesa->unitsState;
+ GLboolean have32bpp = (fxMesa->colDepth == 32);
+ GLboolean haveAlpha = fxMesa->haveHwAlpha;
GrAlphaBlendFnc_t sfact, dfact, asfact, adfact;
- /* From the Glide documentation:
- For alpha source and destination blend function factor
- parameters, Voodoo Graphics supports only
- GR_BLEND_ZERO and GR_BLEND_ONE.
+ /* [dBorca] Hack alert:
+ * We should condition *DST_ALPHA* modes
+ * by the boolean `haveAlpha' above!
+ * It indicates whether we really have HW alpha buffer...
*/
+/*
+When the value A_COLOR is selected as the destination alpha blending factor,
+the source pixel color is used as the destination blending factor. When the
+value A_COLOR is selected as the source alpha blending factor, the destination
+pixel color is used as the source blending factor. When the value A_SAMECOLOR
+is selected as the destination alpha blending factor, the destination pixel
+color is used as the destination blending factor. When the value A_SAMECOLOR
+is selected as the source alpha blending factor, the source pixel color is
+used as the source blending factor. Note also that the alpha blending
+function 0xf (A_COLORBEFOREFOG/ASATURATE) is different depending upon whether
+it is being used as a source or destination alpha blending function. When the
+value 0xf is selected as the destination alpha blending factor, the source
+color before the fog unit ("unfogged" color) is used as the destination
+blending factor -- this alpha blending function is useful for multi-pass
+rendering with atmospheric effects. When the value 0xf is selected as the
+source alpha blending factor, the alpha-saturate anti-aliasing algorithm is
+selected -- this MIN function performs polygonal anti-aliasing for polygons
+which are drawn front-to-back.
+
+15/16 BPP alpha channel alpha blending modes
+ 0x0 AZERO Zero
+ 0x4 AONE One
+
+32 BPP alpha channel alpha blending modes
+ 0x0 AZERO Zero
+ 0x1 ASRC_ALPHA Source alpha
+ 0x3 ADST_ALPHA Destination alpha
+ 0x4 AONE One
+ 0x5 AOMSRC_ALPHA 1 - Source alpha
+ 0x7 AOMDST_ALPHA 1 - Destination alpha
+*/
+
switch (sfactor) {
case GL_ZERO:
- asfact = sfact = GR_BLEND_ZERO;
+ sfact = GR_BLEND_ZERO;
break;
case GL_ONE:
- asfact = sfact = GR_BLEND_ONE;
+ sfact = GR_BLEND_ONE;
break;
case GL_DST_COLOR:
sfact = GR_BLEND_DST_COLOR;
- asfact = GR_BLEND_ONE;
break;
case GL_ONE_MINUS_DST_COLOR:
sfact = GR_BLEND_ONE_MINUS_DST_COLOR;
- asfact = GR_BLEND_ONE;
break;
case GL_SRC_ALPHA:
sfact = GR_BLEND_SRC_ALPHA;
- asfact = GR_BLEND_ONE;
break;
case GL_ONE_MINUS_SRC_ALPHA:
sfact = GR_BLEND_ONE_MINUS_SRC_ALPHA;
- asfact = GR_BLEND_ONE;
break;
case GL_DST_ALPHA:
sfact = GR_BLEND_DST_ALPHA;
- asfact = GR_BLEND_ONE;
break;
case GL_ONE_MINUS_DST_ALPHA:
sfact = GR_BLEND_ONE_MINUS_DST_ALPHA;
- asfact = GR_BLEND_ONE;
break;
case GL_SRC_ALPHA_SATURATE:
sfact = GR_BLEND_ALPHA_SATURATE;
- asfact = GR_BLEND_ONE;
break;
case GL_SRC_COLOR:
case GL_ONE_MINUS_SRC_COLOR:
/* USELESS */
- asfact = sfact = GR_BLEND_ONE;
+ sfact = GR_BLEND_ONE;
break;
default:
- asfact = sfact = GR_BLEND_ONE;
+ sfact = GR_BLEND_ONE;
break;
}
- if ((sfact != us->blendSrcFuncRGB) || (asfact != us->blendSrcFuncAlpha)) {
- us->blendSrcFuncRGB = sfact;
- us->blendSrcFuncAlpha = asfact;
- fxMesa->new_state |= FX_NEW_BLEND;
+ switch (asfactor) {
+ case GL_ZERO:
+ asfact = GR_BLEND_ZERO;
+ break;
+ case GL_ONE:
+ asfact = GR_BLEND_ONE;
+ break;
+ case GL_DST_COLOR:
+ asfact = GR_BLEND_ONE/*bad*/;
+ break;
+ case GL_ONE_MINUS_DST_COLOR:
+ asfact = GR_BLEND_ONE/*bad*/;
+ break;
+ case GL_SRC_ALPHA:
+ asfact = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ONE/*bad*/;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ asfact = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ONE/*bad*/;
+ break;
+ case GL_DST_ALPHA:
+ asfact = have32bpp ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*bad*/;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ asfact = have32bpp ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ONE/*bad*/;
+ break;
+ case GL_SRC_ALPHA_SATURATE:
+ asfact = GR_BLEND_ONE/*bad*/;
+ break;
+ case GL_SRC_COLOR:
+ case GL_ONE_MINUS_SRC_COLOR:
+ /* USELESS */
+ asfact = GR_BLEND_ONE/*bad*/;
+ break;
+ default:
+ asfact = GR_BLEND_ONE/*bad*/;
+ break;
}
switch (dfactor) {
case GL_ZERO:
- adfact = dfact = GR_BLEND_ZERO;
+ dfact = GR_BLEND_ZERO;
break;
case GL_ONE:
- adfact = dfact = GR_BLEND_ONE;
+ dfact = GR_BLEND_ONE;
break;
case GL_SRC_COLOR:
dfact = GR_BLEND_SRC_COLOR;
- adfact = GR_BLEND_ZERO;
break;
case GL_ONE_MINUS_SRC_COLOR:
dfact = GR_BLEND_ONE_MINUS_SRC_COLOR;
- adfact = GR_BLEND_ZERO;
break;
case GL_SRC_ALPHA:
dfact = GR_BLEND_SRC_ALPHA;
- adfact = GR_BLEND_ZERO;
break;
case GL_ONE_MINUS_SRC_ALPHA:
dfact = GR_BLEND_ONE_MINUS_SRC_ALPHA;
- adfact = GR_BLEND_ZERO;
break;
case GL_DST_ALPHA:
/* dfact=GR_BLEND_DST_ALPHA; */
/* We can't do DST_ALPHA */
dfact = GR_BLEND_ONE;
- adfact = GR_BLEND_ZERO;
break;
case GL_ONE_MINUS_DST_ALPHA:
/* dfact=GR_BLEND_ONE_MINUS_DST_ALPHA; */
/* We can't do DST_ALPHA */
dfact = GR_BLEND_ZERO;
+ break;
+ case GL_SRC_ALPHA_SATURATE:
+ case GL_DST_COLOR:
+ case GL_ONE_MINUS_DST_COLOR:
+ /* USELESS */
+ dfact = GR_BLEND_ZERO;
+ break;
+ default:
+ dfact = GR_BLEND_ZERO;
+ break;
+ }
+
+ switch (adfactor) {
+ case GL_ZERO:
adfact = GR_BLEND_ZERO;
break;
+ case GL_ONE:
+ adfact = GR_BLEND_ONE;
+ break;
+ case GL_SRC_COLOR:
+ adfact = GR_BLEND_ZERO/*bad*/;
+ break;
+ case GL_ONE_MINUS_SRC_COLOR:
+ adfact = GR_BLEND_ZERO/*bad*/;
+ break;
+ case GL_SRC_ALPHA:
+ adfact = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ZERO/*bad*/;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ adfact = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ZERO/*bad*/;
+ break;
+ case GL_DST_ALPHA:
+ adfact = have32bpp ? GR_BLEND_DST_ALPHA : GR_BLEND_ZERO/*bad*/;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ adfact = have32bpp ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*bad*/;
+ break;
case GL_SRC_ALPHA_SATURATE:
case GL_DST_COLOR:
case GL_ONE_MINUS_DST_COLOR:
/* USELESS */
- adfact = dfact = GR_BLEND_ZERO;
+ adfact = GR_BLEND_ZERO/*bad*/;
break;
default:
- adfact = dfact = GR_BLEND_ZERO;
+ adfact = GR_BLEND_ZERO/*bad*/;
break;
}
+ if ((sfact != us->blendSrcFuncRGB) || (asfact != us->blendSrcFuncAlpha)) {
+ us->blendSrcFuncRGB = sfact;
+ us->blendSrcFuncAlpha = asfact;
+ fxMesa->new_state |= FX_NEW_BLEND;
+ }
+
if ((dfact != us->blendDstFuncRGB) || (adfact != us->blendDstFuncAlpha)) {
us->blendDstFuncRGB = dfact;
us->blendDstFuncAlpha = adfact;
@@ -1243,18 +1387,66 @@ fxDDBlendFunc(GLcontext * ctx, GLenum sfactor, GLenum dfactor)
}
}
+void
+fxDDBlendFunc(GLcontext * ctx, GLenum sfactor, GLenum dfactor)
+{
+ fxDDBlendFuncSeparate(ctx, sfactor, dfactor, sfactor, dfactor);
+}
+
+void
+fxDDBlendEquation(GLcontext * ctx, GLenum mode)
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ tfxUnitsState *us = &fxMesa->unitsState;
+ GrAlphaBlendOp_t q;
+
+ switch (mode) {
+ case GL_FUNC_ADD_EXT:
+ q = GR_BLEND_OP_ADD;
+ break;
+ case GL_FUNC_SUBTRACT_EXT:
+ q = GR_BLEND_OP_SUB;
+ break;
+ case GL_FUNC_REVERSE_SUBTRACT_EXT:
+ q = GR_BLEND_OP_REVSUB;
+ break;
+ default:
+ return;
+ }
+
+ if ((q != us->blendEq) && fxMesa->HavePixExt) {
+ us->blendEq = q;
+ fxMesa->new_state |= FX_NEW_BLEND;
+ }
+}
+
static void
fxSetupBlend(GLcontext * ctx)
{
- fxMesaContext fxMesa = FX_CONTEXT(ctx);
- tfxUnitsState *us = &fxMesa->unitsState;
-
- if (us->blendEnabled)
- grAlphaBlendFunction(us->blendSrcFuncRGB, us->blendDstFuncRGB,
- us->blendSrcFuncAlpha, us->blendDstFuncAlpha);
- else
- grAlphaBlendFunction(GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ONE,
- GR_BLEND_ZERO);
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ tfxUnitsState *us = &fxMesa->unitsState;
+
+ if (fxMesa->HavePixExt) {
+ if (us->blendEnabled) {
+ fxMesa->Glide.grAlphaBlendFunctionExt(us->blendSrcFuncRGB, us->blendDstFuncRGB,
+ us->blendEq,
+ us->blendSrcFuncAlpha, us->blendDstFuncAlpha,
+ us->blendEq);
+ } else {
+ fxMesa->Glide.grAlphaBlendFunctionExt(GR_BLEND_ONE, GR_BLEND_ZERO,
+ GR_BLEND_OP_ADD,
+ GR_BLEND_ONE, GR_BLEND_ZERO,
+ GR_BLEND_OP_ADD);
+ }
+ } else {
+ if (us->blendEnabled) {
+ grAlphaBlendFunction(us->blendSrcFuncRGB, us->blendDstFuncRGB,
+ us->blendSrcFuncAlpha, us->blendDstFuncAlpha);
+ } else {
+ grAlphaBlendFunction(GR_BLEND_ONE, GR_BLEND_ZERO,
+ GR_BLEND_ONE, GR_BLEND_ZERO);
+ }
+ }
}
/************************************************************************/
@@ -1468,8 +1660,8 @@ fxSetupColorMask(GLcontext * ctx)
}
else {
/* 16 bpp mode */
- grColorMask(ctx->Color.ColorMask[RCOMP] ||
- ctx->Color.ColorMask[GCOMP] ||
+ grColorMask(ctx->Color.ColorMask[RCOMP] |
+ ctx->Color.ColorMask[GCOMP] |
ctx->Color.ColorMask[BCOMP],
ctx->Color.ColorMask[ACOMP] && fxMesa->haveHwAlpha);
}
diff --git a/src/mesa/drivers/glide/fxsetup.h b/src/mesa/drivers/glide/fxsetup.h
new file mode 100644
index 0000000000..90aefe2758
--- /dev/null
+++ b/src/mesa/drivers/glide/fxsetup.h
@@ -0,0 +1,1128 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 4.0
+ *
+ * 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:
+ * David Bucciarelli
+ * Brian Paul
+ * Daryll Strauss
+ * Keith Whitwell
+ * Daniel Borca
+ * Hiroshi Morii
+ */
+
+/* fxsetup.c - 3Dfx VooDoo rendering mode setup functions */
+/* [dBorca] Hack alert:
+ * this code belongs to fxsetup.c, but I didn't want to clutter
+ * the original code with Napalm specifics, in order to keep things
+ * clear -- especially for backward compatibility. I should have
+ * put it into another .c file, but I didn't want to export so many
+ * things...
+ * The point is, Napalm uses a different technique for texture env.
+ * SST1 Single texturing:
+ * setup standard grTexCombine
+ * fiddle with grColorCombine/grAlphaCombine
+ * SST1 Multi texturing:
+ * fiddle with grTexCombine/grColorCombine/grAlphaCombine
+ * Napalm Single texturing:
+ * setup standard grColorCombineExt/grAlphaCombineExt
+ * fiddle with grTexColorCombine/grTexAlphaCombine
+ * Napalm Multi texturing:
+ * setup standard grColorCombineExt/grAlphaCombineExt
+ * fiddle with grTexColorCombine/grTexAlphaCombine
+ */
+
+/*
+ * These macros are used below when handling COMBINE_EXT.
+ */
+#define TEXENV_OPERAND_INVERTED(operand) \
+ (((operand) == GL_ONE_MINUS_SRC_ALPHA) \
+ || ((operand) == GL_ONE_MINUS_SRC_COLOR))
+#define TEXENV_OPERAND_ALPHA(operand) \
+ (((operand) == GL_SRC_ALPHA) || ((operand) == GL_ONE_MINUS_SRC_ALPHA))
+#define TEXENV_SETUP_ARG_A(param, source, operand, iteratedAlpha) \
+ switch (source) { \
+ case GL_TEXTURE: \
+ param = GR_CMBX_LOCAL_TEXTURE_ALPHA; \
+ break; \
+ case GL_CONSTANT_EXT: \
+ param = GR_CMBX_TMU_CALPHA; \
+ break; \
+ case GL_PRIMARY_COLOR_EXT: \
+ param = GR_CMBX_ITALPHA; \
+ break; \
+ case GL_PREVIOUS_EXT: \
+ param = iteratedAlpha; \
+ break; \
+ default: \
+ /* \
+ * This is here just to keep from getting \
+ * compiler warnings. \
+ */ \
+ param = GR_CMBX_ZERO; \
+ break; \
+ }
+
+#define TEXENV_SETUP_ARG_RGB(param, source, operand, iteratedColor, iteratedAlpha) \
+ if (!TEXENV_OPERAND_ALPHA(operand)) { \
+ switch (source) { \
+ case GL_TEXTURE: \
+ param = GR_CMBX_LOCAL_TEXTURE_RGB; \
+ break; \
+ case GL_CONSTANT_EXT: \
+ param = GR_CMBX_TMU_CCOLOR; \
+ break; \
+ case GL_PRIMARY_COLOR_EXT: \
+ param = GR_CMBX_ITRGB; \
+ break; \
+ case GL_PREVIOUS_EXT: \
+ param = iteratedColor; \
+ break; \
+ default: \
+ /* \
+ * This is here just to keep from getting \
+ * compiler warnings. \
+ */ \
+ param = GR_CMBX_ZERO; \
+ break; \
+ } \
+ } else { \
+ switch (source) { \
+ case GL_TEXTURE: \
+ param = GR_CMBX_LOCAL_TEXTURE_ALPHA; \
+ break; \
+ case GL_CONSTANT_EXT: \
+ param = GR_CMBX_TMU_CALPHA; \
+ break; \
+ case GL_PRIMARY_COLOR_EXT: \
+ param = GR_CMBX_ITALPHA; \
+ break; \
+ case GL_PREVIOUS_EXT: \
+ param = iteratedAlpha; \
+ break; \
+ default: \
+ /* \
+ * This is here just to keep from getting \
+ * compiler warnings. \
+ */ \
+ param = GR_CMBX_ZERO; \
+ break; \
+ } \
+ }
+
+#define TEXENV_SETUP_MODE_RGB(param, operand) \
+ switch (operand) { \
+ case GL_SRC_COLOR: \
+ case GL_SRC_ALPHA: \
+ param = GR_FUNC_MODE_X; \
+ break; \
+ case GL_ONE_MINUS_SRC_ALPHA: \
+ case GL_ONE_MINUS_SRC_COLOR: \
+ param = GR_FUNC_MODE_ONE_MINUS_X; \
+ break; \
+ default: \
+ param = GR_FUNC_MODE_ZERO; \
+ break; \
+ }
+
+#define TEXENV_SETUP_MODE_A(param, operand) \
+ switch (operand) { \
+ case GL_SRC_ALPHA: \
+ param = GR_FUNC_MODE_X; \
+ break; \
+ case GL_ONE_MINUS_SRC_ALPHA: \
+ param = GR_FUNC_MODE_ONE_MINUS_X; \
+ break; \
+ default: \
+ param = GR_FUNC_MODE_ZERO; \
+ break; \
+ }
+
+static void
+fxSetupTextureEnvNapalm_NoLock(GLcontext * ctx, GLuint textureset, GLuint tmu, GLboolean iterated)
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[textureset];
+ struct tdfx_combine_alpha_ext alphaComb;
+ struct tdfx_combine_color_ext colorComb;
+ GLfloat *envColor = texUnit->EnvColor;
+ GrCombineLocal_t localc, locala; /* fragmentColor/Alpha */
+ GLint ifmt;
+ tfxTexInfo *ti;
+ struct gl_texture_object *tObj = texUnit->Current2D;
+
+ if (TDFX_DEBUG & VERBOSE_DRIVER) {
+ fprintf(stderr, "%s(...)\n", __FUNCTION__);
+ }
+
+ ti = fxTMGetTexInfo(tObj);
+
+ ifmt = ti->baseLevelInternalFormat;
+
+ if (iterated) {
+ /* we don't have upstream TMU */
+ locala = GR_CMBX_ITALPHA;
+ localc = GR_CMBX_ITRGB;
+ } else {
+ /* we have upstream TMU */
+ locala = GR_CMBX_OTHER_TEXTURE_ALPHA;
+ localc = GR_CMBX_OTHER_TEXTURE_RGB;
+ }
+
+ alphaComb.InvertD = FXFALSE;
+ alphaComb.Shift = 0;
+ alphaComb.Invert = FXFALSE;
+ colorComb.InvertD = FXFALSE;
+ colorComb.Shift = 0;
+ colorComb.Invert = FXFALSE;
+
+ switch (texUnit->EnvMode) {
+ case GL_DECAL:
+ alphaComb.SourceA = locala;
+ alphaComb.ModeA = GR_FUNC_MODE_X;
+ alphaComb.SourceB = GR_CMBX_ZERO;
+ alphaComb.ModeB = GR_FUNC_MODE_X;
+ alphaComb.SourceC = GR_CMBX_ZERO;
+ alphaComb.InvertC = FXTRUE;
+ alphaComb.SourceD = GR_CMBX_ZERO;
+
+ colorComb.SourceA = GR_CMBX_LOCAL_TEXTURE_RGB;
+ colorComb.ModeA = GR_FUNC_MODE_X;
+ colorComb.SourceB = localc;
+ colorComb.ModeB = GR_FUNC_MODE_NEGATIVE_X;
+ colorComb.SourceC = GR_CMBX_LOCAL_TEXTURE_ALPHA;
+ colorComb.InvertC = FXFALSE;
+ colorComb.SourceD = GR_CMBX_B;
+ break;
+ case GL_MODULATE:
+ if (ifmt == GL_LUMINANCE || ifmt == GL_RGB) {
+ alphaComb.SourceA = locala;
+ alphaComb.ModeA = GR_FUNC_MODE_X;
+ alphaComb.SourceB = GR_CMBX_ZERO;
+ alphaComb.ModeB = GR_FUNC_MODE_X;
+ alphaComb.SourceC = GR_CMBX_ZERO;
+ alphaComb.InvertC = FXTRUE;
+ alphaComb.SourceD = GR_CMBX_ZERO;
+ } else {
+ alphaComb.SourceA = locala;
+ alphaComb.ModeA = GR_FUNC_MODE_X;
+ alphaComb.SourceB = GR_CMBX_ZERO;
+ alphaComb.ModeB = GR_FUNC_MODE_X;
+ alphaComb.SourceC = GR_CMBX_LOCAL_TEXTURE_ALPHA;
+ alphaComb.InvertC = FXFALSE;
+ alphaComb.SourceD = GR_CMBX_ZERO;
+ }
+
+ if (ifmt == GL_ALPHA) {
+ colorComb.SourceA = localc;
+ colorComb.ModeA = GR_FUNC_MODE_X;
+ colorComb.SourceB = GR_CMBX_ZERO;
+ colorComb.ModeB = GR_FUNC_MODE_X;
+ colorComb.SourceC = GR_CMBX_ZERO;
+ colorComb.InvertC = FXTRUE;
+ colorComb.SourceD = GR_CMBX_ZERO;
+ } else {
+ colorComb.SourceA = localc;
+ colorComb.ModeA = GR_FUNC_MODE_X;
+ colorComb.SourceB = GR_CMBX_ZERO;
+ colorComb.ModeB = GR_FUNC_MODE_X;
+ colorComb.SourceC = GR_CMBX_LOCAL_TEXTURE_RGB;
+ colorComb.InvertC = FXFALSE;
+ colorComb.SourceD = GR_CMBX_ZERO;
+ }
+ break;
+ case GL_BLEND:
+ if (ifmt == GL_INTENSITY) {
+ alphaComb.SourceA = GR_CMBX_TMU_CALPHA;
+ alphaComb.ModeA = GR_FUNC_MODE_X;
+ alphaComb.SourceB = locala;
+ alphaComb.ModeB = GR_FUNC_MODE_X;
+ alphaComb.SourceC = GR_CMBX_LOCAL_TEXTURE_ALPHA;
+ alphaComb.InvertC = FXFALSE;
+ alphaComb.SourceD = GR_CMBX_ZERO;
+ } else {
+ alphaComb.SourceA = locala;
+ alphaComb.ModeA = GR_FUNC_MODE_X;
+ alphaComb.SourceB = GR_CMBX_ZERO;
+ alphaComb.ModeB = GR_FUNC_MODE_X;
+ alphaComb.SourceC = GR_CMBX_LOCAL_TEXTURE_ALPHA;
+ alphaComb.InvertC = FXFALSE;
+ alphaComb.SourceD = GR_CMBX_ZERO;
+ }
+
+ if (ifmt == GL_ALPHA) {
+ colorComb.SourceA = localc;
+ colorComb.ModeA = GR_FUNC_MODE_X;
+ colorComb.SourceB = GR_CMBX_ZERO;
+ colorComb.ModeB = GR_FUNC_MODE_X;
+ colorComb.SourceC = GR_CMBX_ZERO;
+ colorComb.InvertC = FXTRUE;
+ colorComb.SourceD = GR_CMBX_ZERO;
+ } else {
+ colorComb.SourceA = GR_CMBX_TMU_CCOLOR;
+ colorComb.ModeA = GR_FUNC_MODE_X;
+ colorComb.SourceB = localc;
+ colorComb.ModeB = GR_FUNC_MODE_NEGATIVE_X;
+ colorComb.SourceC = GR_CMBX_LOCAL_TEXTURE_RGB;
+ colorComb.InvertC = FXFALSE;
+ colorComb.SourceD = GR_CMBX_B;
+ }
+
+ fxMesa->Glide.grConstantColorValueExt(tmu,
+ ((GLuint)((envColor[0] * 255.0f)) ) |
+ ((GLuint)((envColor[1] * 255.0f)) << 8) |
+ ((GLuint)((envColor[2] * 255.0f)) << 16) |
+ ((GLuint)((envColor[3] * 255.0f)) << 24));
+ break;
+ case GL_REPLACE:
+ if (ifmt == GL_LUMINANCE || ifmt == GL_RGB) {
+ alphaComb.SourceA = locala;
+ alphaComb.ModeA = GR_FUNC_MODE_X;
+ alphaComb.SourceB = GR_CMBX_ZERO;
+ alphaComb.ModeB = GR_FUNC_MODE_X;
+ alphaComb.SourceC = GR_CMBX_ZERO;
+ alphaComb.InvertC = FXTRUE;
+ alphaComb.SourceD = GR_CMBX_ZERO;
+ } else {
+ alphaComb.SourceA = GR_CMBX_LOCAL_TEXTURE_ALPHA;
+ alphaComb.ModeA = GR_FUNC_MODE_X;
+ alphaComb.SourceB = GR_CMBX_ZERO;
+ alphaComb.ModeB = GR_FUNC_MODE_X;
+ alphaComb.SourceC = GR_CMBX_ZERO;
+ alphaComb.InvertC = FXTRUE;
+ alphaComb.SourceD = GR_CMBX_ZERO;
+ }
+
+ if (ifmt == GL_ALPHA) {
+ colorComb.SourceA = localc;
+ colorComb.ModeA = GR_FUNC_MODE_X;
+ colorComb.SourceB = GR_CMBX_ZERO;
+ colorComb.ModeB = GR_FUNC_MODE_X;
+ colorComb.SourceC = GR_CMBX_ZERO;
+ colorComb.InvertC = FXTRUE;
+ colorComb.SourceD = GR_CMBX_ZERO;
+ } else {
+ colorComb.SourceA = GR_CMBX_LOCAL_TEXTURE_RGB;
+ colorComb.ModeA = GR_FUNC_MODE_X;
+ colorComb.SourceB = GR_CMBX_ZERO;
+ colorComb.ModeB = GR_FUNC_MODE_X;
+ colorComb.SourceC = GR_CMBX_ZERO;
+ colorComb.InvertC = FXTRUE;
+ colorComb.SourceD = GR_CMBX_ZERO;
+ }
+ break;
+ case GL_ADD:
+ if (ifmt == GL_LUMINANCE || ifmt == GL_RGB) {
+ alphaComb.SourceA = locala;
+ alphaComb.ModeA = GR_FUNC_MODE_X;
+ alphaComb.SourceB = GR_CMBX_ZERO;
+ alphaComb.ModeB = GR_FUNC_MODE_X;
+ alphaComb.SourceC = GR_CMBX_ZERO;
+ alphaComb.InvertC = FXTRUE;
+ alphaComb.SourceD = GR_CMBX_ZERO;
+ } else if (ifmt == GL_INTENSITY) {
+ alphaComb.SourceA = locala;
+ alphaComb.ModeA = GR_FUNC_MODE_X;
+ alphaComb.SourceB = GR_CMBX_LOCAL_TEXTURE_ALPHA;
+ alphaComb.ModeB = GR_FUNC_MODE_X;
+ alphaComb.SourceC = GR_CMBX_ZERO;
+ alphaComb.InvertC = FXTRUE;
+ alphaComb.SourceD = GR_CMBX_ZERO;
+ } else {
+ alphaComb.SourceA = locala;
+ alphaComb.ModeA = GR_FUNC_MODE_X;
+ alphaComb.SourceB = GR_CMBX_ZERO;
+ alphaComb.ModeB = GR_FUNC_MODE_X;
+ alphaComb.SourceC = GR_CMBX_LOCAL_TEXTURE_ALPHA;
+ alphaComb.InvertC = FXFALSE;
+ alphaComb.SourceD = GR_CMBX_ZERO;
+ }
+
+ if (ifmt == GL_ALPHA) {
+ colorComb.SourceA = localc;
+ colorComb.ModeA = GR_FUNC_MODE_X;
+ colorComb.SourceB = GR_CMBX_ZERO;
+ colorComb.ModeB = GR_FUNC_MODE_X;
+ colorComb.SourceC = GR_CMBX_ZERO;
+ colorComb.InvertC = FXTRUE;
+ colorComb.SourceD = GR_CMBX_ZERO;
+ } else {
+ colorComb.SourceA = localc;
+ colorComb.ModeA = GR_FUNC_MODE_X;
+ colorComb.SourceB = GR_CMBX_LOCAL_TEXTURE_RGB;
+ colorComb.ModeB = GR_FUNC_MODE_X;
+ colorComb.SourceC = GR_CMBX_ZERO;
+ colorComb.InvertC = FXTRUE;
+ colorComb.SourceD = GR_CMBX_ZERO;
+ }
+ break;
+ /* COMBINE_EXT */
+ case GL_COMBINE_EXT:
+ if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE)) {
+ fprintf(stderr, "COMBINE_EXT: %s + %s\n",
+ _mesa_lookup_enum_by_nr(texUnit->CombineModeRGB),
+ _mesa_lookup_enum_by_nr(texUnit->CombineModeA));
+ }
+
+ alphaComb.Shift = texUnit->CombineScaleShiftA;
+ colorComb.Shift = texUnit->CombineScaleShiftRGB;
+
+ switch (texUnit->CombineModeRGB) {
+ case GL_MODULATE:
+ /* Arg0 * Arg1 == (A + 0) * C + 0 */
+ TEXENV_SETUP_ARG_RGB(colorComb.SourceA,
+ texUnit->CombineSourceRGB[0],
+ texUnit->CombineOperandRGB[0],
+ localc, locala);
+ TEXENV_SETUP_MODE_RGB(colorComb.ModeA,
+ texUnit->CombineOperandRGB[0]);
+ colorComb.SourceB = GR_CMBX_ZERO;
+ colorComb.ModeB = GR_FUNC_MODE_ZERO;
+ TEXENV_SETUP_ARG_RGB(colorComb.SourceC,
+ texUnit->CombineSourceRGB[1],
+ texUnit->CombineOperandRGB[1],
+ localc, locala);
+ colorComb.InvertC = TEXENV_OPERAND_INVERTED(
+ texUnit->CombineOperandRGB[1]);
+ colorComb.SourceD = GR_CMBX_ZERO;
+ break;
+ default:
+ fprintf(stderr, "COMBINE_EXT_color: %s\n",
+ _mesa_lookup_enum_by_nr(texUnit->CombineModeRGB));
+ }
+
+ switch (texUnit->CombineModeA) {
+ case GL_MODULATE:
+ /* Arg0 * Arg1 == (A + 0) * C + 0 */
+ TEXENV_SETUP_ARG_A(alphaComb.SourceA,
+ texUnit->CombineSourceA[0],
+ texUnit->CombineOperandA[0],
+ locala);
+ TEXENV_SETUP_MODE_A(alphaComb.ModeA,
+ texUnit->CombineOperandA[0]);
+ alphaComb.SourceB = GR_CMBX_ZERO;
+ alphaComb.ModeB = GR_FUNC_MODE_ZERO;
+ TEXENV_SETUP_ARG_A(alphaComb.SourceC,
+ texUnit->CombineSourceA[1],
+ texUnit->CombineOperandA[1],
+ locala);
+ alphaComb.InvertC = TEXENV_OPERAND_INVERTED(
+ texUnit->CombineOperandA[1]);
+ alphaComb.SourceD = GR_CMBX_ZERO;
+ break;
+ default:
+ fprintf(stderr, "COMBINE_EXT_alpha: %s\n",
+ _mesa_lookup_enum_by_nr(texUnit->CombineModeA));
+ }
+
+ fxMesa->Glide.grConstantColorValueExt(tmu,
+ ((GLuint)((envColor[0] * 255.0f)) ) |
+ ((GLuint)((envColor[1] * 255.0f)) << 8) |
+ ((GLuint)((envColor[2] * 255.0f)) << 16) |
+ ((GLuint)((envColor[3] * 255.0f)) << 24));
+ break;
+#if 0
+ {
+ FxU32 A_RGB, B_RGB, C_RGB, D_RGB;
+ FxU32 Amode_RGB, Bmode_RGB;
+ FxBool Cinv_RGB, Dinv_RGB, Ginv_RGB;
+ FxU32 Shift_RGB;
+ FxU32 A_A, B_A, C_A, D_A;
+ FxU32 Amode_A, Bmode_A;
+ FxBool Cinv_A, Dinv_A, Ginv_A;
+ FxU32 Shift_A;
+
+ /*
+ *
+ * In the formulas below, we write:
+ * o "1(x)" for the identity function applied to x,
+ * so 1(x) = x.
+ * o "0(x)" for the constant function 0, so
+ * 0(x) = 0 for all values of x.
+ *
+ * Calculate the color combination.
+ */
+ Shift_RGB = texUnit->CombineScaleShiftRGB;
+ Shift_A = texUnit->CombineScaleShiftA;
+ switch (texUnit->CombineModeRGB) {
+ case GL_REPLACE:
+ /*
+ * The formula is: Arg0
+ * We implement this by the formula:
+ * (Arg0 + 0(0))*(1-0) + 0
+ */
+ TEXENV_SETUP_ARG_RGB(A_RGB,
+ texUnit->CombineSourceRGB[0],
+ texUnit->CombineOperandRGB[0],
+ incomingRGB, incomingAlpha);
+ TEXENV_SETUP_MODE_RGB(Amode_RGB,
+ texUnit->CombineOperandRGB[0]);
+ B_RGB = C_RGB = D_RGB = GR_CMBX_ZERO;
+ Bmode_RGB = GR_FUNC_MODE_ZERO;
+ Cinv_RGB = FXTRUE;
+ Dinv_RGB = Ginv_RGB = FXFALSE;
+ break;
+ case GL_MODULATE:
+ /*
+ * The formula is: Arg0 * Arg1
+ *
+ * We implement this by the formula
+ * (Arg0 + 0(0)) * Arg1 + 0(0)
+ */
+ TEXENV_SETUP_ARG_RGB(A_RGB,
+ texUnit->CombineSourceRGB[0],
+ texUnit->CombineOperandRGB[0],
+ incomingRGB, incomingAlpha);
+ TEXENV_SETUP_MODE_RGB(Amode_RGB,
+ texUnit->CombineOperandRGB[0]);
+ B_RGB = GR_CMBX_ZERO;
+ Bmode_RGB = GR_CMBX_ZERO;
+ TEXENV_SETUP_ARG_RGB(C_RGB,
+ texUnit->CombineSourceRGB[1],
+ texUnit->CombineOperandRGB[1],
+ incomingRGB, incomingAlpha);
+ Cinv_RGB = TEXENV_OPERAND_INVERTED
+ (texUnit->CombineOperandRGB[1]);
+ D_RGB = GR_CMBX_ZERO;
+ Dinv_RGB = Ginv_RGB = FXFALSE;
+ break;
+ case GL_ADD:
+ /*
+ * The formula is Arg0 + Arg1
+ */
+ TEXENV_SETUP_ARG_RGB(A_RGB,
+ texUnit->CombineSourceRGB[0],
+ texUnit->CombineOperandRGB[0],
+ incomingRGB, incomingAlpha);
+ TEXENV_SETUP_MODE_RGB(Amode_RGB,
+ texUnit->CombineOperandRGB[0]);
+ TEXENV_SETUP_ARG_RGB(B_RGB,
+ texUnit->CombineSourceRGB[1],
+ texUnit->CombineOperandRGB[1],
+ incomingRGB, incomingAlpha);
+ TEXENV_SETUP_MODE_RGB(Bmode_RGB,
+ texUnit->CombineOperandRGB[1]);
+ C_RGB = D_RGB = GR_CMBX_ZERO;
+ Cinv_RGB = FXTRUE;
+ Dinv_RGB = Ginv_RGB = FXFALSE;
+ break;
+ case GL_ADD_SIGNED_EXT:
+ /*
+ * The formula is: Arg0 + Arg1 - 0.5.
+ * We compute this by calculating:
+ * (Arg0 - 1/2) + Arg1 if op0 is SRC_{COLOR,ALPHA}
+ * Arg0 + (Arg1 - 1/2) if op1 is SRC_{COLOR,ALPHA}
+ * If both op0 and op1 are ONE_MINUS_SRC_{COLOR,ALPHA}
+ * we cannot implement the formula properly.
+ */
+ TEXENV_SETUP_ARG_RGB(A_RGB,
+ texUnit->CombineSourceRGB[0],
+ texUnit->CombineOperandRGB[0],
+ incomingRGB, incomingAlpha);
+ TEXENV_SETUP_ARG_RGB(B_RGB,
+ texUnit->CombineSourceRGB[1],
+ texUnit->CombineOperandRGB[1],
+ incomingRGB, incomingAlpha);
+ if (!TEXENV_OPERAND_INVERTED(texUnit->CombineOperandRGB[0])) {
+ /*
+ * A is not inverted. So, choose it.
+ */
+ Amode_RGB = GR_FUNC_MODE_X_MINUS_HALF;
+ if (!TEXENV_OPERAND_INVERTED
+ (texUnit->CombineOperandRGB[1])) {
+ Bmode_RGB = GR_FUNC_MODE_X;
+ }
+ else {
+ Bmode_RGB = GR_FUNC_MODE_ONE_MINUS_X;
+ }
+ }
+ else {
+ /*
+ * A is inverted, so try to subtract 1/2
+ * from B.
+ */
+ Amode_RGB = GR_FUNC_MODE_ONE_MINUS_X;
+ if (!TEXENV_OPERAND_INVERTED
+ (texUnit->CombineOperandRGB[1])) {
+ Bmode_RGB = GR_FUNC_MODE_X_MINUS_HALF;
+ }
+ else {
+ /*
+ * Both are inverted. This is the case
+ * we cannot handle properly. We just
+ * choose to not add the - 1/2.
+ */
+ Bmode_RGB = GR_FUNC_MODE_ONE_MINUS_X;
+ return GL_FALSE;
+ }
+ }
+ C_RGB = D_RGB = GR_CMBX_ZERO;
+ Cinv_RGB = FXTRUE;
+ Dinv_RGB = Ginv_RGB = FXFALSE;
+ break;
+ case GL_INTERPOLATE_EXT:
+ /*
+ * The formula is: Arg0 * Arg2 + Arg1 * (1 - Arg2).
+ * We compute this by the formula:
+ * (Arg0 - Arg1) * Arg2 + Arg1
+ * == Arg0 * Arg2 - Arg1 * Arg2 + Arg1
+ * == Arg0 * Arg2 + Arg1 * (1 - Arg2)
+ * However, if both Arg1 is ONE_MINUS_X, the HW does
+ * not support it properly.
+ */
+ TEXENV_SETUP_ARG_RGB(A_RGB,
+ texUnit->CombineSourceRGB[0],
+ texUnit->CombineOperandRGB[0],
+ incomingRGB, incomingAlpha);
+ TEXENV_SETUP_MODE_RGB(Amode_RGB,
+ texUnit->CombineOperandRGB[0]);
+ TEXENV_SETUP_ARG_RGB(B_RGB,
+ texUnit->CombineSourceRGB[1],
+ texUnit->CombineOperandRGB[1],
+ incomingRGB, incomingAlpha);
+ if (TEXENV_OPERAND_INVERTED(texUnit->CombineOperandRGB[1])) {
+ /*
+ * This case is wrong.
+ */
+ Bmode_RGB = GR_FUNC_MODE_NEGATIVE_X;
+ return GL_FALSE;
+ }
+ else {
+ Bmode_RGB = GR_FUNC_MODE_NEGATIVE_X;
+ }
+ /*
+ * The Source/Operand for the C value must
+ * specify some kind of alpha value.
+ */
+ TEXENV_SETUP_ARG_A(C_RGB,
+ texUnit->CombineSourceRGB[2],
+ texUnit->CombineOperandRGB[2],
+ incomingAlpha);
+ Cinv_RGB = FXFALSE;
+ D_RGB = GR_CMBX_B;
+ Dinv_RGB = Ginv_RGB = FXFALSE;
+ break;
+ default:
+ /*
+ * This is here mostly to keep from getting
+ * a compiler warning about these not being set.
+ * However, this should set all the texture values
+ * to zero.
+ */
+ A_RGB = B_RGB = C_RGB = D_RGB = GR_CMBX_ZERO;
+ Amode_RGB = Bmode_RGB = GR_FUNC_MODE_X;
+ Cinv_RGB = Dinv_RGB = Ginv_RGB = FXFALSE;
+ break;
+ }
+ /*
+ * Calculate the alpha combination.
+ */
+ switch (texUnit->CombineModeA) {
+ case GL_REPLACE:
+ /*
+ * The formula is: Arg0
+ * We implement this by the formula:
+ * (Arg0 + 0(0))*(1-0) + 0
+ */
+ TEXENV_SETUP_ARG_A(A_A,
+ texUnit->CombineSourceA[0],
+ texUnit->CombineOperandA[0],
+ incomingAlpha);
+ TEXENV_SETUP_MODE_A(Amode_A,
+ texUnit->CombineOperandA[0]);
+ B_A = GR_CMBX_ITALPHA;
+ Bmode_A = GR_FUNC_MODE_ZERO;
+ C_A = D_A = GR_CMBX_ZERO;
+ Cinv_A = FXTRUE;
+ Dinv_A = Ginv_A = FXFALSE;
+ break;
+ case GL_MODULATE:
+ /*
+ * The formula is: Arg0 * Arg1
+ *
+ * We implement this by the formula
+ * (Arg0 + 0(0)) * Arg1 + 0(0)
+ */
+ TEXENV_SETUP_ARG_A(A_A,
+ texUnit->CombineSourceA[0],
+ texUnit->CombineOperandA[0],
+ incomingAlpha);
+ TEXENV_SETUP_MODE_A(Amode_A,
+ texUnit->CombineOperandA[0]);
+ B_A = GR_CMBX_ZERO;
+ Bmode_A = GR_CMBX_ZERO;
+ TEXENV_SETUP_ARG_A(C_A,
+ texUnit->CombineSourceA[1],
+ texUnit->CombineOperandA[1],
+ incomingAlpha);
+ Cinv_A = TEXENV_OPERAND_INVERTED
+ (texUnit->CombineOperandA[1]);
+ D_A = GR_CMBX_ZERO;
+ Dinv_A = Ginv_A = FXFALSE;
+ break;
+ case GL_ADD:
+ /*
+ * The formula is Arg0 + Arg1
+ */
+ TEXENV_SETUP_ARG_A(A_A,
+ texUnit->CombineSourceA[0],
+ texUnit->CombineOperandA[0],
+ incomingAlpha);
+ TEXENV_SETUP_MODE_A(Amode_A,
+ texUnit->CombineOperandA[0]);
+ TEXENV_SETUP_ARG_A(B_A,
+ texUnit->CombineSourceA[1],
+ texUnit->CombineOperandA[1],
+ incomingAlpha);
+ TEXENV_SETUP_MODE_A(Bmode_A,
+ texUnit->CombineOperandA[1]);
+ C_A = D_A = GR_CMBX_ZERO;
+ Cinv_A = FXTRUE;
+ Dinv_A = Ginv_A = FXFALSE;
+ break;
+ case GL_ADD_SIGNED_EXT:
+ /*
+ * The formula is: Arg0 + Arg1 - 0.5.
+ * We compute this by calculating:
+ * (Arg0 - 1/2) + Arg1 if op0 is SRC_{COLOR,ALPHA}
+ * Arg0 + (Arg1 - 1/2) if op1 is SRC_{COLOR,ALPHA}
+ * If both op0 and op1 are ONE_MINUS_SRC_{COLOR,ALPHA}
+ * we cannot implement the formula properly.
+ */
+ TEXENV_SETUP_ARG_A(A_A,
+ texUnit->CombineSourceA[0],
+ texUnit->CombineOperandA[0],
+ incomingAlpha);
+ TEXENV_SETUP_ARG_A(B_A,
+ texUnit->CombineSourceA[1],
+ texUnit->CombineOperandA[1],
+ incomingAlpha);
+ if (!TEXENV_OPERAND_INVERTED(texUnit->CombineOperandA[0])) {
+ /*
+ * A is not inverted. So, choose it.
+ */
+ Amode_A = GR_FUNC_MODE_X_MINUS_HALF;
+ if (!TEXENV_OPERAND_INVERTED
+ (texUnit->CombineOperandA[1])) {
+ Bmode_A = GR_FUNC_MODE_X;
+ } else {
+ Bmode_A = GR_FUNC_MODE_ONE_MINUS_X;
+ }
+ } else {
+ /*
+ * A is inverted, so try to subtract 1/2
+ * from B.
+ */
+ Amode_A = GR_FUNC_MODE_ONE_MINUS_X;
+ if (!TEXENV_OPERAND_INVERTED
+ (texUnit->CombineOperandA[1])) {
+ Bmode_A = GR_FUNC_MODE_X_MINUS_HALF;
+ } else {
+ /*
+ * Both are inverted. This is the case
+ * we cannot handle properly. We just
+ * choose to not add the - 1/2.
+ */
+ Bmode_A = GR_FUNC_MODE_ONE_MINUS_X;
+ return GL_FALSE;
+ }
+ }
+ C_A = D_A = GR_CMBX_ZERO;
+ Cinv_A = FXTRUE;
+ Dinv_A = Ginv_A = FXFALSE;
+ break;
+ case GL_INTERPOLATE_EXT:
+ /*
+ * The formula is: Arg0 * Arg2 + Arg1 * (1 - Arg2).
+ * We compute this by the formula:
+ * (Arg0 - Arg1) * Arg2 + Arg1
+ * == Arg0 * Arg2 - Arg1 * Arg2 + Arg1
+ * == Arg0 * Arg2 + Arg1 * (1 - Arg2)
+ * However, if both Arg1 is ONE_MINUS_X, the HW does
+ * not support it properly.
+ */
+ TEXENV_SETUP_ARG_A(A_A,
+ texUnit->CombineSourceA[0],
+ texUnit->CombineOperandA[0],
+ incomingAlpha);
+ TEXENV_SETUP_MODE_A(Amode_A,
+ texUnit->CombineOperandA[0]);
+ TEXENV_SETUP_ARG_A(B_A,
+ texUnit->CombineSourceA[1],
+ texUnit->CombineOperandA[1],
+ incomingAlpha);
+ if (!TEXENV_OPERAND_INVERTED(texUnit->CombineOperandA[1])) {
+ Bmode_A = GR_FUNC_MODE_NEGATIVE_X;
+ }
+ else {
+ /*
+ * This case is wrong.
+ */
+ Bmode_A = GR_FUNC_MODE_NEGATIVE_X;
+ return GL_FALSE;
+ }
+ /*
+ * The Source/Operand for the C value must
+ * specify some kind of alpha value.
+ */
+ TEXENV_SETUP_ARG_A(C_A,
+ texUnit->CombineSourceA[2],
+ texUnit->CombineOperandA[2],
+ incomingAlpha);
+ Cinv_A = FXFALSE;
+ D_A = GR_CMBX_B;
+ Dinv_A = Ginv_A = FXFALSE;
+ break;
+ default:
+ /*
+ * This is here mostly to keep from getting
+ * a compiler warning about these not being set.
+ * However, this should set all the alpha values
+ * to one.
+ */
+ A_A = B_A = C_A = D_A = GR_CMBX_ZERO;
+ Amode_A = Bmode_A = GR_FUNC_MODE_X;
+ Cinv_A = Dinv_A = FXFALSE;
+ Ginv_A = FXTRUE;
+ break;
+ }
+ /*
+ * Save the parameters.
+ */
+ env->Color.SourceA = A_RGB;
+ env->Color.ModeA = Amode_RGB;
+ env->Color.SourceB = B_RGB;
+ env->Color.ModeB = Bmode_RGB;
+ env->Color.SourceC = C_RGB;
+ env->Color.InvertC = Cinv_RGB;
+ env->Color.SourceD = D_RGB;
+ env->Color.InvertD = Dinv_RGB;
+ env->Color.Shift = Shift_RGB;
+ env->Color.Invert = Ginv_RGB;
+ env->Alpha.SourceA = A_A;
+ env->Alpha.ModeA = Amode_A;
+ env->Alpha.SourceB = B_A;
+ env->Alpha.ModeB = Bmode_A;
+ env->Alpha.SourceC = C_A;
+ env->Alpha.InvertC = Cinv_A;
+ env->Alpha.SourceD = D_A;
+ env->Alpha.InvertD = Dinv_A;
+ env->Alpha.Shift = Shift_A;
+ env->Alpha.Invert = Ginv_A;
+ env->EnvColor = PACK_RGBA32(texUnit->EnvColor[0] * 255.0F,
+ texUnit->EnvColor[1] * 255.0F,
+ texUnit->EnvColor[2] * 255.0F,
+ texUnit->EnvColor[3] * 255.0F);
+ }
+ break;
+#endif
+ default:
+ if (TDFX_DEBUG & VERBOSE_DRIVER) {
+ fprintf(stderr, "%s: %x Texture.EnvMode not yet supported\n", __FUNCTION__,
+ texUnit->EnvMode);
+ }
+ return;
+ }
+
+ /* On Napalm we simply put the color combine unit into passthrough mode
+ * and do everything we need with the texture combine units. */
+ fxMesa->Glide.grColorCombineExt(GR_CMBX_TEXTURE_RGB,
+ GR_FUNC_MODE_X,
+ GR_CMBX_ZERO,
+ GR_FUNC_MODE_X,
+ GR_CMBX_ZERO,
+ FXTRUE,
+ GR_CMBX_ZERO,
+ FXFALSE,
+ 0,
+ FXFALSE);
+ fxMesa->Glide.grAlphaCombineExt(GR_CMBX_TEXTURE_ALPHA,
+ GR_FUNC_MODE_X,
+ GR_CMBX_ZERO,
+ GR_FUNC_MODE_X,
+ GR_CMBX_ZERO,
+ FXTRUE,
+ GR_CMBX_ZERO,
+ FXFALSE,
+ 0,
+ FXFALSE);
+
+ fxMesa->Glide.grTexAlphaCombineExt(tmu,
+ alphaComb.SourceA,
+ alphaComb.ModeA,
+ alphaComb.SourceB,
+ alphaComb.ModeB,
+ alphaComb.SourceC,
+ alphaComb.InvertC,
+ alphaComb.SourceD,
+ alphaComb.InvertD,
+ alphaComb.Shift,
+ alphaComb.Invert);
+ fxMesa->Glide.grTexColorCombineExt(tmu,
+ colorComb.SourceA,
+ colorComb.ModeA,
+ colorComb.SourceB,
+ colorComb.ModeB,
+ colorComb.SourceC,
+ colorComb.InvertC,
+ colorComb.SourceD,
+ colorComb.InvertD,
+ colorComb.Shift,
+ colorComb.Invert);
+}
+
+
+/************************* Single Texture Set ***************************/
+
+static void
+fxSelectSingleTMUSrcNapalm_NoLock(fxMesaContext fxMesa, GLint tmu, FxBool LODblend)
+{
+ if (TDFX_DEBUG & VERBOSE_DRIVER) {
+ fprintf(stderr, "%s(%d, %d)\n", __FUNCTION__, tmu, LODblend);
+ }
+
+ if (LODblend) {
+ /* [dBorca] Hack alert:
+ * TODO: GR_CMBX_LOD_FRAC
+ */
+
+ fxMesa->tmuSrc = FX_TMU_SPLIT;
+ }
+ else {
+ if (tmu != FX_TMU1) {
+ /* disable tex1 */
+ if (fxMesa->haveTwoTMUs) {
+ fxMesa->Glide.grTexAlphaCombineExt(FX_TMU1,
+ GR_CMBX_ZERO,
+ GR_FUNC_MODE_ZERO,
+ GR_CMBX_ZERO,
+ GR_FUNC_MODE_ZERO,
+ GR_CMBX_ZERO,
+ FXTRUE,
+ GR_CMBX_ZERO,
+ FXFALSE,
+ 0,
+ FXFALSE);
+ fxMesa->Glide.grTexColorCombineExt(FX_TMU1,
+ GR_CMBX_ZERO,
+ GR_FUNC_MODE_ZERO,
+ GR_CMBX_ZERO,
+ GR_FUNC_MODE_ZERO,
+ GR_CMBX_ZERO,
+ FXTRUE,
+ GR_CMBX_ZERO,
+ FXFALSE,
+ 0,
+ FXFALSE);
+ }
+
+ fxMesa->tmuSrc = FX_TMU0;
+ }
+ else {
+ grTexCombine(GR_TMU0,
+ GR_COMBINE_FUNCTION_BLEND,
+ GR_COMBINE_FACTOR_ONE,
+ GR_COMBINE_FUNCTION_BLEND,
+ GR_COMBINE_FACTOR_ONE,
+ FXFALSE,
+ FXFALSE);
+ /*
+ fxMesa->Glide.grTexAlphaCombineExt(FX_TMU0,
+ GR_CMBX_OTHER_TEXTURE_ALPHA,
+ GR_FUNC_MODE_X,
+ GR_CMBX_ZERO,
+ GR_FUNC_MODE_X,
+ GR_CMBX_ZERO,
+ FXTRUE,
+ GR_CMBX_ZERO,
+ FXFALSE,
+ 0,
+ FXFALSE);
+ fxMesa->Glide.grTexColorCombineExt(FX_TMU0,
+ GR_CMBX_OTHER_TEXTURE_RGB,
+ GR_FUNC_MODE_X,
+ GR_CMBX_ZERO,
+ GR_FUNC_MODE_X,
+ GR_CMBX_ZERO,
+ FXTRUE,
+ GR_CMBX_ZERO,
+ FXFALSE,
+ 0,
+ FXFALSE);
+ */
+
+ fxMesa->tmuSrc = FX_TMU1;
+ }
+ }
+}
+
+static void
+fxSetupTextureSingleTMUNapalm_NoLock(GLcontext * ctx, GLuint textureset)
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ GLuint unitsmode;
+ tfxTexInfo *ti;
+ struct gl_texture_object *tObj = ctx->Texture.Unit[textureset].Current2D;
+ int tmu;
+
+ if (TDFX_DEBUG & VERBOSE_DRIVER) {
+ fprintf(stderr, "%s(%d)\n", __FUNCTION__, textureset);
+ }
+
+ ti = fxTMGetTexInfo(tObj);
+
+ fxTexValidate(ctx, tObj);
+
+ fxSetupSingleTMU_NoLock(fxMesa, tObj);
+
+ if (ti->whichTMU == FX_TMU_BOTH)
+ tmu = FX_TMU0;
+ else
+ tmu = ti->whichTMU;
+ if (fxMesa->tmuSrc != tmu)
+ fxSelectSingleTMUSrcNapalm_NoLock(fxMesa, tmu, ti->LODblend);
+
+ if (textureset == 0 || !fxMesa->haveTwoTMUs)
+ unitsmode = fxGetTexSetConfiguration(ctx, tObj, NULL);
+ else
+ unitsmode = fxGetTexSetConfiguration(ctx, NULL, tObj);
+
+/* if(fxMesa->lastUnitsMode==unitsmode) */
+/* return; */
+
+ fxMesa->lastUnitsMode = unitsmode;
+
+ fxMesa->stw_hint_state = 0;
+ FX_grHints_NoLock(GR_HINT_STWHINT, 0);
+
+ if (TDFX_DEBUG & (VERBOSE_DRIVER | VERBOSE_TEXTURE))
+ fprintf(stderr, "%s: envmode is %s\n", __FUNCTION__,
+ _mesa_lookup_enum_by_nr(ctx->Texture.Unit[textureset].EnvMode));
+
+ /* [dBorca] Hack alert:
+ * what if we're in split mode? (LODBlend)
+ */
+ fxSetupTextureEnvNapalm_NoLock(ctx, textureset, tmu, GL_TRUE);
+}
+
+
+/************************* Double Texture Set ***************************/
+
+static void
+fxSetupTextureDoubleTMUNapalm_NoLock(GLcontext * ctx)
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ tfxTexInfo *ti0, *ti1;
+ struct gl_texture_object *tObj0 = ctx->Texture.Unit[0].Current2D;
+ struct gl_texture_object *tObj1 = ctx->Texture.Unit[1].Current2D;
+ GLuint unitsmode;
+ int tmu0 = 0, tmu1 = 1;
+
+ if (TDFX_DEBUG & VERBOSE_DRIVER) {
+ fprintf(stderr, "%s(...)\n", __FUNCTION__);
+ }
+
+ ti0 = fxTMGetTexInfo(tObj0);
+ fxTexValidate(ctx, tObj0);
+
+ ti1 = fxTMGetTexInfo(tObj1);
+ fxTexValidate(ctx, tObj1);
+
+ fxSetupDoubleTMU_NoLock(fxMesa, tObj0, tObj1);
+
+ unitsmode = fxGetTexSetConfiguration(ctx, tObj0, tObj1);
+
+/* if(fxMesa->lastUnitsMode==unitsmode) */
+/* return; */
+
+ fxMesa->lastUnitsMode = unitsmode;
+
+ fxMesa->stw_hint_state |= GR_STWHINT_ST_DIFF_TMU1;
+ FX_grHints_NoLock(GR_HINT_STWHINT, fxMesa->stw_hint_state);
+
+ 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));
+
+
+ if ((ti0->whichTMU == FX_TMU1) || (ti1->whichTMU == FX_TMU0)) {
+ tmu0 = 1;
+ tmu1 = 0;
+ }
+ fxMesa->tmuSrc = FX_TMU_BOTH;
+
+ /* OpenGL vs Glide texture pipeline */
+ /* [dBorca] Hack alert:
+ * TODO: revise this ASAP!!!
+ */
+ fxSetupTextureEnvNapalm_NoLock(ctx, FX_TMU1 - tmu0, tmu0, tmu0 != 0);
+ fxSetupTextureEnvNapalm_NoLock(ctx, FX_TMU1 - tmu1, tmu1, tmu1 != 0);
+}
+
+/************************* No Texture ***************************/
+
+static void
+fxSetupTextureNoneNapalm_NoLock(GLcontext * ctx)
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+
+ if (TDFX_DEBUG & VERBOSE_DRIVER) {
+ fprintf(stderr, "%s(...)\n", __FUNCTION__);
+ }
+
+ /* the combiner formula is: (A + B) * C + D
+ **
+ ** a = tc_otherselect
+ ** a_mode = tc_invert_other
+ ** b = tc_localselect
+ ** b_mode = tc_invert_local
+ ** c = (tc_mselect, tc_mselect_7)
+ ** d = (tc_add_clocal, tc_add_alocal)
+ ** shift = tc_outshift
+ ** invert = tc_invert_output
+ */
+
+ fxMesa->Glide.grColorCombineExt(GR_CMBX_ITRGB,
+ GR_FUNC_MODE_X,
+ GR_CMBX_ZERO,
+ GR_FUNC_MODE_ZERO,
+ GR_CMBX_ZERO,
+ FXTRUE,
+ GR_CMBX_ZERO,
+ FXFALSE,
+ 0,
+ FXFALSE);
+ fxMesa->Glide.grAlphaCombineExt(GR_CMBX_ITALPHA,
+ GR_FUNC_MODE_X,
+ GR_CMBX_ZERO,
+ GR_FUNC_MODE_ZERO,
+ GR_CMBX_ZERO,
+ FXTRUE,
+ GR_CMBX_ZERO,
+ FXFALSE,
+ 0,
+ FXFALSE);
+
+ fxMesa->lastUnitsMode = FX_UM_NONE;
+}
diff --git a/src/mesa/drivers/glide/fxtexman.c b/src/mesa/drivers/glide/fxtexman.c
index 35b4205106..90704e3479 100644
--- a/src/mesa/drivers/glide/fxtexman.c
+++ b/src/mesa/drivers/glide/fxtexman.c
@@ -1,5 +1,3 @@
-/* $Id: fxtexman.c,v 1.18 2003/10/09 15:12:21 dborca Exp $ */
-
/*
* Mesa 3-D graphics library
* Version: 4.0
@@ -199,6 +197,10 @@ fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, int size)
int result;
struct gl_texture_object *obj;
+ if (fxMesa->HaveTexUma) {
+ tmu = FX_TMU0;
+ }
+
while (1) {
prev = 0;
tmp = fxMesa->tmFree[tmu];
@@ -235,11 +237,38 @@ fxTMFindStartAddr(fxMesaContext fxMesa, GLint tmu, int size)
}
}
+int fxTMCheckStartAddr (fxMesaContext fxMesa, GLint tmu, tfxTexInfo *ti)
+{
+ MemRange *prev, *tmp;
+ int size;
+ struct gl_texture_object *obj;
+
+ if (fxMesa->HaveTexUma) {
+ return FXTRUE;
+ }
+
+ size = grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &(ti->info));
+
+ tmp = fxMesa->tmFree[tmu];
+ while (tmp) {
+ if (tmp->endAddr - tmp->startAddr >= size) { /* Fits here */
+ return FXTRUE;
+ }
+ tmp = tmp->next;
+ }
+
+ return FXFALSE;
+}
+
static void
fxTMRemoveRange(fxMesaContext fxMesa, GLint tmu, MemRange * range)
{
MemRange *tmp, *prev;
+ if (fxMesa->HaveTexUma) {
+ tmu = FX_TMU0;
+ }
+
if (range->startAddr == range->endAddr) {
fxTMDeleteRangeNode(fxMesa, range);
return;
@@ -529,7 +558,17 @@ fxTMReloadMipMapLevel(fxMesaContext fxMesa, struct gl_texture_object *tObj,
}
tmu = (int) ti->whichTMU;
+#if 0
+ /* [dBorca]
+ * We get here by (see Tex[Sub]Image2D), thus we are in TMU.
+ * Also, we just set the correct TMU above. fxTMMoveInTM will
+ * bail early, so don't bother...
+ */
fxTMMoveInTM(fxMesa, tObj, tmu);
+#else
+ fxMesa->stats.reqTexUpload++;
+ fxMesa->stats.texUpload++;
+#endif
lodlevel = ti->info.largeLodLog2 - (level - ti->minLevel);
@@ -757,9 +796,13 @@ fxTMInit(fxMesaContext fxMesa)
fxMesa->texBindNumber = 0;
fxMesa->tmPool = 0;
+ if (fxMesa->HaveTexUma) {
+ grEnable(GR_TEXTURE_UMA_EXT);
+ }
+
fxTMUInit(fxMesa, FX_TMU0);
- if (fxMesa->haveTwoTMUs)
+ if (!fxMesa->HaveTexUma && fxMesa->haveTwoTMUs)
fxTMUInit(fxMesa, FX_TMU1);
texBoundMask = (fxMesa->type >= GR_SSTTYPE_Banshee) ? -1 : (FX_2MB_SPLIT - 1);
diff --git a/src/mesa/drivers/glide/fxtris.c b/src/mesa/drivers/glide/fxtris.c
index 4eb536a813..d60b874027 100644
--- a/src/mesa/drivers/glide/fxtris.c
+++ b/src/mesa/drivers/glide/fxtris.c
@@ -1,5 +1,3 @@
-/* $Id: fxtris.c,v 1.25 2003/10/09 15:12:21 dborca Exp $ */
-
/*
* Mesa 3-D graphics library
* Version: 4.0
@@ -332,7 +330,7 @@ do { \
#define LOCAL_VARS(n) \
fxMesaContext fxMesa = FX_CONTEXT(ctx); \
GLubyte color[n][4]; \
- (void) color;
+ (void) color;
@@ -1026,11 +1024,24 @@ static void fxRunPipeline( GLcontext *ctx )
fprintf(stderr, "fxRunPipeline()\n");
}
+#if 0
/* Recalculate fog table on projection matrix changes. This used to
* be triggered by the NearFar callback.
*/
if (new_gl_state & _NEW_PROJECTION)
fxMesa->new_state |= FX_NEW_FOG;
+ /* [dBorca] Hack alert:
+ * the above _NEW_PROJECTION is not included in the test below,
+ * so we may end up with fxMesa->new_state still dirty by the end
+ * of the routine. The fact is, we don't have NearFar callback
+ * anymore. We could use fxDDDepthRange instead, but it seems
+ * fog needs to be updated only by a fog-basis.
+ * Implementing fxDDDepthRange correctly is another story:
+ * that, together with a presumable fxDDViewport function would set
+ * fxMesa->SetupNewInputs |= VERT_BIT_CLIP;
+ * which might be useful in fxBuildVertices...
+ */
+#endif
if (new_gl_state & (_FX_NEW_IS_IN_HARDWARE |
_FX_NEW_RENDERSTATE |
@@ -1174,7 +1185,7 @@ void fxCheckIsInHardware( GLcontext *ctx )
if (newfallback) {
if (oldfallback == 0) {
if (fxMesa->verbose) {
- fprintf(stderr, "Voodoo ! begin SW 0x%08x %s\n", newfallback, getFallbackString(newfallback));
+ fprintf(stderr, "Voodoo ! enter SW 0x%08x %s\n", newfallback, getFallbackString(newfallback));
}
_swsetup_Wakeup( ctx );
}
@@ -1195,7 +1206,7 @@ void fxCheckIsInHardware( GLcontext *ctx )
fxChooseVertexState(ctx);
fxDDChooseRenderState(ctx);
if (fxMesa->verbose) {
- fprintf(stderr, "Voodoo ! end SW 0x%08x %s\n", oldfallback, getFallbackString(oldfallback));
+ fprintf(stderr, "Voodoo ! leave SW 0x%08x %s\n", oldfallback, getFallbackString(oldfallback));
}
}
}
diff --git a/src/mesa/drivers/glide/fxvb.c b/src/mesa/drivers/glide/fxvb.c
index 857093b5c9..c8d6495f54 100644
--- a/src/mesa/drivers/glide/fxvb.c
+++ b/src/mesa/drivers/glide/fxvb.c
@@ -1,5 +1,3 @@
-/* $Id: fxvb.c,v 1.20 2003/10/09 15:12:21 dborca Exp $ */
-
/*
* Mesa 3-D graphics library
* Version: 5.1
diff --git a/src/mesa/drivers/glide/fxvbtmp.h b/src/mesa/drivers/glide/fxvbtmp.h
index 306a47c9b3..7d5741cd75 100644
--- a/src/mesa/drivers/glide/fxvbtmp.h
+++ b/src/mesa/drivers/glide/fxvbtmp.h
@@ -1,5 +1,3 @@
-/* $Id: fxvbtmp.h,v 1.14 2003/10/09 15:12:21 dborca Exp $ */
-
/*
* Mesa 3-D graphics library
* Version: 4.1
diff --git a/src/mesa/drivers/glide/fxwgl.c b/src/mesa/drivers/glide/fxwgl.c
index f03def4996..8ab9d23c98 100644
--- a/src/mesa/drivers/glide/fxwgl.c
+++ b/src/mesa/drivers/glide/fxwgl.c
@@ -1,5 +1,3 @@
-/* $Id: fxwgl.c,v 1.19 2003/10/13 11:14:58 dborca Exp $ */
-
/*
* Mesa 3-D graphics library
* Version: 4.0
@@ -365,7 +363,7 @@ wglCreateContext(HDC hdc)
SetWindowLong(hWnd, GWL_WNDPROC, (LONG) __wglMonitor);
}
-#ifdef FX_DEBUG
+#if FX_DEBUG
freopen("MESA.LOG", "w", stderr);
#endif