+/* $Id: fxdd.c,v 1.95 2003/01/08 21:32:36 brianp Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.3
+ * Version: 4.0
*
- * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
+ * 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"),
* 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.
- *
- *
- * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
- * terms stated above.
- *
- * Thank you for your contribution, David!
- *
- * Please make note of the above copyright/license statement. If you
- * contributed code or bug fixes to this code under the previous (GNU
- * Library) license and object to the new license, your code will be
- * removed at your request. Please see the Mesa docs/COPYRIGHT file
- * for more information.
- *
- * Additional Mesa/3Dfx driver developers:
- * Daryll Strauss <daryll@precisioninsight.com>
- * Keith Whitwell <keith@precisioninsight.com>
- *
- * See fxapi.h for more revision/author details.
*/
+/* Authors:
+ * David Bucciarelli
+ * Brian Paul
+ * Daryll Strauss
+ * Keith Whitwell
+ */
/* fxdd.c - 3Dfx VooDoo Mesa device driver functions */
#include "fxdrv.h"
#include "enums.h"
#include "extensions.h"
+#include "mmath.h"
#include "texstore.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
/* Return buffer size information */
static void
-fxDDBufferSize(GLcontext * ctx, GLuint * width, GLuint * height)
+fxDDBufferSize(GLframebuffer *buffer, GLuint * width, GLuint * height)
{
- fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
+ GET_CURRENT_CONTEXT(ctx);
+ if (ctx && ctx->DriverCtx) {
+ fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
- if (MESA_VERBOSE & VERBOSE_DRIVER) {
- fprintf(stderr, "fxmesa: fxDDBufferSize(...) Start\n");
- }
+ if (MESA_VERBOSE & VERBOSE_DRIVER) {
+ fprintf(stderr, "fxmesa: fxDDBufferSize(...) Start\n");
+ }
- *width = fxMesa->width;
- *height = fxMesa->height;
+ *width = fxMesa->width;
+ *height = fxMesa->height;
- if (MESA_VERBOSE & VERBOSE_DRIVER) {
- fprintf(stderr, "fxmesa: fxDDBufferSize(...) End\n");
+ if (MESA_VERBOSE & VERBOSE_DRIVER) {
+ fprintf(stderr, "fxmesa: fxDDBufferSize(...) End\n");
+ }
}
}
/* Implements glClearColor() */
static void
-fxDDClearColor(GLcontext * ctx, const GLchan color[4])
+fxDDClearColor(GLcontext * ctx, const GLfloat color[4])
{
fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
GLubyte col[4];
if (MESA_VERBOSE & VERBOSE_DRIVER) {
- fprintf(stderr, "fxmesa: fxDDClearColor(%d,%d,%d,%d)\n",
+ fprintf(stderr, "fxmesa: fxDDClearColor(%f,%f,%f,%f)\n",
color[0], color[1], color[2], color[3]);
}
- ASSIGN_4V(col, color[0], color[1], color[2], 255);
+ CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]);
+ CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]);
+ CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]);
+ CLAMPED_FLOAT_TO_UBYTE(col[3], color[3]);
+
fxMesa->clearC = FXCOLOR4(col);
- fxMesa->clearA = color[3];
+ fxMesa->clearA = col[3];
}
FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
FX_grColorMask(FXTRUE, ctx->Color.ColorMask[ACOMP]
&& fxMesa->haveAlphaBuffer);
- if (ctx->Color.DrawDestMask & FRONT_LEFT_BIT)
+ if (ctx->Color._DrawDestMask & FRONT_LEFT_BIT)
FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
if (!ctx->Depth.Test || !ctx->Depth.Mask)
FX_grDepthMask(FXFALSE);
/* Set the buffer used for drawing */
/* XXX support for separate read/draw buffers hasn't been tested */
-static GLboolean
+static void
fxDDSetDrawBuffer(GLcontext * ctx, GLenum mode)
{
fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
if (mode == GL_FRONT_LEFT) {
fxMesa->currentFB = GR_BUFFER_FRONTBUFFER;
FX_grRenderBuffer(fxMesa->currentFB);
- return GL_TRUE;
}
else if (mode == GL_BACK_LEFT) {
fxMesa->currentFB = GR_BUFFER_BACKBUFFER;
FX_grRenderBuffer(fxMesa->currentFB);
- return GL_TRUE;
}
else if (mode == GL_NONE) {
FX_grColorMask(FXFALSE, FXFALSE);
- return GL_TRUE;
}
else {
- return GL_FALSE;
+ /* we'll need a software fallback */
+ /* XXX not implemented */
}
+
+ /* update s/w fallback state */
+ _swrast_DrawBuffer(ctx, mode);
}
ctx->Stencil.Enabled ||
ctx->Scissor.Enabled ||
(ctx->DrawBuffer->UseSoftwareAlphaBuffers &&
- ctx->Color.ColorMask[ACOMP]) || ctx->Color.MultiDrawBuffer) {
+ ctx->Color.ColorMask[ACOMP]) ||
+ (ctx->Color._DrawDestMask != FRONT_LEFT_BIT &&
+ ctx->Color._DrawDestMask != BACK_LEFT_BIT)) {
_swrast_Bitmap(ctx, px, py, width, height, unpack, bitmap);
return;
}
fxDDInitFxMesaContext(fxMesaContext fxMesa)
{
int i;
- static int firsttime = 1;
for (i = 0; i < 256; i++) {
gl_ubyte_to_float_255_color_tab[i] = (float) i;
}
- if (firsttime) {
- fxDDSetupInit();
- fxDDTrifuncInit();
- firsttime = 0;
- }
-
FX_setupGrVertexLayout();
if (getenv("FX_EMULATE_SINGLE_TMU"))
fxMesa->haveTwoTMUs = GL_FALSE;
- fxMesa->emulateTwoTMUs = fxMesa->haveTwoTMUs;
-
- if (!getenv("FX_DONT_FAKE_MULTITEX"))
- fxMesa->emulateTwoTMUs = GL_TRUE;
-
if (getenv("FX_GLIDE_SWAPINTERVAL"))
fxMesa->swapInterval = atoi(getenv("FX_GLIDE_SWAPINTERVAL"));
else
fxMesa->unitsState.alphaTestEnabled = GL_FALSE;
fxMesa->unitsState.alphaTestFunc = GR_CMP_ALWAYS;
- fxMesa->unitsState.alphaTestRefValue = 0;
+ fxMesa->unitsState.alphaTestRefValue = 0.0;
fxMesa->unitsState.blendEnabled = GL_FALSE;
fxMesa->unitsState.blendSrcFuncRGB = GR_BLEND_ONE;
}
fxMesa->state = malloc(FX_grGetInteger(FX_GLIDE_STATE_SIZE));
- fxMesa->fogTable = malloc(FX_grGetInteger(FX_FOG_TABLE_ENTRIES) *
+ fxMesa->fogTable = (GrFog_t *) malloc(FX_grGetInteger(FX_FOG_TABLE_ENTRIES) *
sizeof(GrFog_t));
if (!fxMesa->state || !fxMesa->fogTable) {
if (fxMesa->haveZBuffer)
FX_grDepthBufferMode(GR_DEPTHBUFFER_ZBUFFER);
-#if (!FXMESA_USE_ARGB)
+#ifndef FXMESA_USE_ARGB
FX_grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); /* Not every Glide has this */
#endif
fxMesa->textureAlign = FX_grGetInteger(FX_TEXTURE_ALIGN);
fxMesa->glCtx->Const.MaxTextureLevels = 9;
- fxMesa->glCtx->Const.MaxTextureSize = 256;
- fxMesa->glCtx->Const.MaxTextureUnits = fxMesa->emulateTwoTMUs ? 2 : 1;
+ fxMesa->glCtx->Const.MaxTextureUnits = fxMesa->haveTwoTMUs ? 2 : 1;
fxMesa->new_state = _NEW_ALL;
/* Initialize the software rasterizer and helper modules.
fxAllocVB(fxMesa->glCtx);
fxSetupDDPointers(fxMesa->glCtx);
+ fxDDInitTriFuncs(fxMesa->glCtx);
/* Tell the software rasterizer to use pixel fog always.
*/
fxDDInitExtensions(fxMesa->glCtx);
-#ifdef FXVTXFMT
- fxDDInitVtxfmt(fxMesa->glCtx);
-#endif
-
FX_grGlideGetState((GrState *) fxMesa->state);
- /* Run the config file */
- _mesa_context_initialize(fxMesa->glCtx);
-
return 1;
}
if (fxMesa->haveTwoTMUs)
_mesa_enable_extension(ctx, "GL_EXT_texture_env_add");
- if (fxMesa->emulateTwoTMUs)
+ if (fxMesa->haveTwoTMUs)
_mesa_enable_extension(ctx, "GL_ARB_multitexture");
}
*
* Performs similar work to fxDDChooseRenderState() - should be merged.
*/
-static GLboolean
-fxIsInHardware(GLcontext * ctx)
+GLboolean
+fx_check_IsInHardware(GLcontext * ctx)
{
fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
return GL_FALSE;
if (ctx->Stencil.Enabled ||
- ctx->Color.MultiDrawBuffer ||
+ (ctx->Color._DrawDestMask != FRONT_LEFT_BIT &&
+ ctx->Color._DrawDestMask != BACK_LEFT_BIT) ||
((ctx->Color.BlendEnabled)
&& (ctx->Color.BlendEquation != GL_FUNC_ADD_EXT))
|| ((ctx->Color.ColorLogicOpEnabled)
}
/* Unsupported texture/multitexture cases */
- if (fxMesa->emulateTwoTMUs) {
- if (ctx->Texture._ReallyEnabled & (TEXTURE0_3D | TEXTURE1_3D))
- return GL_FALSE; /* can't do 3D textures */
- if (ctx->Texture._ReallyEnabled & (TEXTURE0_1D | TEXTURE1_1D))
- return GL_FALSE; /* can't do 1D textures */
+ if (fxMesa->haveTwoTMUs) {
+ /* we can only do 2D textures */
+ if (ctx->Texture.Unit[0]._ReallyEnabled & ~TEXTURE_2D_BIT)
+ return GL_FALSE;
+ if (ctx->Texture.Unit[1]._ReallyEnabled & ~TEXTURE_2D_BIT)
+ return GL_FALSE;
- if (ctx->Texture._ReallyEnabled & TEXTURE0_2D) {
+ if (ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_2D_BIT) {
if (ctx->Texture.Unit[0].EnvMode == GL_BLEND &&
- (ctx->Texture._ReallyEnabled & TEXTURE1_2D ||
+ (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_2D_BIT ||
ctx->Texture.Unit[0].EnvColor[0] != 0 ||
ctx->Texture.Unit[0].EnvColor[1] != 0 ||
ctx->Texture.Unit[0].EnvColor[2] != 0 ||
return GL_FALSE;
}
- if (ctx->Texture._ReallyEnabled & TEXTURE1_2D) {
+ if (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_2D_BIT) {
if (ctx->Texture.Unit[1].EnvMode == GL_BLEND)
return GL_FALSE;
- if (ctx->Texture.Unit[0]._Current->Image[0]->Border > 0)
+ if (ctx->Texture.Unit[1]._Current->Image[0]->Border > 0)
return GL_FALSE;
}
/* KW: This was wrong (I think) and I changed it... which doesn't mean
* it is now correct...
+ * BP: The old condition just seemed to test if both texture units
+ * were enabled. That's easy!
*/
- if ((ctx->_Enabled & (TEXTURE0_1D | TEXTURE0_2D | TEXTURE0_3D)) &&
- (ctx->_Enabled & (TEXTURE1_1D | TEXTURE1_2D | TEXTURE1_3D))) {
+ if (ctx->Texture._EnabledUnits == 0x3) {
/* Can't use multipass to blend a multitextured triangle - fall
* back to software.
*/
}
}
else {
- if ((ctx->_Enabled & (TEXTURE1_1D | TEXTURE1_2D | TEXTURE1_3D)) ||
- /* Not very well written ... */
- ((ctx->_Enabled & TEXTURE0_1D) && (!(ctx->_Enabled & TEXTURE0_2D)))
- ) {
+ /* we have just one texture unit */
+ if (ctx->Texture._EnabledUnits > 0x1) {
return GL_FALSE;
}
-
- if ((ctx->Texture._ReallyEnabled & TEXTURE0_2D) &&
+ if ((ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_2D_BIT) &&
(ctx->Texture.Unit[0].EnvMode == GL_BLEND)) {
return GL_FALSE;
}
return GL_TRUE;
}
+
+
static void
update_texture_scales(GLcontext * ctx)
{
static void
fxDDUpdateDDPointers(GLcontext * ctx, GLuint new_state)
{
- TNLcontext *tnl = TNL_CONTEXT(ctx);
+ /* TNLcontext *tnl = TNL_CONTEXT(ctx);*/
fxMesaContext fxMesa = FX_CONTEXT(ctx);
_swrast_InvalidateState(ctx, new_state);
if (new_state & (_FX_NEW_IS_IN_HARDWARE |
_FX_NEW_RENDERSTATE |
- _FX_NEW_SETUP_FUNCTION | _NEW_TEXTURE)) {
+ _FX_NEW_SETUP_FUNCTION |
+ _NEW_TEXTURE)) {
if (new_state & _FX_NEW_IS_IN_HARDWARE)
- fxMesa->is_in_hardware = fxIsInHardware(ctx);
+ fxCheckIsInHardware(ctx);
if (fxMesa->new_state)
fxSetupFXUnits(ctx);
- if (new_state & _FX_NEW_RENDERSTATE)
- fxDDChooseRenderState(ctx);
+ if (fxMesa->is_in_hardware) {
+ if (new_state & _FX_NEW_RENDERSTATE)
+ fxDDChooseRenderState(ctx);
- if (new_state & _FX_NEW_SETUP_FUNCTION)
- tnl->Driver.BuildProjectedVertices = fx_validate_BuildProjVerts;
+ if (new_state & _FX_NEW_SETUP_FUNCTION)
+ fxChooseVertexState(ctx);
+ }
if (new_state & _NEW_TEXTURE)
update_texture_scales(ctx);
-
- }
-
-#ifdef FXVTXFMT
- if (fxMesa->allow_vfmt) {
- if (new_state & _NEW_LIGHT)
- fx_update_lighting(ctx);
-
- if (new_state & _FX_NEW_VTXFMT)
- fxDDCheckVtxfmt(ctx);
- }
-#endif
-}
-
-static void
-fxDDRenderPrimitive(GLcontext * ctx, GLenum mode)
-{
- fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
-
- if (!fxMesa->is_in_hardware) {
- _swsetup_RenderPrimitive(ctx, mode);
- }
- else {
- fxMesa->render_prim = mode;
}
}
-static void
-fxDDRenderStart(GLcontext * ctx)
-{
- fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
-
- _swsetup_RenderStart(ctx);
-
- if (fxMesa->new_state) {
- fxSetupFXUnits(ctx);
- }
-}
-
-static void
-fxDDRenderFinish(GLcontext * ctx)
-{
- fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
-
- if (!fxMesa->is_in_hardware) {
- _swsetup_RenderFinish(ctx);
- }
-}
-
void
ctx->Driver.ClearIndex = NULL;
ctx->Driver.ClearColor = fxDDClearColor;
ctx->Driver.Clear = fxDDClear;
- ctx->Driver.SetDrawBuffer = fxDDSetDrawBuffer;
+ 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;
ctx->Driver.ReadPixels = fxDDReadPixels;
- ctx->Driver.ResizeBuffersMESA = _swrast_alloc_buffers;
+ ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
ctx->Driver.Finish = fxDDFinish;
ctx->Driver.Flush = NULL;
+ ctx->Driver.ChooseTextureFormat = fxDDChooseTextureFormat;
ctx->Driver.TexImage1D = _mesa_store_teximage1d;
ctx->Driver.TexImage2D = fxDDTexImage2D;
ctx->Driver.TexImage3D = _mesa_store_teximage3d;
ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
ctx->Driver.TexSubImage2D = fxDDTexSubImage2D;
ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
+ ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d;
+ ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d;
+ ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d;
+ ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;
+ ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;
+ ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;
ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
ctx->Driver.ShadeModel = fxDDShadeModel;
ctx->Driver.Enable = fxDDEnable;
- tnl->Driver.RenderStart = fxDDRenderStart;
- tnl->Driver.RenderFinish = fxDDRenderFinish;
- tnl->Driver.ResetLineStipple = _swrast_ResetLineStipple;
- tnl->Driver.RenderPrimitive = fxDDRenderPrimitive;
- tnl->Driver.RenderInterp = _swsetup_RenderInterp;
- tnl->Driver.RenderCopyPV = _swsetup_RenderCopyPV;
- tnl->Driver.RenderClippedLine = _swsetup_RenderClippedLine;
- tnl->Driver.RenderClippedPolygon = _swsetup_RenderClippedPolygon;
+ tnl->Driver.RunPipeline = _tnl_run_pipeline;
fxSetupDDSpanPointers(ctx);
fxDDUpdateDDPointers(ctx, ~0);