From d81d2aeca8ee43ddec39a043a5acb4cb44be70ac Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 7 May 2004 17:30:31 +0000 Subject: [PATCH] Add support for the 3rd and 4th texture units. The actual number of available units is configurable via the texture_units option. --- src/mesa/drivers/dri/i830/i830_context.c | 35 +- src/mesa/drivers/dri/i830/i830_context.h | 23 +- src/mesa/drivers/dri/i830/i830_debug.c | 49 ++- src/mesa/drivers/dri/i830/i830_screen.c | 15 + src/mesa/drivers/dri/i830/i830_screen.h | 6 + src/mesa/drivers/dri/i830/i830_state.c | 82 +++- src/mesa/drivers/dri/i830/i830_texmem.c | 21 +- src/mesa/drivers/dri/i830/i830_texstate.c | 443 +++++++++++----------- src/mesa/drivers/dri/i830/i830_tris.c | 13 +- 9 files changed, 405 insertions(+), 282 deletions(-) diff --git a/src/mesa/drivers/dri/i830/i830_context.c b/src/mesa/drivers/dri/i830/i830_context.c index 97a9f793fc2..1c169e1d33f 100644 --- a/src/mesa/drivers/dri/i830/i830_context.c +++ b/src/mesa/drivers/dri/i830/i830_context.c @@ -64,6 +64,7 @@ #include "utils.h" +#include "xmlpool.h" /* for symbolic values of enum-type options */ #ifndef I830_DEBUG int I830_DEBUG = (0); #endif @@ -75,9 +76,6 @@ int I830_DEBUG = (0); #define DRIVER_DATE "20040506" -const char __driConfigOptions[] = { 0 }; -const GLuint __driNConfigOptions = 0; - static const GLubyte *i830DDGetString( GLcontext *ctx, GLenum name ) { const char * chipset; @@ -248,6 +246,8 @@ GLboolean i830CreateContext( const __GLcontextModes *mesaVis, imesa->sarea = saPriv; imesa->glBuffer = NULL; + driParseConfigFiles (&imesa->optionCache, &screen->optionCache, + screen->driScrnPriv->myNum, "i830"); (void) memset( imesa->texture_heaps, 0, sizeof( imesa->texture_heaps ) ); make_empty_list( & imesa->swapped ); @@ -263,16 +263,16 @@ GLboolean i830CreateContext( const __GLcontextModes *mesaVis, sizeof( struct i830_texture_object_t ), (destroy_texture_object_t *) i830DestroyTexObj ); - /* Set the maximum texture size small enough that we can guarantee - * that both texture units can bind a maximal texture and have them + * that every texture unit can bind a maximal texture and have them * in memory at once. */ ctx = imesa->glCtx; - ctx->Const.MaxTextureUnits = 2; - ctx->Const.MaxTextureImageUnits = 2; - ctx->Const.MaxTextureCoordUnits = 2; + ctx->Const.MaxTextureUnits = driQueryOptioni(&imesa->optionCache, + "texture_units"); + ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits; + ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits; /* FIXME: driCalculateMaxTextureLevels assumes that mipmaps are tightly * FIXME: packed, but they're not in Intel graphics hardware. @@ -478,16 +478,21 @@ static void i830XMesaWindowMoved( i830ContextPtr imesa ) GLboolean i830UnbindContext(__DRIcontextPrivate *driContextPriv) { i830ContextPtr imesa = (i830ContextPtr) driContextPriv->driverPrivate; + unsigned i; + if (imesa) { /* Might want to change this so texblend isn't always updated */ imesa->dirty |= (I830_UPLOAD_CTX | I830_UPLOAD_BUFFERS | I830_UPLOAD_STIPPLE | I830_UPLOAD_TEXBLEND0 | - I830_UPLOAD_TEXBLEND1); + I830_UPLOAD_TEXBLEND1 | + I830_UPLOAD_TEXBLEND2 | + I830_UPLOAD_TEXBLEND3); - if (imesa->CurrentTexObj[0]) imesa->dirty |= I830_UPLOAD_TEX0; - if (imesa->CurrentTexObj[1]) imesa->dirty |= I830_UPLOAD_TEX1; + for ( i = 0 ; i < imesa->glCtx->Const.MaxTextureUnits ; i++ ) { + if (imesa->CurrentTexObj[i]) imesa->dirty |= I830_UPLOAD_TEX_N( i ); + } } return GL_TRUE; } @@ -549,10 +554,10 @@ void i830GetLock( i830ContextPtr imesa, GLuint flags ) I830_UPLOAD_BUFFERS | I830_UPLOAD_STIPPLE); - if(imesa->CurrentTexObj[0]) imesa->dirty |= I830_UPLOAD_TEX0; - if(imesa->CurrentTexObj[1]) imesa->dirty |= I830_UPLOAD_TEX1; - if(imesa->TexBlendWordsUsed[0]) imesa->dirty |= I830_UPLOAD_TEXBLEND0; - if(imesa->TexBlendWordsUsed[1]) imesa->dirty |= I830_UPLOAD_TEXBLEND1; + for ( i = 0 ; i < imesa->glCtx->Const.MaxTextureUnits ; i++ ) { + if(imesa->CurrentTexObj[i]) imesa->dirty |= I830_UPLOAD_TEX_N( i ); + if(imesa->TexBlendWordsUsed[i]) imesa->dirty |= I830_UPLOAD_TEXBLEND_N( i ); + } sarea->perf_boxes = imesa->perf_boxes | I830_BOX_LOST_CONTEXT; sarea->ctxOwner = me; diff --git a/src/mesa/drivers/dri/i830/i830_context.h b/src/mesa/drivers/dri/i830/i830_context.h index 95c2e925e22..6dcaf1febe6 100644 --- a/src/mesa/drivers/dri/i830/i830_context.h +++ b/src/mesa/drivers/dri/i830/i830_context.h @@ -63,6 +63,8 @@ typedef void (*i830_tri_func)(i830ContextPtr, i830Vertex *, i830Vertex *, typedef void (*i830_line_func)(i830ContextPtr, i830Vertex *, i830Vertex *); typedef void (*i830_point_func)(i830ContextPtr, i830Vertex *); +#define I830_MAX_TEXTURE_UNITS 4 + #define I830_FALLBACK_TEXTURE 0x1 #define I830_FALLBACK_DRAW_BUFFER 0x2 #define I830_FALLBACK_READ_BUFFER 0x4 @@ -80,14 +82,14 @@ struct i830_context_t /*From I830 stuff*/ int TextureMode; GLuint renderindex; - GLuint TexBlendWordsUsed[I830_TEXBLEND_COUNT]; - GLuint TexBlend[I830_TEXBLEND_COUNT][I830_TEXBLEND_SIZE]; - GLuint Init_TexBlend[I830_TEXBLEND_COUNT][I830_TEXBLEND_SIZE]; - GLuint Init_TexBlendWordsUsed[I830_TEXBLEND_COUNT]; - GLuint Init_TexBlendColorPipeNum[I830_TEXBLEND_COUNT]; - GLuint TexBlendColorPipeNum[I830_TEXBLEND_COUNT]; + GLuint TexBlendWordsUsed[I830_MAX_TEXTURE_UNITS]; + GLuint TexBlend[I830_MAX_TEXTURE_UNITS][I830_TEXBLEND_SIZE]; + GLuint Init_TexBlend[I830_MAX_TEXTURE_UNITS][I830_TEXBLEND_SIZE]; + GLuint Init_TexBlendWordsUsed[I830_MAX_TEXTURE_UNITS]; + GLuint Init_TexBlendColorPipeNum[I830_MAX_TEXTURE_UNITS]; + GLuint TexBlendColorPipeNum[I830_MAX_TEXTURE_UNITS]; GLuint Init_BufferSetup[I830_DEST_SETUP_SIZE]; - GLuint LodBias[2]; + GLuint LodBias[I830_MAX_TEXTURE_UNITS]; GLenum palette_format; GLuint palette[256]; @@ -124,7 +126,7 @@ struct i830_context_t driTexHeap * texture_heaps[1]; driTextureObject swapped; - struct i830_texture_object_t *CurrentTexObj[2]; + struct i830_texture_object_t *CurrentTexObj[I830_MAX_TEXTURE_UNITS]; /* Rasterization and vertex state: */ @@ -217,6 +219,11 @@ struct i830_context_t __DRIscreenPrivate *driScreen; i830ScreenPrivate *i830Screen; I830SAREAPtr sarea; + + /** + * Configuration cache + */ + driOptionCache optionCache; }; diff --git a/src/mesa/drivers/dri/i830/i830_debug.c b/src/mesa/drivers/dri/i830/i830_debug.c index 02c36bec7da..56940e223cf 100644 --- a/src/mesa/drivers/dri/i830/i830_debug.c +++ b/src/mesa/drivers/dri/i830/i830_debug.c @@ -318,9 +318,26 @@ void i830EmitHwStateLockedDebug( i830ContextPtr imesa ) for(i = 0; i < I830_TEXTURE_COUNT; i++) { if ((imesa->dirty & I830_UPLOAD_TEX_N(i)) && imesa->CurrentTexObj[i]) { + unsigned * TexState; + imesa->sarea->dirty |= I830_UPLOAD_TEX_N(i); - memcpy(imesa->sarea->TexState[i], - imesa->CurrentTexObj[i]->Setup, + + switch( i ) { + case 0: + case 1: + TexState = & imesa->sarea->TexState[i]; + break; + + case 2: + TexState = & imesa->sarea->TexState2; + break; + + case 3: + TexState = & imesa->sarea->TexState3; + break; + } + + memcpy(TexState, imesa->CurrentTexObj[i]->Setup, sizeof(imesa->sarea->TexState[i])); i830DumpTextureState(imesa, i); } @@ -329,11 +346,33 @@ void i830EmitHwStateLockedDebug( i830ContextPtr imesa ) for(i = 0; i < I830_TEXBLEND_COUNT; i++) { if (imesa->dirty & I830_UPLOAD_TEXBLEND_N(i)) { + unsigned * TexBlendState; + unsigned * words_used; + imesa->sarea->dirty |= I830_UPLOAD_TEXBLEND_N(i); - memcpy(imesa->sarea->TexBlendState[i],imesa->TexBlend[i], + + switch( i ) { + case 0: + case 1: + TexBlendState = imesa->sarea->TexBlendState[i]; + words_used = & imesa->sarea->TexBlendStateWordsUsed[i]; + break; + + case 2: + TexBlendState = imesa->sarea->TexBlendState2; + words_used = & imesa->sarea->TexBlendStateWordsUsed2; + break; + + case 3: + TexBlendState = imesa->sarea->TexBlendState3; + words_used = & imesa->sarea->TexBlendStateWordsUsed3; + break; + } + + memcpy(TexBlendState, imesa->TexBlend[i], imesa->TexBlendWordsUsed[i] * 4); - imesa->sarea->TexBlendStateWordsUsed[i] = - imesa->TexBlendWordsUsed[i]; + *words_used = imesa->TexBlendWordsUsed[i]; + i830DumpTextureBlendState(imesa, i); } } diff --git a/src/mesa/drivers/dri/i830/i830_screen.c b/src/mesa/drivers/dri/i830/i830_screen.c index b0117210f52..1aa4027096c 100644 --- a/src/mesa/drivers/dri/i830/i830_screen.c +++ b/src/mesa/drivers/dri/i830/i830_screen.c @@ -50,6 +50,16 @@ #include "i830_dri.h" +#include "xmlpool.h" + +const char __driConfigOptions[] = +DRI_CONF_BEGIN + DRI_CONF_SECTION_PERFORMANCE + DRI_CONF_MAX_TEXTURE_UNITS(4,2,4) + DRI_CONF_SECTION_END +DRI_CONF_END; +const GLuint __driNConfigOptions = 1; + static int i830_malloc_proxy_buf(drmBufMapPtr buffers) { @@ -152,6 +162,11 @@ static GLboolean i830InitDriver(__DRIscreenPrivate *sPriv) return GL_FALSE; } + /* parse information in __driConfigOptions */ + driParseOptionInfo (&i830Screen->optionCache, + __driConfigOptions, __driNConfigOptions); + + i830Screen->driScrnPriv = sPriv; sPriv->private = (void *)i830Screen; diff --git a/src/mesa/drivers/dri/i830/i830_screen.h b/src/mesa/drivers/dri/i830/i830_screen.h index 8153828ffc1..eabb6084ad4 100644 --- a/src/mesa/drivers/dri/i830/i830_screen.h +++ b/src/mesa/drivers/dri/i830/i830_screen.h @@ -37,6 +37,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include "dri_util.h" +#include "xmlconfig.h" typedef struct { @@ -82,6 +83,11 @@ typedef struct int drmMinor; int irq_active; + + /** + * Configuration cache with default values for all contexts + */ + driOptionCache optionCache; }i830ScreenPrivate; diff --git a/src/mesa/drivers/dri/i830/i830_state.c b/src/mesa/drivers/dri/i830/i830_state.c index a8edf854264..9bd97379cac 100644 --- a/src/mesa/drivers/dri/i830/i830_state.c +++ b/src/mesa/drivers/dri/i830/i830_state.c @@ -1266,15 +1266,19 @@ static void i830DepthRange( GLcontext *ctx, void i830PrintDirty( const char *msg, GLuint state ) { - fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s\n", + fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s%s%s%s%s\n", msg, (unsigned int) state, (state & I830_UPLOAD_TEX0) ? "upload-tex0, " : "", (state & I830_UPLOAD_TEX1) ? "upload-tex1, " : "", + (state & I830_UPLOAD_TEX2) ? "upload-tex2, " : "", + (state & I830_UPLOAD_TEX3) ? "upload-tex3, " : "", (state & I830_UPLOAD_CTX) ? "upload-ctx, " : "", (state & I830_UPLOAD_BUFFERS) ? "upload-bufs, " : "", (state & I830_UPLOAD_TEXBLEND0) ? "upload-blend0, " : "", (state & I830_UPLOAD_TEXBLEND1) ? "upload-blend1, " : "", + (state & I830_UPLOAD_TEXBLEND2) ? "upload-blend2, " : "", + (state & I830_UPLOAD_TEXBLEND3) ? "upload-blend3, " : "", (state & I830_UPLOAD_STIPPLE) ? "stipple, " : "" ); } @@ -1288,24 +1292,44 @@ void i830EmitHwStateLocked( i830ContextPtr imesa ) if (I830_DEBUG & DEBUG_STATE) i830PrintDirty( __FUNCTION__, imesa->dirty ); - if ((imesa->dirty & I830_UPLOAD_TEX0_IMAGE) && imesa->CurrentTexObj[0]) - i830UploadTexImagesLocked(imesa, imesa->CurrentTexObj[0]); - if ((imesa->dirty & I830_UPLOAD_TEX1_IMAGE) && imesa->CurrentTexObj[1]) - i830UploadTexImagesLocked(imesa, imesa->CurrentTexObj[1]); + for ( i = 0 ; i < imesa->glCtx->Const.MaxTextureUnits ; i++ ) { + if ( ((imesa->dirty & I830_UPLOAD_TEX_N_IMAGE( i )) != 0) + && (imesa->CurrentTexObj[i] != NULL) ) { + i830UploadTexImagesLocked(imesa, imesa->CurrentTexObj[i]); + } + } + if (imesa->dirty & I830_UPLOAD_CTX) { memcpy( imesa->sarea->ContextState, imesa->Setup, sizeof(imesa->Setup) ); } - for (i = 0; i < I830_TEXTURE_COUNT; i++) { + for ( i = 0 ; i < imesa->glCtx->Const.MaxTextureUnits ; i++ ) { if ((imesa->dirty & I830_UPLOAD_TEX_N(i)) && imesa->CurrentTexObj[i]) { + unsigned * TexState; + imesa->sarea->dirty |= I830_UPLOAD_TEX_N(i); - memcpy(imesa->sarea->TexState[i], - imesa->CurrentTexObj[i]->Setup, + + switch( i ) { + case 0: + case 1: + TexState = imesa->sarea->TexState[i]; + break; + + case 2: + TexState = imesa->sarea->TexState2; + break; + + case 3: + TexState = imesa->sarea->TexState3; + break; + } + + memcpy(TexState, imesa->CurrentTexObj[i]->Setup, sizeof(imesa->sarea->TexState[i])); - imesa->sarea->TexState[i][I830_TEXREG_TM0S3] &= ~TM0S3_LOD_BIAS_MASK; - imesa->sarea->TexState[i][I830_TEXREG_TM0S3] |= imesa->LodBias[i]; + TexState[I830_TEXREG_TM0S3] &= ~TM0S3_LOD_BIAS_MASK; + TexState[I830_TEXREG_TM0S3] |= imesa->LodBias[i]; /* Update the LRU usage */ if (imesa->CurrentTexObj[i]->base.memBlock) @@ -1315,13 +1339,34 @@ void i830EmitHwStateLocked( i830ContextPtr imesa ) } /* Need to figure out if texturing state, or enable changed. */ - for (i = 0; i < I830_TEXBLEND_COUNT; i++) { + for ( i = 0 ; i < imesa->glCtx->Const.MaxTextureUnits ; i++ ) { if (imesa->dirty & I830_UPLOAD_TEXBLEND_N(i)) { + unsigned * TexBlendState; + unsigned * words_used; + imesa->sarea->dirty |= I830_UPLOAD_TEXBLEND_N(i); - memcpy(imesa->sarea->TexBlendState[i],imesa->TexBlend[i], + + switch( i ) { + case 0: + case 1: + TexBlendState = imesa->sarea->TexBlendState[i]; + words_used = & imesa->sarea->TexBlendStateWordsUsed[i]; + break; + + case 2: + TexBlendState = imesa->sarea->TexBlendState2; + words_used = & imesa->sarea->TexBlendStateWordsUsed2; + break; + + case 3: + TexBlendState = imesa->sarea->TexBlendState3; + words_used = & imesa->sarea->TexBlendStateWordsUsed3; + break; + } + + memcpy(TexBlendState, imesa->TexBlend[i], imesa->TexBlendWordsUsed[i] * 4); - imesa->sarea->TexBlendStateWordsUsed[i] = - imesa->TexBlendWordsUsed[i]; + *words_used = imesa->TexBlendWordsUsed[i]; } } @@ -1378,11 +1423,10 @@ void i830DDInitState( GLcontext *ctx ) imesa->mask_alpha = GL_FALSE; /* Zero all texture state */ - for (i = 0; i < I830_TEXBLEND_COUNT; i++) { - for (j = 0; j < I830_TEXBLEND_SIZE; j++) { - imesa->TexBlend[i][j] = 0; - imesa->Init_TexBlend[i][j] = 0; - } + for (i = 0; i < I830_MAX_TEXTURE_UNITS; i++) { + (void) memset( imesa->TexBlend[i], 0, sizeof( imesa->TexBlend[i] ) ); + (void) memset( imesa->Init_TexBlend[i], 0, sizeof( imesa->Init_TexBlend[i] ) ); + imesa->TexBlendWordsUsed[i] = 0; imesa->Init_TexBlendWordsUsed[i] = 0; imesa->TexBlendColorPipeNum[i] = 0; diff --git a/src/mesa/drivers/dri/i830/i830_texmem.c b/src/mesa/drivers/dri/i830/i830_texmem.c index b61ce6f8674..b41957cafc6 100644 --- a/src/mesa/drivers/dri/i830/i830_texmem.c +++ b/src/mesa/drivers/dri/i830/i830_texmem.c @@ -62,7 +62,7 @@ void i830DestroyTexObj(i830ContextPtr imesa, i830TextureObjectPtr t) for ( i = 0 ; i < imesa->glCtx->Const.MaxTextureUnits ; i++ ) { if ( t == imesa->CurrentTexObj[ i ] ) { imesa->CurrentTexObj[ i ] = NULL; - imesa->dirty &= ~(I830_UPLOAD_TEX0 << i); + imesa->dirty &= ~I830_UPLOAD_TEX_N( i ); } } } @@ -162,6 +162,7 @@ static void i830UploadTexLevel( i830ContextPtr imesa, int i830UploadTexImagesLocked( i830ContextPtr imesa, i830TextureObjectPtr t ) { int ofs; + int i; if ( t->base.memBlock == NULL ) { int heap; @@ -178,18 +179,11 @@ int i830UploadTexImagesLocked( i830ContextPtr imesa, i830TextureObjectPtr t ) t->Setup[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | (imesa->i830Screen->textureOffset + ofs)); - if (t == imesa->CurrentTexObj[0]) - imesa->dirty |= I830_UPLOAD_TEX0; - - if (t == imesa->CurrentTexObj[1]) - imesa->dirty |= I830_UPLOAD_TEX1; -#if 0 - if (t == imesa->CurrentTexObj[2]) - I830_STATECHANGE(imesa, I830_UPLOAD_TEX2); - - if (t == imesa->CurrentTexObj[3]) - I830_STATECHANGE(imesa, I830_UPLOAD_TEX3); -#endif + for ( i = 0 ; i < imesa->glCtx->Const.MaxTextureUnits ; i++ ) { + if (t == imesa->CurrentTexObj[i]) { + imesa->dirty |= I830_UPLOAD_TEX_N( i ); + } + } } @@ -202,7 +196,6 @@ int i830UploadTexImagesLocked( i830ContextPtr imesa, i830TextureObjectPtr t ) /* Upload any images that are new */ if (t->base.dirty_images[0]) { - int i; const int numLevels = t->base.lastLevel - t->base.firstLevel + 1; for (i = 0 ; i < numLevels ; i++) { diff --git a/src/mesa/drivers/dri/i830/i830_texstate.c b/src/mesa/drivers/dri/i830/i830_texstate.c index e3d6819d88d..d27ac916604 100644 --- a/src/mesa/drivers/dri/i830/i830_texstate.c +++ b/src/mesa/drivers/dri/i830/i830_texstate.c @@ -168,7 +168,8 @@ static void i830SetTexImages( i830ContextPtr imesa, t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAX_MIP_MASK; t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_MIP_MASK; t->Setup[I830_TEXREG_TM0S3] |= ((numLevels - 1)*4) << TM0S3_MIN_MIP_SHIFT; - t->dirty = I830_UPLOAD_TEX0 | I830_UPLOAD_TEX1; + t->dirty = I830_UPLOAD_TEX0 | I830_UPLOAD_TEX1 + | I830_UPLOAD_TEX2 | I830_UPLOAD_TEX3; LOCK_HARDWARE( imesa ); i830UploadTexImagesLocked( imesa, t ); @@ -197,6 +198,16 @@ static void i830SetTexImages( i830ContextPtr imesa, * \c GL_ZERO as combine inputs (which the code already supports). It can * also handle the \c GL_MODULATE_ADD_ATI mode. Is it worth investigating * partial support for the extension? + * + * \todo + * Some thought needs to be put into the way combiners work. The driver + * treats the hardware as if there's a specific combine unit tied to each + * texture unit. That's why there's the special case for a disabled texture + * unit. That's not the way the hardware works. In reality, there are 4 + * texture units and four general instruction slots. Each instruction slot + * can use any texture as an input. There's no need for this wierd "no-op" + * stuff. If texture units 0 and 3 are enabled, the instructions to combine + * them should be in slots 0 and 1, not 0 and 3 with two no-ops inbetween. */ static void i830UpdateTexEnv( GLcontext *ctx, GLuint unit ) @@ -241,215 +252,247 @@ static void i830UpdateTexEnv( GLcontext *ctx, GLuint unit ) _mesa_lookup_enum_by_nr(texUnit->EnvMode)); - switch(texUnit->_CurrentCombine->ModeRGB) { - case GL_REPLACE: - blendop = TEXBLENDOP_ARG1; - break; - case GL_MODULATE: - blendop = TEXBLENDOP_MODULATE; - break; - case GL_ADD: - blendop = TEXBLENDOP_ADD; - break; - case GL_ADD_SIGNED: - blendop = TEXBLENDOP_ADDSIGNED; - break; - case GL_INTERPOLATE: - blendop = TEXBLENDOP_BLEND; - break; - case GL_SUBTRACT: - blendop = TEXBLENDOP_SUBTRACT; - break; - case GL_DOT3_RGB_EXT: - case GL_DOT3_RGBA_EXT: - /* The EXT version of the DOT3 extension does not support the - * scale factor, but the ARB version (and the version in OpenGL - * 1.3) does. - */ - rgb_shift = 0; - alpha_shift = 0; - /* FALLTHROUGH */ - - case GL_DOT3_RGB: - case GL_DOT3_RGBA: - blendop = TEXBLENDOP_DOT3; - break; - default: - return; + if ( !texUnit->_ReallyEnabled ) { + imesa->TexBlend[unit][0] = (STATE3D_MAP_BLEND_OP_CMD(unit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[unit][1] = (STATE3D_MAP_BLEND_OP_CMD(unit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[unit][2] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[unit][3] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendColorPipeNum[unit] = 0; + imesa->TexBlendWordsUsed[unit] = 4; } - - blendop |= (rgb_shift << TEXOP_SCALE_SHIFT); - - switch(texUnit->_CurrentCombine->ModeA) { - case GL_REPLACE: - ablendop = TEXBLENDOP_ARG1; - break; - case GL_MODULATE: - ablendop = TEXBLENDOP_MODULATE; - break; - case GL_ADD: - ablendop = TEXBLENDOP_ADD; - break; - case GL_ADD_SIGNED: - ablendop = TEXBLENDOP_ADDSIGNED; - break; - case GL_INTERPOLATE: - ablendop = TEXBLENDOP_BLEND; - break; - case GL_SUBTRACT: - ablendop = TEXBLENDOP_SUBTRACT; + else { + switch(texUnit->_CurrentCombine->ModeRGB) { + case GL_REPLACE: + blendop = TEXBLENDOP_ARG1; break; - default: - return; - } - - if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT) - || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ) { - ablendop = TEXBLENDOP_DOT3; - } - - ablendop |= (alpha_shift << TEXOP_SCALE_SHIFT); - - /* Handle RGB args */ - for( i = 0 ; i < numColorArgs ; i++ ) { - const int op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR; - - assert( (op >= 0) && (op <= 3) ); - switch(texUnit->_CurrentCombine->SourceRGB[i]) { - case GL_TEXTURE: - args_RGB[i] = TEXBLENDARG_TEXEL0 + unit; - break; - case GL_TEXTURE0: - case GL_TEXTURE1: - case GL_TEXTURE2: - case GL_TEXTURE3: - args_RGB[i] = TEXBLENDARG_TEXEL0 - + (texUnit->_CurrentCombine->SourceRGB[i] & 0x03); + case GL_MODULATE: + blendop = TEXBLENDOP_MODULATE; break; - case GL_CONSTANT: - args_RGB[i] = TEXBLENDARG_FACTOR_N; - need_constant_color = GL_TRUE; + case GL_ADD: + blendop = TEXBLENDOP_ADD; break; - case GL_PRIMARY_COLOR: - args_RGB[i] = TEXBLENDARG_DIFFUSE; + case GL_ADD_SIGNED: + blendop = TEXBLENDOP_ADDSIGNED; break; - case GL_PREVIOUS: - args_RGB[i] = TEXBLENDARG_CURRENT; + case GL_INTERPOLATE: + blendop = TEXBLENDOP_BLEND; break; - case GL_ONE: - args_RGB[i] = TEXBLENDARG_ONE; + case GL_SUBTRACT: + blendop = TEXBLENDOP_SUBTRACT; break; - case GL_ZERO: - args_RGB[i] = TEXBLENDARG_ONE | TEXBLENDARG_INV_ARG; + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGBA_EXT: + /* The EXT version of the DOT3 extension does not support the + * scale factor, but the ARB version (and the version in OpenGL + * 1.3) does. + */ + rgb_shift = 0; + alpha_shift = 0; + /* FALLTHROUGH */ + + case GL_DOT3_RGB: + case GL_DOT3_RGBA: + blendop = TEXBLENDOP_DOT3; break; - default: + default: return; } - /* Xor is used so that GL_ONE_MINUS_SRC_COLOR with GL_ZERO - * works correctly. - */ - args_RGB[i] ^= op_rgb[op]; - } - - /* Handle A args */ - for( i = 0 ; i < numAlphaArgs ; i++ ) { - const int op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA; + blendop |= (rgb_shift << TEXOP_SCALE_SHIFT); - assert( (op >= 0) && (op <= 1) ); - switch(texUnit->_CurrentCombine->SourceA[i]) { - case GL_TEXTURE: - args_A[i] = TEXBLENDARG_TEXEL0 + unit; + switch(texUnit->_CurrentCombine->ModeA) { + case GL_REPLACE: + ablendop = TEXBLENDOP_ARG1; break; - case GL_TEXTURE0: - case GL_TEXTURE1: - case GL_TEXTURE2: - case GL_TEXTURE3: - args_A[i] = TEXBLENDARG_TEXEL0 - + (texUnit->_CurrentCombine->SourceA[i] & 0x03); + case GL_MODULATE: + ablendop = TEXBLENDOP_MODULATE; break; - case GL_CONSTANT: - args_A[i] = TEXBLENDARG_FACTOR_N; - need_constant_color = GL_TRUE; + case GL_ADD: + ablendop = TEXBLENDOP_ADD; break; - case GL_PRIMARY_COLOR: - args_A[i] = TEXBLENDARG_DIFFUSE; + case GL_ADD_SIGNED: + ablendop = TEXBLENDOP_ADDSIGNED; break; - case GL_PREVIOUS: - args_A[i] = TEXBLENDARG_CURRENT; + case GL_INTERPOLATE: + ablendop = TEXBLENDOP_BLEND; break; - case GL_ONE: - args_A[i] = TEXBLENDARG_ONE; + case GL_SUBTRACT: + ablendop = TEXBLENDOP_SUBTRACT; break; - case GL_ZERO: - args_A[i] = TEXBLENDARG_ONE | TEXBLENDARG_INV_ARG; - break; - default: + default: return; } - /* We cheat. :) The register values for this are the same as for - * RGB. Xor is used so that GL_ONE_MINUS_SRC_ALPHA with GL_ZERO - * works correctly. - */ - args_A[i] ^= op_rgb[op]; - } + if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT) + || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ) { + ablendop = TEXBLENDOP_DOT3; + } - /* Native Arg1 == Arg0 in GL_EXT_texture_env_combine spec */ - /* Native Arg2 == Arg1 in GL_EXT_texture_env_combine spec */ - /* Native Arg0 == Arg2 in GL_EXT_texture_env_combine spec */ + ablendop |= (alpha_shift << TEXOP_SCALE_SHIFT); + + /* Handle RGB args */ + for( i = 0 ; i < numColorArgs ; i++ ) { + const int op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR; + + assert( (op >= 0) && (op <= 3) ); + switch(texUnit->_CurrentCombine->SourceRGB[i]) { + case GL_TEXTURE: + args_RGB[i] = TEXBLENDARG_TEXEL0 + unit; + break; + case GL_TEXTURE0: + case GL_TEXTURE1: + case GL_TEXTURE2: + case GL_TEXTURE3: + args_RGB[i] = TEXBLENDARG_TEXEL0 + + (texUnit->_CurrentCombine->SourceRGB[i] & 0x03); + break; + case GL_CONSTANT: + args_RGB[i] = TEXBLENDARG_FACTOR_N; + need_constant_color = GL_TRUE; + break; + case GL_PRIMARY_COLOR: + args_RGB[i] = TEXBLENDARG_DIFFUSE; + break; + case GL_PREVIOUS: + args_RGB[i] = TEXBLENDARG_CURRENT; + break; + case GL_ONE: + args_RGB[i] = TEXBLENDARG_ONE; + break; + case GL_ZERO: + args_RGB[i] = TEXBLENDARG_ONE | TEXBLENDARG_INV_ARG; + break; + default: + return; + } + + /* Xor is used so that GL_ONE_MINUS_SRC_COLOR with GL_ZERO + * works correctly. + */ + args_RGB[i] ^= op_rgb[op]; + } - /* When we render we need to figure out which is the last really enabled - * tex unit, and put last stage on it - */ + /* Handle A args */ + for( i = 0 ; i < numAlphaArgs ; i++ ) { + const int op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA; + + assert( (op >= 0) && (op <= 1) ); + switch(texUnit->_CurrentCombine->SourceA[i]) { + case GL_TEXTURE: + args_A[i] = TEXBLENDARG_TEXEL0 + unit; + break; + case GL_TEXTURE0: + case GL_TEXTURE1: + case GL_TEXTURE2: + case GL_TEXTURE3: + args_A[i] = TEXBLENDARG_TEXEL0 + + (texUnit->_CurrentCombine->SourceA[i] & 0x03); + break; + case GL_CONSTANT: + args_A[i] = TEXBLENDARG_FACTOR_N; + need_constant_color = GL_TRUE; + break; + case GL_PRIMARY_COLOR: + args_A[i] = TEXBLENDARG_DIFFUSE; + break; + case GL_PREVIOUS: + args_A[i] = TEXBLENDARG_CURRENT; + break; + case GL_ONE: + args_A[i] = TEXBLENDARG_ONE; + break; + case GL_ZERO: + args_A[i] = TEXBLENDARG_ONE | TEXBLENDARG_INV_ARG; + break; + default: + return; + } + + /* We cheat. :) The register values for this are the same as for + * RGB. Xor is used so that GL_ONE_MINUS_SRC_ALPHA with GL_ZERO + * works correctly. + */ + args_A[i] ^= op_rgb[op]; + } - imesa->TexBlendColorPipeNum[unit] = 0; - - /* Build color pipeline */ - - used = 0; - imesa->TexBlend[unit][used++] = (STATE3D_MAP_BLEND_OP_CMD(unit) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_MODIFY_PARMS | - blendop); - - imesa->TexBlend[unit][used++] = (STATE3D_MAP_BLEND_OP_CMD(unit) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_MODIFY_PARMS | - ablendop); - - for ( i = 0 ; i < numColorArgs ; i++ ) { - imesa->TexBlend[unit][used++] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | - tex_blend_rgb[i] | - args_RGB[i]); - } + /* Native Arg1 == Arg0 in GL_EXT_texture_env_combine spec */ + /* Native Arg2 == Arg1 in GL_EXT_texture_env_combine spec */ + /* Native Arg0 == Arg2 in GL_EXT_texture_env_combine spec */ - for ( i = 0 ; i < numAlphaArgs ; i++ ) { - imesa->TexBlend[unit][used++] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | - tex_blend_a[i] | - args_A[i]); - } + /* When we render we need to figure out which is the last really enabled + * tex unit, and put last stage on it + */ + imesa->TexBlendColorPipeNum[unit] = 0; + used = 0; + + /* Build color pipeline */ + + imesa->TexBlend[unit][used++] = (STATE3D_MAP_BLEND_OP_CMD(unit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_MODIFY_PARMS | + blendop); + + imesa->TexBlend[unit][used++] = (STATE3D_MAP_BLEND_OP_CMD(unit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_MODIFY_PARMS | + ablendop); + + for ( i = 0 ; i < numColorArgs ; i++ ) { + imesa->TexBlend[unit][used++] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | + tex_blend_rgb[i] | + args_RGB[i]); + } - if ( need_constant_color ) { - GLubyte r, g, b, a; - const GLfloat * const fc = texUnit->EnvColor; + for ( i = 0 ; i < numAlphaArgs ; i++ ) { + imesa->TexBlend[unit][used++] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | + tex_blend_a[i] | + args_A[i]); + } - FLOAT_COLOR_TO_UBYTE_COLOR(r, fc[RCOMP]); - FLOAT_COLOR_TO_UBYTE_COLOR(g, fc[GCOMP]); - FLOAT_COLOR_TO_UBYTE_COLOR(b, fc[BCOMP]); - FLOAT_COLOR_TO_UBYTE_COLOR(a, fc[ACOMP]); - imesa->TexBlend[unit][used++] = STATE3D_COLOR_FACTOR_CMD(unit); - imesa->TexBlend[unit][used++] = ((a << 24) | (r << 16) | (g << 8) | b); + if ( need_constant_color ) { + GLubyte r, g, b, a; + const GLfloat * const fc = texUnit->EnvColor; + + FLOAT_COLOR_TO_UBYTE_COLOR(r, fc[RCOMP]); + FLOAT_COLOR_TO_UBYTE_COLOR(g, fc[GCOMP]); + FLOAT_COLOR_TO_UBYTE_COLOR(b, fc[BCOMP]); + FLOAT_COLOR_TO_UBYTE_COLOR(a, fc[ACOMP]); + + imesa->TexBlend[unit][used++] = STATE3D_COLOR_FACTOR_CMD(unit); + imesa->TexBlend[unit][used++] = ((a << 24) | (r << 16) | (g << 8) | b); + } + + imesa->TexBlendWordsUsed[unit] = used; } - imesa->TexBlendWordsUsed[unit] = used; I830_STATECHANGE( imesa, I830_UPLOAD_TEXBLEND_N(unit) ); } @@ -507,7 +550,7 @@ static GLboolean enable_tex_common( GLcontext *ctx, GLuint unit ) imesa->CurrentTexObj[unit]->base.bound &= ~(1U << unit); } - I830_STATECHANGE(imesa, (I830_UPLOAD_TEX0<CurrentTexObj[unit] = t; i830TexSetUnit(t, unit); } @@ -541,7 +584,7 @@ static GLboolean enable_tex_rect( GLcontext *ctx, GLuint unit ) mcs |= TEXCOORDS_ARE_IN_TEXELUNITS; if (mcs != t->Setup[I830_TEXREG_MCS]) { - I830_STATECHANGE(imesa, (I830_UPLOAD_TEX0<Setup[I830_TEXREG_MCS] = mcs; } @@ -561,7 +604,7 @@ static GLboolean enable_tex_2d( GLcontext *ctx, GLuint unit ) mcs |= TEXCOORDS_ARE_NORMAL; if (mcs != t->Setup[I830_TEXREG_MCS]) { - I830_STATECHANGE(imesa, (I830_UPLOAD_TEX0<Setup[I830_TEXREG_MCS] = mcs; } @@ -569,9 +612,8 @@ static GLboolean enable_tex_2d( GLcontext *ctx, GLuint unit ) } -static GLboolean disable_tex0( GLcontext *ctx ) +static GLboolean disable_tex( GLcontext *ctx, int unit ) { - const int unit = 0; i830ContextPtr imesa = I830_CONTEXT(ctx); /* This is happening too often. I need to conditionally send diffuse @@ -593,34 +635,7 @@ static GLboolean disable_tex0( GLcontext *ctx ) imesa->TexEnvImageFmt[unit] = 0; imesa->dirty &= ~(I830_UPLOAD_TEX_N(unit)); - imesa->TexBlend[unit][0] = (STATE3D_MAP_BLEND_OP_CMD(unit) | - TEXPIPE_COLOR | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - DISABLE_TEX_CNTRL_STAGE | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[unit][1] = (STATE3D_MAP_BLEND_OP_CMD(unit) | - TEXPIPE_ALPHA | - ENABLE_TEXOUTPUT_WRT_SEL | - TEXOP_OUTPUT_CURRENT | - TEXOP_SCALE_1X | - TEXOP_MODIFY_PARMS | - TEXBLENDOP_ARG1); - imesa->TexBlend[unit][2] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | - TEXPIPE_COLOR | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlend[unit][3] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | - TEXPIPE_ALPHA | - TEXBLEND_ARG1 | - TEXBLENDARG_MODIFY_PARMS | - TEXBLENDARG_CURRENT); - imesa->TexBlendColorPipeNum[unit] = 0; - imesa->TexBlendWordsUsed[unit] = 4; - I830_STATECHANGE(imesa, (I830_UPLOAD_TEXBLEND_N(unit))); + i830UpdateTexEnv( ctx, unit ); return GL_TRUE; } @@ -643,10 +658,8 @@ static GLboolean i830UpdateTexUnit( GLcontext *ctx, GLuint unit ) else if (texUnit->_ReallyEnabled) { return GL_FALSE; } - else if (unit == 0) { - return disable_tex0( ctx ); - } else { + disable_tex( ctx, unit ); return GL_TRUE; } } diff --git a/src/mesa/drivers/dri/i830/i830_tris.c b/src/mesa/drivers/dri/i830/i830_tris.c index addbfff965b..6dcaa73f18c 100644 --- a/src/mesa/drivers/dri/i830/i830_tris.c +++ b/src/mesa/drivers/dri/i830/i830_tris.c @@ -764,10 +764,7 @@ static void i830RenderStart( GLcontext *ctx ) if (index & _TNL_BITS_TEX_ANY) { int i, last_stage = 0; - /* Still using 2 as max tex units, but this code is fine for all - * 8 units supported by mesa: - */ - for (i = 0; i < 2 ; i++) + for (i = 0; i < ctx->Const.MaxTextureUnits ; i++) if (index & _TNL_BIT_TEX(i)) last_stage = i+1; @@ -1010,7 +1007,11 @@ void i830Fallback( i830ContextPtr imesa, GLuint bit, GLboolean mode ) /* Initialization. */ /**********************************************************************/ - +/** + * \bug + * How are the magic numbers 12 and 26 in the call to \c _tnl_init_vertices + * derived? + */ void i830InitTriFuncs( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); @@ -1031,7 +1032,7 @@ void i830InitTriFuncs( GLcontext *ctx ) tnl->Driver.Render.Interp = _tnl_interp; _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, - 22 * sizeof(GLfloat) ); + 26 * sizeof(GLfloat) ); I830_CONTEXT(ctx)->verts = (char *)tnl->clipspace.vertex_buf; } -- 2.30.2