#if defined(FX)
-#include "image.h"
-#include "mtypes.h"
+#include "main/image.h"
+#include "main/mtypes.h"
#include "fxdrv.h"
-#include "enums.h"
-#include "extensions.h"
-#include "macros.h"
-#include "texstore.h"
-#include "teximage.h"
+#include "main/buffers.h"
+#include "main/enums.h"
+#include "main/extensions.h"
+#include "main/macros.h"
+#include "main/texstore.h"
+#include "main/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"
#include "tnl/t_pipeline.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
*/
static void fxDisableColor (fxMesaContext fxMesa)
{
- if (fxMesa->colDepth != 16) {
- /* 32bpp mode or 15bpp mode */
+ if (fxMesa->colDepth == 32) {
+ /* 32bpp mode */
fxMesa->Glide.grColorMaskExt(FXFALSE, FXFALSE, FXFALSE, FXFALSE);
} else {
- /* 16 bpp mode */
+ /* 15/16 bpp mode */
grColorMask(FXFALSE, FXFALSE);
}
}
/* Return buffer size information */
static void
-fxDDBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
+fxDDGetBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
{
GET_CURRENT_CONTEXT(ctx);
if (ctx && FX_CONTEXT(ctx)) {
fxMesaContext fxMesa = FX_CONTEXT(ctx);
if (TDFX_DEBUG & VERBOSE_DRIVER) {
- fprintf(stderr, "fxDDBufferSize(...)\n");
+ fprintf(stderr, "fxDDGetBufferSize(...)\n");
}
*width = fxMesa->width;
}
+/**
+ * We only implement this function as a mechanism to check if the
+ * framebuffer size has changed (and update corresponding state).
+ */
+static void
+fxDDViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+{
+ GLuint newWidth, newHeight;
+ GLframebuffer *buffer = ctx->WinSysDrawBuffer;
+ fxDDGetBufferSize( buffer, &newWidth, &newHeight );
+ if (buffer->Width != newWidth || buffer->Height != newHeight) {
+ _mesa_resize_framebuffer(ctx, buffer, newWidth, newHeight );
+ }
+}
+
+
/* Implements glClearColor() */
static void
fxDDClearColor(GLcontext * ctx, const GLfloat color[4])
/* Clear the color and/or depth buffers */
-static void fxDDClear( GLcontext *ctx,
- GLbitfield mask, GLboolean all,
- GLint x, GLint y, GLint width, GLint height )
+static void fxDDClear( GLcontext *ctx, GLbitfield mask )
{
fxMesaContext fxMesa = FX_CONTEXT(ctx);
- GLbitfield softwareMask = mask & (DD_ACCUM_BIT);
+ GLbitfield softwareMask = mask & (BUFFER_BIT_ACCUM);
const GLuint stencil_size = fxMesa->haveHwStencil ? ctx->Visual.stencilBits : 0;
- const FxU32 clearD = (FxU32) (ctx->DepthMaxF * ctx->Depth.Clear);
+ const FxU32 clearD = (FxU32) (ctx->DrawBuffer->_DepthMaxF * ctx->Depth.Clear);
const FxU8 clearS = (FxU8) (ctx->Stencil.Clear & 0xff);
if ( TDFX_DEBUG & MESA_VERBOSE ) {
- fprintf( stderr, "fxDDClear( %d, %d, %d, %d )\n",
- (int) x, (int) y, (int) width, (int) height );
+ fprintf( stderr, "fxDDClear\n");
}
- /* Need this check to respond to glScissor and clipping updates */
- /* should also take care of FX_NEW_COLOR_MASK, FX_NEW_STENCIL, depth? */
- if (fxMesa->new_state & FX_NEW_SCISSOR) {
- fxSetupScissor(ctx);
- fxMesa->new_state &= ~FX_NEW_SCISSOR;
- }
-
- /* we can't clear accum buffers */
- mask &= ~(DD_ACCUM_BIT);
+ /* we can't clear accum buffers nor stereo */
+ mask &= ~(BUFFER_BIT_ACCUM | BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT);
- /*
- * As per GL spec, stencil masking should be obeyed when clearing
- */
- if (mask & DD_STENCIL_BIT) {
- if (!fxMesa->haveHwStencil || fxMesa->unitsState.stencilWriteMask != 0xff) {
- /* Napalm seems to have trouble with stencil write masks != 0xff */
- /* do stencil clear in software */
- softwareMask |= DD_STENCIL_BIT;
- mask &= ~(DD_STENCIL_BIT);
- }
+ /* Need this check to respond to certain HW updates */
+ if (fxMesa->new_state & (FX_NEW_SCISSOR | FX_NEW_COLOR_MASK)) {
+ fxSetupScissor(ctx);
+ fxSetupColorMask(ctx);
+ fxMesa->new_state &= ~(FX_NEW_SCISSOR | FX_NEW_COLOR_MASK);
}
/*
* As per GL spec, color masking should be obeyed when clearing
*/
- if (ctx->Visual.greenBits != 8 && ctx->Visual.greenBits != 5) {
+ if (ctx->Visual.greenBits != 8) {
/* can only do color masking if running in 24/32bpp on Napalm */
if (ctx->Color.ColorMask[RCOMP] != ctx->Color.ColorMask[GCOMP] ||
ctx->Color.ColorMask[GCOMP] != ctx->Color.ColorMask[BCOMP]) {
- softwareMask |= (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT));
- mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT);
+ softwareMask |= (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT));
+ mask &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT);
}
}
* in the OGL state.
*/
BEGIN_BOARD_LOCK();
- if (mask & DD_STENCIL_BIT) {
- fxMesa->Glide.grStencilMaskExt(0xff /*fxMesa->unitsState.stencilWriteMask*/);
+ if (mask & BUFFER_BIT_STENCIL) {
+ fxMesa->Glide.grStencilMaskExt(fxMesa->unitsState.stencilWriteMask);
/* set stencil ref value = desired clear value */
fxMesa->Glide.grStencilFuncExt(GR_CMP_ALWAYS, clearS, 0xff);
fxMesa->Glide.grStencilOpExt(GR_STENCILOP_REPLACE,
grDisable(GR_STENCIL_MODE_EXT);
}
END_BOARD_LOCK();
+ } else if (mask & BUFFER_BIT_STENCIL) {
+ softwareMask |= (mask & (BUFFER_BIT_STENCIL));
+ mask &= ~(BUFFER_BIT_STENCIL);
}
/*
* This could probably be done fancier but doing each possible case
* explicitly is less error prone.
*/
- switch (mask & ~DD_STENCIL_BIT) {
- case DD_BACK_LEFT_BIT | DD_DEPTH_BIT:
+ switch (mask & ~BUFFER_BIT_STENCIL) {
+ case BUFFER_BIT_BACK_LEFT | BUFFER_BIT_DEPTH:
/* back buffer & depth */
- /* FX_grColorMaskv_NoLock(ctx, true4); */ /* work around Voodoo3 bug */
- grDepthMask(FXTRUE);
+ grDepthMask(FXTRUE);
grRenderBuffer(GR_BUFFER_BACKBUFFER);
if (stencil_size > 0) {
fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
grBufferClear(fxMesa->clearC,
fxMesa->clearA,
clearD);
- if (!fxMesa->unitsState.depthTestEnabled) {
- grDepthMask(FXFALSE);
- }
break;
- case DD_FRONT_LEFT_BIT | DD_DEPTH_BIT:
+ case BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_DEPTH:
/* XXX it appears that the depth buffer isn't cleared when
* glRenderBuffer(GR_BUFFER_FRONTBUFFER) is set.
* This is a work-around/
*/
/* clear depth */
- grDepthMask(FXTRUE);
- grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ grDepthMask(FXTRUE);
fxDisableColor(fxMesa);
+ grRenderBuffer(GR_BUFFER_BACKBUFFER);
if (stencil_size > 0)
fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
fxMesa->clearA,
grBufferClear(fxMesa->clearC,
fxMesa->clearA,
clearD);
- /* clear front */
fxSetupColorMask(ctx);
+ grDepthMask(FXFALSE);
+ /* clear front */
grRenderBuffer(GR_BUFFER_FRONTBUFFER);
if (stencil_size > 0)
fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
grBufferClear(fxMesa->clearC,
fxMesa->clearA,
clearD);
- if (!fxMesa->unitsState.depthTestEnabled) {
- grDepthMask(FXFALSE);
- }
break;
- case DD_BACK_LEFT_BIT:
+ case BUFFER_BIT_BACK_LEFT:
/* back buffer only */
grDepthMask(FXFALSE);
grRenderBuffer(GR_BUFFER_BACKBUFFER);
grBufferClear(fxMesa->clearC,
fxMesa->clearA,
clearD);
- if (fxMesa->unitsState.depthTestEnabled) {
- grDepthMask(FXTRUE);
- }
break;
- case DD_FRONT_LEFT_BIT:
+ case BUFFER_BIT_FRONT_LEFT:
/* front buffer only */
grDepthMask(FXFALSE);
grRenderBuffer(GR_BUFFER_FRONTBUFFER);
grBufferClear(fxMesa->clearC,
fxMesa->clearA,
clearD);
- if (fxMesa->unitsState.depthTestEnabled) {
- grDepthMask(FXTRUE);
- }
break;
- case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT:
+ case BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT:
/* front and back */
grDepthMask(FXFALSE);
grRenderBuffer(GR_BUFFER_BACKBUFFER);
grBufferClear(fxMesa->clearC,
fxMesa->clearA,
clearD);
- if (fxMesa->unitsState.depthTestEnabled) {
- grDepthMask(FXTRUE);
- }
break;
- case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT | DD_DEPTH_BIT:
- /* clear front */
- grDepthMask(FXFALSE);
- grRenderBuffer(GR_BUFFER_FRONTBUFFER);
- if (stencil_size > 0)
+ case BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT | BUFFER_BIT_DEPTH:
+ /* clear back and depth */
+ grDepthMask(FXTRUE);
+ grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ if (stencil_size > 0)
fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
fxMesa->clearA,
clearD, clearS);
grBufferClear(fxMesa->clearC,
fxMesa->clearA,
clearD);
- /* clear back and depth */
- grDepthMask(FXTRUE);
- grRenderBuffer(GR_BUFFER_BACKBUFFER);
- if (stencil_size > 0)
+ /* clear front */
+ grDepthMask(FXFALSE);
+ grRenderBuffer(GR_BUFFER_FRONTBUFFER);
+ if (stencil_size > 0)
fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
fxMesa->clearA,
clearD, clearS);
grBufferClear(fxMesa->clearC,
fxMesa->clearA,
clearD);
- if (!fxMesa->unitsState.depthTestEnabled) {
- grDepthMask(FXFALSE);
- }
break;
- case DD_DEPTH_BIT:
+ case BUFFER_BIT_DEPTH:
/* just the depth buffer */
- grRenderBuffer(GR_BUFFER_BACKBUFFER);
+ grDepthMask(FXTRUE);
fxDisableColor(fxMesa);
- grDepthMask(FXTRUE);
+ grRenderBuffer(GR_BUFFER_BACKBUFFER);
if (stencil_size > 0)
fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
fxMesa->clearA,
fxMesa->clearA,
clearD);
fxSetupColorMask(ctx);
- if (ctx->Color._DrawDestMask & DD_FRONT_LEFT_BIT) {
- grRenderBuffer(GR_BUFFER_FRONTBUFFER);
- }
- if (!fxMesa->unitsState.depthTestEnabled) {
- grDepthMask(FXFALSE);
- }
break;
default:
/* clear no color buffers or depth buffer but might clear stencil */
- if (stencil_size > 0 && (mask & DD_STENCIL_BIT)) {
+ if ((stencil_size > 0) && (mask & BUFFER_BIT_STENCIL)) {
/* XXX need this RenderBuffer call to work around Glide bug */
- grRenderBuffer(GR_BUFFER_BACKBUFFER);
grDepthMask(FXFALSE);
+ grRenderBuffer(GR_BUFFER_BACKBUFFER);
fxDisableColor(fxMesa);
fxMesa->Glide.grBufferClearExt(fxMesa->clearC,
fxMesa->clearA,
clearD, clearS);
- if (fxMesa->unitsState.depthTestEnabled) {
- grDepthMask(FXTRUE);
- }
fxSetupColorMask(ctx);
- if (ctx->Color._DrawDestMask & DD_FRONT_LEFT_BIT) {
- grRenderBuffer(GR_BUFFER_FRONTBUFFER);
- }
}
}
}
END_CLIP_LOOP();
- if (fxMesa->haveHwStencil && (mask & DD_STENCIL_BIT)) {
- /* We changed the stencil state above. Signal that we need to
- * upload it again.
- */
- fxMesa->new_state |= FX_NEW_STENCIL;
+ if (fxMesa->haveHwStencil) {
+ /* We changed the stencil state above. Restore it! */
+ fxSetupStencil(ctx);
}
+ fxSetupDepthTest(ctx);
+ grRenderBuffer(fxMesa->currentFB);
if (softwareMask)
- _swrast_Clear( ctx, softwareMask, all, x, y, width, height );
+ _swrast_Clear( ctx, softwareMask );
}
/* Set the buffer used for drawing */
/* XXX support for separate read/draw buffers hasn't been tested */
+/* XXX GL_NONE disables color, but fails to correctly maintain state */
static void
fxDDSetDrawBuffer(GLcontext * ctx, GLenum mode)
{
struct gl_pixelstore_attrib scissoredUnpack;
/* check if there's any raster operations enabled which we can't handle */
- if ((swrast->_RasterMask & (ALPHATEST_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 */
+ MASKING_BIT |
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))
- ) {
+ FRAGPROG_BIT)) {
_swrast_Bitmap(ctx, px, py, width, height, unpack, bitmap);
return;
}
/* make sure the pixelpipe is configured correctly */
fxSetupFXUnits(ctx);
+ /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
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
if (!grLfbLock(GR_LFB_WRITE_ONLY,
fxMesa->currentFB,
mode,
- GR_ORIGIN_UPPER_LEFT, FXTRUE, &info)) {
- _swrast_Bitmap(ctx, px, py, width, height, unpack, bitmap);
+ GR_ORIGIN_LOWER_LEFT, FXTRUE, &info)) {
+ _swrast_Bitmap(ctx, px, py, width, height, finalUnpack, bitmap);
return;
}
{
const GLint winX = 0;
- const GLint winY = fxMesa->height - 1;
+ const GLint winY = 0;
/* 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.
GLint row;
/* compute dest address of bottom-left pixel in bitmap */
GLushort *dst = (GLushort *) info.lfbPtr
- + (winY - py) * dstStride + (winX + px);
+ + (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);
+ (const GLubyte *) _mesa_image_address2d(finalUnpack,
+ bitmap, width, height,
+ GL_COLOR_INDEX, GL_BITMAP,
+ row, 0);
if (finalUnpack->LsbFirst) {
/* least significan bit first */
GLubyte mask = 1U << (finalUnpack->SkipPixels & 0x7);
if (mask != 128)
src++;
}
- dst -= dstStride;
+ dst += dstStride;
}
}
/*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 |
/* make sure the pixelpipe is configured correctly */
fxSetupFXUnits(ctx);
+ /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
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
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);
+ GR_ORIGIN_LOWER_LEFT, FXTRUE, &info)) {
+ _swrast_Bitmap(ctx, px, py, width, height, finalUnpack, bitmap);
return;
}
{
const GLint winX = 0;
- const GLint winY = fxMesa->height - 1;
+ const GLint winY = 0;
/* 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.
GLint row;
/* compute dest address of bottom-left pixel in bitmap */
GLuint *dst = (GLuint *) info.lfbPtr
- + (winY - py) * dstStride + (winX + px);
+ + (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);
+ (const GLubyte *) _mesa_image_address2d(finalUnpack,
+ bitmap, width, height,
+ GL_COLOR_INDEX, GL_BITMAP,
+ row, 0);
if (finalUnpack->LsbFirst) {
/* least significan bit first */
GLubyte mask = 1U << (finalUnpack->SkipPixels & 0x7);
if (mask != 128)
src++;
}
- dst -= dstStride;
+ dst += dstStride;
}
}
const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */
const GLushort *src = (const GLushort *) info.lfbPtr
+ (winY - y) * srcStride + (winX + x);
- GLubyte *dst = (GLubyte *) _mesa_image_address(packing, dstImage,
+ GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, dstImage,
width, height, format,
- type, 0, 0, 0);
+ type, 0, 0);
GLint dstStride =
_mesa_image_row_stride(packing, width, format, type);
const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */
const GLushort *src = (const GLushort *) info.lfbPtr
+ (winY - y) * srcStride + (winX + x);
- GLubyte *dst = (GLubyte *) _mesa_image_address(packing, dstImage,
+ GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, dstImage,
width, height, format,
- type, 0, 0, 0);
+ type, 0, 0);
GLint dstStride =
_mesa_image_row_stride(packing, width, format, type);
src -= srcStride;
}
}
- else if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) {
+ else if (format == GL_BGRA && type == GL_UNSIGNED_SHORT_1_5_5_5_REV) {
/* directly memcpy 5R5G5B pixels into client's buffer */
const GLint widthInBytes = width * 2;
GLint row;
const GLint srcStride = info.strideInBytes / 4; /* stride in GLuints */
const GLuint *src = (const GLuint *) info.lfbPtr
+ (winY - y) * srcStride + (winX + x);
- GLubyte *dst = (GLubyte *) _mesa_image_address(packing, dstImage,
+ GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, dstImage,
width, height, format,
- type, 0, 0, 0);
+ type, 0, 0);
GLint dstStride =
_mesa_image_row_stride(packing, width, format, type);
}
-/* [dBorca] Hack alert:
- * not finished!!!
- * revise fallback tests and fix scissor; implement new formats
- * also write its siblings: 565 and 1555
- */
-void
+static void
+fxDDDrawPixels555 (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);
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ GrLfbInfo_t info;
+ const struct gl_pixelstore_attrib *finalUnpack;
+ struct gl_pixelstore_attrib scissoredUnpack;
+
+ if (ctx->Pixel.ZoomX != 1.0F ||
+ ctx->Pixel.ZoomY != 1.0F ||
+ (ctx->_ImageTransferState & (IMAGE_SCALE_BIAS_BIT|
+ IMAGE_MAP_COLOR_BIT)) ||
+ (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 |
+ MULTI_DRAW_BIT |
+ OCCLUSION_BIT | /* nope! at least not yet */
+ TEXTURE_BIT |
+ FRAGPROG_BIT)) ||
+ fxMesa->fallback)
+ {
+ _swrast_DrawPixels( ctx, x, y, width, height, format, type,
+ unpack, pixels );
+ return;
+ }
+
+ /* make sure the pixelpipe is configured correctly */
+ fxSetupFXUnits(ctx);
+
+ /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
+ 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 (x < ctx->Scissor.X) {
+ scissoredUnpack.SkipPixels += (ctx->Scissor.X - x);
+ width -= (ctx->Scissor.X - x);
+ x = ctx->Scissor.X;
+ }
+ /* clip right */
+ if (x + width >= ctx->Scissor.X + ctx->Scissor.Width) {
+ width -= (x + width - (ctx->Scissor.X + ctx->Scissor.Width));
+ }
+ /* clip bottom */
+ if (y < ctx->Scissor.Y) {
+ scissoredUnpack.SkipRows += (ctx->Scissor.Y - y);
+ height -= (ctx->Scissor.Y - y);
+ y = ctx->Scissor.Y;
+ }
+ /* clip top */
+ if (y + height >= ctx->Scissor.Y + ctx->Scissor.Height) {
+ height -= (y + height - (ctx->Scissor.Y + ctx->Scissor.Height));
+ }
+
+ if (width <= 0 || height <= 0)
+ return;
+ }
+ else {
+ finalUnpack = unpack;
+ }
+
+ info.size = sizeof(info);
+ if (!grLfbLock(GR_LFB_WRITE_ONLY,
+ fxMesa->currentFB,
+ GR_LFBWRITEMODE_1555,
+ GR_ORIGIN_LOWER_LEFT, FXTRUE, &info)) {
+ _swrast_DrawPixels(ctx, x, y, width, height, format, type, finalUnpack, pixels);
+ return;
+ }
+
+ {
+ const GLint winX = 0;
+ const GLint winY = 0;
+
+ const GLint dstStride = info.strideInBytes / 2; /* stride in GLushorts */
+ GLushort *dst = (GLushort *) info.lfbPtr + (winY + y) * dstStride + (winX + x);
+
+ if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
+ GLint row;
+ for (row = 0; row < height; row++) {
+ GLubyte *src = (GLubyte *) _mesa_image_address2d(finalUnpack,
+ pixels, width, height, format, type, row, 0);
+ GLint col;
+ for (col = 0; col < width; col++) {
+ dst[col] = TDFXPACKCOLOR1555(src[2], src[1], src[0], src[3]);
+ src += 4;
+ }
+ dst += dstStride;
+ }
+ }
+ else if (format == GL_RGB && type == GL_UNSIGNED_BYTE) {
+ GLint row;
+ for (row = 0; row < height; row++) {
+ GLubyte *src = (GLubyte *) _mesa_image_address2d(finalUnpack,
+ pixels, width, height, format, type, row, 0);
+ GLint col;
+ for (col = 0; col < width; col++) {
+ dst[col] = TDFXPACKCOLOR1555(src[2], src[1], src[0], 255);
+ src += 3;
+ }
+ dst += dstStride;
+ }
+ }
+ else {
+ grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB);
+ _swrast_DrawPixels(ctx, x, y, width, height, format, type, finalUnpack, pixels);
+ return;
+ }
+
+ }
+
+ grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB);
+}
+
+
+static void
+fxDDDrawPixels565 (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);
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ GrLfbInfo_t info;
+ const struct gl_pixelstore_attrib *finalUnpack;
+ struct gl_pixelstore_attrib scissoredUnpack;
+
+ if (ctx->Pixel.ZoomX != 1.0F ||
+ ctx->Pixel.ZoomY != 1.0F ||
+ (ctx->_ImageTransferState & (IMAGE_SCALE_BIAS_BIT|
+ IMAGE_MAP_COLOR_BIT)) ||
+ (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 |
+ MULTI_DRAW_BIT |
+ OCCLUSION_BIT | /* nope! at least not yet */
+ TEXTURE_BIT |
+ FRAGPROG_BIT)) ||
+ fxMesa->fallback)
+ {
+ _swrast_DrawPixels( ctx, x, y, width, height, format, type,
+ unpack, pixels );
+ return;
+ }
+
+ /* make sure the pixelpipe is configured correctly */
+ fxSetupFXUnits(ctx);
+
+ /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
+ 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 (x < ctx->Scissor.X) {
+ scissoredUnpack.SkipPixels += (ctx->Scissor.X - x);
+ width -= (ctx->Scissor.X - x);
+ x = ctx->Scissor.X;
+ }
+ /* clip right */
+ if (x + width >= ctx->Scissor.X + ctx->Scissor.Width) {
+ width -= (x + width - (ctx->Scissor.X + ctx->Scissor.Width));
+ }
+ /* clip bottom */
+ if (y < ctx->Scissor.Y) {
+ scissoredUnpack.SkipRows += (ctx->Scissor.Y - y);
+ height -= (ctx->Scissor.Y - y);
+ y = ctx->Scissor.Y;
+ }
+ /* clip top */
+ if (y + height >= ctx->Scissor.Y + ctx->Scissor.Height) {
+ height -= (y + height - (ctx->Scissor.Y + ctx->Scissor.Height));
+ }
+
+ if (width <= 0 || height <= 0)
+ return;
+ }
+ else {
+ finalUnpack = unpack;
+ }
+
+ info.size = sizeof(info);
+ if (!grLfbLock(GR_LFB_WRITE_ONLY,
+ fxMesa->currentFB,
+ GR_LFBWRITEMODE_565,
+ GR_ORIGIN_LOWER_LEFT, FXTRUE, &info)) {
+ _swrast_DrawPixels(ctx, x, y, width, height, format, type, finalUnpack, pixels);
+ return;
+ }
+
+ {
+ const GLint winX = 0;
+ const GLint winY = 0;
+
+ const GLint dstStride = info.strideInBytes / 2; /* stride in GLushorts */
+ GLushort *dst = (GLushort *) info.lfbPtr + (winY + y) * dstStride + (winX + x);
+
+ if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
+ GLint row;
+ for (row = 0; row < height; row++) {
+ GLubyte *src = (GLubyte *) _mesa_image_address2d(finalUnpack,
+ pixels, width, height, format, type, row, 0);
+ GLint col;
+ for (col = 0; col < width; col++) {
+ dst[col] = TDFXPACKCOLOR565(src[2], src[1], src[0]);
+ src += 4;
+ }
+ dst += dstStride;
+ }
+ }
+ else if (format == GL_RGB && type == GL_UNSIGNED_BYTE) {
+ GLint row;
+ for (row = 0; row < height; row++) {
+ GLubyte *src = (GLubyte *) _mesa_image_address2d(finalUnpack,
+ pixels, width, height, format, type, row, 0);
+ GLint col;
+ for (col = 0; col < width; col++) {
+ dst[col] = TDFXPACKCOLOR565(src[2], src[1], src[0]);
+ src += 3;
+ }
+ dst += dstStride;
+ }
+ }
+ else {
+ grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB);
+ _swrast_DrawPixels(ctx, x, y, width, height, format, type, finalUnpack, pixels);
+ return;
+ }
+
+ }
+
+ grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB);
+}
+
+
+static void
+fxDDDrawPixels565_rev (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);
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ GrLfbInfo_t info;
+ const struct gl_pixelstore_attrib *finalUnpack;
+ struct gl_pixelstore_attrib scissoredUnpack;
+
+ if (ctx->Pixel.ZoomX != 1.0F ||
+ ctx->Pixel.ZoomY != 1.0F ||
+ (ctx->_ImageTransferState & (IMAGE_SCALE_BIAS_BIT|
+ IMAGE_MAP_COLOR_BIT)) ||
+ (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 |
+ MULTI_DRAW_BIT |
+ OCCLUSION_BIT | /* nope! at least not yet */
+ TEXTURE_BIT |
+ FRAGPROG_BIT)) ||
+ fxMesa->fallback)
+ {
+ _swrast_DrawPixels( ctx, x, y, width, height, format, type,
+ unpack, pixels );
+ return;
+ }
+
+ /* make sure the pixelpipe is configured correctly */
+ fxSetupFXUnits(ctx);
+
+ /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
+ 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 (x < ctx->Scissor.X) {
+ scissoredUnpack.SkipPixels += (ctx->Scissor.X - x);
+ width -= (ctx->Scissor.X - x);
+ x = ctx->Scissor.X;
+ }
+ /* clip right */
+ if (x + width >= ctx->Scissor.X + ctx->Scissor.Width) {
+ width -= (x + width - (ctx->Scissor.X + ctx->Scissor.Width));
+ }
+ /* clip bottom */
+ if (y < ctx->Scissor.Y) {
+ scissoredUnpack.SkipRows += (ctx->Scissor.Y - y);
+ height -= (ctx->Scissor.Y - y);
+ y = ctx->Scissor.Y;
+ }
+ /* clip top */
+ if (y + height >= ctx->Scissor.Y + ctx->Scissor.Height) {
+ height -= (y + height - (ctx->Scissor.Y + ctx->Scissor.Height));
+ }
+
+ if (width <= 0 || height <= 0)
+ return;
+ }
+ else {
+ finalUnpack = unpack;
+ }
+
+ info.size = sizeof(info);
+ if (!grLfbLock(GR_LFB_WRITE_ONLY,
+ fxMesa->currentFB,
+ GR_LFBWRITEMODE_565,
+ GR_ORIGIN_LOWER_LEFT, FXTRUE, &info)) {
+ _swrast_DrawPixels(ctx, x, y, width, height, format, type, finalUnpack, pixels);
+ return;
+ }
+
+ {
+ const GLint winX = 0;
+ const GLint winY = 0;
+
+ const GLint dstStride = info.strideInBytes / 2; /* stride in GLushorts */
+ GLushort *dst = (GLushort *) info.lfbPtr + (winY + y) * dstStride + (winX + x);
+
+ if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
+ GLint row;
+ for (row = 0; row < height; row++) {
+ GLubyte *src = (GLubyte *) _mesa_image_address2d(finalUnpack,
+ pixels, width, height, format, type, row, 0);
+ GLint col;
+ for (col = 0; col < width; col++) {
+ dst[col] = TDFXPACKCOLOR565(src[0], src[1], src[2]);
+ src += 4;
+ }
+ dst += dstStride;
+ }
+ }
+ else if (format == GL_RGB && type == GL_UNSIGNED_BYTE) {
+ GLint row;
+ for (row = 0; row < height; row++) {
+ GLubyte *src = (GLubyte *) _mesa_image_address2d(finalUnpack,
+ pixels, width, height, format, type, row, 0);
+ GLint col;
+ for (col = 0; col < width; col++) {
+ dst[col] = TDFXPACKCOLOR565(src[0], src[1], src[2]);
+ src += 3;
+ }
+ dst += dstStride;
+ }
+ }
+ else {
+ grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB);
+ _swrast_DrawPixels(ctx, x, y, width, height, format, type, finalUnpack, pixels);
+ return;
+ }
+
+ }
+
+ grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB);
+}
+
+
+static void
fxDDDrawPixels8888 (GLcontext * ctx, GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
const GLvoid * pixels)
{
fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
GrLfbInfo_t info;
+ const struct gl_pixelstore_attrib *finalUnpack;
+ struct gl_pixelstore_attrib scissoredUnpack;
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 ||
+ (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 */
+ MULTI_DRAW_BIT |
+ OCCLUSION_BIT | /* nope! at least not yet */
+ TEXTURE_BIT |
+ FRAGPROG_BIT)) ||
fxMesa->fallback)
{
- _swrast_DrawPixels( ctx, x, y, width, height, format, type,
+ _swrast_DrawPixels( ctx, x, y, width, height, format, type,
unpack, pixels );
- return;
+ 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;
+ /* FIXME! _RasterMask & CLIP_BIT gets set if we're out of Viewport, also! */
+ 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 (x < ctx->Scissor.X) {
+ scissoredUnpack.SkipPixels += (ctx->Scissor.X - x);
+ width -= (ctx->Scissor.X - x);
+ x = ctx->Scissor.X;
}
+ /* clip right */
+ if (x + width >= ctx->Scissor.X + ctx->Scissor.Width) {
+ width -= (x + width - (ctx->Scissor.X + ctx->Scissor.Width));
+ }
+ /* clip bottom */
+ if (y < ctx->Scissor.Y) {
+ scissoredUnpack.SkipRows += (ctx->Scissor.Y - y);
+ height -= (ctx->Scissor.Y - y);
+ y = ctx->Scissor.Y;
+ }
+ /* clip top */
+ if (y + height >= ctx->Scissor.Y + ctx->Scissor.Height) {
+ height -= (y + height - (ctx->Scissor.Y + ctx->Scissor.Height));
+ }
+
+ if (width <= 0 || height <= 0)
+ return;
+ }
+ else {
+ finalUnpack = unpack;
}
-#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);
+ GR_ORIGIN_LOWER_LEFT, FXTRUE, &info)) {
+ _swrast_DrawPixels(ctx, x, y, width, height, format, type, finalUnpack, pixels);
return;
}
{
const GLint winX = 0;
- const GLint winY = fxMesa->height - 1;
+ const GLint winY = 0;
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);
+ GLuint *dst = (GLuint *) info.lfbPtr + (winY + y) * dstStride + (winX + x);
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++) {
+ GLubyte *src = (GLubyte *) _mesa_image_address2d(finalUnpack,
+ pixels, width, height, format, type, row, 0);
MEMCPY(dst, src, widthInBytes);
- dst -= dstStride;
- src += srcStride;
+ dst += dstStride;
+ }
+ }
+ else if (format == GL_RGB && type == GL_UNSIGNED_BYTE) {
+ GLint row;
+ for (row = 0; row < height; row++) {
+ GLubyte *src = (GLubyte *) _mesa_image_address2d(finalUnpack,
+ pixels, width, height, format, type, row, 0);
+ GLint col;
+ for (col = 0; col < width; col++) {
+ dst[col] = TDFXPACKCOLOR8888(src[2], src[1], src[0], 255);
+ src += 3;
+ }
+ dst += dstStride;
}
}
else {
grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB);
- END_BOARD_LOCK();
- _swrast_DrawPixels(ctx, x, y, width, height, format, type, unpack, pixels);
+ _swrast_DrawPixels(ctx, x, y, width, height, format, type, finalUnpack, pixels);
return;
}
}
grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB);
- END_BOARD_LOCK();
}
}
static const struct tnl_pipeline_stage *fx_pipeline[] = {
- &_tnl_vertex_transform_stage, /* TODO: Add the fastpath here */
+ &_tnl_vertex_transform_stage, /* XXX todo - Add the fastpath here */
&_tnl_normal_transform_stage,
&_tnl_lighting_stage,
&_tnl_fog_coordinate_stage,
&_tnl_texgen_stage,
&_tnl_texture_transform_stage,
&_tnl_point_attenuation_stage,
+#if defined(FEATURE_NV_vertex_program) || defined(FEATURE_ARB_vertex_program)
+ &_tnl_vertex_program_stage,
+#endif
&_tnl_render_stage,
0,
};
int
fxDDInitFxMesaContext(fxMesaContext fxMesa)
{
- int i;
GLcontext *ctx = fxMesa->glCtx;
FX_setupGrVertexLayout();
fxMesa->unitsState.stencilWriteMask = 0xff;
- if (fxMesa->colDepth != 16) {
- /* 32bpp mode or 15bpp mode */
+ if (fxMesa->colDepth == 32) {
+ /* 32bpp */
fxMesa->Glide.grColorMaskExt(FXTRUE, FXTRUE, FXTRUE, fxMesa->haveHwAlpha);
} else {
- /* 16 bpp mode */
+ /* 15/16 bpp mode */
grColorMask(FXTRUE, fxMesa->haveHwAlpha);
}
return 0;
}
- /* [dBorca] Hack alert:
- * Unlike the rest of the Voodoo family, the Rush
- * doesn't support ZBUFFER with WBUFFER-like depth functions!
- * I guess we could use WBUFFER, which is better, but we can't
- * because the depth span functions would need to translate
- * depth values to 4.12 floating point...
- */
if (fxMesa->haveZBuffer) {
- grDepthBufferMode((fxMesa->type == GR_SSTTYPE_SST96)
- ? GR_DEPTHBUFFER_WBUFFER
- : GR_DEPTHBUFFER_ZBUFFER);
+ grDepthBufferMode(GR_DEPTHBUFFER_ZBUFFER);
}
if (!fxMesa->bgrOrder) {
textureLevels++;
} while ((textureSize >>= 0x1) & 0x7ff);
ctx->Const.MaxTextureLevels = textureLevels;
+ ctx->Const.MaxTextureLodBias = /*textureLevels - 1*/8; /* Glide bug */
#if FX_RESCALE_BIG_TEXURES_HACK
fxMesa->textureMaxLod = textureLevels - 1;
if ((env = getenv("MESA_FX_MAXLOD")) != NULL) {
ctx->Const.MaxTextureCoordUnits =
ctx->Const.MaxTextureImageUnits = fxMesa->haveTwoTMUs ? 2 : 1;
ctx->Const.MaxTextureUnits = MAX2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits);
-
+
fxMesa->new_state = _NEW_ALL;
if (!fxMesa->haveHwStencil) {
/* don't touch stencil if there is none */
/* Initialize the software rasterizer and helper modules.
*/
_swrast_CreateContext(ctx);
- _ac_CreateContext(ctx);
+ _vbo_CreateContext(ctx);
_tnl_CreateContext(ctx);
_swsetup_CreateContext(ctx);
fxDDInitExtensions(ctx);
#if 0
- /* [dBorca] Hack alert:
- * do we want dither? It just looks bad...
- */
+ /* do we want dither? It just looks bad... */
grEnable(GR_ALLOW_MIPMAP_DITHER);
- grTexNccTable(GR_NCCTABLE_NCC0); /* set this once... no multipass */
#endif
grGlideGetState((GrState *) fxMesa->state);
{
_swsetup_DestroyContext(fxMesa->glCtx);
_tnl_DestroyContext(fxMesa->glCtx);
- _ac_DestroyContext(fxMesa->glCtx);
+ _vbo_DestroyContext(fxMesa->glCtx);
_swrast_DestroyContext(fxMesa->glCtx);
if (fxMesa->state)
_mesa_enable_extension(ctx, "GL_EXT_secondary_color");
#endif
+ _mesa_enable_extension(ctx, "GL_ARB_point_sprite");
_mesa_enable_extension(ctx, "GL_EXT_point_parameters");
_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");
+ _mesa_enable_extension(ctx, "GL_EXT_texture_env_add");
+ _mesa_enable_extension(ctx, "GL_EXT_stencil_wrap");
+ _mesa_enable_extension(ctx, "GL_EXT_stencil_two_side");
if (fxMesa->haveTwoTMUs) {
- _mesa_enable_extension(ctx, "GL_EXT_texture_env_add");
_mesa_enable_extension(ctx, "GL_ARB_multitexture");
}
- if (fxMesa->haveHwStencil) {
- _mesa_enable_extension( ctx, "GL_EXT_stencil_wrap" );
- }
-
- /* [dBorca] Hack alert:
- * True texture compression can be done only on Napalm.
- * We will advertise, however, generic texture compression
- * on all Voodoo cards; the Mesa logic allows us to eventually
- * fallback to uncompressed. This will fix those dumb applications
- * which refuse to run w/o texture compression! We actually _can_
- * do texture compression for pre-Napalm cores, through NCC. But
- * NCC poses many issues:
- * 1) NCC w/o DITHER_ERR has poor quality and NCC w/ DITHER_ERR is
- * damn slow!
- * 2) NCC compression cannot be used with multitexturing, because
- * the decompression tables are not per TMU anymore (bear in mind
- * that earlier Voodoos could handle 2 NCC tables for each TMU --
- * just look for POINTCAST_PALETTE). As a last resort, we could
- * fake NCC multitexturing through multipass rendering, but...
- * ohwell, it's not worth the effort...
- * This stand true for multitexturing palletized textures.
- * 3) since NCC is not an OpenGL standard (as opposed to FXT1/DXTC), we
- * can't use precompressed textures!
- */
if (fxMesa->type >= GR_SSTTYPE_Voodoo4) {
_mesa_enable_extension(ctx, "GL_ARB_texture_compression");
_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");
_mesa_enable_extension(ctx, "GL_NV_blend_square");
- } else if (fxMesa->HaveTexus2) {
- _mesa_enable_extension(ctx, "GL_ARB_texture_compression");
+ } else {
+ /* [dBorca]
+ * We should enable generic texture compression functions,
+ * but some poorly written apps automatically assume S3TC.
+ * Binding NCC to GL_COMPRESSED_RGB[A] is an unnecessary hassle,
+ * since it's slow and ugly (better with palette textures, then).
+ * Moreover, NCC is not an OpenGL standard, so we can't use
+ * precompressed textures. Last, but not least, NCC runs amok
+ * when multitexturing on a Voodoo3 and up (see POINTCAST vs UMA).
+ * Note: this is also a problem with palette textures, but
+ * faking multitex by multipass is evil...
+ * Implementing NCC requires three stages:
+ * fxDDChooseTextureFormat:
+ * bind GL_COMPRESSED_RGB[A] to _mesa_texformat_argb8888,
+ * so we can quantize properly, at a later time
+ * fxDDTexImage:
+ * if GL_COMPRESSED_RGB
+ * use _mesa_texformat_l8 to get 1bpt and set GR_TEXFMT_YIQ_422
+ * if GL_COMPRESSED_RGBA
+ * use _mesa_texformat_al88 to get 2bpt and set GR_TEXFMT_AYIQ_8422
+ * txMipQuantize(...);
+ * if (level == 0) {
+ * txPalToNcc((GuNccTable *)(&(ti->palette)), pxMip.pal);
+ * }
+ * fxSetupSingleTMU_NoLock/fxSetupDoubleTMU_NoLock:
+ * grTexDownloadTable(GR_TEXTABLE_NCC0, &(ti->palette));
+ */
+ /*_mesa_enable_extension(ctx, "GL_ARB_texture_compression");*/
+ _mesa_enable_extension(ctx, "GL_SGIS_generate_mipmap");
}
if (fxMesa->HaveCmbExt) {
+ _mesa_enable_extension(ctx, "GL_ARB_texture_env_combine");
_mesa_enable_extension(ctx, "GL_EXT_texture_env_combine");
}
_mesa_enable_extension(ctx, "GL_EXT_multi_draw_arrays");
_mesa_enable_extension(ctx, "GL_IBM_multimode_draw_arrays");
_mesa_enable_extension(ctx, "GL_ARB_vertex_buffer_object");
+ /* dangerous */
+ if (getenv("MESA_FX_ALLOW_VP")) {
+ _mesa_enable_extension(ctx, "GL_ARB_vertex_program");
+ _mesa_enable_extension(ctx, "GL_NV_vertex_program");
+ _mesa_enable_extension(ctx, "GL_NV_vertex_program1_1");
+ _mesa_enable_extension(ctx, "GL_MESA_program_debug");
+ }
#if 0
- /* not until texel fetchers are right */
- _mesa_enable_extension(ctx, "GL_SGIS_generate_mipmap");
-#endif
-#if 0
- /* not just yet */
- _mesa_enable_extension(ctx, "GL_ARB_fragment_program");
- _mesa_enable_extension(ctx, "GL_ARB_vertex_program");
+ /* this requires _tnl_vertex_cull_stage in the pipeline */
+ _mesa_enable_extension(ctx, "EXT_cull_vertex");
#endif
}
return FX_FALLBACK_STENCIL;
}
- if (ctx->Color._DrawDestMask != DD_FRONT_LEFT_BIT &&
- ctx->Color._DrawDestMask != DD_BACK_LEFT_BIT) {
+ if ((ctx->DrawBuffer->_ColorDrawBufferIndexes[0] != BUFFER_BIT_FRONT_LEFT) &&
+ (ctx->DrawBuffer->_ColorDrawBufferIndexes[0] != BUFFER_BIT_BACK_LEFT)) {
return FX_FALLBACK_DRAW_BUFFER;
}
if (ctx->Color.BlendEnabled) {
- if ((ctx->Color.BlendEquationRGB != GL_FUNC_ADD) ||
- (ctx->Color.BlendEquationA != GL_FUNC_ADD)) {
+ if (ctx->Color.BlendEquationRGB != GL_FUNC_ADD) {
if (!fxMesa->HavePixExt ||
((ctx->Color.BlendEquationRGB != GL_FUNC_SUBTRACT) &&
- (ctx->Color.BlendEquationRGB != GL_FUNC_REVERSE_SUBTRACT)) ||
+ (ctx->Color.BlendEquationRGB != GL_FUNC_REVERSE_SUBTRACT))) {
+ return FX_FALLBACK_BLEND;
+ }
+ }
+
+ if (ctx->Color.BlendEquationA != GL_FUNC_ADD) {
+ if (!fxMesa->HavePixExt ||
((ctx->Color.BlendEquationA != GL_FUNC_SUBTRACT) &&
(ctx->Color.BlendEquationA != GL_FUNC_REVERSE_SUBTRACT))) {
return FX_FALLBACK_BLEND;
}
}
+
+#if 0
+ /* [dBorca]
+ * We fail the spec here, unless certain blending modes:
+ * RGB: (GL_ONE + GL_*) or (GL_ZERO + GL_*) or ...
+ */
+ if (NEED_SECONDARY_COLOR(ctx)) {
+ if ((ctx->Color.BlendEquationRGB != GL_FUNC_ADD) &&
+ (ctx->Color.BlendSrcRGB != GL_ONE)) {
+ /* Can't use multipass to blend ColorSum stage */
+ return FX_FALLBACK_SPECULAR;
+ }
+ }
+#endif
}
/* [dBorca]
return FX_FALLBACK_LOGICOP;
}
-#if 0 /* multipass ColorSum stage */
- if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) {
- return FX_FALLBACK_SPECULAR;
- }
-#endif
-
- if ((fxMesa->colDepth == 16) &&
+ if ((fxMesa->colDepth != 32) &&
((ctx->Color.ColorMask[RCOMP] != ctx->Color.ColorMask[GCOMP]) ||
(ctx->Color.ColorMask[GCOMP] != ctx->Color.ColorMask[BCOMP]))) {
return FX_FALLBACK_COLORMASK;
* were enabled. That's easy!
*/
if (ctx->Texture._EnabledUnits == 0x3) {
+#if 0
/* Can't use multipass to blend a multitextured triangle - fall
* back to software.
- * [dBorca] we hit this case only when we try to emulate
- * multitexture by multipass!
*/
if (!fxMesa->haveTwoTMUs && ctx->Color.BlendEnabled) {
return FX_FALLBACK_TEXTURE_MULTI;
}
+#endif
- if ((ctx->Texture.Unit[0].EnvMode != ctx->Texture.Unit[1].EnvMode) &&
+ if (!fxMesa->HaveCmbExt &&
+ (ctx->Texture.Unit[0].EnvMode != ctx->Texture.Unit[1].EnvMode) &&
(ctx->Texture.Unit[0].EnvMode != GL_MODULATE) &&
(ctx->Texture.Unit[0].EnvMode != GL_REPLACE)) { /* q2, seems ok... */
if (TDFX_DEBUG & VERBOSE_DRIVER)
static void
fxDDUpdateDDPointers(GLcontext * ctx, GLuint new_state)
{
- /* TNLcontext *tnl = TNL_CONTEXT(ctx);*/
+ /* TNLcontext *tnl = TNL_CONTEXT(ctx); */
fxMesaContext fxMesa = FX_CONTEXT(ctx);
if (TDFX_DEBUG & VERBOSE_DRIVER) {
}
_swrast_InvalidateState(ctx, new_state);
- _ac_InvalidateState(ctx, new_state);
+ _vbo_InvalidateState(ctx, new_state);
_tnl_InvalidateState(ctx, new_state);
_swsetup_InvalidateState(ctx, new_state);
fxSetupDDPointers(GLcontext * ctx)
{
fxMesaContext fxMesa = FX_CONTEXT(ctx);
- TNLcontext *tnl = TNL_CONTEXT(ctx);
+ /* TNLcontext *tnl = TNL_CONTEXT(ctx); */
if (TDFX_DEBUG & VERBOSE_DRIVER) {
fprintf(stderr, "fxSetupDDPointers()\n");
ctx->Driver.ClearColor = fxDDClearColor;
ctx->Driver.Clear = fxDDClear;
ctx->Driver.DrawBuffer = fxDDSetDrawBuffer;
- ctx->Driver.GetBufferSize = fxDDBufferSize;
+ ctx->Driver.GetBufferSize = fxDDGetBufferSize;
+ ctx->Driver.Viewport = fxDDViewport;
switch (fxMesa->colDepth) {
- case 15:
- ctx->Driver.ReadPixels = fxDDReadPixels555;
- ctx->Driver.Bitmap = fxDDDrawBitmap2;
- break;
- case 16:
- ctx->Driver.ReadPixels = fxDDReadPixels565;
- ctx->Driver.Bitmap = fxDDDrawBitmap2;
- break;
- case 32:
- ctx->Driver.DrawPixels = fxDDDrawPixels8888;
- ctx->Driver.ReadPixels = fxDDReadPixels8888;
- ctx->Driver.Bitmap = fxDDDrawBitmap4;
- break;
+ case 15:
+ ctx->Driver.DrawPixels = fxDDDrawPixels555;
+ ctx->Driver.ReadPixels = fxDDReadPixels555;
+ ctx->Driver.Bitmap = fxDDDrawBitmap2;
+ break;
+ case 16:
+ ctx->Driver.DrawPixels = !fxMesa->bgrOrder ? fxDDDrawPixels565 : fxDDDrawPixels565_rev;
+ ctx->Driver.ReadPixels = fxDDReadPixels565;
+ ctx->Driver.Bitmap = fxDDDrawBitmap2;
+ break;
+ case 32:
+ ctx->Driver.DrawPixels = fxDDDrawPixels8888;
+ ctx->Driver.ReadPixels = fxDDReadPixels8888;
+ ctx->Driver.Bitmap = fxDDDrawBitmap4;
+ break;
}
ctx->Driver.Finish = fxDDFinish;
ctx->Driver.Flush = NULL;
ctx->Driver.ShadeModel = fxDDShadeModel;
ctx->Driver.Enable = fxDDEnable;
if (fxMesa->haveHwStencil) {
- ctx->Driver.StencilFunc = fxDDStencilFunc;
- ctx->Driver.StencilMask = fxDDStencilMask;
- ctx->Driver.StencilOp = fxDDStencilOp;
+ ctx->Driver.StencilFuncSeparate = fxDDStencilFuncSeparate;
+ ctx->Driver.StencilMaskSeparate = fxDDStencilMaskSeparate;
+ ctx->Driver.StencilOpSeparate = fxDDStencilOpSeparate;
}
fxSetupDDSpanPointers(ctx);