diff options
Diffstat (limited to 'xc/extras/Mesa/src/FX')
-rw-r--r-- | xc/extras/Mesa/src/FX/fxapi.c | 205 | ||||
-rw-r--r-- | xc/extras/Mesa/src/FX/fxdd.c | 664 | ||||
-rw-r--r-- | xc/extras/Mesa/src/FX/fxddspan.c | 1709 | ||||
-rw-r--r-- | xc/extras/Mesa/src/FX/fxddtex.c | 1620 | ||||
-rw-r--r-- | xc/extras/Mesa/src/FX/fxdrv.h | 93 | ||||
-rw-r--r-- | xc/extras/Mesa/src/FX/fxglidew.c | 46 | ||||
-rw-r--r-- | xc/extras/Mesa/src/FX/fxglidew.h | 110 | ||||
-rw-r--r-- | xc/extras/Mesa/src/FX/fxsetup.c | 363 | ||||
-rw-r--r-- | xc/extras/Mesa/src/FX/fxtexman.c | 27 | ||||
-rw-r--r-- | xc/extras/Mesa/src/FX/fxtritmp.h | 66 |
10 files changed, 3269 insertions, 1634 deletions
diff --git a/xc/extras/Mesa/src/FX/fxapi.c b/xc/extras/Mesa/src/FX/fxapi.c index 0b96cf439..6d680bcb9 100644 --- a/xc/extras/Mesa/src/FX/fxapi.c +++ b/xc/extras/Mesa/src/FX/fxapi.c @@ -623,7 +623,7 @@ #if defined(FX) #include "fxdrv.h" -fxMesaContext fxMesaCurrentCtx=NULL; +static fxMesaContext fxMesaCurrentCtx=NULL; /* * Status of 3Dfx hardware initialization @@ -694,22 +694,11 @@ void GLAPIENTRY fxMesaSetNearFar(GLfloat n, GLfloat f) /* - * The extension GL_FXMESA_global_texture_lod_bias - */ -void GLAPIENTRY glGlobalTextureLODBiasFXMESA(GLfloat biasVal) -{ - grTexLodBiasValue(GR_TMU0,biasVal); - - if(fxMesaCurrentCtx->haveTwoTMUs) - grTexLodBiasValue(GR_TMU1,biasVal); -} - - -/* * The 3Dfx Global Palette extension for GLQuake. * More a trick than a real extesion, use the shared global * palette extension. */ +extern void GLAPIENTRY gl3DfxSetPaletteEXT(GLuint *pal); /* silence warning */ void GLAPIENTRY gl3DfxSetPaletteEXT(GLuint *pal) { fxMesaContext fxMesa =fxMesaCurrentCtx; @@ -866,6 +855,8 @@ fxMesaContext GLAPIENTRY fxMesaCreateContext(GLuint win, GLcontext *ctx = 0; /*FX_GrContext_t glideContext = 0;*/ char *errorstr; + GLboolean useBGR; + char *system = NULL; if (MESA_VERBOSE&VERBOSE_DRIVER) { fprintf(stderr,"fxmesa: fxMesaCreateContext() Start\n"); @@ -890,8 +881,10 @@ fxMesaContext GLAPIENTRY fxMesaCreateContext(GLuint win, case FXMESA_DEPTH_SIZE: i++; depthSize=attribList[i]; - if(depthSize) + if(depthSize) { aux=1; + depthSize = 16; + } break; case FXMESA_STENCIL_SIZE: i++; @@ -924,10 +917,7 @@ fxMesaContext GLAPIENTRY fxMesaCreateContext(GLuint win, if(depthSize && alphaBuffer) alphaBuffer=0; - if(verbose) - fprintf(stderr,"Mesa fx Voodoo Device Driver v0.30\nWritten by David Bucciarelli (davibu@tin.it.it)\n"); - - if((type=fxQueryHardware()) < 0) { + if ((type=fxQueryHardware()) < 0) { fprintf(stderr,"fx Driver: ERROR no Voodoo1/2 Graphics or Voodoo Rush !\n"); return NULL; } @@ -950,10 +940,8 @@ fxMesaContext GLAPIENTRY fxMesaCreateContext(GLuint win, else fxMesa->haveTwoTMUs=GL_FALSE; - fxMesa->haveDoubleBuffer=doubleBuffer; fxMesa->haveAlphaBuffer=alphaBuffer; fxMesa->haveGlobalPaletteTexture=GL_FALSE; - fxMesa->haveZBuffer=depthSize ? 1 : 0; fxMesa->verbose=verbose; fxMesa->board=glbCurrentBoard; @@ -971,28 +959,83 @@ fxMesaContext GLAPIENTRY fxMesaCreateContext(GLuint win, goto errorhandler; } - /* Pixel tables are use during pixel read-back */ + /* + * Pixel tables are use during pixel read-back + * Either initialize them for RGB or BGR order. + */ #if FXMESA_USE_ARGB - fxInitPixelTables(fxMesa, GL_FALSE); /* Force RGB pixel order */ + useBGR = GL_FALSE; /* Force RGB pixel order */ + system = "FXMESA_USE_ARGB"; #else if (glbHWConfig.SSTs[glbCurrentBoard].type == GR_SSTTYPE_VOODOO) { - /* jk991130 - GROSS HACK!!! - Voodoo 3s don't use BGR!! - * the only way to tell if it's a Voodoo 3 at this stage of the - * ballgame (no Glide 3.x for linux *yet*) is to query the # of TMUs + /* jk991130 - Voodoo 3s don't use BGR. Query the # of TMUs * as Voodoo3s have 2 TMUs on board, Banshee has only 1 - * Thanks to Joseph Kain for that one + * bk000413 - another suggestion from Joseph Kain is using + * VendorID 0x121a for all 3dfx boards + * DeviceID VG 1/V2 2/VB 3/V3 5 + * For now we cehck for known BGR devices, and presume + * everything else to be a V3/RGB. */ - if (glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.nTexelfx == 2) { - fxInitPixelTables(fxMesa, GL_FALSE); /* use RGB pixel order (Voodoo3) */ + GrVoodooConfig_t *voodoo; + voodoo = &glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig; + + if (voodoo->nTexelfx == 1) { + /* Voodoo1 or Banshee */ + useBGR = GL_TRUE; + system = "Voodoo1"; + } + else if (voodoo->nTexelfx == 2 && + voodoo->fbiRev == 260 && + voodoo->tmuConfig[0].tmuRev == 4 && + (voodoo->tmuConfig[0].tmuRam == 2 || + voodoo->tmuConfig[0].tmuRam == 4)) { + /* Voodoo 2 */ + useBGR = GL_TRUE; + system = "Voodoo2"; + } + else if (voodoo->nTexelfx == 2 && + voodoo->fbiRev == 2 && + voodoo->tmuConfig[0].tmuRev == 1 && + voodoo->tmuConfig[0].tmuRam == 4) { + /* Quantum3D Obsidian 50/100 */ + useBGR = GL_TRUE; + system = "Quantum3D Obsidian"; + } + else + /* Brian + * (voodoo->nTexelfx == 2 && + * voodoo->fbiRev == 0 && + * voodoo->tmuConfig[0].tmuRev == 148441048 && + * voodoo->tmuConfig[0].tmuRam == 3) + * Bernd + * (voodoo->nTexelfx == 2 && + * voodoo->fbiRev == 69634 && + * voodoo->tmuConfig[0].tmuRev == 69634 && + * voodoo->tmuConfig[0].tmuRam == 2 ) + */ + { + /* Presumed Voodoo3 */ + useBGR = GL_FALSE; + system = "Voodoo3"; } - else { - fxInitPixelTables(fxMesa, GL_TRUE); /* use BGR pixel order on Voodoo1/2 */ + if (getenv("MESA_FX_INFO")) { + printf("Voodoo: Texelfx: %d / FBI Rev.: %d / TMU Rev.: %d / TMU RAM: %d\n", + voodoo->nTexelfx, + voodoo->fbiRev, + voodoo->tmuConfig[0].tmuRev, + voodoo->tmuConfig[0].tmuRam ); } } else { - fxInitPixelTables(fxMesa, GL_FALSE); /* use RGB pixel order otherwise */ + useBGR = GL_FALSE; /* use RGB pixel order otherwise */ + system = "non-voodoo"; } -#endif +#endif /*FXMESA_USE_ARGB*/ + + if (getenv("MESA_FX_INFO")) + printf("Voodoo pixel order: %s (%s)\n", useBGR ? "BGR" : "RGB", system); + + fxInitPixelTables(fxMesa, useBGR); fxMesa->width=FX_grSstScreenWidth(); fxMesa->height=FX_grSstScreenHeight(); @@ -1011,7 +1054,7 @@ fxMesaContext GLAPIENTRY fxMesaCreateContext(GLuint win, fxMesa->needClip = 0; if(verbose) - fprintf(stderr,"Glide screen size: %dx%d\n", + fprintf(stderr,"Voodoo Glide screen size: %dx%d\n", (int)FX_grSstScreenWidth(),(int)FX_grSstScreenHeight()); fxMesa->glVis=gl_create_visual(GL_TRUE, /* RGB mode */ @@ -1046,7 +1089,7 @@ fxMesaContext GLAPIENTRY fxMesaCreateContext(GLuint win, fxMesa->glBuffer=gl_create_framebuffer(fxMesa->glVis, GL_FALSE, /* no software depth */ fxMesa->glVis->StencilBits > 0, - fxMesa->glVis->AccumBits > 0, + fxMesa->glVis->AccumRedBits > 0, fxMesa->glVis->AlphaBits > 0 ); if (!fxMesa->glBuffer) { errorstr = "gl_create_framebuffer"; @@ -1221,6 +1264,25 @@ void GLAPIENTRY fxMesaMakeCurrent(fxMesaContext fxMesa) } +#if 0 +static void QueryCounters(void) +{ + static GLuint prevPassed = 0; + static GLuint prevFailed = 0; + GLuint failed, passed; + GrSstPerfStats_t st; + + FX_grSstPerfStats(&st); + failed = st.zFuncFail - st.aFuncFail - st.chromaFail; + passed = st.pixelsIn - failed; + printf("failed: %d passed: %d\n", failed - prevFailed, passed - prevPassed); + + prevPassed = passed; + prevFailed = failed; +} +#endif + + /* * Swap front/back buffers for current context if double buffered. */ @@ -1233,7 +1295,7 @@ void GLAPIENTRY fxMesaSwapBuffers(void) if(fxMesaCurrentCtx) { FLUSH_VB( fxMesaCurrentCtx->glCtx, "swap buffers" ); - if(fxMesaCurrentCtx->haveDoubleBuffer) { + if (fxMesaCurrentCtx->glVis->DBflag) { grBufferSwap(fxMesaCurrentCtx->swapInterval); @@ -1263,40 +1325,45 @@ int GLAPIENTRY fxQueryHardware(void) fprintf(stderr,"fxmesa: fxQueryHardware() Start\n"); } - if(!glbGlideInitialized) { + if (!glbGlideInitialized) { grGlideInit(); - if(FX_grSstQueryHardware(&glbHWConfig)) { + if (FX_grSstQueryHardware(&glbHWConfig)) { grSstSelect(glbCurrentBoard); - glb3DfxPresent=1; + glb3DfxPresent = 1; - if(getenv("MESA_FX_INFO")) { + if (getenv("MESA_FX_INFO")) { char buf[80]; FX_grGlideGetVersion(buf); - fprintf(stderr,"Using Glide V%s\n",""); - fprintf(stderr,"Number of boards: %d\n",glbHWConfig.num_sst); - - if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_VOODOO) { - fprintf(stderr,"Framebuffer RAM: %d\n", - glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.sliDetect ? - (glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.fbRam*2) : - glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.fbRam); - fprintf(stderr,"Number of TMUs: %d\n", - glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.nTexelfx); - fprintf(stderr,"SLI detected: %d\n", - glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.sliDetect); - } else if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_SST96) { - fprintf(stderr,"Framebuffer RAM: %d\n", - glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config.fbRam); - fprintf(stderr,"Number of TMUs: %d\n", - glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config.nTexelfx); + fprintf(stderr, "Voodoo Using Glide V%s\n", buf); + fprintf(stderr, "Voodoo Number of boards: %d\n", glbHWConfig.num_sst); + + if (glbHWConfig.SSTs[glbCurrentBoard].type == GR_SSTTYPE_VOODOO) { + GrVoodooConfig_t *voodoo; + voodoo = &glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig; + + fprintf(stderr, "Voodoo Framebuffer RAM: %d\n", + voodoo->sliDetect ? (voodoo->fbRam*2) : voodoo->fbRam); + fprintf(stderr, "Voodoo Number of TMUs: %d\n", voodoo->nTexelfx); + fprintf(stderr, "Voodoo fbRam: %d\n", voodoo->fbRam); + fprintf(stderr, "Voodoo fbiRev: %d\n", voodoo->fbiRev); + + fprintf(stderr,"Voodoo SLI detected: %d\n", voodoo->sliDetect); + } + else if (glbHWConfig.SSTs[glbCurrentBoard].type == GR_SSTTYPE_SST96) { + GrSst96Config_t *sst96; + sst96 = &glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config; + fprintf(stderr, "Voodoo Framebuffer RAM: %d\n", sst96->fbRam); + fprintf(stderr, "Voodoo Number of TMUs: %d\n", sst96->nTexelfx); } } - } else - glb3DfxPresent=0; + } + else { + glb3DfxPresent = 0; + } - glbGlideInitialized=1; + glbGlideInitialized = 1; #if defined(__WIN32__) onexit((_onexit_t)cleangraphics); @@ -1308,17 +1375,11 @@ int GLAPIENTRY fxQueryHardware(void) #endif } - if(!glb3DfxPresent) { - if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxQueryHardware() End (-1)\n"); - } - return(-1); - } - if (MESA_VERBOSE&VERBOSE_DRIVER) { fprintf(stderr,"fxmesa: fxQueryHardware() End (voodooo)\n"); } - return(glbHWConfig.SSTs[glbCurrentBoard].type); + + return glbHWConfig.SSTs[glbCurrentBoard].type; } @@ -1327,8 +1388,8 @@ int GLAPIENTRY fxQueryHardware(void) */ void GLAPIENTRY fxCloseHardware(void) { - if(glbGlideInitialized) { - if(getenv("MESA_FX_INFO")) { + if (glbGlideInitialized) { + if (getenv("MESA_FX_INFO")) { GrSstPerfStats_t st; FX_grSstPerfStats(&st); @@ -1340,9 +1401,9 @@ void GLAPIENTRY fxCloseHardware(void) fprintf(stderr," # pixels drawn (including buffer clears and LFB writes): %u\n",(unsigned)st.pixelsOut); } - if(glbTotNumCtx==0) { + if (glbTotNumCtx == 0) { grGlideShutdown(); - glbGlideInitialized=0; + glbGlideInitialized = 0; } } } @@ -1354,7 +1415,7 @@ void GLAPIENTRY fxCloseHardware(void) /* * Need this to provide at least one external definition. */ - +extern int gl_fx_dummy_function_api(void); int gl_fx_dummy_function_api(void) { return 0; diff --git a/xc/extras/Mesa/src/FX/fxdd.c b/xc/extras/Mesa/src/FX/fxdd.c index b44ec4dbe..59a4bec93 100644 --- a/xc/extras/Mesa/src/FX/fxdd.c +++ b/xc/extras/Mesa/src/FX/fxdd.c @@ -52,6 +52,7 @@ #if defined(FX) +#include <dlfcn.h> #include "image.h" #include "types.h" #include "fxdrv.h" @@ -102,34 +103,20 @@ void fxInitPixelTables(fxMesaContext fxMesa, GLboolean bgrOrder) /***** Miscellaneous functions *****/ /**********************************************************************/ -/* Enalbe/Disable dithering */ -static void fxDDDither(GLcontext *ctx, GLboolean enable) -{ - if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxDDDither()\n"); - } - - if (enable) { - FX_grDitherMode(GR_DITHER_4x4); - } else { - FX_grDitherMode(GR_DITHER_DISABLE); - } -} - /* Return buffer size information */ static void fxDDBufferSize(GLcontext *ctx, GLuint *width, GLuint *height) { - fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; + fxMesaContext fxMesa = FX_CONTEXT(ctx); - if (MESA_VERBOSE&VERBOSE_DRIVER) { + 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) { + if (MESA_VERBOSE & VERBOSE_DRIVER) { fprintf(stderr,"fxmesa: fxDDBufferSize(...) End\n"); } } @@ -139,15 +126,13 @@ static void fxDDBufferSize(GLcontext *ctx, GLuint *width, GLuint *height) static void fxDDSetColor(GLcontext *ctx, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha ) { - fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; + fxMesaContext fxMesa = FX_CONTEXT(ctx); GLubyte col[4]; ASSIGN_4V( col, red, green, blue, alpha ); - - if (MESA_VERBOSE&VERBOSE_DRIVER) { + if (MESA_VERBOSE & VERBOSE_DRIVER) { fprintf(stderr,"fxmesa: fxDDSetColor(%d,%d,%d,%d)\n",red,green,blue,alpha); } - - fxMesa->color=FXCOLOR4(col); + fxMesa->color = FXCOLOR4(col); } @@ -155,19 +140,14 @@ static void fxDDSetColor(GLcontext *ctx, GLubyte red, GLubyte green, static void fxDDClearColor(GLcontext *ctx, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha ) { - fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; + fxMesaContext fxMesa = FX_CONTEXT(ctx); GLubyte col[4]; - - - ASSIGN_4V( col, red, green, blue, 255 ); - - if (MESA_VERBOSE&VERBOSE_DRIVER) { + if (MESA_VERBOSE & VERBOSE_DRIVER) { fprintf(stderr,"fxmesa: fxDDClearColor(%d,%d,%d,%d)\n",red,green,blue,alpha); } - - fxMesa->clearC=FXCOLOR4( col ); - fxMesa->clearA=alpha; + fxMesa->clearC = FXCOLOR4( col ); + fxMesa->clearA = alpha; } @@ -177,8 +157,18 @@ static GLbitfield fxDDClear(GLcontext *ctx, GLbitfield mask, GLboolean all, { fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); - const FxU16 clearD = (FxU16) (ctx->Depth.Clear * 0xffff); - GLbitfield softwareMask = mask & (DD_STENCIL_BIT | DD_ACCUM_BIT); + const FxU32 clearD = (FxU32) (ctx->Depth.Clear * fxMesa->depthClear); + const FxU32 clearS = (FxU32) (ctx->Stencil.Clear); + GLbitfield softwareMask = mask & (DD_ACCUM_BIT); + + /* we can't clear accum buffers */ + mask &= ~(DD_ACCUM_BIT); + + if ((mask & DD_STENCIL_BIT) && !fxMesa->haveHwStencil) { + /* software stencil buffer */ + mask &= ~(DD_STENCIL_BIT); + softwareMask |= DD_STENCIL_BIT; + } if (MESA_VERBOSE & VERBOSE_DRIVER) { fprintf(stderr,"fxmesa: fxDDClear(%d,%d,%d,%d)\n", (int) x, (int) y, @@ -186,21 +176,40 @@ static GLbitfield fxDDClear(GLcontext *ctx, GLbitfield mask, GLboolean all, } if (colorMask != 0xffffffff) { - /* do color buffer clears in software */ + /* do masked color buffer clears in software */ softwareMask |= (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)); mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT); } + + /* disable stencil ops if enabled (it screws up clearing) */ + if (ctx->Stencil.Enabled) + FX_grDisable(GR_STENCIL_MODE_EXT); + + if (fxMesa->haveHwStencil) { + if (mask & DD_STENCIL_BIT) { + FX_grStencilMask(0xff); + /* set stencil ref value = desired clear value */ + FX_grStencilFunc(GR_CMP_ALWAYS, ctx->Stencil.Clear, 0xff); + } + else { + FX_grStencilMask(0x00); + } + } + /* * This could probably be done fancier but doing each possible case * explicitly is less error prone. */ - switch (mask) { + switch (mask & ~DD_STENCIL_BIT) { case DD_BACK_LEFT_BIT | DD_DEPTH_BIT: /* back buffer & depth */ FX_grDepthMask(FXTRUE); FX_grRenderBuffer(GR_BUFFER_BACKBUFFER); - FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); + if (mask & DD_STENCIL_BIT) + FX_grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); + else + FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); if (!ctx->Depth.Mask) { FX_grDepthMask(FXFALSE); } @@ -211,75 +220,114 @@ static GLbitfield fxDDClear(GLcontext *ctx, GLbitfield mask, GLboolean all, * This is a work-around/ */ /* clear depth */ + FX_grDepthMask(FXTRUE); FX_grRenderBuffer(GR_BUFFER_BACKBUFFER); FX_grColorMask(FXFALSE,FXFALSE); - FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); + if (mask & DD_STENCIL_BIT) + FX_grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); + else + FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); /* clear front */ FX_grColorMask(FXTRUE, ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer); FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER); - FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); + if (mask & DD_STENCIL_BIT) + FX_grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); + else + FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); break; case DD_BACK_LEFT_BIT: /* back buffer only */ FX_grDepthMask(FXFALSE); FX_grRenderBuffer(GR_BUFFER_BACKBUFFER); - FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); - if (!ctx->Depth.Mask) { - FX_grDepthMask(FXFALSE); + if (mask & DD_STENCIL_BIT) + FX_grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); + else + FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); + if (ctx->Depth.Mask) { + FX_grDepthMask(FXTRUE); } break; case DD_FRONT_LEFT_BIT: /* front buffer only */ FX_grDepthMask(FXFALSE); FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER); - FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); - if (!ctx->Depth.Mask) { - FX_grDepthMask(FXFALSE); + if (mask & DD_STENCIL_BIT) + FX_grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); + else + FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); + if (ctx->Depth.Mask) { + FX_grDepthMask(FXTRUE); } break; case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT: /* front and back */ FX_grDepthMask(FXFALSE); FX_grRenderBuffer(GR_BUFFER_BACKBUFFER); - FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); + if (mask & DD_STENCIL_BIT) + FX_grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); + else + FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER); - FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); - if (!ctx->Depth.Mask) { - FX_grDepthMask(FXFALSE); + if (mask & DD_STENCIL_BIT) + FX_grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); + else + FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); + if (ctx->Depth.Mask) { + FX_grDepthMask(FXTRUE); } break; case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT | DD_DEPTH_BIT: /* clear front */ FX_grDepthMask(FXFALSE); FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER); - FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); + if (mask & DD_STENCIL_BIT) + FX_grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); + else + FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); /* clear back and depth */ FX_grDepthMask(FXTRUE); FX_grRenderBuffer(GR_BUFFER_BACKBUFFER); - FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); + if (mask & DD_STENCIL_BIT) + FX_grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); + else + FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); if (!ctx->Depth.Mask) { FX_grDepthMask(FXFALSE); } break; case DD_DEPTH_BIT: /* just the depth buffer */ + FX_grRenderBuffer(GR_BUFFER_BACKBUFFER); FX_grColorMask(FXFALSE,FXFALSE); - FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, - (FxU16)(ctx->Depth.Clear*0xffff)); + FX_grDepthMask(FXTRUE); + if (mask & DD_STENCIL_BIT) + FX_grBufferClearExt(fxMesa->clearC, fxMesa->clearA, clearD, clearS); + else + FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD); FX_grColorMask(FXTRUE, ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer); + if (ctx->Color.DrawDestMask & FRONT_LEFT_BIT) + FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER); break; default: /* error */ ; } + if (ctx->Stencil.Enabled) { + /* restore stencil state to as it was before the clear */ + FX_grEnable(GR_STENCIL_MODE_EXT); + FX_grStencilMask(ctx->Stencil.WriteMask); + FX_grStencilFunc(ctx->Stencil.Function - GL_NEVER, + ctx->Stencil.Ref, ctx->Stencil.ValueMask); + } + return softwareMask; } /* Set the buffer used for drawing */ /* XXX support for separate read/draw buffers hasn't been tested */ -static GLboolean fxDDSetDrawBuffer(GLcontext *ctx, GLenum mode ) +static GLboolean fxDDSetDrawBuffer(GLcontext *ctx, GLenum mode) { fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; @@ -297,6 +345,10 @@ static GLboolean fxDDSetDrawBuffer(GLcontext *ctx, GLenum mode ) FX_grRenderBuffer(fxMesa->currentFB); return GL_TRUE; } + else if (mode == GL_NONE) { + FX_grColorMask(FXFALSE,FXFALSE); + return GL_TRUE; + } else { return GL_FALSE; } @@ -326,6 +378,58 @@ static void fxDDSetReadBuffer(GLcontext *ctx, GLframebuffer *buffer, } +/* + * These functions just set new-state flags. The exact state + * values will be evaluated later. + */ +static void +fxDDStencilFunc(GLcontext *ctx, GLenum func, GLint ref, GLuint mask) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + (void) func; (void) ref; (void) mask; + fxMesa->new_state |= FX_NEW_STENCIL; + ctx->Driver.RenderStart = fxSetupFXUnits; +} + +static void +fxDDStencilMask(GLcontext *ctx, GLuint mask) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + (void) mask; + fxMesa->new_state |= FX_NEW_STENCIL; + ctx->Driver.RenderStart = fxSetupFXUnits; +} + +static void +fxDDStencilOp(GLcontext *ctx, GLenum sfail, GLenum zfail, GLenum zpass) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + (void) sfail; (void) zfail; (void) zpass; + fxMesa->new_state |= FX_NEW_STENCIL; + ctx->Driver.RenderStart = fxSetupFXUnits; +} + +static void +fxDDDepthFunc(GLcontext *ctx, GLenum func) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + (void) func; + fxMesa->new_state |= FX_NEW_DEPTH; + ctx->Driver.RenderStart = fxSetupFXUnits; +} + +static void +fxDDDepthMask(GLcontext *ctx, GLboolean mask) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + (void) mask; + fxMesa->new_state |= FX_NEW_DEPTH; + ctx->Driver.RenderStart = fxSetupFXUnits; +} + + + + #ifdef XF86DRI /* test if window coord (px,py) is visible */ static GLboolean inClipRects(fxMesaContext fxMesa, int px, int py) @@ -342,10 +446,12 @@ static GLboolean inClipRects(fxMesaContext fxMesa, int px, int py) #endif -static GLboolean fxDDDrawBitMap(GLcontext *ctx, GLint px, GLint py, - GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, - const GLubyte *bitmap) + +static GLboolean +bitmap_R5G6B5(GLcontext *ctx, GLint px, GLint py, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap) { fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; GrLfbInfo_t info; @@ -463,7 +569,7 @@ static GLboolean fxDDDrawBitMap(GLcontext *ctx, GLint px, GLint py, + (winX + px); for (row = 0; row < height; row++) { - const GLubyte *src = (const GLubyte *) gl_pixel_addr_in_image( finalUnpack, + 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 */ @@ -515,6 +621,303 @@ static GLboolean fxDDDrawBitMap(GLcontext *ctx, GLint px, GLint py, return GL_TRUE; } + +static GLboolean +bitmap_R8G8B8A8(GLcontext *ctx, GLint px, GLint py, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap) +{ + fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; + GrLfbInfo_t info; + GrLfbWriteMode_t mode; + /*FxU16 color;*/ + GLuint 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->RasterMask & (ALPHATEST_BIT | + BLEND_BIT | + DEPTH_BIT | + FOG_BIT | + LOGIC_OP_BIT | + SCISSOR_BIT | + STENCIL_BIT | + MASKING_BIT | + ALPHABUF_BIT | + MULTI_DRAW_BIT)) + return GL_FALSE; + + 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 GL_TRUE; /* totally scissored away */ + } + else { + finalUnpack = unpack; + } + + /* 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); + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + color = PACK_BGRA32(r, g, b, a); + else + color = PACK_RGBA32(r, g, b, a); + } + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + mode = GR_LFBWRITEMODE_8888; + else + mode = GR_LFBWRITEMODE_888; + + info.size = sizeof(info); + if (!FX_grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + mode, + GR_ORIGIN_UPPER_LEFT, + FXFALSE, + &info)) { +#ifndef FX_SILENT + fprintf(stderr,"fx Driver: error locking the linear frame buffer\n"); +#endif + return GL_TRUE; + } + +#ifdef XF86DRI +#define INSIDE(c, x, y) inClipRects((c), (x), (y)) +#else +#define INSIDE(c, x, y) (1) +#endif + + { + const GLint winX = fxMesa->x_offset; + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + GLint dstStride; + GLuint *dst; + GLint row; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + dstStride = fxMesa->screen_width; + dst = (GLuint *) info.lfbPtr + (winY - py) * dstStride + (winX + px); + } + else { + dstStride = info.strideInBytes / 4; + dst = (GLuint *) info.lfbPtr + (winY - py) * dstStride + (winX + px); + } + + /* compute dest address of bottom-left pixel in bitmap */ + 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) { + if (INSIDE(fxMesa, winX + px + col, winY - py - row)) + 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) { + if (INSIDE(fxMesa, winX + px + col, winY - py - row)) + dst[col] = color; + } + if (mask == 1U) { + src++; + mask = 128U; + } + else { + mask = mask >> 1; + } + } + if (mask != 128) + src++; + } + dst -= dstStride; + } + } + +#undef INSIDE + + FX_grLfbUnlock(GR_LFB_WRITE_ONLY,fxMesa->currentFB); + return GL_TRUE; +} + + +static GLboolean +readpixels_R5G6B5( GLcontext *ctx, GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *packing, + GLvoid *dstImage ) +{ + if (ctx->Pixel.ScaleOrBiasRGBA || ctx->Pixel.MapColorFlag) { + return GL_FALSE; /* can't do this */ + } + else { + fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; + GrLfbInfo_t info; + GLboolean result = GL_FALSE; + + BEGIN_BOARD_LOCK(); + info.size=sizeof(info); + if (grLfbLock(GR_LFB_READ_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_ANY, + GR_ORIGIN_UPPER_LEFT, + FXFALSE, + &info)) { + const GLint winX = fxMesa->x_offset; + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; +#ifdef XF86DRI + const GLint srcStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + ? (fxMesa->screen_width) : (info.strideInBytes / 2); +#else + const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */ +#endif + const GLushort *src = (const GLushort *) info.lfbPtr + + (winY - y) * srcStride + (winX + x); + GLubyte *dst = (GLubyte *) _mesa_image_address(packing, dstImage, + width, height, format, type, 0, 0, 0); + GLint dstStride = _mesa_image_row_stride(packing, width, format, type); + + if (format == GL_RGB && type == GL_UNSIGNED_BYTE) { + /* convert 5R6G5B into 8R8G8B */ + GLint row, col; + const GLint halfWidth = width >> 1; + const GLint extraPixel = (width & 1); + for (row = 0; row < height; row++) { + GLubyte *d = dst; + for (col = 0; col < halfWidth; col++) { + const GLuint pixel = ((const GLuint *) src)[col]; + const GLint pixel0 = pixel & 0xffff; + const GLint pixel1 = pixel >> 16; + *d++ = FX_PixelToR[pixel0]; + *d++ = FX_PixelToG[pixel0]; + *d++ = FX_PixelToB[pixel0]; + *d++ = FX_PixelToR[pixel1]; + *d++ = FX_PixelToG[pixel1]; + *d++ = FX_PixelToB[pixel1]; + } + if (extraPixel) { + GLushort pixel = src[width-1]; + *d++ = FX_PixelToR[pixel]; + *d++ = FX_PixelToG[pixel]; + *d++ = FX_PixelToB[pixel]; + } + dst += dstStride; + src -= srcStride; + } + result = GL_TRUE; + } + else if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) { + /* convert 5R6G5B into 8R8G8B8A */ + GLint row, col; + const GLint halfWidth = width >> 1; + const GLint extraPixel = (width & 1); + for (row = 0; row < height; row++) { + GLubyte *d = dst; + for (col = 0; col < halfWidth; col++) { + const GLuint pixel = ((const GLuint *) src)[col]; + const GLint pixel0 = pixel & 0xffff; + const GLint pixel1 = pixel >> 16; + *d++ = FX_PixelToR[pixel0]; + *d++ = FX_PixelToG[pixel0]; + *d++ = FX_PixelToB[pixel0]; + *d++ = 255; + *d++ = FX_PixelToR[pixel1]; + *d++ = FX_PixelToG[pixel1]; + *d++ = FX_PixelToB[pixel1]; + *d++ = 255; + } + if (extraPixel) { + const GLushort pixel = src[width-1]; + *d++ = FX_PixelToR[pixel]; + *d++ = FX_PixelToG[pixel]; + *d++ = FX_PixelToB[pixel]; + *d++ = 255; + } + dst += dstStride; + src -= srcStride; + } + result = GL_TRUE; + } + else if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) { + /* directly memcpy 5R6G5B pixels into client's buffer */ + const GLint widthInBytes = width * 2; + GLint row; + for (row = 0; row < height; row++) { + MEMCPY(dst, src, widthInBytes); + dst += dstStride; + src -= srcStride; + } + result = GL_TRUE; + } + else { + result = GL_FALSE; + } + + grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(); + return result; + } +} + + + static void fxDDFinish(GLcontext *ctx) { FX_grFlush(); @@ -568,7 +971,7 @@ static const GLubyte *fxDDGetString(GLcontext *ctx, GLenum name) } } /* now make the GL_RENDERER string */ - sprintf(buffer, "Mesa DRI %s 20000224", hardware); + sprintf(buffer, "Mesa DRI %s 20000608", hardware); return buffer; } case GL_VENDOR: @@ -625,6 +1028,19 @@ static const GLubyte *fxDDGetString(GLcontext *ctx, GLenum name) int fxDDInitFxMesaContext( fxMesaContext fxMesa ) { + /* Get Glide3vn function pointers */ + { + void *handle; + handle = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); + if (!handle) + return 0; + grStencilFuncPtr = dlsym(handle, "grStencilFunc"); + grStencilMaskPtr = dlsym(handle, "grStencilMask"); + grStencilOpPtr = dlsym(handle, "grStencilOp"); + grBufferClearExtPtr = dlsym(handle, "grBufferClearExt"); + /* call dlclose()? */ + } + FX_setupGrVertexLayout(); @@ -651,6 +1067,8 @@ int fxDDInitFxMesaContext( fxMesaContext fxMesa ) else fxMesa->verbose=GL_FALSE; + fxMesa->depthClear = FX_grGetInteger(FX_ZDEPTH_MAX); + fxMesa->color=0xffffffff; fxMesa->clearC=0; fxMesa->clearA=0; @@ -661,7 +1079,6 @@ int fxDDInitFxMesaContext( fxMesaContext fxMesa ) fxMesa->stats.memTexUpload=0; fxMesa->tmuSrc=FX_TMU_NONE; - fxMesa->lastUnitsMode=FX_UM_NONE; fxTMInit(fxMesa); /* FX units setup */ @@ -676,16 +1093,19 @@ int fxDDInitFxMesaContext( fxMesaContext fxMesa ) fxMesa->unitsState.blendSrcFuncAlpha=GR_BLEND_ONE; fxMesa->unitsState.blendDstFuncAlpha=GR_BLEND_ZERO; + /* fxMesa->unitsState.depthTestEnabled =GL_FALSE; fxMesa->unitsState.depthMask =GL_TRUE; fxMesa->unitsState.depthTestFunc =GR_CMP_LESS; + */ FX_grColorMask(FXTRUE, fxMesa->haveAlphaBuffer ? FXTRUE : FXFALSE); - if(fxMesa->haveDoubleBuffer) { - fxMesa->currentFB=GR_BUFFER_BACKBUFFER; + if (fxMesa->glVis->DBflag) { + fxMesa->currentFB = GR_BUFFER_BACKBUFFER; FX_grRenderBuffer(GR_BUFFER_BACKBUFFER); - } else { - fxMesa->currentFB=GR_BUFFER_FRONTBUFFER; + } + else { + fxMesa->currentFB = GR_BUFFER_FRONTBUFFER; FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER); } @@ -701,7 +1121,7 @@ int fxDDInitFxMesaContext( fxMesaContext fxMesa ) return 0; } - if(fxMesa->haveZBuffer) + if (fxMesa->glVis->DepthBits > 0) FX_grDepthBufferMode(GR_DEPTHBUFFER_ZBUFFER); #if (!FXMESA_USE_ARGB) @@ -714,7 +1134,7 @@ int fxDDInitFxMesaContext( fxMesaContext fxMesa ) fxMesa->glCtx->Const.MaxTextureUnits=fxMesa->emulateTwoTMUs ? 2 : 1; fxMesa->glCtx->NewState|=NEW_DRVSTATE1; fxMesa->new_state = NEW_ALL; - + fxDDSetupInit(); fxDDCvaInit(); fxDDClipInit(); @@ -744,6 +1164,10 @@ int fxDDInitFxMesaContext( fxMesaContext fxMesa ) fxMesa->glCtx->PipelineStage, fxMesa->glCtx->NrPipelineStages); + /* this little bit ensures that all Glide state gets initialized */ + fxMesa->new_state = NEW_ALL; + fxMesa->glCtx->Driver.RenderStart = fxSetupFXUnits; + /* Run the config file */ gl_context_initialize( fxMesa->glCtx ); @@ -768,10 +1192,8 @@ void fxDDInitExtensions( GLcontext *ctx ) gl_extensions_disable(ctx, "GL_EXT_blend_minmax"); gl_extensions_disable(ctx, "GL_EXT_blend_subtract"); gl_extensions_disable(ctx, "GL_EXT_blend_color"); - gl_extensions_disable(ctx, "GL_EXT_paletted_texture"); gl_extensions_add(ctx, DEFAULT_ON, "3DFX_set_global_palette", 0); - gl_extensions_add(ctx, DEFAULT_ON, "GL_FXMESA_global_texture_lod_bias", 0); if (!fxMesa->haveTwoTMUs) gl_extensions_disable(ctx, "GL_EXT_texture_env_add"); @@ -816,8 +1238,7 @@ static GLboolean fxIsInHardware(GLcontext *ctx) if (!ctx->Hint.AllowDrawMem) return GL_TRUE; /* you'll take it and like it */ - if((ctx->RasterMask & STENCIL_BIT) || - ((ctx->Color.BlendEnabled) && (ctx->Color.BlendEquation!=GL_FUNC_ADD_EXT)) || + if(((ctx->Color.BlendEnabled) && (ctx->Color.BlendEquation!=GL_FUNC_ADD_EXT)) || ((ctx->Color.ColorLogicOpEnabled) && (ctx->Color.LogicOp!=GL_COPY)) || (ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) || (!((ctx->Color.ColorMask[RCOMP]==ctx->Color.ColorMask[GCOMP]) && @@ -838,17 +1259,26 @@ static GLboolean fxIsInHardware(GLcontext *ctx) return GL_FALSE; } - if((ctx->Texture.ReallyEnabled & TEXTURE0_2D) && - (ctx->Texture.Unit[0].EnvMode==GL_BLEND)) { - return GL_FALSE; + if (ctx->Texture.ReallyEnabled & TEXTURE0_2D) { + if (ctx->Texture.Unit[0].EnvMode == GL_BLEND && + (ctx->Texture.ReallyEnabled & TEXTURE1_2D || + ctx->Texture.Unit[0].EnvColor[0] != 0 || + ctx->Texture.Unit[0].EnvColor[1] != 0 || + ctx->Texture.Unit[0].EnvColor[2] != 0 || + ctx->Texture.Unit[0].EnvColor[3] != 1)) { + return GL_FALSE; + } + if (ctx->Texture.Unit[0].Current->Image[0]->Border > 0) + return GL_FALSE; } - if((ctx->Texture.ReallyEnabled & TEXTURE1_2D) && - (ctx->Texture.Unit[1].EnvMode==GL_BLEND)) { - return GL_FALSE; + if (ctx->Texture.ReallyEnabled & TEXTURE1_2D) { + if (ctx->Texture.Unit[1].EnvMode == GL_BLEND) + return GL_FALSE; + if (ctx->Texture.Unit[0].Current->Image[0]->Border > 0) + return GL_FALSE; } - if (MESA_VERBOSE & (VERBOSE_DRIVER|VERBOSE_TEXTURE)) fprintf(stderr, "fxMesa: fxIsInHardware, envmode is %s/%s\n", gl_lookup_enum_by_nr(ctx->Texture.Unit[0].EnvMode), @@ -892,6 +1322,9 @@ static GLboolean fxIsInHardware(GLcontext *ctx) } } + if (ctx->Stencil.Enabled && !fxMesa->haveHwStencil) + return GL_FALSE; + return GL_TRUE; } @@ -943,58 +1376,68 @@ static void fxDDReducedPrimitiveChange(GLcontext *ctx, GLenum prim) } } + void fxSetupDDPointers(GLcontext *ctx) { - if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxSetupDDPointers()\n"); - } + fxMesaContext fxMesa = FX_CONTEXT(ctx); - ctx->Driver.UpdateState=fxDDUpdateDDPointers; + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxSetupDDPointers()\n"); + } + ctx->Driver.UpdateState = fxDDUpdateDDPointers; + ctx->Driver.ClearIndex = NULL; + ctx->Driver.ClearColor = fxDDClearColor; + ctx->Driver.Clear = fxDDClear; + ctx->Driver.Index = NULL; + ctx->Driver.Color = fxDDSetColor; + ctx->Driver.SetDrawBuffer = fxDDSetDrawBuffer; + ctx->Driver.SetReadBuffer = fxDDSetReadBuffer; + ctx->Driver.GetBufferSize = fxDDBufferSize; + ctx->Driver.Finish = fxDDFinish; + ctx->Driver.Flush = NULL; + ctx->Driver.GetString = fxDDGetString; + ctx->Driver.NearFar = fxDDSetNearFar; + ctx->Driver.GetParameteri = fxDDGetParameteri; ctx->Driver.WriteDepthSpan=fxDDWriteDepthSpan; ctx->Driver.WriteDepthPixels=fxDDWriteDepthPixels; ctx->Driver.ReadDepthSpan=fxDDReadDepthSpan; ctx->Driver.ReadDepthPixels=fxDDReadDepthPixels; - ctx->Driver.GetString=fxDDGetString; - - ctx->Driver.Dither=fxDDDither; - - ctx->Driver.NearFar=fxDDSetNearFar; - - ctx->Driver.GetParameteri=fxDDGetParameteri; - - ctx->Driver.ClearIndex=NULL; - ctx->Driver.ClearColor=fxDDClearColor; - ctx->Driver.Clear=fxDDClear; - - ctx->Driver.Index=NULL; - ctx->Driver.Color=fxDDSetColor; - - ctx->Driver.SetDrawBuffer=fxDDSetDrawBuffer; - ctx->Driver.SetReadBuffer=fxDDSetReadBuffer; - ctx->Driver.GetBufferSize=fxDDBufferSize; - - ctx->Driver.Bitmap=fxDDDrawBitMap; - ctx->Driver.DrawPixels=NULL; - - ctx->Driver.Finish=fxDDFinish; - ctx->Driver.Flush=NULL; + if (ctx->Visual->RedBits == 8 && + ctx->Visual->GreenBits == 8 && + ctx->Visual->BlueBits == 8 && + ctx->Visual->AlphaBits == 8) { + ctx->Driver.Bitmap = bitmap_R8G8B8A8; + ctx->Driver.DrawPixels = NULL; + ctx->Driver.ReadPixels = NULL; + } + else { + ctx->Driver.Bitmap = bitmap_R5G6B5; + ctx->Driver.DrawPixels = NULL; + ctx->Driver.ReadPixels = readpixels_R5G6B5; + } ctx->Driver.RenderStart=NULL; ctx->Driver.RenderFinish=NULL; + ctx->Driver.TexImage2D = fxDDTexImage2D; + ctx->Driver.TexSubImage2D = fxDDTexSubImage2D; + ctx->Driver.GetTexImage = fxDDGetTexImage; ctx->Driver.TexEnv=fxDDTexEnv; - ctx->Driver.TexImage=fxDDTexImg; - ctx->Driver.TexSubImage=fxDDTexSubImg; ctx->Driver.TexParameter=fxDDTexParam; ctx->Driver.BindTexture=fxDDTexBind; ctx->Driver.DeleteTexture=fxDDTexDel; ctx->Driver.UpdateTexturePalette=fxDDTexPalette; - ctx->Driver.UseGlobalTexturePalette=fxDDTexUseGlbPalette; ctx->Driver.RectFunc=NULL; + if (fxMesa->haveHwStencil) { + ctx->Driver.StencilFunc = fxDDStencilFunc; + ctx->Driver.StencilMask = fxDDStencilMask; + ctx->Driver.StencilOp = fxDDStencilOp; + } + ctx->Driver.AlphaFunc=fxDDAlphaFunc; ctx->Driver.BlendFunc=fxDDBlendFunc; ctx->Driver.DepthFunc=fxDDDepthFunc; @@ -1031,6 +1474,7 @@ void fxSetupDDPointers(GLcontext *ctx) } + #else diff --git a/xc/extras/Mesa/src/FX/fxddspan.c b/xc/extras/Mesa/src/FX/fxddspan.c index ec5513480..2c53da8d3 100644 --- a/xc/extras/Mesa/src/FX/fxddspan.c +++ b/xc/extras/Mesa/src/FX/fxddspan.c @@ -46,33 +46,193 @@ /* fxdd.c - 3Dfx VooDoo Mesa span and pixel functions */ -#ifdef HAVE_CONFIG_H -#include "conf.h" -#endif +#include "fxdrv.h" -#if defined(FX) -#include "fxdrv.h" -#ifdef _MSC_VER -#ifdef _WIN32 -#pragma warning( disable : 4090 4022 ) -/* 4101 : "different 'const' qualifier" - * 4022 : "pointer mistmatch for actual parameter 'n' +/* + * Examine the cliprects to generate an array of flags to indicate + * which pixels in a span are visible. Note: (x,y) is a screen + * coordinate. */ -#endif -#endif +static void +generate_vismask(const fxMesaContext fxMesa, GLint x, GLint y, GLint n, + GLubyte vismask[]) +{ + GLboolean initialized = GL_FALSE; + GLint i, j; + + /* turn on flags for all visible pixels */ + for (i = 0; i < fxMesa->numClipRects; i++) { + const XF86DRIClipRectPtr rect = &fxMesa->pClipRects[i]; + + if (y >= rect->y1 && y < rect->y2) { + if (x >= rect->x1 && x + n <= rect->x2) { + /* common case, whole span inside cliprect */ + MEMSET(vismask, 1, n); + return; + } + if (x < rect->x2 && x + n >= rect->x1) { + /* some of the span is inside the rect */ + GLint start, end; + if (!initialized) { + MEMSET(vismask, 0, n); + initialized = GL_TRUE; + } + if (x < rect->x1) + start = rect->x1 - x; + else + start = 0; + if (x + n > rect->x2) + end = rect->x2 - x; + else + end = n; + assert(start >= 0); + assert(end <= n); + for (j = start; j < end; j++) + vismask[j] = 1; + } + } + } +} -#if !defined(FXMESA_USE_ARGB) +/* + * Examine cliprects and determine if the given screen pixel is visible. + */ +static GLboolean +visible_pixel(const fxMesaContext fxMesa, int scrX, int scrY) +{ + int i; + for (i = 0; i < fxMesa->numClipRects; i++) { + const XF86DRIClipRectPtr rect = &fxMesa->pClipRects[i]; + if (scrX >= rect->x1 && + scrX < rect->x2 && + scrY >= rect->y1 && + scrY < rect->y2) + return GL_TRUE; + } + return GL_FALSE; +} -#if defined(FX_GLIDE3) && defined(XF86DRI) + +typedef enum { FBS_READ, FBS_WRITE } FBS_DIRECTION; +/* + * Read or write a single span from the frame buffer. + * Input Parameters: + * fxMesa: The context + * target_buffer: Which buffer to read from. + * xpos, ypos: Starting Coordinates. + * xlength: Length of the span. + * data_size: Size of data elements: 1, 2, or 4. + * buffer: Pointer to the buffer to read + * to or write from. This needs + * to be turned into a pointer. + * direction: Read or Write. + */ +static void +rw_fb_span(fxMesaContext fxMesa, + GrBuffer_t target_buffer, + FxU32 xpos, + FxU32 ypos, + FxU32 xlength, + FxU32 data_size, + void *buffer, + FBS_DIRECTION direction) +{ + GrLfbInfo_t info; + BEGIN_BOARD_LOCK(); + info.size=sizeof(info); + + if (grLfbLock(direction == FBS_READ ? GR_LFB_READ_ONLY : GR_LFB_WRITE_ONLY, + target_buffer, + GR_LFBWRITEMODE_ANY, + GR_ORIGIN_UPPER_LEFT, + FXFALSE, + &info)) { + const GLint winX = fxMesa->x_offset; + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; +#ifdef XF86DRI + /* stride in data elements */ + const GLint srcStride = + (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + ? (fxMesa->screen_width) + : (info.strideInBytes / data_size); +#else + /* stride in data elements */ + const GLint srcStride = info.strideInBytes / data_size; +#endif + GLushort *data16 = (GLushort *) info.lfbPtr + + (winY - ypos) * srcStride + + (winX + xpos); + GLubyte *target16 = (GLubyte *) buffer; + GLubyte *data8 = (GLubyte *) data16; + GLubyte *target8 = (GLubyte *) buffer; + GLuint *data32 = (GLuint *) data16; + GLuint *target32 = (GLuint *) buffer; + GLuint i, j; + + for (i = j = 0; i < xlength; i += 1, j += 1) { + switch (data_size) { + case 1: + switch (direction) { + case FBS_READ: + *target8++ = *data8++; + break; + case FBS_WRITE: + *data8++ = *target8++; + break; + } + break; + case 2: + switch (direction) { + case FBS_READ: + *target16++ = *data16++; + break; + case FBS_WRITE: + *data16++ = *target16++; + break; + } + break; + case 4: + switch (direction) { + case FBS_READ: + *target32++ = *data32++; + break; + case FBS_WRITE: + *data32++ = *target32++; + break; + } + break; + } + } + grLfbUnlock(direction == FBS_READ ? GR_LFB_READ_ONLY : GR_LFB_WRITE_ONLY, + target_buffer); + } + END_BOARD_LOCK(); +} + +static FxBool +fb_point_is_clipped(fxMesaContext fxMesa, + FxU32 dst_x, FxU32 dst_y) +{ + int i; + for (i=0; i<fxMesa->numClipRects; i++) { + if ((dst_x>=fxMesa->pClipRects[i].x1) && + (dst_x<fxMesa->pClipRects[i].x2) && + (dst_y>=fxMesa->pClipRects[i].y1) && + (dst_y<fxMesa->pClipRects[i].y2)) { + return GL_FALSE; + } + } + return GL_TRUE; +} static FxBool writeRegionClipped(fxMesaContext fxMesa, GrBuffer_t dst_buffer, - FxU32 dst_x, FxU32 dst_y, GrLfbSrcFmt_t src_format, - FxU32 src_width, FxU32 src_height, FxI32 src_stride, - void *src_data) + FxU32 dst_x, FxU32 dst_y, GrLfbSrcFmt_t src_format, + FxU32 src_width, FxU32 src_height, FxI32 src_stride, + void *src_data) { int i, x, w, srcElt; void *data; @@ -80,12 +240,12 @@ static FxBool writeRegionClipped(fxMesaContext fxMesa, GrBuffer_t dst_buffer, if (src_width==1 && src_height==1) { /* Easy case writing a point */ for (i=0; i<fxMesa->numClipRects; i++) { if ((dst_x>=fxMesa->pClipRects[i].x1) && - (dst_x<fxMesa->pClipRects[i].x2) && - (dst_y>=fxMesa->pClipRects[i].y1) && - (dst_y<fxMesa->pClipRects[i].y2)) { - FX_grLfbWriteRegion(dst_buffer, dst_x, dst_y, src_format, - 1, 1, src_stride, src_data); - return GL_TRUE; + (dst_x<fxMesa->pClipRects[i].x2) && + (dst_y>=fxMesa->pClipRects[i].y1) && + (dst_y<fxMesa->pClipRects[i].y2)) { + FX_grLfbWriteRegion(dst_buffer, dst_x, dst_y, src_format, + 1, 1, src_stride, src_data); + return GL_TRUE; } } } else if (src_height==1) { /* Writing a span */ @@ -97,20 +257,20 @@ static FxBool writeRegionClipped(fxMesaContext fxMesa, GrBuffer_t dst_buffer, } for (i=0; i<fxMesa->numClipRects; i++) { if (dst_y>=fxMesa->pClipRects[i].y1 && dst_y<fxMesa->pClipRects[i].y2) { - if (dst_x<fxMesa->pClipRects[i].x1) { - x=fxMesa->pClipRects[i].x1; - data=((char*)src_data)+srcElt*(dst_x-x); - w=src_width-(x-dst_x); - } else { - x=dst_x; - data=src_data; - w=src_width; - } - if (x+w>fxMesa->pClipRects[i].x2) { - w=fxMesa->pClipRects[i].x2-x; - } - FX_grLfbWriteRegion(dst_buffer, x, dst_y, src_format, w, 1, - src_stride, data); + if (dst_x<fxMesa->pClipRects[i].x1) { + x=fxMesa->pClipRects[i].x1; + data=((char*)src_data)+srcElt*(x - dst_x); + w=src_width-(x-dst_x); + } else { + x=dst_x; + data=src_data; + w=src_width; + } + if (x+w>fxMesa->pClipRects[i].x2) { + w=fxMesa->pClipRects[i].x2-x; + } + FX_grLfbWriteRegion(dst_buffer, x, dst_y, src_format, w, 1, + src_stride, data); } } } else { /* Punt on the case of arbitrary rectangles */ @@ -119,88 +279,42 @@ static FxBool writeRegionClipped(fxMesaContext fxMesa, GrBuffer_t dst_buffer, return GL_TRUE; } -#else - -#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) - -#endif /* 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) \ - - -#else /* !defined(FXMESA_USE_RGBA) */ - -#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) - - -#define MESACOLOR_TO_ARGB(c) ( \ - ( ((unsigned int)(c[ACOMP]))<<24 ) | \ - ( ((unsigned int)(c[RCOMP]))<<16 ) | \ - ( ((unsigned int)(c[GCOMP]))<<8 ) | \ - ( (unsigned int)(c[BCOMP])) ) - -inline void LFB_WRITE_SPAN_MESA(GrBuffer_t dst_buffer, - FxU32 dst_x, - FxU32 dst_y, - FxU32 src_width, - FxI32 src_stride, - void *src_data ) -{ - /* Covert to ARGB */ - GLubyte (*rgba)[4] = src_data; - GLuint argb[MAX_WIDTH]; - int i; - - for (i = 0; i < src_width; i++) - { - argb[i] = MESACOLOR_TO_ARGB(rgba[i]); - } - writeRegionClipped( /*fxMesa,*/ NULL, dst_buffer, - dst_x, - dst_y, - GR_LFB_SRC_FMT_8888, - src_width, - 1, - src_stride, - (void*)argb); -} - -#endif /* !defined(FXMESA_USE_RGBA) */ +#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 *****/ -/************************************************************************/ -static void fxDDWriteRGBASpan(const GLcontext *ctx, - GLuint n, GLint x, GLint y, - const GLubyte rgba[][4], const GLubyte mask[]) +/* + * 16bpp span/pixel functions + */ + +static void +write_R5G6B5_rgba_span(const GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLubyte rgba[][4], const GLubyte mask[]) { fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; GLuint i; GLint bottom=fxMesa->height+fxMesa->y_offset-1; if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxDDWriteRGBASpan(...)\n"); + fprintf(stderr,"fxmesa: fxDDWriteRGBASpan(...)\n"); } x+=fxMesa->x_offset; @@ -213,7 +327,7 @@ static void fxDDWriteRGBASpan(const GLcontext *ctx, } else { if (span > 0) { LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x+i-span, bottom-y, - /* GR_LFB_SRC_FMT_8888,*/ span, /*1,*/ 0, (void *) rgba[i-span] ); + /* GR_LFB_SRC_FMT_8888,*/ span, /*1,*/ 0, (void *) rgba[i-span] ); span = 0; } } @@ -221,16 +335,16 @@ static void fxDDWriteRGBASpan(const GLcontext *ctx, if (span > 0) LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x+n-span, bottom-y, - /* GR_LFB_SRC_FMT_8888, */ span, /*1,*/ 0, (void *) rgba[n-span] ); + /* GR_LFB_SRC_FMT_8888, */ span, /*1,*/ 0, (void *) rgba[n-span] ); } else LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x, bottom-y,/* GR_LFB_SRC_FMT_8888,*/ - n,/* 1,*/ 0, (void *) rgba ); + n,/* 1,*/ 0, (void *) rgba ); } -static void fxDDWriteRGBSpan(const GLcontext *ctx, - GLuint n, GLint x, GLint y, - const GLubyte rgb[][3], const GLubyte mask[]) +static void +write_R5G6B5_rgb_span(const GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLubyte rgb[][3], const GLubyte mask[]) { fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; GLuint i; @@ -238,7 +352,7 @@ static void fxDDWriteRGBSpan(const GLcontext *ctx, GLubyte rgba[MAX_WIDTH][4]; if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxDDWriteRGBSpan()\n"); + fprintf(stderr,"fxmesa: fxDDWriteRGBSpan()\n"); } x+=fxMesa->x_offset; @@ -255,7 +369,7 @@ static void fxDDWriteRGBSpan(const GLcontext *ctx, } else { if (span > 0) { LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x+i-span, bottom-y, - /*GR_LFB_SRC_FMT_8888,*/ span,/* 1,*/ 0, (void *) rgba ); + /*GR_LFB_SRC_FMT_8888,*/ span,/* 1,*/ 0, (void *) rgba ); span = 0; } } @@ -263,7 +377,7 @@ static void fxDDWriteRGBSpan(const GLcontext *ctx, if (span > 0) LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x+n-span, bottom-y, - /*GR_LFB_SRC_FMT_8888,*/ span,/* 1,*/ 0, (void *) rgba ); + /*GR_LFB_SRC_FMT_8888,*/ span,/* 1,*/ 0, (void *) rgba ); } else { for (i=0;i<n;i++) { rgba[i][RCOMP]=rgb[i][0]; @@ -273,14 +387,14 @@ static void fxDDWriteRGBSpan(const GLcontext *ctx, } LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x, bottom-y,/* GR_LFB_SRC_FMT_8888,*/ - n,/* 1,*/ 0, (void *) rgba ); + n,/* 1,*/ 0, (void *) rgba ); } } -static void fxDDWriteMonoRGBASpan(const GLcontext *ctx, - GLuint n, GLint x, GLint y, - const GLubyte mask[]) +static void +write_R5G6B5_mono_span(const GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLubyte mask[]) { fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; GLuint i; @@ -288,7 +402,7 @@ static void fxDDWriteMonoRGBASpan(const GLcontext *ctx, GLuint data[MAX_WIDTH]; if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxDDWriteMonoRGBASpan(...)\n"); + fprintf(stderr,"fxmesa: fxDDWriteMonoRGBASpan(...)\n"); } x+=fxMesa->x_offset; @@ -302,8 +416,8 @@ static void fxDDWriteMonoRGBASpan(const GLcontext *ctx, } else { if (span > 0) { writeRegionClipped(fxMesa, fxMesa->currentFB, x+i-span, bottom-y, - GR_LFB_SRC_FMT_8888, span, 1, 0, - (void *) data ); + GR_LFB_SRC_FMT_8888, span, 1, 0, + (void *) data ); span = 0; } } @@ -311,95 +425,129 @@ static void fxDDWriteMonoRGBASpan(const GLcontext *ctx, if (span > 0) writeRegionClipped(fxMesa, fxMesa->currentFB, x+n-span, bottom-y, - GR_LFB_SRC_FMT_8888, span, 1, 0, - (void *) data ); + GR_LFB_SRC_FMT_8888, span, 1, 0, + (void *) data ); } else { for (i=0;i<n;i++) { data[i]=(GLuint) fxMesa->color; } writeRegionClipped(fxMesa, fxMesa->currentFB, x, bottom-y, GR_LFB_SRC_FMT_8888, - n, 1, 0, (void *) data ); + n, 1, 0, (void *) data ); } } -static void fxDDReadRGBASpan(const GLcontext *ctx, - GLuint n, GLint x, GLint y, GLubyte rgba[][4]) +/* + * Read a span of 16-bit RGB pixels. Note, we don't worry about cliprects + * since OpenGL says obscured pixels have undefined values. + */ +static void +read_R5G6B5_span(const GLcontext *ctx, GLuint n, GLint x, GLint y, + GLubyte rgba[][4]) { - fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; - GLushort data[MAX_WIDTH]; - GLuint i; - GLint bottom=fxMesa->height+fxMesa->y_offset-1; - - if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxDDReadRGBASpan(...)\n"); - } - - assert(n < MAX_WIDTH); - - x+=fxMesa->x_offset; - FX_grLfbReadRegion( fxMesa->currentFB, x, bottom-y, n, 1, 0, data); + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbInfo_t info; + BEGIN_BOARD_LOCK(); + info.size=sizeof(info); + if (grLfbLock(GR_LFB_READ_ONLY, + fxMesa->currentFB, + GR_LFBWRITEMODE_ANY, + GR_ORIGIN_UPPER_LEFT, + FXFALSE, + &info)) { + const GLint winX = fxMesa->x_offset; + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; +#ifdef XF86DRI + const GLint srcStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + ? (fxMesa->screen_width) : (info.strideInBytes / 2); +#else + const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */ +#endif + const GLushort *data16 = (const GLushort *) info.lfbPtr + + (winY - y) * srcStride + + (winX + x); + const GLuint *data32 = (const GLuint *) data16; + GLuint i, j; + GLuint extraPixel = (n & 1); + n -= extraPixel; + for (i = j = 0; i < n; i += 2, j++) { + GLuint pixel = data32[j]; + GLuint pixel0 = pixel & 0xffff; + GLuint pixel1 = pixel >> 16; + rgba[i][RCOMP] = FX_PixelToR[pixel0]; + rgba[i][GCOMP] = FX_PixelToG[pixel0]; + rgba[i][BCOMP] = FX_PixelToB[pixel0]; + rgba[i][ACOMP] = 255; + rgba[i+1][RCOMP] = FX_PixelToR[pixel1]; + rgba[i+1][GCOMP] = FX_PixelToG[pixel1]; + rgba[i+1][BCOMP] = FX_PixelToB[pixel1]; + rgba[i+1][ACOMP] = 255; + } + if (extraPixel) { + GLushort pixel = data16[n]; + rgba[n][RCOMP] = FX_PixelToR[pixel]; + rgba[n][GCOMP] = FX_PixelToG[pixel]; + rgba[n][BCOMP] = FX_PixelToB[pixel]; + rgba[n][ACOMP] = 255; + } - for (i=0;i<n;i++) { - GLushort pixel = data[i]; - rgba[i][RCOMP] = FX_PixelToR[pixel]; - rgba[i][GCOMP] = FX_PixelToG[pixel]; - rgba[i][BCOMP] = FX_PixelToB[pixel]; - rgba[i][ACOMP] = 255; + grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); } + END_BOARD_LOCK(); } -/************************************************************************/ -/***** Pixel functions *****/ -/************************************************************************/ -static void fxDDWriteRGBAPixels(const GLcontext *ctx, - GLuint n, const GLint x[], const GLint y[], - CONST GLubyte rgba[][4], const GLubyte mask[]) +static void +write_R5G6B5_pixels(const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + CONST GLubyte rgba[][4], const GLubyte mask[]) { fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; GLuint i; GLint bottom=fxMesa->height+fxMesa->y_offset-1; if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxDDWriteRGBAPixels(...)\n"); + fprintf(stderr,"fxmesa: fxDDWriteRGBAPixels(...)\n"); } for(i=0;i<n;i++) if(mask[i]) - LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x[i]+fxMesa->x_offset, bottom-y[i], - 1, 1, (void *)rgba[i]); + LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x[i]+fxMesa->x_offset, bottom-y[i], + 1, 1, (void *)rgba[i]); } -static void fxDDWriteMonoRGBAPixels(const GLcontext *ctx, - GLuint n, const GLint x[], const GLint y[], - const GLubyte mask[]) + +static void +write_R5G6B5_mono_pixels(const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + const GLubyte mask[]) { fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; GLuint i; GLint bottom=fxMesa->height+fxMesa->y_offset-1; if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxDDWriteMonoRGBAPixels(...)\n"); + fprintf(stderr,"fxmesa: fxDDWriteMonoRGBAPixels(...)\n"); } for(i=0;i<n;i++) if(mask[i]) writeRegionClipped(fxMesa, fxMesa->currentFB,x[i]+fxMesa->x_offset,bottom-y[i], - GR_LFB_SRC_FMT_8888,1,1,0,(void *) &fxMesa->color); + GR_LFB_SRC_FMT_8888,1,1,0,(void *) &fxMesa->color); } -static void fxDDReadRGBAPixels(const GLcontext *ctx, - GLuint n, const GLint x[], const GLint y[], - GLubyte rgba[][4], const GLubyte mask[]) +static void +read_R5G6B5_pixels(const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLubyte rgba[][4], const GLubyte mask[]) { fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; GLuint i; - GLint bottom=fxMesa->y_delta-1; + GLint bottom=fxMesa->height+fxMesa->y_offset-1; if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxDDReadRGBAPixels(...)\n"); + fprintf(stderr,"fxmesa: fxDDReadRGBAPixels(...)\n"); } for(i=0;i<n;i++) { @@ -415,19 +563,663 @@ static void fxDDReadRGBAPixels(const GLcontext *ctx, } -/************************************************************************/ -/***** Depth functions *****/ -/************************************************************************/ +/* + * 24bpp span/pixel functions + */ + +static void +write_R8G8B8_rgb_span(const GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLubyte rgb[][3], const GLubyte mask[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbWriteMode_t mode; + GrLfbInfo_t info; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + mode = GR_LFBWRITEMODE_888; + else + mode = GR_LFBWRITEMODE_888; + + BEGIN_BOARD_LOCK(); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + mode, + GR_ORIGIN_UPPER_LEFT, + FXFALSE, + &info)) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + const GLint scrX = winX + x; + const GLint scrY = winY - y; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + /*GLint dstStride = fxMesa->screen_width * 3;*/ + GLint dstStride = info.strideInBytes / 1; + GLubyte *dst = (GLubyte *) info.lfbPtr + + (winY - y) * dstStride + (winX + x) * 1; + GLuint *dst32 = (GLuint *) dst; + GLubyte visMask[MAX_WIDTH]; + GLuint i; + generate_vismask(fxMesa, scrX, scrY, n, visMask); + for (i = 0; i < n; i++) { + if (visMask[i] && (!mask || mask[i])) { + dst32[i] = PACK_BGRA32(rgb[i][0], rgb[i][1], rgb[i][2], 255); + } + } + } + else { + /* back buffer */ + GLint dstStride = info.strideInBytes; + GLubyte *dst = (GLubyte *) info.lfbPtr + + (winY - y) * dstStride + (winX + x) * 4; + GLuint *dst32 = (GLuint *) dst; + if (mask) { + GLuint i; + for (i = 0; i < n; i++) { + if (mask[i]) { + dst32[i] = PACK_RGBA32(rgb[i][0], rgb[i][1], rgb[i][2], 255); + } + } + } + else { + GLuint i; + for (i = 0; i < n; i++) { + dst32[i] = PACK_RGBA32(rgb[i][2], rgb[i][1], rgb[i][0], 255); + } + } + } + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(); +} + + + +static void +write_R8G8B8_rgba_span(const GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLubyte rgba[][4], const GLubyte mask[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbWriteMode_t mode; + GrLfbInfo_t info; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + mode = GR_LFBWRITEMODE_8888; + else + mode = GR_LFBWRITEMODE_888 /*565*/; + + BEGIN_BOARD_LOCK(); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + mode, + GR_ORIGIN_UPPER_LEFT, + FXFALSE, + &info)) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + const GLint scrX = winX + x; + const GLint scrY = winY - y; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + /* XXX have to do cliprect clipping! */ + GLint dstStride = fxMesa->screen_width * 4; + GLubyte *dst = (GLubyte *) info.lfbPtr + + (winY - y) * dstStride + (winX + x) * 4; + GLuint *dst32 = (GLuint *) dst; + GLubyte visMask[MAX_WIDTH]; + GLuint i; + generate_vismask(fxMesa, scrX, scrY, n, visMask); + for (i = 0; i < n; i++) { + if (visMask[i] && (!mask || mask[i])) { + dst32[i] = PACK_BGRA32(rgba[i][0], rgba[i][1], rgba[i][2], rgba[i][3]); + } + } + } + else { + /* back buffer */ + GLint dstStride = info.strideInBytes; + GLubyte *dst = (GLubyte *) info.lfbPtr + + (winY - y) * dstStride + (winX + x) * 4; + if (mask) { + const GLuint *src32 = (const GLuint *) rgba; + GLuint *dst32 = (GLuint *) dst; + GLuint i; + for (i = 0; i < n; i++) { + if (mask[i]) { + dst32[i] = src32[i]; + } + } + } + else { + /* no mask, write all pixels */ + MEMCPY(dst, rgba, 4 * n); + } + } + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(); +} + + +static void +write_R8G8B8_mono_span(const GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLubyte mask[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLubyte rgba[MAX_WIDTH][4]; + GLuint *data = (GLuint *) rgba; + GLuint i; + + /* XXX this is a simple-minded implementation but good enough for now */ + for (i = 0; i < n; i++) { + data[i] = (GLuint) fxMesa->color; + } + write_R8G8B8_rgba_span(ctx, n, x, y, (const GLubyte (*)[4]) rgba, mask); +} + + +static void +read_R8G8B8_span(const GLcontext *ctx, GLuint n, GLint x, GLint y, + GLubyte rgba[][4]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbWriteMode_t mode; + GrLfbInfo_t info; + + if (1 || fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + mode = GR_LFBWRITEMODE_8888; + } + else { + mode = GR_LFBWRITEMODE_565; /*888*/ /*565*/; + } + + BEGIN_BOARD_LOCK(); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_READ_ONLY, + fxMesa->currentFB, + mode, /*GR_LFBWRITEMODE_ANY,*/ + GR_ORIGIN_UPPER_LEFT, + FXFALSE, + &info)) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + GLint srcStride = fxMesa->screen_width * 4; + const GLubyte *src = (const GLubyte *) info.lfbPtr + + (winY - y) * srcStride + (winX + x) * 4; + GLuint i; + for (i = 0; i < n; i++) { + rgba[i][0] = src[i * 4 + 2]; + rgba[i][1] = src[i * 4 + 1]; + rgba[i][2] = src[i * 4 + 0]; + rgba[i][3] = src[i * 4 + 3]; + } + } + else { + /* back buffer */ + GLint srcStride = /*info.strideInBytes;*/ 8192 / 2; /* XXX a hack! */ + const GLubyte *src = (const GLubyte *) info.lfbPtr + + (winY - y) * srcStride + (winX + x) * 4; + GLuint i; + for (i = 0; i < n; i++) { + rgba[i][0] = src[i * 4 + 2]; + rgba[i][1] = src[i * 4 + 1]; + rgba[i][2] = src[i * 4 + 0]; + rgba[i][3] = src[i * 4 + 3]; + } + } + grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(); +} + + +static void +write_R8G8B8_pixels(const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + CONST GLubyte rgba[][4], const GLubyte mask[]) +{ +#if 00 + GLuint i; + for (i = 0; i < n; i++) { + write_R8G8B8_rgba_span(ctx, 1, x[i], y[i], rgba + i, mask + i); + } + +#else + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbWriteMode_t mode; + GrLfbInfo_t info; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + mode = GR_LFBWRITEMODE_8888; + else + mode = GR_LFBWRITEMODE_888 /*565*/; + + BEGIN_BOARD_LOCK(); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + mode, + GR_ORIGIN_UPPER_LEFT, + FXFALSE, + &info)) { + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + GLuint i; + for (i = 0; i < n; i++) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + const GLint scrX = winX + x[i]; + const GLint scrY = winY - y[i]; + if (mask[i] && visible_pixel(fxMesa, scrX, scrY)) { + GLint dstStride = fxMesa->screen_width * 4; + GLubyte *dst = (GLubyte *) info.lfbPtr + scrY * dstStride + scrX * 4; + GLuint *dst32 = (GLuint *) dst; + *dst32 = PACK_BGRA32(rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3]); + } + } + } + else { + /* back buffer */ + GLuint i; + for (i = 0; i < n; i++) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + const GLint scrX = winX + x[i]; + const GLint scrY = winY - y[i]; + if (mask[i] && visible_pixel(fxMesa, scrX, scrY)) { + GLint dstStride = info.strideInBytes; + GLubyte *dst = (GLubyte *) info.lfbPtr + scrY * dstStride + scrX * 4; + GLuint *dst32 = (GLuint *) dst; + const GLuint *src32 = (const GLuint *) rgba; + *dst32 = src32[i]; + } + } + } + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(); +#endif +} + + +static void +write_R8G8B8_mono_pixels(const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + const GLubyte mask[]) +{ +} + + +static void +read_R8G8B8_pixels(const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLubyte rgba[][4], const GLubyte mask[]) +{ + printf("read_R8G8B8_pixels %d\n", n); +} + + + +/* + * 32bpp span/pixel functions + */ + +static void +write_R8G8B8A8_rgb_span(const GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLubyte rgb[][3], const GLubyte mask[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbWriteMode_t mode; + GrLfbInfo_t info; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + mode = GR_LFBWRITEMODE_8888; + else + mode = GR_LFBWRITEMODE_888 /*565*/; + + BEGIN_BOARD_LOCK(); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + mode, + GR_ORIGIN_UPPER_LEFT, + FXFALSE, + &info)) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + const GLint scrX = winX + x; + const GLint scrY = winY - y; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + GLint dstStride = fxMesa->screen_width * 4; + GLubyte * dst = (GLubyte *) info.lfbPtr + + (winY - y) * dstStride + (winX + x) * 4; + GLuint *dst32 = (GLuint *) dst; + GLubyte visMask[MAX_WIDTH]; + GLuint i; + generate_vismask(fxMesa, scrX, scrY, n, visMask); + for (i = 0; i < n; i++) { + if (visMask[i] && (!mask || mask[i])) { + dst32[i] = PACK_BGRA32(rgb[i][0], rgb[i][1], rgb[i][2], 255); + } + } + } + else { + /* back buffer */ + GLint dstStride = info.strideInBytes; + GLubyte *dst = (GLubyte *) info.lfbPtr + + (winY - y) * dstStride + (winX + x) * 4; + if (mask) { + GLuint *dst32 = (GLuint *) dst; + GLuint i; + for (i = 0; i < n; i++) { + if (mask[i]) { + dst32[i] = PACK_RGBA32(rgb[i][0], rgb[i][1], rgb[i][2], 255); + } + } + } + else { + GLuint *dst32 = (GLuint *) dst; + GLuint i; + for (i = 0; i < n; i++) { + dst32[i] = PACK_RGBA32(rgb[i][0], rgb[i][1], rgb[i][2], 255); + } + } + } + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(); +} + + +/* + *XXX test of grLfbWriteRegion in 32bpp mode. Doesn't seem to work! + */ +#if 0 +static void +write_R8G8B8A8_rgb_span2(const GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLubyte rgb[][3], const GLubyte mask[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLint bottom = fxMesa->height + fxMesa->y_offset - 1; + GLint x2 = fxMesa->x_offset +x; + GLint y2 = bottom - y; + + FX_grLfbWriteRegion(fxMesa->currentFB, x2, y2, GR_LFB_SRC_FMT_888, + n, 1, 0, rgb); +} +#endif + + +static void +write_R8G8B8A8_rgba_span(const GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLubyte rgba[][4], const GLubyte mask[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbWriteMode_t mode; + GrLfbInfo_t info; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + mode = GR_LFBWRITEMODE_8888; + else + mode = GR_LFBWRITEMODE_888 /*565*/; + + BEGIN_BOARD_LOCK(); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + mode, + GR_ORIGIN_UPPER_LEFT, + FXFALSE, + &info)) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + const GLint scrX = winX + x; + const GLint scrY = winY - y; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + GLint dstStride = fxMesa->screen_width * 4; + GLubyte *dst = (GLubyte *) info.lfbPtr + + (winY - y) * dstStride + (winX + x) * 4; + GLuint *dst32 = (GLuint *) dst; + GLubyte visMask[MAX_WIDTH]; + GLuint i; + generate_vismask(fxMesa, scrX, scrY, n, visMask); + for (i = 0; i < n; i++) { + if (visMask[i] && (!mask || mask[i])) { + dst32[i] = PACK_BGRA32(rgba[i][0], rgba[i][1], rgba[i][2], rgba[i][3]); + } + } + } + else { + /* back buffer */ + GLint dstStride = 8192; /* XXX a hack info.strideInBytes; */ + GLubyte *dst = (GLubyte *) info.lfbPtr + + (winY - y) * dstStride + (winX + x) * 4; + if (mask) { + const GLuint *src32 = (const GLuint *) rgba; + GLuint *dst32 = (GLuint *) dst; + GLuint i; + for (i = 0; i < n; i++) { + if (mask[i]) { + dst32[i] = src32[i]; + } + } + } + else { + /* no mask, write all pixels */ + MEMCPY(dst, rgba, 4 * n); + } + } + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + } + else { + info.strideInBytes = -1; + } + END_BOARD_LOCK(); +} + + +static void +write_R8G8B8A8_mono_span(const GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLubyte mask[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GLubyte rgba[MAX_WIDTH][4]; + GLuint *data = (GLuint *) rgba; + GLuint i; + + /* XXX this is a simple-minded implementation but good enough for now */ + for (i = 0; i < n; i++) { + data[i] = (GLuint) fxMesa->color; + } + write_R8G8B8A8_rgba_span(ctx, n, x, y, (const GLubyte (*)[4]) rgba, mask); +} + + +static void +read_R8G8B8A8_span(const GLcontext *ctx, GLuint n, GLint x, GLint y, + GLubyte rgba[][4]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbWriteMode_t mode; + GrLfbInfo_t info; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + mode = GR_LFBWRITEMODE_8888; + } + else { + mode = GR_LFBWRITEMODE_8888; /*565;*/ + } + + BEGIN_BOARD_LOCK(); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_READ_ONLY, + fxMesa->currentFB, + mode, + GR_ORIGIN_UPPER_LEFT, + FXFALSE, + &info)) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + GLint srcStride = fxMesa->screen_width; + const GLuint *src32 = (const GLuint *) info.lfbPtr + + (winY - y) * srcStride + (winX + x); + GLuint i; + for (i = 0; i < n; i++) { + const GLuint p = src32[i]; + rgba[i][0] = (p >> 16) & 0xff; + rgba[i][1] = (p >> 8) & 0xff; + rgba[i][2] = (p >> 0) & 0xff; + rgba[i][3] = (p >> 24) & 0xff; + } + } + else { + /* back buffer */ + GLint srcStride = 1024; /* XXX a hack */ + const GLuint *src32 = (const GLuint *) info.lfbPtr + + (winY - y) * srcStride + (winX + x); + GLuint i; + for (i = 0; i < n; i++) { + GLuint p = src32[i]; + rgba[i][0] = (p >> 16) & 0xff; + rgba[i][1] = (p >> 8) & 0xff; + rgba[i][2] = (p >> 0) & 0xff; + rgba[i][3] = (p >> 24) & 0xff; + } + } + grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB); + } + else + info.strideInBytes = -1; + END_BOARD_LOCK(); +} + + +static void +write_R8G8B8A8_pixels(const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + CONST GLubyte rgba[][4], const GLubyte mask[]) +{ +#if 00 + GLuint i; + for (i = 0; i < n; i++) { + write_R8G8B8A8_rgba_span(ctx, 1, x[i], y[i], rgba + i, mask + i); + } + +#else + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbWriteMode_t mode; + GrLfbInfo_t info; + + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) + mode = GR_LFBWRITEMODE_8888; + else + mode = GR_LFBWRITEMODE_888 /*565*/; + + BEGIN_BOARD_LOCK(); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_WRITE_ONLY, + fxMesa->currentFB, + mode, + GR_ORIGIN_UPPER_LEFT, + FXFALSE, + &info)) { + if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) { + GLuint i; + for (i = 0; i < n; i++) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + const GLint scrX = winX + x[i]; + const GLint scrY = winY - y[i]; + if (mask[i] && visible_pixel(fxMesa, scrX, scrY)) { + GLint dstStride = fxMesa->screen_width * 4; + GLubyte *dst = (GLubyte *) info.lfbPtr + scrY * dstStride + scrX * 4; + GLuint *dst32 = (GLuint *) dst; + *dst32 = PACK_BGRA32(rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3]); + } + } + } + else { + /* back buffer */ + GLuint i; + for (i = 0; i < n; i++) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + const GLint scrX = winX + x[i]; + const GLint scrY = winY - y[i]; + if (mask[i] && visible_pixel(fxMesa, scrX, scrY)) { + GLint dstStride = info.strideInBytes; + GLubyte *dst = (GLubyte *) info.lfbPtr + scrY * dstStride + scrX * 4; + GLuint *dst32 = (GLuint *) dst; + const GLuint *src32 = (const GLuint *) rgba; + *dst32 = src32[i]; + } + } + } + grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB); + } + END_BOARD_LOCK(); +#endif +} + + +static void +write_R8G8B8A8_mono_pixels(const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + const GLubyte mask[]) +{ + fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx; + GLuint i; + GLuint color = fxMesa->color; + for (i = 0; i < n; i++) { + if (mask[i]) { + write_R8G8B8A8_rgba_span(ctx, 1, x[i], y[i], + (const GLubyte (*)[4]) &color, mask + i); + } + } +} + + + +static void +read_R8G8B8A8_pixels(const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLubyte rgba[][4], const GLubyte mask[]) +{ + GLuint i; + for (i = 0; i < n; i++) { + if (mask[i]) { + read_R8G8B8A8_span(ctx, 1, x[i], y[i], rgba + i); + } + } + printf("read_R8G8B8A8_pixels %d\n", n); +} + + + +/* + * Depth buffer read/write functions. + */ void fxDDWriteDepthSpan(GLcontext *ctx, GLuint n, GLint x, GLint y, const GLdepth depth[], const GLubyte mask[]) { - fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; - GLint bottom=fxMesa->height+fxMesa->y_offset-1; + fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx; + GLint bottom = fxMesa->height + fxMesa->y_offset - 1; + GLuint depth_size = fxMesa->glVis->DepthBits; + GLuint stencil_size = fxMesa->glVis->StencilBits; - if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxDDReadDepthSpanInt(...)\n"); + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDWriteDepthSpan(...)\n"); } x += fxMesa->x_offset; @@ -436,14 +1228,77 @@ void fxDDWriteDepthSpan(GLcontext *ctx, GLint i; for (i = 0; i < n; i++) { if (mask[i]) { - writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x + i, bottom-y, - GR_LFB_SRC_FMT_ZA16, 1, 1, 0, (void *) &depth[i]); + GLshort d16; + GLuint d32; + switch (depth_size) { + case 16: + d16 = depth[i]; + writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x + i, bottom - y, + GR_LFB_SRC_FMT_ZA16, 1, 1, 0, (void *) &d16); + break; + case 32: + if (!fb_point_is_clipped(fxMesa, x+i, bottom-y)) { + if (stencil_size > 0) { + rw_fb_span(fxMesa, + GR_BUFFER_AUXBUFFER, + x + i, bottom - y, + 1, + sizeof(GLdepth), + &d32, + FBS_READ); + d32 = depth[i] & 0xFF000000; + break; + } else { + d32 = depth[i]; + } + rw_fb_span(fxMesa, + GR_BUFFER_AUXBUFFER, + x + i, bottom - y, + 1, + sizeof(GLdepth), + &d32, + FBS_WRITE); + } + } } } - } - else { - writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x, bottom-y, - GR_LFB_SRC_FMT_ZA16, n, 1, 0, (void *) depth); + } else { + GLushort depth16[MAX_WIDTH]; + GLint i; + GLuint d32; + switch (depth_size) { + case 16: + 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); + break; + case 32: + for (i = 0; i < n; i++) { + if (fb_point_is_clipped(fxMesa, x+i, bottom-y)) { + if (stencil_size > 0) { + rw_fb_span(fxMesa, + GR_BUFFER_AUXBUFFER, + x + i, bottom - y, + 1, + sizeof(GLdepth), + &d32, + FBS_READ); + d32 = (d32 & 0xFF0000) | (depth[i] & 0x00FFFFFF); + } else { + d32 = depth[i]; + } + rw_fb_span(fxMesa, + GR_BUFFER_AUXBUFFER, + x + i, bottom - y, + 1, + sizeof(GLdepth), + &d32, + FBS_WRITE); + } + } + } } } @@ -451,15 +1306,39 @@ void fxDDWriteDepthSpan(GLcontext *ctx, void fxDDReadDepthSpan(GLcontext *ctx, GLuint n, GLint x, GLint y, GLdepth depth[]) { - fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; - GLint bottom=fxMesa->height+fxMesa->y_offset-1; + fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx; + GLint bottom = fxMesa->height + fxMesa->y_offset - 1; + GLushort depth16[MAX_WIDTH]; + GLuint i; + GLuint depth_size = fxMesa->glVis->DepthBits; + GLuint stencil_size = fxMesa->glVis->StencilBits; - if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxDDReadDepthSpanInt(...)\n"); + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDReadDepthSpan(...)\n"); } - x+=fxMesa->x_offset; - FX_grLfbReadRegion(GR_BUFFER_AUXBUFFER,x,bottom-y,n,1,0,depth); + x += fxMesa->x_offset; + switch (depth_size) { + case 16: + FX_grLfbReadRegion(GR_BUFFER_AUXBUFFER, x, bottom - y, n, 1, 0, depth16); + for (i = 0; i < n; i++) { + depth[i] = depth16[i]; + } + break; + case 32: + rw_fb_span(fxMesa, + GR_BUFFER_AUXBUFFER, + x, bottom - y, + n, + sizeof(GLdepth), + depth, + FBS_READ); + if (stencil_size > 0) { + for (i = 0; i < n; i++) { + depth[i] &= 0xFFFFFF; + } + } + } } @@ -468,20 +1347,56 @@ void fxDDWriteDepthPixels(GLcontext *ctx, GLuint n, const GLint x[], const GLint y[], const GLdepth depth[], const GLubyte mask[]) { - fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; - GLint bottom=fxMesa->height+fxMesa->y_offset-1; + fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx; + GLint bottom = fxMesa->height + fxMesa->y_offset - 1; GLuint i; + GLuint d32; + GLuint depth_size = fxMesa->glVis->DepthBits; + GLuint stencil_size = fxMesa->glVis->StencilBits; - if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxDDReadDepthSpanInt(...)\n"); + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDWriteDepthPixels(...)\n"); } for (i = 0; i < n; i++) { if (mask[i]) { int xpos = x[i] + fxMesa->x_offset; int ypos = bottom - y[i]; - writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, xpos, ypos, - GR_LFB_SRC_FMT_ZA16, 1, 1, 0, (void *) &depth[i]); + GLushort d16 = depth[i]; + switch (depth_size) { + case 16: + writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, xpos, ypos, + GR_LFB_SRC_FMT_ZA16, 1, 1, 0, + (void *) &d16); + break; + case 32: + if (!fb_point_is_clipped(fxMesa, xpos, ypos)) { + if (stencil_size > 0) { + /* + * Should I sign extend this? I don't + * believe so, since GLdepth is unsigned. + */ + rw_fb_span(fxMesa, + GR_BUFFER_AUXBUFFER, + xpos, ypos, + 1, + sizeof(GLdepth), + &d32, + FBS_READ); + d32 = (d32 &~ 0xFF000000) | (depth[i] & 0x00FFFFFF); + } else { + d32 = depth[i]; + } + rw_fb_span(fxMesa, + GR_BUFFER_AUXBUFFER, + xpos, ypos, + 1, + sizeof(GLdepth), + &d32, + FBS_WRITE); + } + break; + } } } } @@ -490,60 +1405,420 @@ void fxDDWriteDepthPixels(GLcontext *ctx, void fxDDReadDepthPixels(GLcontext *ctx, GLuint n, const GLint x[], const GLint y[], GLdepth depth[]) { - fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; - GLint bottom=fxMesa->height+fxMesa->y_offset-1; + fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx; + GLint bottom = fxMesa->height + fxMesa->y_offset - 1; GLuint i; - if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxDDReadDepthSpanInt(...)\n"); + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDReadDepthPixels(...)\n"); } - for (i = 0; i < n; i++) { int xpos = x[i] + fxMesa->x_offset; int ypos = bottom - y[i]; - FX_grLfbReadRegion(GR_BUFFER_AUXBUFFER,xpos,ypos,1,1,0,&depth[i]); + GLushort d16; + GLuint d32; + GLuint depth_size = fxMesa->glVis->DepthBits; + GLuint stencil_size = fxMesa->glVis->StencilBits; + + assert((depth_size == 16) || (depth_size == 32)); + switch (depth_size) { + case 16: + FX_grLfbReadRegion(GR_BUFFER_AUXBUFFER, xpos, ypos, 1, 1, 0, &d16); + depth[i] = d16; + break; + case 32: + rw_fb_span(fxMesa, + GR_BUFFER_AUXBUFFER, + xpos, ypos, + 1, + depth_size/8, + &d32, + FBS_READ); + /* + * Get rid of the stencil bits. Should I sign + * extend this? I don't believe so, since GLdepth + * is unsigned. + */ + if (stencil_size > 0) { + d32 &= 0xFFFFFF; + } + depth[i] = d32; + break; + default: + assert(0); + } } } +/* + * Stencil buffer read/write functions. + */ +#define DEPTH_VALUE_TO_STENCIL_VALUE(d) (((d) >> 24) & 0xFF) +#define STENCIL_VALUE_TO_DEPTH_VALUE(s,d) \ + ((((s) & 0xFF) << 24) | ((d) & 0xFFFFFF)) +#define ASSEMBLE_STENCIL_VALUE(os, ns, mask) \ + (((os) &~ (mask)) | ((ns) & (mask))) -/************************************************************************/ +#if 00 +/* + * Read a horizontal span of stencil values from the stencil buffer. + */ +void +fxDDReadStencilSpan( GLcontext *ctx, + GLuint n, + GLint x, + GLint y, + GLstencil stencil[] ) +{ + fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx; + GLint bottom = fxMesa->height + fxMesa->y_offset - 1; + GLuint i; + int xpos = x + fxMesa->x_offset; + int ypos = bottom - y; + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDReadStencilSpan(...)\n"); + } -void fxSetupDDSpanPointers(GLcontext *ctx) -{ - ctx->Driver.WriteRGBASpan =fxDDWriteRGBASpan; - ctx->Driver.WriteRGBSpan =fxDDWriteRGBSpan; - ctx->Driver.WriteMonoRGBASpan =fxDDWriteMonoRGBASpan; - ctx->Driver.WriteRGBAPixels =fxDDWriteRGBAPixels; - ctx->Driver.WriteMonoRGBAPixels =fxDDWriteMonoRGBAPixels; + for (i = 0; i < n; i++, ypos += 1) { + GLuint d; + rw_fb_span(fxMesa, + GR_BUFFER_AUXBUFFER, + xpos, ypos, + 1, + sizeof(GLdepth), + &d, + FBS_READ); + stencil[i] = DEPTH_VALUE_TO_STENCIL_VALUE(d); + } +} - ctx->Driver.WriteCI8Span =NULL; - ctx->Driver.WriteCI32Span =NULL; - ctx->Driver.WriteMonoCISpan =NULL; - ctx->Driver.WriteCI32Pixels =NULL; - ctx->Driver.WriteMonoCIPixels =NULL; +/* + * Write a horizontal span of stencil values into the stencil buffer. + * If mask is NULL, write all stencil values. + * Else, only write stencil[i] if mask[i] is non-zero. + */ +void +fxDDWriteStencilSpan( GLcontext *ctx, + GLuint n, + GLint x, + GLint y, + const GLstencil stencil[], + const GLubyte mask[] ) +{ + fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx; + GLint bottom = fxMesa->height + fxMesa->y_offset - 1; + GLuint i; + int xpos = x + fxMesa->x_offset; + int ypos = bottom - y; - ctx->Driver.ReadRGBASpan =fxDDReadRGBASpan; - ctx->Driver.ReadRGBAPixels =fxDDReadRGBAPixels; + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDWriteStencilSpan(...)\n"); + } - ctx->Driver.ReadCI32Span =NULL; - ctx->Driver.ReadCI32Pixels =NULL; + for (i = 0; i < n; i++, ypos += 1) { + GLdepth d; + GLstencil ns; + rw_fb_span(fxMesa, + GR_BUFFER_AUXBUFFER, + xpos, ypos, + 1, + sizeof(GLdepth), + &d, + FBS_READ); + /* + * Find the old stencil value, and strip off the bits + * we are going to write. + */ + ns = ASSEMBLE_STENCIL_VALUE(DEPTH_VALUE_TO_STENCIL_VALUE(d), + stencil[i], + mask[i]); + /* + * Now, assemble the new StenDepth value, with the old + * depth value, the old stencil value in the bits + * where mask is 0, and the new stencil value in the bits + * where mask is 1. + */ + d = STENCIL_VALUE_TO_DEPTH_VALUE(ns, d); + rw_fb_span(fxMesa, + GR_BUFFER_AUXBUFFER, + xpos, ypos, + 1, + sizeof(GLdepth), + &d, + FBS_WRITE); + } } +/* Write an array of stencil values into the stencil buffer. + * If mask is NULL, write all stencil values. + * Else, only write stencil[i] if mask[i] is non-zero. + */ +void +fxDDReadStencilPixels( GLcontext *ctx, + GLuint n, + const GLint x[], + const GLint y[], + GLstencil stencil[]) +{ + fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx; + GLint bottom = fxMesa->height + fxMesa->y_offset - 1; + GLuint i; -#else + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDReadStencilPixels(...)\n"); + } + for (i = 0; i < n; i++) { + int xpos = x[i] + fxMesa->x_offset; + int ypos = bottom - y[i]; + GLuint d; + rw_fb_span(fxMesa, + GR_BUFFER_AUXBUFFER, + xpos, ypos, + 1, + sizeof(GLdepth), + &d, + FBS_READ); + stencil[i] = DEPTH_VALUE_TO_STENCIL_VALUE(d); + } +} /* - * Need this to provide at least one external definition. + * Read an array of stencil values from the stencil buffer. */ +void +fxDDWriteStencilPixels( GLcontext *ctx, + GLuint n, + const GLint x[], + const GLint y[], + const GLstencil stencil[], + const GLstencil mask[]) +{ + fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx; + GLint bottom = fxMesa->height + fxMesa->y_offset - 1; + GLuint i; + + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDWriteStencilPixels(...)\n"); + } + + for (i = 0; i < n; i++) { + int xpos = x[i] + fxMesa->x_offset; + int ypos = bottom - y[i]; + GLuint d; + rw_fb_span(fxMesa, + GR_BUFFER_AUXBUFFER, + xpos, ypos, + 1, + sizeof(GLdepth), + &d, + FBS_READ); + d = STENCIL_VALUE_TO_DEPTH_VALUE(stencil[i], d); + rw_fb_span(fxMesa, + GR_BUFFER_AUXBUFFER, + xpos, ypos, + 1, + sizeof(GLdepth), + &d, + FBS_WRITE); + } +} +#endif /* disable fxddStencil* funcs */ + + +#define EXTRACT_S_FROM_ZS(zs) (((zs) >> 24) & 0xFF) +#define EXTRACT_Z_FROM_ZS(zs) ((zs) & 0xffffff) +#define BUILD_ZS(z, s) (((s) << 24) | (z)) + +static void write_stencil_span(GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLstencil stencil[], + const GLubyte mask[] ) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbInfo_t info; + int s; + void *d; + + BEGIN_BOARD_LOCK(); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_WRITE_ONLY, + GR_BUFFER_AUXBUFFER, + GR_LFBWRITEMODE_Z32, + GR_ORIGIN_UPPER_LEFT, + FXFALSE, + &info)) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + const GLint scrX = winX + x; + const GLint scrY = winY - y; + + GLint dstStride = info.strideInBytes; + GLubyte *dst = (GLubyte *) info.lfbPtr + + (winY - y) * dstStride + (winX + x) * 4; + GLuint *dst32 = (GLuint *) dst; + GLubyte visMask[MAX_WIDTH]; + GLuint i; + generate_vismask(fxMesa, scrX, scrY, n, visMask); + s = dstStride; + d = dst32; + for (i = 0; i < n; i++) { + if (visMask[i] && (!mask || mask[i])) { + GLuint zs = dst32[i]; + GLuint z = EXTRACT_Z_FROM_ZS(zs); + zs = BUILD_ZS(z, stencil[i]); + dst32[i] = /*zs;*/ stencil[i]; + } + } + grLfbUnlock(GR_LFB_WRITE_ONLY, GR_BUFFER_AUXBUFFER); + } + else { + s = -1; + d = 0; + } + END_BOARD_LOCK(); + /* + printf("write stencil span %d %p\n", s, d); + printf("info: size=%d lfbPtr=%p stride=%x writeMode=%x origin=%x\n", + info.size, info.lfbPtr, info.strideInBytes, info.writeMode, info.origin); + */ +} + + +static void +read_stencil_span(GLcontext *ctx, GLuint n, GLint x, GLint y, + GLstencil stencil[]) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + GrLfbInfo_t info; + /* + int s; + void *d; + */ + + BEGIN_BOARD_LOCK(); + info.size = sizeof(info); + if (grLfbLock(GR_LFB_READ_ONLY, + GR_BUFFER_AUXBUFFER, + GR_LFBWRITEMODE_Z32, + GR_ORIGIN_UPPER_LEFT, + FXFALSE, + &info)) { + const GLint winY = fxMesa->y_offset + fxMesa->height - 1; + const GLint winX = fxMesa->x_offset; + GLint srcStride = /*info.strideInBytes;*/ 8192 ; /* XXX a hack! */ + const GLubyte *src = (const GLubyte *) info.lfbPtr + + (winY - y) * srcStride + (winX + x) * 4; + const GLuint *src32 = (const GLuint *) src; + GLuint i; + /* + s = srcStride; + d = src32; + */ + for (i = 0; i < n; i++) { + stencil[i] = EXTRACT_S_FROM_ZS(src32[i]); + } + grLfbUnlock(GR_LFB_READ_ONLY, GR_BUFFER_AUXBUFFER); + } + END_BOARD_LOCK(); + /* + printf("read stencil span %d %p\n", s, d); + printf("info: size=%d lfbPtr=%p stride=%x writeMode=%x origin=%x\n", + info.size, info.lfbPtr, info.strideInBytes, info.writeMode, info.origin); + */ +} + + +static void +write_stencil_pixels( GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + const GLstencil stencil[], const GLubyte mask[]) +{ + /* XXX optimize this */ + GLuint i; + for (i = 0; i < n; i++) { + if (mask[i]) { + write_stencil_span(ctx, 1, x[i], y[i], stencil + i, mask + i); + } + } +} -int gl_fx_dummy_function_span(void) + +static void +read_stencil_pixels(GLcontext *ctx, GLuint n, const GLint x[], const GLint y[], + GLstencil stencil[]) { - return 0; + /* XXX optimize this */ + GLuint i; + for (i = 0; i < n; i++) { + read_stencil_span(ctx, 1, x[i], y[i], stencil + i); + } } -#endif /* FX */ + + +void fxSetupDDSpanPointers(GLcontext *ctx) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (ctx->Visual->RedBits == 5 && + ctx->Visual->GreenBits == 6 && + ctx->Visual->BlueBits == 5 && + ctx->Visual->AlphaBits == 0) { + /* 16bpp mode */ + ctx->Driver.WriteRGBASpan = write_R5G6B5_rgba_span; + ctx->Driver.WriteRGBSpan = write_R5G6B5_rgb_span; + ctx->Driver.WriteMonoRGBASpan = write_R5G6B5_mono_span; + ctx->Driver.WriteRGBAPixels = write_R5G6B5_pixels; + ctx->Driver.WriteMonoRGBAPixels = write_R5G6B5_mono_pixels; + ctx->Driver.ReadRGBASpan = read_R5G6B5_span; + ctx->Driver.ReadRGBAPixels = read_R5G6B5_pixels; + } + else if (ctx->Visual->RedBits == 8 && + ctx->Visual->GreenBits == 8 && + ctx->Visual->BlueBits == 8 && + ctx->Visual->AlphaBits == 0) { + /* 24bpp mode */ + ctx->Driver.WriteRGBASpan = write_R8G8B8_rgba_span; + ctx->Driver.WriteRGBSpan = write_R8G8B8_rgb_span; + ctx->Driver.WriteMonoRGBASpan = write_R8G8B8_mono_span; + ctx->Driver.WriteRGBAPixels = write_R8G8B8_pixels; + ctx->Driver.WriteMonoRGBAPixels = write_R8G8B8_mono_pixels; + ctx->Driver.ReadRGBASpan = read_R8G8B8_span; + ctx->Driver.ReadRGBAPixels = read_R8G8B8_pixels; + } + else if (ctx->Visual->RedBits == 8 && + ctx->Visual->GreenBits == 8 && + ctx->Visual->BlueBits == 8 && + ctx->Visual->AlphaBits == 8) { + /* 32bpp mode */ + ctx->Driver.WriteRGBASpan = write_R8G8B8A8_rgba_span; + ctx->Driver.WriteRGBSpan = write_R8G8B8A8_rgb_span; + ctx->Driver.WriteMonoRGBASpan = write_R8G8B8A8_mono_span; + ctx->Driver.WriteRGBAPixels = write_R8G8B8A8_pixels; + ctx->Driver.WriteMonoRGBAPixels = write_R8G8B8A8_mono_pixels; + ctx->Driver.ReadRGBASpan = read_R8G8B8A8_span; + ctx->Driver.ReadRGBAPixels = read_R8G8B8A8_pixels; + } + else { + abort(); + } + + if (fxMesa->haveHwStencil) { + ctx->Driver.WriteStencilSpan = write_stencil_span; + ctx->Driver.ReadStencilSpan = read_stencil_span; + ctx->Driver.WriteStencilPixels = write_stencil_pixels; + ctx->Driver.ReadStencilPixels = read_stencil_pixels; + } + + ctx->Driver.WriteCI8Span = NULL; + ctx->Driver.WriteCI32Span = NULL; + ctx->Driver.WriteMonoCISpan = NULL; + ctx->Driver.WriteCI32Pixels = NULL; + ctx->Driver.WriteMonoCIPixels = NULL; + ctx->Driver.ReadCI32Span = NULL; + ctx->Driver.ReadCI32Pixels = NULL; +} diff --git a/xc/extras/Mesa/src/FX/fxddtex.c b/xc/extras/Mesa/src/FX/fxddtex.c index 71d1e97ad..69ceebaa9 100644 --- a/xc/extras/Mesa/src/FX/fxddtex.c +++ b/xc/extras/Mesa/src/FX/fxddtex.c @@ -50,6 +50,9 @@ #if defined(FX) #include "fxdrv.h" +#include "image.h" +#include "texutil.h" + void fxPrintTextureData(tfxTexInfo *ti) { @@ -63,17 +66,18 @@ void fxPrintTextureData(tfxTexInfo *ti) } else fprintf(stderr, "\tName: UNNAMED\n"); fprintf(stderr, "\tLast used: %d\n", ti->lastTimeUsed); - fprintf(stderr, "\tTMU: %d\n", ti->whichTMU); + fprintf(stderr, "\tTMU: %ld\n", ti->whichTMU); fprintf(stderr, "\t%s\n", (ti->isInTM)?"In TMU":"Not in TMU"); if (ti->tm[0]) - fprintf(stderr, "\tMem0: %x-%x\n", ti->tm[0]->startAddr, - ti->tm[0]->endAddr); + fprintf(stderr, "\tMem0: %x-%x\n", (unsigned) ti->tm[0]->startAddr, + (unsigned) ti->tm[0]->endAddr); if (ti->tm[1]) - fprintf(stderr, "\tMem1: %x-%x\n", ti->tm[1]->startAddr, - ti->tm[1]->endAddr); + fprintf(stderr, "\tMem1: %x-%x\n", (unsigned) ti->tm[1]->startAddr, + (unsigned) ti->tm[1]->endAddr); fprintf(stderr, "\tMipmaps: %d-%d\n", ti->minLevel, ti->maxLevel); - fprintf(stderr, "\tFilters: min %d min %d\n", ti->minFilt, ti->maxFilt); - fprintf(stderr, "\tClamps: s %d t %d\n", ti->sClamp, ti->tClamp); + fprintf(stderr, "\tFilters: min %d min %d\n", + (int) ti->minFilt, (int) ti->maxFilt); + fprintf(stderr, "\tClamps: s %d t %d\n", (int) ti->sClamp, (int) ti->tClamp); fprintf(stderr, "\tScales: s %f t %f\n", ti->sScale, ti->tScale); fprintf(stderr, "\tInt Scales: s %d t %d\n", ti->int_sScale/0x800000, ti->int_tScale/0x800000); @@ -86,14 +90,14 @@ void fxPrintTextureData(tfxTexInfo *ti) /*************************** Texture Mapping ****************************/ /************************************************************************/ -void fxTexInvalidate(GLcontext *ctx, struct gl_texture_object *tObj) +static void fxTexInvalidate(GLcontext *ctx, struct gl_texture_object *tObj) { fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; tfxTexInfo *ti; - fxTMMoveOutTM(fxMesa,tObj); /* TO DO: SLOW but easy to write */ - ti=fxTMGetTexInfo(tObj); + if (ti->isInTM) fxTMMoveOutTM(fxMesa,tObj); /* TO DO: SLOW but easy to write */ + ti->validated=GL_FALSE; fxMesa->new_state|=FX_NEW_TEXTURING; ctx->Driver.RenderStart = fxSetupFXUnits; @@ -128,7 +132,6 @@ static tfxTexInfo *fxAllocTexObjData(fxMesaContext fxMesa) ti->LODblend=FXFALSE; for(i=0;i<MAX_TEXTURE_LEVELS;i++) { - ti->mipmapLevel[i].used=GL_FALSE; ti->mipmapLevel[i].data=NULL; } @@ -160,7 +163,7 @@ void fxDDTexBind(GLcontext *ctx, GLenum target, struct gl_texture_object *tObj) ctx->Driver.RenderStart = fxSetupFXUnits; } -void fxDDTexEnv(GLcontext *ctx, GLenum pname, const GLfloat *param) +void fxDDTexEnv(GLcontext *ctx, GLenum target, GLenum pname, const GLfloat *param) { fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; @@ -171,6 +174,16 @@ void fxDDTexEnv(GLcontext *ctx, GLenum pname, const GLfloat *param) fprintf(stderr,"fxmesa: texenv(%x)\n",pname); } + /* apply any lod biasing right now */ + if (pname==GL_TEXTURE_LOD_BIAS_EXT) { + FX_grTexLodBiasValue(GR_TMU0,*param); + + if(fxMesa->haveTwoTMUs) { + FX_grTexLodBiasValue(GR_TMU1,*param); + } + + } + fxMesa->new_state|=FX_NEW_TEXTURING; ctx->Driver.RenderStart = fxSetupFXUnits; } @@ -312,124 +325,154 @@ void fxDDTexParam(GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, void fxDDTexDel(GLcontext *ctx, struct gl_texture_object *tObj) { - fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; - tfxTexInfo *ti=fxTMGetTexInfo(tObj); + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxTexInfo *ti = fxTMGetTexInfo(tObj); - if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxDDTexDel(%d,%x)\n",tObj->Name,(GLuint)ti); + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDTexDel(%d,%p)\n", tObj->Name, ti); } - if(!ti) + if (!ti) return; - fxTMFreeTexture(fxMesa,tObj); + fxTMFreeTexture(fxMesa, tObj); FREE(ti); - tObj->DriverData=NULL; + tObj->DriverData = NULL; - ctx->NewState|=NEW_TEXTURING; + ctx->NewState |= NEW_TEXTURING; } -void fxDDTexPalette(GLcontext *ctx, struct gl_texture_object *tObj) -{ - fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; - int i; - FxU32 r,g,b,a; - tfxTexInfo *ti; - if(tObj) { - if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxDDTexPalette(%d,%x)\n",tObj->Name,(GLuint)tObj->DriverData); - } - if(tObj->Palette.Format!=GL_RGBA) { -#ifndef FX_SILENT - fprintf(stderr,"fx Driver: unsupported palette format in texpalette()\n"); -#endif - return; - } - - if(tObj->Palette.Size>256) { -#ifndef FX_SILENT - fprintf(stderr,"fx Driver: unsupported palette size in texpalette()\n"); -#endif - return; - } - - if (!tObj->DriverData) - tObj->DriverData=fxAllocTexObjData(fxMesa); - - ti=fxTMGetTexInfo(tObj); - - for(i=0;i<tObj->Palette.Size;i++) { - r=tObj->Palette.Table[i*4]; - g=tObj->Palette.Table[i*4+1]; - b=tObj->Palette.Table[i*4+2]; - a=tObj->Palette.Table[i*4+3]; - ti->palette.data[i]=(a<<24)|(r<<16)|(g<<8)|b; - } +/* + * Convert a gl_color_table texture palette to Glide's format. + */ +static void +convertPalette(FxU32 data[256], const struct gl_color_table *table) +{ + const GLubyte *tableUB = (const GLubyte *) table->Table; + GLint width = table->Size; + FxU32 r, g, b, a; + GLint i; + + ASSERT(table->TableType == GL_UNSIGNED_BYTE); + + switch (table->Format) { + case GL_INTENSITY: + for (i = 0; i < width; i++) { + r = tableUB[i]; + g = tableUB[i]; + b = tableUB[i]; + a = tableUB[i]; + data[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + break; + case GL_LUMINANCE: + for (i = 0; i < width; i++) { + r = tableUB[i]; + g = tableUB[i]; + b = tableUB[i]; + a = 255; + data[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + break; + case GL_ALPHA: + for (i = 0; i < width; i++) { + r = g = b = 255; + a = tableUB[i]; + data[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + break; + case GL_LUMINANCE_ALPHA: + for (i = 0; i < width; i++) { + r = g = b = tableUB[i*2+0]; + a = tableUB[i*2+1]; + data[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + break; + case GL_RGB: + for (i = 0; i < width; i++) { + r = tableUB[i*3+0]; + g = tableUB[i*3+1]; + b = tableUB[i*3+2]; + a = 255; + data[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + break; + case GL_RGBA: + for (i = 0; i < width; i++) { + r = tableUB[i*4+0]; + g = tableUB[i*4+1]; + b = tableUB[i*4+2]; + a = tableUB[i*4+3]; + data[i] = (a << 24) | (r << 16) | (g << 8) | b; + } + break; + } +} - fxTexInvalidate(ctx,tObj); - } else { - if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxDDTexPalette(global)\n"); - } - if(ctx->Texture.Palette.Format!=GL_RGBA) { -#ifndef FX_SILENT - fprintf(stderr,"fx Driver: unsupported palette format in texpalette()\n"); -#endif - return; - } - if(ctx->Texture.Palette.Size>256) { -#ifndef FX_SILENT - fprintf(stderr,"fx Driver: unsupported palette size in texpalette()\n"); -#endif - return; +void fxDDTexPalette(GLcontext *ctx, struct gl_texture_object *tObj) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + + if (tObj) { + /* per-texture palette */ + tfxTexInfo *ti; + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDTexPalette(%d,%x)\n", + tObj->Name, (GLuint) tObj->DriverData); } - - for(i=0;i<ctx->Texture.Palette.Size;i++) { - r=ctx->Texture.Palette.Table[i*4]; - g=ctx->Texture.Palette.Table[i*4+1]; - b=ctx->Texture.Palette.Table[i*4+2]; - a=ctx->Texture.Palette.Table[i*4+3]; - fxMesa->glbPalette.data[i]=(a<<24)|(r<<16)|(g<<8)|b; + if (!tObj->DriverData) + tObj->DriverData = fxAllocTexObjData(fxMesa); + ti = fxTMGetTexInfo(tObj); + convertPalette(ti->palette.data, &tObj->Palette); + fxTexInvalidate(ctx, tObj); + } + else { + /* global texture palette */ + if (MESA_VERBOSE & VERBOSE_DRIVER) { + fprintf(stderr, "fxmesa: fxDDTexPalette(global)\n"); } - - fxMesa->new_state|=FX_NEW_TEXTURING; + convertPalette(fxMesa->glbPalette.data, &ctx->Texture.Palette); + fxMesa->new_state |= FX_NEW_TEXTURING; ctx->Driver.RenderStart = fxSetupFXUnits; } } + void fxDDTexUseGlbPalette(GLcontext *ctx, GLboolean state) { - fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; + fxMesaContext fxMesa = FX_CONTEXT(ctx); if (MESA_VERBOSE&VERBOSE_DRIVER) { fprintf(stderr,"fxmesa: fxDDTexUseGlbPalette(%d)\n",state); } - if(state) { - fxMesa->haveGlobalPaletteTexture=1; + if (state) { + fxMesa->haveGlobalPaletteTexture = 1; - FX_grTexDownloadTable(GR_TMU0,GR_TEXTABLE_PALETTE,&(fxMesa->glbPalette)); + FX_grTexDownloadTable(GR_TMU0,GR_TEXTABLE_PALETTE, &(fxMesa->glbPalette)); if (fxMesa->haveTwoTMUs) - FX_grTexDownloadTable(GR_TMU1,GR_TEXTABLE_PALETTE,&(fxMesa->glbPalette)); - } else { - fxMesa->haveGlobalPaletteTexture=0; + FX_grTexDownloadTable(GR_TMU1, GR_TEXTABLE_PALETTE, &(fxMesa->glbPalette)); + } + else { + fxMesa->haveGlobalPaletteTexture = 0; - if((ctx->Texture.Unit[0].Current==ctx->Texture.Unit[0].CurrentD[2]) && - (ctx->Texture.Unit[0].Current!=NULL)) { - struct gl_texture_object *tObj=ctx->Texture.Unit[0].Current; + if ((ctx->Texture.Unit[0].Current == ctx->Texture.Unit[0].CurrentD[2]) && + (ctx->Texture.Unit[0].Current != NULL)) { + struct gl_texture_object *tObj = ctx->Texture.Unit[0].Current; if (!tObj->DriverData) - tObj->DriverData=fxAllocTexObjData(fxMesa); + tObj->DriverData = fxAllocTexObjData(fxMesa); - fxTexInvalidate(ctx,tObj); + fxTexInvalidate(ctx, tObj); } } } + static int logbase2(int n) { GLint i = 1; @@ -453,209 +496,68 @@ static int logbase2(int n) /* Need different versions for different cpus. */ -#define INT_TRICK(l2) (0x800000 * l2) - - -int fxTexGetInfo(int w, int h, GrLOD_t *lodlevel, GrAspectRatio_t *ar, +#define INT_TRICK(l2) (0x800000 * (l2)) +int fxTexGetInfo(int w, int h, GrLOD_t *lodlevel, + GrAspectRatio_t *aspectratio, float *sscale, float *tscale, int *i_sscale, int *i_tscale, int *wscale, int *hscale) { - - static GrLOD_t lod[9]={GR_LOD_256,GR_LOD_128,GR_LOD_64,GR_LOD_32, - GR_LOD_16,GR_LOD_8,GR_LOD_4,GR_LOD_2,GR_LOD_1}; - - int logw,logh,ws,hs; - GrLOD_t l; - GrAspectRatio_t aspectratio; - float s,t; - int is,it; + int logw, logh, ar, l, is, it, ws, hs; + float s, t; logw=logbase2(w); logh=logbase2(h); - - switch(logw-logh) { - case 0: - aspectratio=GR_ASPECT_1x1; - l=lod[8-logw]; - s=t=256.0f; - is=it=INT_TRICK(8); - ws=hs=1; - break; - case 1: - aspectratio=GR_ASPECT_2x1; - l=lod[8-logw]; - s=256.0f; - t=128.0f; - is=INT_TRICK(8);it=INT_TRICK(7); - ws=1; - hs=1; - break; - case 2: - aspectratio=GR_ASPECT_4x1; - l=lod[8-logw]; - s=256.0f; - t=64.0f; - is=INT_TRICK(8);it=INT_TRICK(6); - ws=1; - hs=1; - break; - case 3: - aspectratio=GR_ASPECT_8x1; - l=lod[8-logw]; - s=256.0f; - t=32.0f; - is=INT_TRICK(8);it=INT_TRICK(5); - ws=1; - hs=1; - break; - case 4: - aspectratio=GR_ASPECT_8x1; - l=lod[8-logw]; - s=256.0f; - t=32.0f; - is=INT_TRICK(8);it=INT_TRICK(5); - ws=1; - hs=2; - break; - case 5: - aspectratio=GR_ASPECT_8x1; - l=lod[8-logw]; - s=256.0f; - t=32.0f; - is=INT_TRICK(8);it=INT_TRICK(5); + ar=logw-logh; + /* Hardware only allows a maximum aspect ratio of 8x1, so handle + |ar|>3 by scaling the image and using an 8x1 aspect ratio */ + if (ar>=0) { + l=logw; + s=256.0; + is=INT_TRICK(8); ws=1; - hs=4; - break; - case 6: - aspectratio=GR_ASPECT_8x1; - l=lod[8-logw]; - s=256.0f; - t=32.0f; - is=INT_TRICK(8);it=INT_TRICK(5); - ws=1; - hs=8; - break; - case 7: - aspectratio=GR_ASPECT_8x1; - l=lod[8-logw]; - s=256.0f; - t=32.0f; - is=INT_TRICK(8);it=INT_TRICK(5); - ws=1; - hs=16; - break; - case 8: - aspectratio=GR_ASPECT_8x1; - l=lod[8-logw]; - s=256.0f; - t=32.0f; - is=INT_TRICK(8);it=INT_TRICK(5); - ws=1; - hs=32; - break; - case -1: - aspectratio=GR_ASPECT_1x2; - l=lod[8-logh]; - s=128.0f; - t=256.0f; - is=INT_TRICK(7);it=INT_TRICK(8); - ws=1; - hs=1; - break; - case -2: - aspectratio=GR_ASPECT_1x4; - l=lod[8-logh]; - s=64.0f; - t=256.0f; - is=INT_TRICK(6);it=INT_TRICK(8); - ws=1; - hs=1; - break; - case -3: - aspectratio=GR_ASPECT_1x8; - l=lod[8-logh]; - s=32.0f; - t=256.0f; - is=INT_TRICK(5);it=INT_TRICK(8); - ws=1; - hs=1; - break; - case -4: - aspectratio=GR_ASPECT_1x8; - l=lod[8-logh]; - s=32.0f; - t=256.0f; - is=INT_TRICK(5);it=INT_TRICK(8); - ws=2; - hs=1; - break; - case -5: - aspectratio=GR_ASPECT_1x8; - l=lod[8-logh]; - s=32.0f; - t=256.0f; - is=INT_TRICK(5);it=INT_TRICK(8); - ws=4; - hs=1; - break; - case -6: - aspectratio=GR_ASPECT_1x8; - l=lod[8-logh]; - s=32.0f; - t=256.0f; - is=INT_TRICK(5);it=INT_TRICK(8); - ws=8; - hs=1; - break; - case -7: - aspectratio=GR_ASPECT_1x8; - l=lod[8-logh]; - s=32.0f; - t=256.0f; - is=INT_TRICK(5);it=INT_TRICK(8); - ws=16; - hs=1; - break; - case -8: - aspectratio=GR_ASPECT_1x8; - l=lod[8-logh]; - s=32.0f; - t=256.0f; - is=INT_TRICK(5);it=INT_TRICK(8); - ws=32; + if (ar<3) { + t=256>>ar; + it=INT_TRICK(8-ar); + hs=1; + } else { + t=32.0; + it=INT_TRICK(5); + hs=1<<(ar-3); + } + } else { + l=logh; + t=256.0; + it=INT_TRICK(8); hs=1; - break; - default: - return 0; - break; + if (-ar<3) { + s=256>>-ar; + is=INT_TRICK(8+ar); + ws=1; + } else { + s=32.0; + is=INT_TRICK(5); + ws=1<<(-ar-3); + } } - - if(lodlevel) - (*lodlevel)=l; - - if(ar) - (*ar)=aspectratio; - - if(sscale) - (*sscale)=s; - - if(tscale) - (*tscale)=t; - - if(wscale) - (*wscale)=ws; - - if(hscale) - (*hscale)=hs; - - if (i_sscale) - *i_sscale = is; - - if (i_tscale) - *i_tscale = it; - - + if (ar<-3) ar=-3; + if (ar>3) ar=3; + + /* The above numbers are calculated sensibly and work for Glide3, but + we change them to the whacky glide2 values if needed. */ +#ifdef FX_GLIDE3 + if (lodlevel) *lodlevel=l; + if (aspectratio) *aspectratio=ar; +#else + if (lodlevel) *lodlevel=8-l; + if (aspectratio) *aspectratio=3-ar; +#endif + if (sscale) *sscale=s; + if (tscale) *tscale=t; + if (wscale) *wscale=ws; + if (hscale) *hscale=hs; + if (i_sscale) *i_sscale = is; + if (i_tscale) *i_tscale = it; return 1; } @@ -666,752 +568,506 @@ int fxTexGetInfo(int w, int h, GrLOD_t *lodlevel, GrAspectRatio_t *ar, void fxTexGetFormat(GLenum glformat, GrTextureFormat_t *tfmt, GLint *ifmt) { switch(glformat) { - case 1: - case GL_LUMINANCE: - case GL_LUMINANCE4: - case GL_LUMINANCE8: - case GL_LUMINANCE12: - case GL_LUMINANCE16: - if(tfmt) - (*tfmt)=GR_TEXFMT_INTENSITY_8; - if(ifmt) - (*ifmt)=GL_LUMINANCE; - break; - case 2: - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE4_ALPHA4: - case GL_LUMINANCE6_ALPHA2: - case GL_LUMINANCE8_ALPHA8: - case GL_LUMINANCE12_ALPHA4: - case GL_LUMINANCE12_ALPHA12: - case GL_LUMINANCE16_ALPHA16: - if(tfmt) - (*tfmt)=GR_TEXFMT_ALPHA_INTENSITY_88; - if(ifmt) - (*ifmt)=GL_LUMINANCE_ALPHA; - break; - case GL_INTENSITY: - case GL_INTENSITY4: - case GL_INTENSITY8: - case GL_INTENSITY12: - case GL_INTENSITY16: - if(tfmt) - (*tfmt)=GR_TEXFMT_ALPHA_8; - if(ifmt) - (*ifmt)=GL_INTENSITY; - break; - case GL_ALPHA: - case GL_ALPHA4: - case GL_ALPHA8: - case GL_ALPHA12: - case GL_ALPHA16: - if(tfmt) - (*tfmt)=GR_TEXFMT_ALPHA_8; - if(ifmt) - (*ifmt)=GL_ALPHA; - break; - case 3: - case GL_RGB: - case GL_R3_G3_B2: - case GL_RGB4: - case GL_RGB5: - case GL_RGB8: - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: - if(tfmt) - (*tfmt)=GR_TEXFMT_RGB_565; - if(ifmt) - (*ifmt)=GL_RGB; - break; - case 4: - case GL_RGBA: - case GL_RGBA2: - case GL_RGBA4: - case GL_RGBA8: - case GL_RGB10_A2: - case GL_RGBA12: - case GL_RGBA16: - if(tfmt) - (*tfmt)=GR_TEXFMT_ARGB_4444; - if(ifmt) - (*ifmt)=GL_RGBA; - break; - case GL_RGB5_A1: - if(tfmt) - (*tfmt)=GR_TEXFMT_ARGB_1555; - if(ifmt) - (*ifmt)=GL_RGBA; - break; - case GL_COLOR_INDEX: - case GL_COLOR_INDEX1_EXT: - case GL_COLOR_INDEX2_EXT: - case GL_COLOR_INDEX4_EXT: - case GL_COLOR_INDEX8_EXT: - case GL_COLOR_INDEX12_EXT: - case GL_COLOR_INDEX16_EXT: - if(tfmt) - (*tfmt)=GR_TEXFMT_P_8; - if(ifmt) - (*ifmt)=GL_RGBA; - break; - default: - fprintf(stderr,"fx Driver: unsupported internalFormat in fxTexGetFormat()\n"); - fxCloseHardware(); - exit(-1); - break; + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + if(tfmt) + (*tfmt)=GR_TEXFMT_INTENSITY_8; + if(ifmt) + (*ifmt)=GL_LUMINANCE; + break; + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + if(tfmt) + (*tfmt)=GR_TEXFMT_ALPHA_INTENSITY_88; + if(ifmt) + (*ifmt)=GL_LUMINANCE_ALPHA; + break; + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + if(tfmt) + (*tfmt)=GR_TEXFMT_ALPHA_8; + if(ifmt) + (*ifmt)=GL_INTENSITY; + break; + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + if(tfmt) + (*tfmt)=GR_TEXFMT_ALPHA_8; + if(ifmt) + (*ifmt)=GL_ALPHA; + break; + case 3: + case GL_RGB: + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + if(tfmt) + (*tfmt)=GR_TEXFMT_RGB_565; + if(ifmt) + (*ifmt)=GL_RGB; + break; + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + if(tfmt) + (*tfmt)=GR_TEXFMT_ARGB_8888; + if(ifmt) + (*ifmt)=GL_RGB; + break; + case 4: + case GL_RGBA: + case GL_RGBA2: + case GL_RGBA4: + if(tfmt) + (*tfmt)=GR_TEXFMT_ARGB_4444; + if(ifmt) + (*ifmt)=GL_RGBA; + break; + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + if(tfmt) + (*tfmt)=GR_TEXFMT_ARGB_8888; + if(ifmt) + (*ifmt)=GL_RGBA; + break; + case GL_RGB5_A1: + if(tfmt) + (*tfmt)=GR_TEXFMT_ARGB_1555; + if(ifmt) + (*ifmt)=GL_RGBA; + break; + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX8_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + if(tfmt) + (*tfmt)=GR_TEXFMT_P_8; + if(ifmt) + (*ifmt)=GL_RGBA; /* XXX why is this RGBA? */ + break; + default: + fprintf(stderr, + "fx Driver: unsupported internalFormat in fxTexGetFormat()\n"); + fxCloseHardware(); + exit(-1); + break; } } -static int fxIsTexSupported(GLenum target, GLint internalFormat, - const struct gl_texture_image *image) +static GLboolean fxIsTexSupported(GLenum target, GLint internalFormat, + const struct gl_texture_image *image) { - if(target!=GL_TEXTURE_2D) - return GL_FALSE; - - switch(internalFormat) { - case GL_INTENSITY: - case GL_INTENSITY4: - case GL_INTENSITY8: - case GL_INTENSITY12: - case GL_INTENSITY16: - case 1: - case GL_LUMINANCE: - case GL_LUMINANCE4: - case GL_LUMINANCE8: - case GL_LUMINANCE12: - case GL_LUMINANCE16: - case 2: - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE4_ALPHA4: - case GL_LUMINANCE6_ALPHA2: - case GL_LUMINANCE8_ALPHA8: - case GL_LUMINANCE12_ALPHA4: - case GL_LUMINANCE12_ALPHA12: - case GL_LUMINANCE16_ALPHA16: - case GL_ALPHA: - case GL_ALPHA4: - case GL_ALPHA8: - case GL_ALPHA12: - case GL_ALPHA16: - case 3: - case GL_RGB: - case GL_R3_G3_B2: - case GL_RGB4: - case GL_RGB5: - case GL_RGB8: - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: - case 4: - case GL_RGBA: - case GL_RGBA2: - case GL_RGBA4: - case GL_RGB5_A1: - case GL_RGBA8: - case GL_RGB10_A2: - case GL_RGBA12: - case GL_RGBA16: - case GL_COLOR_INDEX: - case GL_COLOR_INDEX1_EXT: - case GL_COLOR_INDEX2_EXT: - case GL_COLOR_INDEX4_EXT: - case GL_COLOR_INDEX8_EXT: - case GL_COLOR_INDEX12_EXT: - case GL_COLOR_INDEX16_EXT: - break; - default: - return GL_FALSE; - } - - if(image->Width>256) - return GL_FALSE; - - if(image->Height>256) + if(target != GL_TEXTURE_2D) return GL_FALSE; if(!fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL)) return GL_FALSE; + if (image->Border > 0) + return GL_FALSE; + return GL_TRUE; } -static void fxTexBuildImageMap(const struct gl_texture_image *image, - GLint internalFormat, unsigned short **dest, - GLboolean *istranslate) -{ - unsigned short *src; - unsigned char *data; - int x,y,w,h,wscale,hscale,idx; - - fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL, - &wscale,&hscale); - w=image->Width*wscale; - h=image->Height*hscale; - - data=image->Data; - switch(internalFormat) { - case GL_INTENSITY: - case GL_INTENSITY4: - case GL_INTENSITY8: - case GL_INTENSITY12: - case GL_INTENSITY16: - case 1: - case GL_LUMINANCE: - case GL_LUMINANCE4: - case GL_LUMINANCE8: - case GL_LUMINANCE12: - case GL_LUMINANCE16: - case GL_ALPHA: - case GL_ALPHA4: - case GL_ALPHA8: - case GL_ALPHA12: - case GL_ALPHA16: - case GL_COLOR_INDEX: - case GL_COLOR_INDEX1_EXT: - case GL_COLOR_INDEX2_EXT: - case GL_COLOR_INDEX4_EXT: - case GL_COLOR_INDEX8_EXT: - case GL_COLOR_INDEX12_EXT: - case GL_COLOR_INDEX16_EXT: - /* Optimized for GLQuake */ - - if(wscale==hscale==1) { - (*istranslate)=GL_FALSE; - - (*dest)=(unsigned short *)data; - } else { - unsigned char *srcb; - - (*istranslate)=GL_TRUE; - - if(!(*dest)) { - if(!((*dest)=src=(unsigned short *)MALLOC(sizeof(unsigned char)*w*h))) { - fprintf(stderr,"fx Driver: out of memory !\n"); - fxCloseHardware(); - exit(-1); - } - } else - src=(*dest); - - srcb=(unsigned char *)src; - - for(y=0;y<h;y++) - for(x=0;x<w;x++) { - idx=(x/wscale+(y/hscale)*(w/wscale)); - srcb[x+y*w]=data[idx]; - } - } - break; - case 2: - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE4_ALPHA4: - case GL_LUMINANCE6_ALPHA2: - case GL_LUMINANCE8_ALPHA8: - case GL_LUMINANCE12_ALPHA4: - case GL_LUMINANCE12_ALPHA12: - case GL_LUMINANCE16_ALPHA16: - (*istranslate)=GL_TRUE; - - if(!(*dest)) { - if(!((*dest)=src=(unsigned short *)MALLOC(sizeof(unsigned short)*w*h))) { - fprintf(stderr,"fx Driver: out of memory !\n"); - fxCloseHardware(); - exit(-1); - } - } else - src=(*dest); - - if(wscale==hscale==1) { - int i=0; - int lenght=h*w; - unsigned short a,l; - - while(i++<lenght) { - l=*data++; - a=*data++; - - *src++=(a << 8) | l; - } - } else { - unsigned short a,l; - for(y=0;y<h;y++) - for(x=0;x<w;x++) { - idx=(x/wscale+(y/hscale)*(w/wscale))*2; - l=data[idx]; - a=data[idx+1]; - - src[x+y*w]=(a << 8) | l; - } - } - break; - case 3: - case GL_RGB: - case GL_R3_G3_B2: - case GL_RGB4: - case GL_RGB5: - case GL_RGB8: - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: - (*istranslate)=GL_TRUE; - - if(!(*dest)) { - if(!((*dest)=src=(unsigned short *)MALLOC(sizeof(unsigned short)*w*h))) { - fprintf(stderr,"fx Driver: out of memory !\n"); - fxCloseHardware(); - exit(-1); - } - } else - src=(*dest); - - if(wscale==hscale==1) { - int i=0; - int lenght=h*w; - unsigned int r,g,b; - - while(i++<lenght) { - r=*data++; - g=*data++; - b=*data++; - - *src++=((0xf8 & r) << (11-3)) | - ((0xfc & g) << (5-3+1)) | - ((0xf8 & b) >> 3); - } - } else { - unsigned int r,g,b; - - for(y=0;y<h;y++) - for(x=0;x<w;x++) { - idx=(x/wscale+(y/hscale)*(w/wscale))*3; - r=data[idx]; - g=data[idx+1]; - b=data[idx+2]; - - src[x+y*w]=((0xf8 & r) << (11-3)) | - ((0xfc & g) << (5-3+1)) | - ((0xf8 & b) >> 3); - } - } - break; - case 4: - case GL_RGBA: - case GL_RGBA2: - case GL_RGBA4: - case GL_RGBA8: - case GL_RGB10_A2: - case GL_RGBA12: - case GL_RGBA16: - (*istranslate)=GL_TRUE; - - if(!(*dest)) { - if(!((*dest)=src=(unsigned short *)MALLOC(sizeof(unsigned short)*w*h))) { - fprintf(stderr,"fx Driver: out of memory !\n"); - fxCloseHardware(); - exit(-1); - } - } else - src=(*dest); - - if(wscale==hscale==1) { - int i=0; - int lenght=h*w; - unsigned int r,g,b,a; - - while(i++<lenght) { - r=*data++; - g=*data++; - b=*data++; - a=*data++; - - *src++=((0xf0 & a) << 8) | - ((0xf0 & r) << 4) | - (0xf0 & g) | - ((0xf0 & b) >> 4); - } - } else { - unsigned int r,g,b,a; - - for(y=0;y<h;y++) - for(x=0;x<w;x++) { - idx=(x/wscale+(y/hscale)*(w/wscale))*4; - r=data[idx]; - g=data[idx+1]; - b=data[idx+2]; - a=data[idx+3]; - - src[x+y*w]=((0xf0 & a) << 8) | - ((0xf0 & r) << 4) | - (0xf0 & g) | - ((0xf0 & b) >> 4); - } - } - break; - case GL_RGB5_A1: - (*istranslate)=GL_TRUE; - - if(!(*dest)) { - if(!((*dest)=src=(unsigned short *)malloc(sizeof(unsigned short)*w*h))) { - fprintf(stderr,"fx Driver: out of memory !\n"); - fxCloseHardware(); - exit(-1); - } - } else - src=(*dest); - - if(wscale==hscale==1) { - int i=0; - int lenght=h*w; - unsigned r,g,b,a; - - while(i++<lenght) { - r=*data++; - g=*data++; - b=*data++; - a=*data++; - *src++=((0x80 & a) << 8) | - ((0xf8 & r) << 7) | - ((0xf8 & g) << 2) | - ((0xf8 & b) >> 3); - } - } else { - unsigned r,g,b,a; - - for(y=0;y<h;y++) - for(x=0;x<w;x++) { - idx=(x/wscale+(y/hscale)*(w/wscale))*4; - r=data[idx]; - g=data[idx+1]; - b=data[idx+2]; - a=data[idx+3]; - - src[x+y*w]=((0x80 & a) << 8) | - ((0xf8 & r) << 7) | - ((0xf8 & g) << 2) | - ((0xf8 & b) >> 3); - } - } - break; - default: - fprintf(stderr,"fx Driver: wrong internalFormat in texbuildimagemap()\n"); - fxCloseHardware(); - exit(-1); - break; - } -} +/**********************************************************************/ +/**** NEW TEXTURE IMAGE FUNCTIONS ****/ +/**********************************************************************/ -void fxDDTexImg(GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, GLint level, GLint internalFormat, - const struct gl_texture_image *image) +GLboolean fxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLboolean *retainInternalCopy) { - fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; - tfxTexInfo *ti; + fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx; - if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr, - "fxmesa: (%d) fxDDTexImg(...,level=%d,target=%d,format=%x,width=%d,height=%d...)\n", - tObj->Name, level, target, internalFormat, image->Width, - image->Height); - } - - if(target!=GL_TEXTURE_2D) - return; + if (target != GL_TEXTURE_2D) + return GL_FALSE; - if (!tObj->DriverData) - tObj->DriverData=fxAllocTexObjData(fxMesa); + if (!texObj->DriverData) + texObj->DriverData = fxAllocTexObjData(fxMesa); - ti=fxTMGetTexInfo(tObj); - - if(fxIsTexSupported(target,internalFormat,image)) { + if (fxIsTexSupported(target, texImage->IntFormat, texImage)) { GrTextureFormat_t gldformat; - tfxMipMapLevel *mml=&ti->mipmapLevel[level]; + tfxTexInfo *ti = fxTMGetTexInfo(texObj); + tfxMipMapLevel *mml = &ti->mipmapLevel[level]; + GLint dstWidth, dstHeight, wScale, hScale, texelSize, dstStride; + MesaIntTexFormat intFormat; + + fxTexGetFormat(texImage->IntFormat, &gldformat, NULL); - fxTexGetFormat(internalFormat,&gldformat,NULL); + fxTexGetInfo(texImage->Width, texImage->Height, NULL,NULL,NULL,NULL, + NULL,NULL, &wScale, &hScale); - if(mml->used) { - if((mml->glideFormat==gldformat) && - (mml->width==image->Width) && - (mml->height==image->Height)) { - fxTexBuildImageMap(image,internalFormat,&(mml->data), - &(mml->translated)); - - if(ti->validated && ti->isInTM) - fxTMReloadMipMapLevel(fxMesa,tObj,level); - else - fxTexInvalidate(ctx,tObj); - - return; - } else { - if(mml->translated) - FREE(mml->data); - mml->data=NULL; - } + dstWidth = texImage->Width * wScale; + dstHeight = texImage->Height * hScale; + + switch (texImage->IntFormat) { + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + texelSize = 1; + intFormat = MESA_I8; + break; + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + texelSize = 1; + intFormat = MESA_L8; + break; + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + texelSize = 1; + intFormat = MESA_A8; + break; + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX8_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + texelSize = 1; + intFormat = MESA_C8; + break; + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + texelSize = 2; + intFormat = MESA_A8_L8; + break; + case 3: + case GL_RGB: + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + texelSize = 2; + intFormat = MESA_R5_G6_B5; + break; + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + texelSize = 4; + intFormat = MESA_A8_R8_G8_B8; + break; + case 4: + case GL_RGBA: + case GL_RGBA2: + case GL_RGBA4: + texelSize = 2; + intFormat = MESA_A4_R4_G4_B4; + break; + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + texelSize = 4; + intFormat = MESA_A8_R8_G8_B8; + break; + case GL_RGB5_A1: + texelSize = 2; + intFormat = MESA_A1_R5_G5_B5; + break; + default: + gl_problem(NULL, "tdfx driver: texbuildimagemap() bad format"); + return GL_FALSE; } - mml->glideFormat=gldformat; - mml->width=image->Width; - mml->height=image->Height; - mml->used=GL_TRUE; - - fxTexBuildImageMap(image,internalFormat,&(mml->data), - &(mml->translated)); + _mesa_set_teximage_component_sizes(intFormat, texImage); + + /*printf("teximage:\n");*/ + /* allocate new storage for texture image, if needed */ + if (!mml->data || mml->glideFormat != gldformat || + mml->width != dstWidth || mml->height != dstHeight) { + if (mml->data) + FREE(mml->data); + mml->data = MALLOC(dstWidth * dstHeight * texelSize); + if (!mml->data) + return GL_FALSE; + mml->texelSize = texelSize; + mml->glideFormat = gldformat; + mml->width = dstWidth; + mml->height = dstHeight; + fxTexInvalidate(ctx, texObj); + } - fxTexInvalidate(ctx,tObj); - } -#ifndef FX_SILENT - else - fprintf(stderr,"fx Driver: unsupported texture in fxDDTexImg()\n"); -#endif -} + dstStride = dstWidth * texelSize; -static void fxTexBuildSubImageMap(const struct gl_texture_image *image, - GLint internalFormat, - GLint xoffset, GLint yoffset, GLint width, GLint height, - unsigned short *destimg) -{ - fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL, - NULL,NULL); - - switch(internalFormat) { - case GL_INTENSITY: - case GL_INTENSITY4: - case GL_INTENSITY8: - case GL_INTENSITY12: - case GL_INTENSITY16: - case 1: - case GL_LUMINANCE: - case GL_LUMINANCE4: - case GL_LUMINANCE8: - case GL_LUMINANCE12: - case GL_LUMINANCE16: - case GL_ALPHA: - case GL_ALPHA4: - case GL_ALPHA8: - case GL_ALPHA12: - case GL_ALPHA16: - case GL_COLOR_INDEX: - case GL_COLOR_INDEX1_EXT: - case GL_COLOR_INDEX2_EXT: - case GL_COLOR_INDEX4_EXT: - case GL_COLOR_INDEX8_EXT: - case GL_COLOR_INDEX12_EXT: - case GL_COLOR_INDEX16_EXT: - { - - int y; - unsigned char *bsrc,*bdst; - - bsrc=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset)); - bdst=((unsigned char *)destimg)+(yoffset*image->Width+xoffset); - - for(y=0;y<height;y++) { - MEMCPY(bdst,bsrc,width); - bsrc += image->Width; - bdst += image->Width; - } - } - break; - case 2: - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE4_ALPHA4: - case GL_LUMINANCE6_ALPHA2: - case GL_LUMINANCE8_ALPHA8: - case GL_LUMINANCE12_ALPHA4: - case GL_LUMINANCE12_ALPHA12: - case GL_LUMINANCE16_ALPHA16: - { - int x,y; - unsigned char *src; - unsigned short *dst,a,l; - int simgw,dimgw; - - src=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset)*2); - dst=destimg+(yoffset*image->Width+xoffset); - - simgw=(image->Width-width)*2; - dimgw=image->Width-width; - for(y=0;y<height;y++) { - for(x=0;x<width;x++) { - l=*src++; - a=*src++; - *dst++=(a << 8) | l; - } - - src += simgw; - dst += dimgw; - } + /* store the texture image */ + if (!_mesa_convert_teximage(intFormat, dstWidth, dstHeight, mml->data, + dstStride, + texImage->Width, texImage->Height, + format, type, pixels, packing)) { + return GL_FALSE; } - break; - case 3: - case GL_RGB: - case GL_R3_G3_B2: - case GL_RGB4: - case GL_RGB5: - case GL_RGB8: - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: - { - int x,y; - unsigned char *src; - unsigned short *dst,r,g,b; - int simgw,dimgw; - - src=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset)*3); - dst=destimg+(yoffset*image->Width+xoffset); - simgw=(image->Width-width)*3; - dimgw=image->Width-width; - for(y=0;y<height;y++) { - for(x=0;x<width;x++) { - r=*src++; - g=*src++; - b=*src++; - *dst++=((0xf8 & r) << (11-3)) | - ((0xfc & g) << (5-3+1)) | - ((0xf8 & b) >> 3); - } - - src += simgw; - dst += dimgw; - } + if (ti->validated && ti->isInTM) { + /*printf("reloadmipmaplevels\n");*/ + fxTMReloadMipMapLevel(fxMesa, texObj, level); } - break; - case 4: - case GL_RGBA: - case GL_RGBA2: - case GL_RGBA4: - case GL_RGBA8: - case GL_RGB10_A2: - case GL_RGBA12: - case GL_RGBA16: - { - int x,y; - unsigned char *src; - unsigned short *dst,r,g,b,a; - int simgw,dimgw; - - src=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset)*4); - dst=destimg+(yoffset*image->Width+xoffset); - - simgw=(image->Width-width)*4; - dimgw=image->Width-width; - for(y=0;y<height;y++) { - for(x=0;x<width;x++) { - r=*src++; - g=*src++; - b=*src++; - a=*src++; - *dst++=((0xf0 & a) << 8) | - ((0xf0 & r) << 4) | - (0xf0 & g) | - ((0xf0 & b) >> 4); - } - - src += simgw; - dst += dimgw; - } + else { + /*printf("invalidate2\n");*/ + fxTexInvalidate(ctx,texObj); } - break; - case GL_RGB5_A1: - { - int x,y; - unsigned char *src; - unsigned short *dst,r,g,b,a; - int simgw,dimgw; - - src=(unsigned char *)(image->Data+(yoffset*image->Width+xoffset)*4); - dst=destimg+(yoffset*image->Width+xoffset); - - simgw=(image->Width-width)*4; - dimgw=image->Width-width; - for(y=0;y<height;y++) { - for(x=0;x<width;x++) { - r=*src++; - g=*src++; - b=*src++; - a=*src++; - *dst++= - ((0x80 & a) << 8) | - ((0xf8 & r) << 7) | - ((0xf8 & g) << 2) | - ((0xf8 & b) >> 3); - } - - src += simgw; - dst += dimgw; - } - } - break; - default: - fprintf(stderr,"fx Driver: wrong internalFormat in fxTexBuildSubImageMap()\n"); - fxCloseHardware(); - exit(-1); - break; + + *retainInternalCopy = GL_FALSE; + return GL_TRUE; + } + else { + gl_problem(NULL, "fx Driver: unsupported texture in fxDDTexImg()\n"); + return GL_FALSE; } } - -void fxDDTexSubImg(GLcontext *ctx, GLenum target, - struct gl_texture_object *tObj, GLint level, - GLint xoffset, GLint yoffset, GLint width, GLint height, - GLint internalFormat, const struct gl_texture_image *image) + +GLboolean fxDDTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) { - fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; + fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx; tfxTexInfo *ti; - GrTextureFormat_t gldformat; - int wscale,hscale; + GLint wscale, hscale, dstStride; tfxMipMapLevel *mml; + GLboolean result; - if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr, - "fxmesa: (%d) fxDDTexSubImg(level=%d,target=%d,format=%x,width=%d,height=%d)\n", - tObj->Name, level, target, internalFormat, image->Width, - image->Height); - } + if (target != GL_TEXTURE_2D) + return GL_FALSE; - if(target!=GL_TEXTURE_2D) - return; + if (!texObj->DriverData) + return GL_FALSE; - if (!tObj->DriverData) - return; + ti = fxTMGetTexInfo(texObj); + mml = &ti->mipmapLevel[level]; - ti=fxTMGetTexInfo(tObj); - mml=&ti->mipmapLevel[level]; + fxTexGetInfo( texImage->Width, texImage->Height, NULL,NULL,NULL,NULL, + NULL,NULL, &wscale, &hscale); - fxTexGetFormat(internalFormat,&gldformat,NULL); + assert(mml->data); /* must have an existing texture image! */ - if(mml->glideFormat!=gldformat) { - if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: ti->info.format!=format in fxDDTexSubImg()\n"); - } - fxDDTexImg(ctx,target,tObj,level,internalFormat,image); + switch (mml->glideFormat) { + case GR_TEXFMT_INTENSITY_8: + dstStride = mml->width; + result = _mesa_convert_texsubimage(MESA_I8, xoffset, yoffset, + mml->width, mml->height, mml->data, + dstStride, width, height, + texImage->Width, texImage->Height, + format, type, pixels, packing); + break; + case GR_TEXFMT_ALPHA_8: + dstStride = mml->width; + result = _mesa_convert_texsubimage(MESA_A8, xoffset, yoffset, + mml->width, mml->height, mml->data, + dstStride, width, height, + texImage->Width, texImage->Height, + format, type, pixels, packing); + break; + case GR_TEXFMT_P_8: + dstStride = mml->width; + result = _mesa_convert_texsubimage(MESA_C8, xoffset, yoffset, + mml->width, mml->height, mml->data, + dstStride, width, height, + texImage->Width, texImage->Height, + format, type, pixels, packing); + break; + case GR_TEXFMT_ALPHA_INTENSITY_88: + dstStride = mml->width * 2; + result = _mesa_convert_texsubimage(MESA_A8_L8, xoffset, yoffset, + mml->width, mml->height, mml->data, + dstStride, width, height, + texImage->Width, texImage->Height, + format, type, pixels, packing); + break; + case GR_TEXFMT_RGB_565: + dstStride = mml->width * 2; + result = _mesa_convert_texsubimage(MESA_R5_G6_B5, xoffset, yoffset, + mml->width, mml->height, mml->data, + dstStride, width, height, + texImage->Width, texImage->Height, + format, type, pixels, packing); + break; + case GR_TEXFMT_ARGB_4444: + dstStride = mml->width * 2; + result = _mesa_convert_texsubimage(MESA_A4_R4_G4_B4, xoffset, yoffset, + mml->width, mml->height, mml->data, + dstStride, width, height, + texImage->Width, texImage->Height, + format, type, pixels, packing); + break; + case GR_TEXFMT_ARGB_8888: + dstStride = mml->width * 4; + result = _mesa_convert_texsubimage(MESA_A8_R8_G8_B8, xoffset, yoffset, + mml->width, mml->height, mml->data, + dstStride, width, height, + texImage->Width, texImage->Height, + format, type, pixels, packing); + break; + case GR_TEXFMT_ARGB_1555: + dstStride = mml->width * 2; + result = _mesa_convert_texsubimage(MESA_A1_R5_G5_B5, xoffset, yoffset, + mml->width, mml->height, mml->data, + dstStride, width, height, + texImage->Width, texImage->Height, + format, type, pixels, packing); + break; + default: + gl_problem(NULL, "tdfx driver: fxTexBuildSubImageMap() bad format"); + result = GL_FALSE; + } - return; + if (!result) { + return GL_FALSE; } - fxTexGetInfo(image->Width,image->Height,NULL,NULL,NULL,NULL,NULL,NULL,&wscale,&hscale); + if (ti->validated && ti->isInTM) + fxTMReloadSubMipMapLevel(fxMesa, texObj, level, yoffset, height); + else + fxTexInvalidate(ctx, texObj); - if((wscale!=1) || (hscale!=1)) { - if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: (wscale!=1) || (hscale!=1) in fxDDTexSubImg()\n"); - } - fxDDTexImg(ctx,target,tObj,level,internalFormat,image); + return GL_TRUE; +} - return; + +static void PrintTexture(int w, int h, int c, const GLubyte *data) +{ + int i, j; + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + if (c==2) + printf("%02x %02x ", data[0], data[1]); + else if (c==3) + printf("%02x %02x %02x ", data[0], data[1], data[2]); + data += c; + } + printf("\n"); } +} - if(mml->translated) - fxTexBuildSubImageMap(image,internalFormat,xoffset,yoffset, - width,height,mml->data); - if(ti->validated && ti->isInTM) - fxTMReloadSubMipMapLevel(fxMesa,tObj,level,yoffset,height); - else - fxTexInvalidate(ctx,tObj); +GLvoid *fxDDGetTexImage(GLcontext *ctx, GLenum target, GLint level, + const struct gl_texture_object *texObj, + GLenum *formatOut, GLenum *typeOut, + GLboolean *freeImageOut ) +{ + tfxTexInfo *ti; + tfxMipMapLevel *mml; + + if (target != GL_TEXTURE_2D) + return NULL; + + if (!texObj->DriverData) + return NULL; + + ti = fxTMGetTexInfo(texObj); + mml = &ti->mipmapLevel[level]; + if (mml->data) { + MesaIntTexFormat mesaFormat; + GLenum glFormat; + struct gl_texture_image *texImage = texObj->Image[level]; + GLint srcStride; + + GLubyte *data = (GLubyte *) MALLOC(texImage->Width * texImage->Height * 4); + if (!data) + return NULL; + + switch (mml->glideFormat) { + case GR_TEXFMT_INTENSITY_8: + mesaFormat = MESA_I8; + glFormat = GL_INTENSITY; + srcStride = mml->width; + break; + case GR_TEXFMT_ALPHA_INTENSITY_88: + mesaFormat = MESA_A8_L8; + glFormat = GL_LUMINANCE_ALPHA; + srcStride = mml->width; + break; + case GR_TEXFMT_ALPHA_8: + mesaFormat = MESA_A8; + glFormat = GL_ALPHA; + srcStride = mml->width; + break; + case GR_TEXFMT_RGB_565: + mesaFormat = MESA_R5_G6_B5; + glFormat = GL_RGB; + srcStride = mml->width * 2; + break; + case GR_TEXFMT_ARGB_8888: + mesaFormat = MESA_A8_R8_G8_B8; + glFormat = GL_RGBA; + srcStride = mml->width * 4; + break; + case GR_TEXFMT_ARGB_4444: + mesaFormat = MESA_A4_R4_G4_B4; + glFormat = GL_RGBA; + srcStride = mml->width * 2; + break; + case GR_TEXFMT_ARGB_1555: + mesaFormat = MESA_A1_R5_G5_B5; + glFormat = GL_RGBA; + srcStride = mml->width * 2; + break; + case GR_TEXFMT_P_8: + mesaFormat = MESA_C8; + glFormat = GL_COLOR_INDEX; + srcStride = mml->width; + break; + default: + gl_problem(NULL, "Bad glideFormat in fxDDGetTexImage"); + return NULL; + } + _mesa_unconvert_teximage(mesaFormat, mml->width, mml->height, mml->data, + srcStride, texImage->Width, texImage->Height, + glFormat, data); + *formatOut = glFormat; + *typeOut = GL_UNSIGNED_BYTE; + *freeImageOut = GL_TRUE; + return data; + } + else { + return NULL; + } } diff --git a/xc/extras/Mesa/src/FX/fxdrv.h b/xc/extras/Mesa/src/FX/fxdrv.h index e12a3244f..eea75fc56 100644 --- a/xc/extras/Mesa/src/FX/fxdrv.h +++ b/xc/extras/Mesa/src/FX/fxdrv.h @@ -50,14 +50,10 @@ * you turn debugging on/off from the debugger. */ -#ifndef XFree86Server -#include <math.h> -#include <stdio.h> -#include <stdlib.h> -#include <limits.h> -#include <assert.h> -#else +#ifdef XFree86Server #include "GL/xf86glx.h" +#else +#include "glheader.h" #endif @@ -87,8 +83,8 @@ typedef struct tfxMesaContext *fxMesaContext; -#if defined(MESA_DEBUG) && 0 extern void fx_sanity_triangle( GrVertex *, GrVertex *, GrVertex * ); +#if defined(MESA_DEBUG) && 0 #define grDrawTriangle fx_sanity_triangle #endif @@ -166,6 +162,7 @@ typedef struct { #endif #endif + #define FX_VB_COLOR(fxm, color) \ do { \ if (sizeof(GLint) == 4*sizeof(GLubyte)) { \ @@ -187,9 +184,9 @@ typedef struct { } #if FX_USE_PARGB -#define GOURAUD2(v, c) { \ - GLubyte *col = c; \ - v->argb=MESACOLOR2PARGB(col); \ +#define GOURAUD2(v, c) { \ + GLubyte *col = c; \ + v->argb=MESACOLOR2PARGB(col); \ } #else #define GOURAUD2(v, c) { \ @@ -230,13 +227,13 @@ typedef struct { #define FX_UM_E0_MODULATE 0x00000002 #define FX_UM_E0_DECAL 0x00000004 #define FX_UM_E0_BLEND 0x00000008 -#define FX_UM_E0_ADD 0x00000010 +#define FX_UM_E0_ADD 0x00000010 #define FX_UM_E1_REPLACE 0x00000020 #define FX_UM_E1_MODULATE 0x00000040 #define FX_UM_E1_DECAL 0x00000080 #define FX_UM_E1_BLEND 0x00000100 -#define FX_UM_E1_ADD 0x00000200 +#define FX_UM_E1_ADD 0x00000200 #define FX_UM_E_ENVMODE 0x000003ff @@ -261,6 +258,20 @@ typedef struct { #define FX_UM_ALPHA_ITERATED 0x04000000 #define FX_UM_ALPHA_CONSTANT 0x08000000 + +#define PACK_BGRA32(R, G, B, A) \ + ( (((GLuint) (R)) << 16) | \ + (((GLuint) (G)) << 8) | \ + (((GLuint) (B)) ) | \ + (((GLuint) (A)) << 24) ) + +#define PACK_RGBA32(R, G, B, A) \ + ( (((GLuint) (R)) ) | \ + (((GLuint) (G)) << 8) | \ + (((GLuint) (B)) << 16) | \ + (((GLuint) (A)) << 24) ) + + typedef void (*tfxRenderVBFunc)(GLcontext *); /* @@ -272,11 +283,10 @@ typedef struct MemRange_t { } MemRange; typedef struct { - GLsizei width, height; - GLint glideFormat; - - unsigned short *data; - GLboolean translated, used; + GLsizei width, height; /* image size */ + GLint texelSize; /* How many bytes to a texel */ + GrTextureFormat_t glideFormat; /* Glide image format */ + unsigned short *data; /* Glide-formated texture image */ } tfxMipMapLevel; typedef struct tfxTexInfo_t { @@ -345,27 +355,20 @@ extern tfxLineClipFunc fxLineClipTab[0x8]; typedef struct { /* Alpha test */ - GLboolean alphaTestEnabled; GrCmpFnc_t alphaTestFunc; GrAlpha_t alphaTestRefValue; /* Blend function */ - GLboolean blendEnabled; GrAlphaBlendFnc_t blendSrcFuncRGB; GrAlphaBlendFnc_t blendDstFuncRGB; GrAlphaBlendFnc_t blendSrcFuncAlpha; GrAlphaBlendFnc_t blendDstFuncAlpha; - - /* Depth test */ - - GLboolean depthTestEnabled; - GLboolean depthMask; - GrCmpFnc_t depthTestFunc; } tfxUnitsState; + /* Flags for render_index. */ #define FX_OFFSET 0x1 @@ -386,6 +389,7 @@ typedef struct { #define FX_NEW_SCISSOR 0x20 #define FX_NEW_COLOR_MASK 0x40 #define FX_NEW_CULL 0x80 +#define FX_NEW_STENCIL 0x100 /* FX struct stored in VB->driver_data. */ @@ -427,8 +431,6 @@ extern GLubyte FX_PixelToB[0x10000]; struct tfxMesaContext { - GuTexPalette glbPalette; - GLcontext *glCtx; /* the core Mesa context */ GLvisual *glVis; /* describes the color buffer */ GLframebuffer *glBuffer; /* the ancillary buffers */ @@ -439,6 +441,7 @@ struct tfxMesaContext { GrBuffer_t currentFB; GLboolean bgrOrder; + GLuint depthClear; GrColor_t color; GrColor_t clearC; GrAlpha_t clearA; @@ -448,6 +451,8 @@ struct tfxMesaContext { tfxUnitsState unitsState; tfxUnitsState restoreUnitsState; /* saved during multipass */ + GuTexPalette glbPalette; + GLuint tmu_source[FX_NUM_TMU]; GLuint tex_dest[MAX_TEXTURE_UNITS]; GLuint setupindex; @@ -471,7 +476,6 @@ struct tfxMesaContext { GLuint texBindNumber; GLint tmuSrc; - GLuint lastUnitsMode; GLuint freeTexMem[FX_NUM_TMU]; MemRange *tmPool; MemRange *tmFree[FX_NUM_TMU]; @@ -506,8 +510,7 @@ struct tfxMesaContext { GLboolean haveTwoTMUs; /* True if we really have 2 tmu's */ GLboolean emulateTwoTMUs; /* True if we present 2 tmu's to mesa. */ GLboolean haveAlphaBuffer; - GLboolean haveZBuffer; - GLboolean haveDoubleBuffer; + GLboolean haveHwStencil; GLboolean haveGlobalPaletteTexture; GLint swapInterval; GLint maxPendingSwapBuffers; @@ -534,6 +537,7 @@ typedef void (*tfxSetupFunc)(struct vertex_buffer *, GLuint, GLuint); extern GrHwConfiguration glbHWConfig; extern int glbCurrentBoard; +extern void fxPrintSetupFlags( const char *msg, GLuint flags ); extern void fxSetupFXUnits(GLcontext *); extern void fxSetupDDPointers(GLcontext *); extern void fxDDSetNearFar(GLcontext *, GLfloat, GLfloat); @@ -567,24 +571,34 @@ extern void fxUpdateDDSpanPointers(GLcontext *); extern void fxSetupDDSpanPointers(GLcontext *); extern void fxPrintTextureData(tfxTexInfo *ti); -extern void fxDDTexEnv(GLcontext *, GLenum, const GLfloat *); -extern void fxDDTexImg(GLcontext *, GLenum, struct gl_texture_object *, - GLint, GLint, const struct gl_texture_image *); +extern GLboolean fxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, + GLboolean *retainInternalCopy); +extern GLboolean fxDDTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +extern GLvoid *fxDDGetTexImage(GLcontext *ctx, GLenum target, GLint level, + const struct gl_texture_object *texObj, + GLenum *formatOut, GLenum *typeOut, + GLboolean *freeImageOut ); +extern void fxDDTexEnv(GLcontext *, GLenum, GLenum, const GLfloat *); extern void fxDDTexParam(GLcontext *, GLenum, struct gl_texture_object *, GLenum, const GLfloat *); extern void fxDDTexBind(GLcontext *, GLenum, struct gl_texture_object *); extern void fxDDTexDel(GLcontext *, struct gl_texture_object *); extern void fxDDTexPalette(GLcontext *, struct gl_texture_object *); -extern void fxDDTexuseGlbPalette(GLcontext *, GLboolean); -extern void fxDDTexSubImg(GLcontext *, GLenum, struct gl_texture_object *, GLint, - GLint, GLint, GLint, GLint, GLint, const struct gl_texture_image *); extern void fxDDTexUseGlbPalette(GLcontext *, GLboolean); extern void fxDDEnable(GLcontext *, GLenum, GLboolean); extern void fxDDAlphaFunc(GLcontext *, GLenum, GLclampf); extern void fxDDBlendFunc(GLcontext *, GLenum, GLenum); -extern void fxDDDepthMask(GLcontext *, GLboolean); -extern void fxDDDepthFunc(GLcontext *, GLenum); extern void fxDDRegisterVB( struct vertex_buffer *VB ); extern void fxDDUnregisterVB( struct vertex_buffer *VB ); @@ -619,6 +633,7 @@ extern void fxDDInitExtensions( GLcontext *ctx ); #define fxTMGetTexInfo(o) ((tfxTexInfo*)((o)->DriverData)) extern void fxTMInit(fxMesaContext ctx); extern void fxTMClose(fxMesaContext ctx); +extern void fxTMRestoreTextures_NoLock(fxMesaContext ctx); extern void fxTMMoveInTM(fxMesaContext, struct gl_texture_object *, GLint); extern void fxTMMoveOutTM(fxMesaContext, struct gl_texture_object *); #define fxTMMoveOutTM_NoLock fxTMMoveOutTM diff --git a/xc/extras/Mesa/src/FX/fxglidew.c b/xc/extras/Mesa/src/FX/fxglidew.c index 790e5c923..f01644a60 100644 --- a/xc/extras/Mesa/src/FX/fxglidew.c +++ b/xc/extras/Mesa/src/FX/fxglidew.c @@ -55,6 +55,13 @@ #include <stdlib.h> #include <string.h> + +grStencilFunc_t grStencilFuncPtr = NULL; +grStencilMask_t grStencilMaskPtr = NULL; +grStencilOp_t grStencilOpPtr = NULL; +grBufferClearExt_t grBufferClearExtPtr = NULL; + + FxI32 FX_grGetInteger_NoLock(FxU32 pname) { #if !defined(FX_GLIDE3) @@ -71,6 +78,8 @@ FxI32 FX_grGetInteger_NoLock(FxU32 pname) case FX_TEXTURE_ALIGN: /* This is a guess from reading the glide3 docs */ return 8; + case FX_ZDEPTH_MAX: + return 0xFFFF; default: if (MESA_VERBOSE&VERBOSE_DRIVER) { fprintf(stderr,"Wrong parameter in FX_grGetInteger!\n"); @@ -90,6 +99,12 @@ FxI32 FX_grGetInteger_NoLock(FxU32 pname) case FX_TEXTURE_ALIGN: grname = pname; break; + case FX_ZDEPTH_MAX: { + int zvals[2]; + + grGet(GR_ZDEPTH_MIN_MAX, 8, zvals); + return zvals[0]; + } default: if (MESA_VERBOSE&VERBOSE_DRIVER) { fprintf(stderr,"Wrong parameter in FX_grGetInteger!\n"); @@ -154,7 +169,17 @@ extern FxU32 FX_grTexMaxAddress(GrChipID_t tmu) { FxBool FX_grSstControl(FxU32 code) { #if defined(FX_GLIDE3) - (void) code; + /* The glide 3 sources call for grEnable/grDisable to be called in exchange + * for grSstControl. */ + switch(code) { + case GR_CONTROL_ACTIVATE: + grEnable(GR_PASSTHRU); + break; + case GR_CONTROL_DEACTIVATE: + grDisable(GR_PASSTHRU); + break; + } + /* Appearently GR_CONTROL_RESIZE can be ignored. */ return 1; /* OK? */ #else FxU32 result; @@ -225,12 +250,12 @@ void FX_grGlideGetVersion(char *buf) void FX_grSstPerfStats(GrSstPerfStats_t *st) { - /* ToDo */ - st->pixelsIn = 0; - st->chromaFail = 0; - st->zFuncFail = 0; - st->aFuncFail = 0; - st->pixelsOut = 0; + FxI32 n; + grGet(GR_STATS_PIXELS_IN, 4, &n); st->pixelsIn = n; + grGet(GR_STATS_PIXELS_CHROMA_FAIL, 4, &n); st->chromaFail = n; + grGet(GR_STATS_PIXELS_DEPTHFUNC_FAIL, 4, &n); st->zFuncFail = n; + grGet(GR_STATS_PIXELS_AFUNC_FAIL, 4, &n); st->aFuncFail = n; + grGet(GR_STATS_PIXELS_OUT, 4, &n); st->pixelsOut = n; } void FX_grAADrawLine(GrVertex *a,GrVertex *b) @@ -385,6 +410,10 @@ int FX_grSstQueryHardware(GrHwConfiguration *c) return i; } + +#endif /* FX_GLIDE3 */ + +/* It appears to me that this function is needed either way. */ FX_GrContext_t FX_grSstWinOpen( FxU32 hWnd, GrScreenResolution_t screen_resolution, GrScreenRefresh_t refresh_rate, @@ -403,6 +432,7 @@ FX_GrContext_t FX_grSstWinOpen( FxU32 hWnd, nColBuffers, nAuxBuffers ); + /* fprintf(stderr, "grSstWinOpen( win %d res %d ref %d fmt %d\n" " org %d ncol %d naux %d )\n" @@ -415,13 +445,13 @@ FX_GrContext_t FX_grSstWinOpen( FxU32 hWnd, nColBuffers, nAuxBuffers, i); + */ END_BOARD_LOCK(); return i; } -#endif #else /* diff --git a/xc/extras/Mesa/src/FX/fxglidew.h b/xc/extras/Mesa/src/FX/fxglidew.h index 28556d8c5..4ad2942af 100644 --- a/xc/extras/Mesa/src/FX/fxglidew.h +++ b/xc/extras/Mesa/src/FX/fxglidew.h @@ -47,7 +47,51 @@ #define __FX_GLIDE_WARPER__ #include <glide.h> +#include <g3ext.h> +/* + * These are glide extension definitions. These are not + * defined in glide.h. They should really be defined in + * g3ext.h, but they are not. + */ +#if 0 +FX_ENTRY void FX_CALL +grStencilFunc(GrCmpFnc_t fnc, GrStencil_t ref, GrStencil_t mask); + +FX_ENTRY void FX_CALL +grStencilMask(GrStencil_t write_mask); + +FX_ENTRY void FX_CALL +grStencilOp( + GrStencilOp_t stencil_fail, + GrStencilOp_t depth_fail, + GrStencilOp_t depth_pass); + +FX_ENTRY void FX_CALL +grBufferClearExt( + GrColor_t color, + GrAlpha_t alpha, + FxU32 depth, + GrStencil_t stencil); +#endif + + +typedef void (*grStencilFunc_t)(GrCmpFnc_t fnc, GrStencil_t ref, GrStencil_t mask); +typedef void (*grStencilMask_t)(GrStencil_t write_mask); +typedef void (*grStencilOp_t)(GrStencilOp_t stencil_fail, GrStencilOp_t depth_fail, GrStencilOp_t depth_pass); +typedef void (*grBufferClearExt_t)(GrColor_t color, GrAlpha_t alpha, FxU32 depth, GrStencil_t stencil); + +extern grStencilFunc_t grStencilFuncPtr; +extern grStencilMask_t grStencilMaskPtr; +extern grStencilOp_t grStencilOpPtr; +extern grBufferClearExt_t grBufferClearExtPtr; + + +FX_ENTRY void FX_CALL +grEnable(GrEnableMode_t mode); + +FX_ENTRY void FX_CALL +grEnable(GrEnableMode_t mode); /* * General context: */ @@ -74,12 +118,13 @@ #define FX_PENDING_BUFFERSWAPS GR_PENDING_BUFFERSWAPS #define FX_TEXTURE_ALIGN GR_TEXTURE_ALIGN #endif +#define FX_ZDEPTH_MAX 0x100 /* * Genral warper functions for Glide2/Glide3: */ -extern FxI32 FX_grGetInteger(FxU32 pname); extern FxI32 FX_grGetInteger_NoLock(FxU32 pname); +extern FxI32 FX_grGetInteger(FxU32 pname); /* * Glide2 emulation on Glide3: @@ -253,7 +298,6 @@ typedef struct #endif - /* * Glide2 functions for Glide3 */ @@ -567,6 +611,55 @@ extern void FX_grDrawPolygonVertexList(int n, GrVertex *v); END_CLIP_LOOP(); \ } while (0) +#define FX_grBufferClearExt(c, a, d, s) \ + do { \ + BEGIN_CLIP_LOOP(); \ + (*grBufferClearExtPtr)(c, a, d, s); \ + END_CLIP_LOOP(); \ + } while (0) + +/* + * Enable/Disable + */ +#define FX_grEnable(m) \ + do { \ + BEGIN_BOARD_LOCK(); \ + grEnable(m); \ + END_BOARD_LOCK(); \ + } while (0) + +#define FX_grDisable(m) \ + do { \ + BEGIN_BOARD_LOCK(); \ + grDisable(m); \ + END_BOARD_LOCK(); \ + } while (0) + +/* + * Stencil operations. + */ +#define FX_grStencilFunc(fnc, ref, mask) \ + do { \ + BEGIN_BOARD_LOCK(); \ + (*grStencilFuncPtr)((fnc), (ref), (mask)); \ + END_BOARD_LOCK(); \ + } while (0) + +#define FX_grStencilMask(write_mask) \ + do { \ + BEGIN_BOARD_LOCK(); \ + (*grStencilMaskPtr)(write_mask); \ + END_BOARD_LOCK(); \ + } while (0) + + +#define FX_grStencilOp(stencil_fail, depth_fail, depth_pass) \ + do { \ + BEGIN_BOARD_LOCK(); \ + (*grStencilOpPtr)((stencil_fail), (depth_fail), (depth_pass)); \ + END_BOARD_LOCK(); \ + } while (0) + #define FX_grDepthMask(m) \ do { \ BEGIN_BOARD_LOCK(); \ @@ -821,9 +914,18 @@ extern FxU32 FX_grTexTextureMemRequired(FxU32 evenOdd, GrTexInfo *info); #define FX_grGlideShutdown() \ do { \ - BEGIN_CLIP_LOOP(); \ + BEGIN_BOARD_LOCK(); \ grGlideShutdown(); \ - END_CLIP_LOOP(); \ + END_BOARD_LOCK(); \ + } while (0) + +#define FX_grTexLodBiasValue_NoLock(t, v) grTexLodBiasValue(t, v) + +#define FX_grTexLodBiasValue(t, v) \ + do { \ + BEGIN_BOARD_LOCK(); \ + grTexLodBiasValue(t, v); \ + END_BOARD_LOCK(); \ } while (0) #define FX_grGlideInit_NoLock grGlideInit diff --git a/xc/extras/Mesa/src/FX/fxsetup.c b/xc/extras/Mesa/src/FX/fxsetup.c index 8707aed1d..f07a2ecec 100644 --- a/xc/extras/Mesa/src/FX/fxsetup.c +++ b/xc/extras/Mesa/src/FX/fxsetup.c @@ -62,16 +62,11 @@ static void fxSetupTextureSingleTMU_NoLock(GLcontext *ctx, GLuint textureset); static void fxSetupDoubleTMU_NoLock(fxMesaContext fxMesa, struct gl_texture_object *tObj0, struct gl_texture_object *tObj1); -static void fxSetupTexture_NoLock(GLcontext *ctx); -static void fxSetupTexture(GLcontext *ctx); -static void fxSetupBlend(GLcontext *ctx); -static void fxSetupDepthTest(GLcontext *ctx); -static void fxSetupScissor(GLcontext *ctx); -static void fxSetupCull(GLcontext *ctx); static void gl_print_fx_state_flags( const char *msg, GLuint flags); -static GLboolean fxMultipassBlend(struct vertex_buffer *, GLuint); static GLboolean fxMultipassTexture( struct vertex_buffer *, GLuint ); + + static void fxTexValidate(GLcontext *ctx, struct gl_texture_object *tObj) { tfxTexInfo *ti=fxTMGetTexInfo(tObj); @@ -183,7 +178,7 @@ static GLuint fxGetTexSetConfiguration(GLcontext *ctx, GLuint envmode=0; GLuint ifmt=0; - if((ctx->Light.ShadeModel==GL_SMOOTH) || + if((ctx->Light.ShadeModel==GL_SMOOTH) || 1 || (ctx->Point.SmoothFlag) || (ctx->Line.SmoothFlag) || (ctx->Polygon.SmoothFlag)) @@ -191,11 +186,13 @@ static GLuint fxGetTexSetConfiguration(GLcontext *ctx, else unitsmode|=FX_UM_ALPHA_CONSTANT; - if(ctx->Light.ShadeModel==GL_SMOOTH) + if(ctx->Light.ShadeModel==GL_SMOOTH || 1) unitsmode|=FX_UM_COLOR_ITERATED; else unitsmode|=FX_UM_COLOR_CONSTANT; + + /* OpenGL Feeds Texture 0 into Texture 1 Glide Feeds Texture 1 into Texture 0 @@ -476,11 +473,6 @@ static void fxSetupTextureSingleTMU_NoLock(GLcontext *ctx, GLuint textureset) 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); @@ -555,9 +547,8 @@ static void fxSetupTextureSingleTMU_NoLock(GLcontext *ctx, GLuint textureset) FXTRUE); ctx->Driver.MultipassFunc = fxMultipassBlend; #else -#ifndef FX_SILENT - fprintf(stderr,"fx Driver: GL_BLEND not yet supported\n"); -#endif + if (MESA_VERBOSE&VERBOSE_DRIVER) + fprintf(stderr,"fx Driver: GL_BLEND not yet supported\n"); #endif break; case GL_REPLACE: @@ -588,9 +579,9 @@ static void fxSetupTextureSingleTMU_NoLock(GLcontext *ctx, GLuint textureset) FXFALSE); break; default: -#ifndef FX_SILENT - fprintf(stderr,"fx Driver: %x Texture.EnvMode not yet supported\n",ctx->Texture.Unit[textureset].EnvMode); -#endif + if (MESA_VERBOSE&VERBOSE_DRIVER) + fprintf(stderr, "fx Driver: %x Texture.EnvMode not yet supported\n", + ctx->Texture.Unit[textureset].EnvMode); break; } @@ -599,7 +590,8 @@ static void fxSetupTextureSingleTMU_NoLock(GLcontext *ctx, GLuint textureset) } } -static void fxSetupTextureSingleTMU(GLcontext *ctx, GLuint textureset) { +static void fxSetupTextureSingleTMU(GLcontext *ctx, GLuint textureset) +{ BEGIN_BOARD_LOCK(); fxSetupTextureSingleTMU_NoLock(ctx, textureset); END_BOARD_LOCK(); @@ -764,11 +756,6 @@ static void fxSetupTextureDoubleTMU_NoLock(GLcontext *ctx) 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); @@ -1030,7 +1017,7 @@ static void fxSetupTextureNone_NoLock(GLcontext *ctx) fprintf(stderr,"fxmesa: fxSetupTextureNone(...)\n"); } - if((ctx->Light.ShadeModel==GL_SMOOTH) || + if((ctx->Light.ShadeModel==GL_SMOOTH) || 1 || (ctx->Point.SmoothFlag) || (ctx->Line.SmoothFlag) || (ctx->Polygon.SmoothFlag)) @@ -1038,7 +1025,7 @@ static void fxSetupTextureNone_NoLock(GLcontext *ctx) else locala=GR_COMBINE_LOCAL_CONSTANT; - if(ctx->Light.ShadeModel==GL_SMOOTH) + if(ctx->Light.ShadeModel==GL_SMOOTH || 1) localc=GR_COMBINE_LOCAL_ITERATED; else localc=GR_COMBINE_LOCAL_CONSTANT; @@ -1054,8 +1041,6 @@ static void fxSetupTextureNone_NoLock(GLcontext *ctx) localc, GR_COMBINE_OTHER_NONE, FXFALSE); - - fxMesa->lastUnitsMode=FX_UM_NONE; } /************************************************************************/ @@ -1106,7 +1091,8 @@ static void fxSetupTexture_NoLock(GLcontext *ctx) } } -static void fxSetupTexture(GLcontext *ctx) { +static void fxSetupTexture(GLcontext *ctx) +{ BEGIN_BOARD_LOCK(); fxSetupTexture_NoLock(ctx); END_BOARD_LOCK(); @@ -1239,15 +1225,19 @@ void fxDDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor) static void fxSetupBlend(GLcontext *ctx) { - fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; - tfxUnitsState *us=&fxMesa->unitsState; + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; - if(us->blendEnabled) - FX_grAlphaBlendFunction(us->blendSrcFuncRGB,us->blendDstFuncRGB, - us->blendSrcFuncAlpha,us->blendDstFuncAlpha); + assert(us->blendEnabled == ctx->Color.BlendEnabled); + + if (us->blendEnabled) + FX_grAlphaBlendFunction(us->blendSrcFuncRGB, us->blendDstFuncRGB, + us->blendSrcFuncAlpha, us->blendDstFuncAlpha); else - FX_grAlphaBlendFunction(GR_BLEND_ONE,GR_BLEND_ZERO,GR_BLEND_ONE,GR_BLEND_ZERO); + FX_grAlphaBlendFunction(GR_BLEND_ONE, GR_BLEND_ZERO, + GR_BLEND_ONE, GR_BLEND_ZERO); } + /************************************************************************/ /************************** Alpha Test SetUp ****************************/ @@ -1255,8 +1245,8 @@ static void fxSetupBlend(GLcontext *ctx) void fxDDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref) { - fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; - tfxUnitsState *us=&fxMesa->unitsState; + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; GrCmpFnc_t newfunc; switch(func) { @@ -1316,81 +1306,118 @@ static void fxSetupAlphaTest(GLcontext *ctx) FX_grAlphaTestFunction(GR_CMP_ALWAYS); } -/************************************************************************/ -/************************** Depth Test SetUp ****************************/ -/************************************************************************/ -void fxDDDepthFunc(GLcontext *ctx, GLenum func) +/* + * Evaluate all depth-test state and make the Glide calls. + */ +static void +fxSetupDepthTest(GLcontext *ctx) { - fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; - tfxUnitsState *us=&fxMesa->unitsState; - GrCmpFnc_t dfunc; - - switch(func) { - case GL_NEVER: - dfunc=GR_CMP_NEVER; - break; - case GL_LESS: - dfunc=GR_CMP_LESS; - break; - case GL_GEQUAL: - dfunc=GR_CMP_GEQUAL; - break; - case GL_LEQUAL: - dfunc=GR_CMP_LEQUAL; - break; - case GL_GREATER: - dfunc=GR_CMP_GREATER; - break; - case GL_NOTEQUAL: - dfunc=GR_CMP_NOTEQUAL; - break; - case GL_EQUAL: - dfunc=GR_CMP_EQUAL; - break; - case GL_ALWAYS: - dfunc=GR_CMP_ALWAYS; - break; - default: - fprintf(stderr,"fx Driver: internal error in fxDDDepthFunc()\n"); - fxCloseHardware(); - exit(-1); - break; + if (ctx->Depth.Test) { + GrCmpFnc_t dfunc; + switch (ctx->Depth.Func) { + case GL_NEVER: + dfunc = GR_CMP_NEVER; + break; + case GL_LESS: + dfunc = GR_CMP_LESS; + break; + case GL_GEQUAL: + dfunc = GR_CMP_GEQUAL; + break; + case GL_LEQUAL: + dfunc = GR_CMP_LEQUAL; + break; + case GL_GREATER: + dfunc = GR_CMP_GREATER; + break; + case GL_NOTEQUAL: + dfunc = GR_CMP_NOTEQUAL; + break; + case GL_EQUAL: + dfunc = GR_CMP_EQUAL; + break; + case GL_ALWAYS: + dfunc = GR_CMP_ALWAYS; + break; + default: + gl_problem(ctx, "bad depth mode in fxSetupDepthTest"); + dfunc = GR_CMP_ALWAYS; + } + FX_grDepthBufferFunction(dfunc); + FX_grDepthMask(ctx->Depth.Mask); } - - if(dfunc!=us->depthTestFunc) { - us->depthTestFunc=dfunc; - fxMesa->new_state |= FX_NEW_DEPTH; - ctx->Driver.RenderStart = fxSetupFXUnits; + else { + /* depth test always passes, don't update Z buffer */ + FX_grDepthBufferFunction(GR_CMP_ALWAYS); + FX_grDepthMask(FXFALSE); } - } -void fxDDDepthMask(GLcontext *ctx, GLboolean flag) -{ - fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; - tfxUnitsState *us=&fxMesa->unitsState; - if(flag!=us->depthMask) { - us->depthMask=flag; - fxMesa->new_state |= FX_NEW_DEPTH; - ctx->Driver.RenderStart = fxSetupFXUnits; +/* + * Evaluate all stencil state and make the Glide calls. + */ +static GrStencil_t +fxConvertGLStencilOp(GLenum op) +{ + switch (op) { + case GL_KEEP: + return GR_STENCILOP_KEEP; + case GL_ZERO: + return GR_STENCILOP_ZERO; + case GL_REPLACE: + return GR_STENCILOP_REPLACE; + case GL_INCR: + return GR_STENCILOP_INCR_CLAMP; + case GL_DECR: + return GR_STENCILOP_DECR_CLAMP; + case GL_INVERT: + return GR_STENCILOP_INVERT; + default: + gl_problem(NULL, "bad stencil op in fxConvertGLStencilOp"); } + return GR_STENCILOP_KEEP; /* never get, silence compiler warning */ } -static void fxSetupDepthTest(GLcontext *ctx) +/* + * This function is called just before any rendering is done. + * It will validate the stencil parameters. + */ +static void +fxSetupStencilTest(GLcontext *ctx) { - fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; - tfxUnitsState *us=&fxMesa->unitsState; + if (ctx->Stencil.Enabled) { + GrStencil_t sfail = fxConvertGLStencilOp(ctx->Stencil.FailFunc); + GrStencil_t zfail = fxConvertGLStencilOp(ctx->Stencil.ZFailFunc); + GrStencil_t zpass = fxConvertGLStencilOp(ctx->Stencil.ZPassFunc); + FX_grStencilOp(sfail, zfail, zpass); + FX_grStencilFunc(ctx->Stencil.Function - GL_NEVER, + ctx->Stencil.Ref, ctx->Stencil.ValueMask); + FX_grStencilMask(ctx->Stencil.WriteMask); + FX_grEnable(GR_STENCIL_MODE_EXT); + } + else { + FX_grDisable(GR_STENCIL_MODE_EXT); + } +} - if(us->depthTestEnabled) - FX_grDepthBufferFunction(us->depthTestFunc); - else - FX_grDepthBufferFunction(GR_CMP_ALWAYS); - FX_grDepthMask(us->depthMask); +/* + * Set the state so that stencil is either enabled or disabled. + * This is called from Mesa only. Glide is invoked at + * setup time, not now. + */ +static void +fxDDEnableStencil(GLcontext *ctx, GLboolean state) +{ + fxMesaContext fxMesa = FX_CONTEXT(ctx); + (void) state; + fxMesa->new_state |= FX_NEW_STENCIL; + ctx->Driver.RenderStart = fxSetupFXUnits; } + /************************************************************************/ /**************************** Color Mask SetUp **************************/ /************************************************************************/ @@ -1410,14 +1437,20 @@ static void fxSetupColorMask(GLcontext *ctx) { fxMesaContext fxMesa = FX_CONTEXT(ctx); - FX_grColorMask(ctx->Color.ColorMask[RCOMP] || - ctx->Color.ColorMask[GCOMP] || - ctx->Color.ColorMask[BCOMP], - ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer); + if (ctx->Color.DrawBuffer == GL_NONE) { + FX_grColorMask(FXFALSE, FXFALSE); + } + else { + FX_grColorMask(ctx->Color.ColorMask[RCOMP] || + ctx->Color.ColorMask[GCOMP] || + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer); + } } + /************************************************************************/ /**************************** Fog Mode SetUp ****************************/ /************************************************************************/ @@ -1582,59 +1615,71 @@ static void fxSetupCull(GLcontext *ctx) void fxDDEnable(GLcontext *ctx, GLenum cap, GLboolean state) { - fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; - tfxUnitsState *us=&fxMesa->unitsState; + fxMesaContext fxMesa = FX_CONTEXT(ctx); + tfxUnitsState *us = &fxMesa->unitsState; if (MESA_VERBOSE&VERBOSE_DRIVER) { - fprintf(stderr,"fxmesa: fxDDEnable(...)\n"); + fprintf(stderr,"fxmesa: fxDDEnable(...)\n"); } switch(cap) { - case GL_ALPHA_TEST: - if(state!=us->alphaTestEnabled) { - us->alphaTestEnabled=state; - fxMesa->new_state |= FX_NEW_ALPHA; + case GL_ALPHA_TEST: + if(state!=us->alphaTestEnabled) { + us->alphaTestEnabled=state; + fxMesa->new_state |= FX_NEW_ALPHA; + ctx->Driver.RenderStart = fxSetupFXUnits; + } + break; + case GL_BLEND: + if(state!=us->blendEnabled) { + us->blendEnabled=state; + fxMesa->new_state |= FX_NEW_BLEND; + ctx->Driver.RenderStart = fxSetupFXUnits; + } + break; + case GL_DEPTH_TEST: + fxMesa->new_state |= FX_NEW_DEPTH; ctx->Driver.RenderStart = fxSetupFXUnits; - } - break; - case GL_BLEND: - if(state!=us->blendEnabled) { - us->blendEnabled=state; - fxMesa->new_state |= FX_NEW_BLEND; + break; + case GL_DITHER: + if (state) + FX_grDitherMode(GR_DITHER_4x4); + else + FX_grDitherMode(GR_DITHER_DISABLE); + break; + case GL_SCISSOR_TEST: + fxMesa->new_state |= FX_NEW_SCISSOR; ctx->Driver.RenderStart = fxSetupFXUnits; - } - break; - case GL_DEPTH_TEST: - if(state!=us->depthTestEnabled) { - us->depthTestEnabled=state; - fxMesa->new_state |= FX_NEW_DEPTH; + break; + case GL_SHARED_TEXTURE_PALETTE_EXT: + fxDDTexUseGlbPalette(ctx, state); + break; + case GL_FOG: + fxMesa->new_state |= FX_NEW_FOG; ctx->Driver.RenderStart = fxSetupFXUnits; - } - break; - case GL_SCISSOR_TEST: - fxMesa->new_state |= FX_NEW_SCISSOR; - ctx->Driver.RenderStart = fxSetupFXUnits; - break; - case GL_FOG: - fxMesa->new_state |= FX_NEW_FOG; - ctx->Driver.RenderStart = fxSetupFXUnits; - break; - case GL_CULL_FACE: - fxMesa->new_state |= FX_NEW_CULL; - ctx->Driver.RenderStart = fxSetupFXUnits; - break; - case GL_LINE_SMOOTH: - case GL_POINT_SMOOTH: - case GL_POLYGON_SMOOTH: - case GL_TEXTURE_2D: + break; + case GL_CULL_FACE: + fxMesa->new_state |= FX_NEW_CULL; + ctx->Driver.RenderStart = fxSetupFXUnits; + break; + case GL_LINE_SMOOTH: + case GL_LINE_STIPPLE: + case GL_POINT_SMOOTH: + case GL_POLYGON_SMOOTH: + case GL_TEXTURE_2D: fxMesa->new_state |= FX_NEW_TEXTURING; ctx->Driver.RenderStart = fxSetupFXUnits; break; - default: - ; /* XXX no-op??? */ + case GL_STENCIL_TEST: + fxMesa->new_state |= FX_NEW_STENCIL; + ctx->Driver.RenderStart = fxSetupFXUnits; + break; + default: + ; /* no-op */ } } + #if 0 /* Multipass to do GL_BLEND texture functions @@ -1663,11 +1708,17 @@ static GLboolean fxMultipassBlend(struct vertex_buffer *VB, GLuint pass) } fxDDDepthMask(ctx, FALSE); } + /* + * Disable stencil as well. + */ + if (ctx->Stencil.Enabled) { + fxDDEnableStencil(ctx, GL_FALSE); + } /* Enable Cc*Ct mode */ - /* ??? Set the Constant Color ??? */ + /* XXX Set the Constant Color ? */ fxDDEnable(ctx, GL_BLEND, GL_TRUE); - fxDDBlendFunc(ctx, ???, ???); - fxSetupTextureSingleTMU(ctx, ???); + fxDDBlendFunc(ctx, XXX, XXX); + fxSetupTextureSingleTMU(ctx, XXX); fxSetupBlend(ctx); fxSetupDepthTest(ctx); break; @@ -1675,10 +1726,11 @@ static GLboolean fxMultipassBlend(struct vertex_buffer *VB, GLuint pass) case 2: /* Reset everything back to normal */ fxMesa->unitsState = fxMesa->restoreUnitsState; - fxMesa->setupdone &= ???; - fxSetupTextureSingleTMU(ctx, ???); + fxMesa->setupdone &= XXX; + fxSetupTextureSingleTMU(ctx, XXX); fxSetupBlend(ctx); fxSetupDepthTest(ctx); + fxSetupStencilText(ctx); break; } @@ -1724,13 +1776,15 @@ static GLboolean fxMultipassTexture( struct vertex_buffer *VB, GLuint pass ) case GL_ALWAYS: break; default: - fxDDDepthFunc( ctx, GL_EQUAL ); + /*fxDDDepthFunc( ctx, GL_EQUAL );*/ + FX_grDepthBufferFunction(GR_CMP_EQUAL); break; } - fxDDDepthMask( ctx, GL_FALSE ); + /*fxDDDepthMask( ctx, GL_FALSE ); */ + FX_grDepthMask(FXFALSE); } - + fxDDEnableStencil(ctx, GL_FALSE); if (ctx->Texture.Unit[1].EnvMode == GL_MODULATE) { fxDDEnable( ctx, GL_BLEND, GL_TRUE ); fxDDBlendFunc( ctx, GL_DST_COLOR, GL_ZERO ); @@ -1750,6 +1804,7 @@ static GLboolean fxMultipassTexture( struct vertex_buffer *VB, GLuint pass ) fxSetupTextureSingleTMU( ctx, 0 ); fxSetupBlend( ctx ); fxSetupDepthTest( ctx ); + fxSetupStencilTest( ctx ); break; } @@ -1807,10 +1862,13 @@ void fxSetupFXUnits( GLcontext *ctx ) if (newstate & FX_NEW_ALPHA) fxSetupAlphaTest(ctx); - + if (newstate & FX_NEW_DEPTH) fxSetupDepthTest(ctx); + if (newstate & FX_NEW_STENCIL) + fxSetupStencilTest(ctx); + if (newstate & FX_NEW_FOG) fxSetupFog(ctx); @@ -1822,14 +1880,11 @@ void fxSetupFXUnits( GLcontext *ctx ) if (newstate & FX_NEW_CULL) fxSetupCull(ctx); - fxMesa->new_state = 0; /* ctx->Driver.RenderStart = 0; */ } } - - #else diff --git a/xc/extras/Mesa/src/FX/fxtexman.c b/xc/extras/Mesa/src/FX/fxtexman.c index 87f309adc..5066efa55 100644 --- a/xc/extras/Mesa/src/FX/fxtexman.c +++ b/xc/extras/Mesa/src/FX/fxtexman.c @@ -146,10 +146,10 @@ static void fxTMUInit(fxMesaContext fxMesa, int tmu) end=FX_grTexMaxAddress(tmu); if(fxMesa->verbose) { - fprintf(stderr,"%s configuration:",(tmu==FX_TMU0) ? "TMU0" : "TMU1"); - fprintf(stderr," Lower texture memory address (%u)\n",(unsigned int)start); - fprintf(stderr," Higher texture memory address (%u)\n",(unsigned int)end); - fprintf(stderr," Splitting Texture memory in 2b blocks:\n"); + fprintf(stderr,"Voodoo %s configuration:",(tmu==FX_TMU0) ? "TMU0" : "TMU1"); + fprintf(stderr,"Voodoo Lower texture memory address (%u)\n",(unsigned int)start); + fprintf(stderr,"Voodoo Higher texture memory address (%u)\n",(unsigned int)end); + fprintf(stderr,"Voodoo Splitting Texture memory in 2b blocks:\n"); } fxMesa->freeTexMem[tmu]=end-start; @@ -162,7 +162,7 @@ static void fxTMUInit(fxMesaContext fxMesa, int tmu) else blockend=blockstart+FX_2MB_SPLIT; if(fxMesa->verbose) - fprintf(stderr," %07u-%07u\n", + fprintf(stderr,"Voodoo %07u-%07u\n", (unsigned int)blockstart,(unsigned int)blockend); tmn=fxTMNewRangeNode(fxMesa, blockstart, blockend); @@ -545,12 +545,8 @@ void fxTMReloadSubMipMapLevel(fxMesaContext fxMesa, fxTexGetInfo(ti->mipmapLevel[0].width, ti->mipmapLevel[0].height, &lodlevel, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - if((ti->info.format==GR_TEXFMT_INTENSITY_8) || - (ti->info.format==GR_TEXFMT_P_8) || - (ti->info.format==GR_TEXFMT_ALPHA_8)) - data=ti->mipmapLevel[level].data+((yoffset*ti->mipmapLevel[level].width)>>1); - else - data=ti->mipmapLevel[level].data+yoffset*ti->mipmapLevel[level].width; + data=ti->mipmapLevel[level].data + + yoffset*ti->mipmapLevel[level].width*ti->mipmapLevel[level].texelSize; switch(tmu) { case FX_TMU0: @@ -651,12 +647,11 @@ void fxTMFreeTexture(fxMesaContext fxMesa, struct gl_texture_object *tObj) fxTMMoveOutTM(fxMesa, tObj); - for(i=0; i<MAX_TEXTURE_LEVELS; i++) { - if (ti->mipmapLevel[i].used && - ti->mipmapLevel[i].translated) + for (i=0; i<MAX_TEXTURE_LEVELS; i++) { + if (ti->mipmapLevel[i].data) { FREE(ti->mipmapLevel[i].data); - - (void)ti->mipmapLevel[i].data; + ti->mipmapLevel[i].data = NULL; + } } switch (ti->whichTMU) { case FX_TMU0: diff --git a/xc/extras/Mesa/src/FX/fxtritmp.h b/xc/extras/Mesa/src/FX/fxtritmp.h index 06df4dcd0..6411d167a 100644 --- a/xc/extras/Mesa/src/FX/fxtritmp.h +++ b/xc/extras/Mesa/src/FX/fxtritmp.h @@ -66,7 +66,9 @@ static void TAG(fx_tri)(GLcontext *ctx, GLuint e1, GLuint e2, GLuint e3, GLuint GLuint facing = (c<0.0) ^ ctx->Polygon.FrontBit; GLubyte (*color)[4] = VB->Color[facing]->data; if (IND & FX_FLAT) { - FX_VB_COLOR(fxMesa, color[pv]); + GOURAUD2(v1,color[pv]); + GOURAUD2(v2,color[pv]); + GOURAUD2(v3,color[pv]); } else { GOURAUD2(v1,color[e1]); GOURAUD2(v2,color[e2]); @@ -103,7 +105,9 @@ static void TAG(fx_tri)(GLcontext *ctx, GLuint e1, GLuint e2, GLuint e3, GLuint } else if (IND & FX_FLAT) { GLubyte (*color)[4] = VB->Color[0]->data; - FX_VB_COLOR(fxMesa, color[pv]); + GOURAUD2(v1,color[pv]); + GOURAUD2(v2,color[pv]); + GOURAUD2(v3,color[pv]); } if (IND & FX_FRONT_BACK) { @@ -168,7 +172,10 @@ static void TAG(fx_quad)(GLcontext *ctx, GLuint e1, GLuint e2, GLuint e3, GLuint facing = (c<0.0) ^ ctx->Polygon.FrontBit; GLubyte (*color)[4] = VB->Color[facing]->data; if (IND & FX_FLAT) { - FX_VB_COLOR(fxMesa, color[pv]); + GOURAUD2(v1,color[pv]); + GOURAUD2(v2,color[pv]); + GOURAUD2(v3,color[pv]); + GOURAUD2(v4,color[pv]); } else { GOURAUD2(v1,color[e1]); GOURAUD2(v2,color[e2]); @@ -206,7 +213,10 @@ static void TAG(fx_quad)(GLcontext *ctx, GLuint e1, GLuint e2, GLuint e3, } else if (IND & FX_FLAT) { GLubyte (*color)[4] = VB->Color[0]->data; - FX_VB_COLOR(fxMesa, color[pv]); + GOURAUD2(v1,color[pv]); + GOURAUD2(v2,color[pv]); + GOURAUD2(v3,color[pv]); + GOURAUD2(v4,color[pv]); } if (IND & FX_FRONT_BACK) { @@ -249,9 +259,10 @@ static void TAG(fx_quad)(GLcontext *ctx, GLuint e1, GLuint e2, GLuint e3, } } -#define DRAW_LINE(tmp0, tmp1, width) \ - do { \ - GrVertex verts[4]; \ +#define DRAW_LINE(tmp0, tmp1, width) \ + do { \ + const float xoff = 0.125, yoff = 0.125; \ + GrVertex verts[4]; \ float dx, dy, wx, wy; \ \ dx = tmp0->x - tmp1->x; \ @@ -270,17 +281,17 @@ static void TAG(fx_quad)(GLcontext *ctx, GLuint e1, GLuint e2, GLuint e3, verts[2] = *tmp1; \ verts[3] = *tmp1; \ \ - verts[0].x = tmp0->x - wx; \ - verts[0].y = tmp0->y - wy; \ + verts[0].x = tmp0->x - wx + xoff; \ + verts[0].y = tmp0->y - wy + yoff; \ \ - verts[1].x = tmp0->x + wx; \ - verts[1].y = tmp0->y + wy; \ + verts[1].x = tmp0->x + wx + xoff; \ + verts[1].y = tmp0->y + wy + yoff; \ \ - verts[2].x = tmp1->x + wx; \ - verts[2].y = tmp1->y + wy; \ + verts[2].x = tmp1->x + wx + xoff; \ + verts[2].y = tmp1->y + wy + yoff; \ \ - verts[3].x = tmp1->x - wx; \ - verts[3].y = tmp1->y - wy; \ + verts[3].x = tmp1->x - wx + xoff; \ + verts[3].y = tmp1->y - wy + yoff; \ \ FX_grDrawPolygonVertexList(4, verts); \ } while (0) @@ -291,28 +302,20 @@ static void TAG(fx_line)(GLcontext *ctx, GLuint e1, GLuint e2, GLuint pv) fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx; struct vertex_buffer *VB=ctx->VB; fxVertex *gWin = FX_DRIVER_DATA(VB)->verts; - GLubyte (* const color)[4] = VB->Color[0]->data; + GLubyte (* const color)[4] = VB->ColorPtr->data; GrVertex *v1 = (GrVertex *)gWin[e1].f; GrVertex *v2 = (GrVertex *)gWin[e2].f; GLfloat w = ctx->Line.Width*.5; - if (IND & FX_FLAT) - { - FX_VB_COLOR(fxMesa, color[pv]); - if (IND & FX_ANTIALIAS) -#if FX_USE_PARGB - { - GLuint v1argb = v1->argb; - GLuint v2argb = v2->argb; - v1->argb = (color[pv][ACOMP] << 24) | (v1argb & 0x00FFFFFF); - v2->argb = (color[pv][ACOMP] << 24) | (v2argb & 0x00FFFFFF); - } -#else - v1->a = v2->a = UBYTE_COLOR_TO_FLOAT_255_COLOR(color[pv][3]); -#endif + if (IND & FX_FLAT) { + v1->r = v2->r = UBYTE_COLOR_TO_FLOAT_255_COLOR(color[pv][0]); + v1->g = v2->g = UBYTE_COLOR_TO_FLOAT_255_COLOR(color[pv][1]); + v1->b = v2->b = UBYTE_COLOR_TO_FLOAT_255_COLOR(color[pv][2]); + v1->a = v2->a = UBYTE_COLOR_TO_FLOAT_255_COLOR(color[pv][3]); } else if (IND & FX_TWOSIDE) { + /* XXX use signed area of the polygon to determine front/back color choice */ GOURAUD2(v1,color[e1]); GOURAUD2(v2,color[e2]); } @@ -331,8 +334,7 @@ static void TAG(fx_line)(GLcontext *ctx, GLuint e1, GLuint e2, GLuint pv) else DRAW_LINE(v1,v2,w); - if (IND & FX_FRONT_BACK) - { + if (IND & FX_FRONT_BACK) { FX_grColorMask(ctx->Color.ColorMask[RCOMP] || ctx->Color.ColorMask[GCOMP] || ctx->Color.ColorMask[BCOMP], |