diff options
| author | Ian Romanick <idr@us.ibm.com> | 2004-05-07 17:30:31 +0000 | 
|---|---|---|
| committer | Ian Romanick <idr@us.ibm.com> | 2004-05-07 17:30:31 +0000 | 
| commit | d81d2aeca8ee43ddec39a043a5acb4cb44be70ac (patch) | |
| tree | 954d5e2024d4f7bf68e9eb40d514630fba0bbd0c /src | |
| parent | f539860f792feaec69f8033f2b0b86cc2212ee0b (diff) | |
Add support for the 3rd and 4th texture units.  The actual number of
available units is configurable via the texture_units option.
Diffstat (limited to 'src')
| -rw-r--r-- | src/mesa/drivers/dri/i830/i830_context.c | 35 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i830/i830_context.h | 23 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i830/i830_debug.c | 49 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i830/i830_screen.c | 15 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i830/i830_screen.h | 6 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i830/i830_state.c | 82 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i830/i830_texmem.c | 21 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i830/i830_texstate.c | 435 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i830/i830_tris.c | 13 | 
9 files changed, 401 insertions, 278 deletions
| diff --git a/src/mesa/drivers/dri/i830/i830_context.c b/src/mesa/drivers/dri/i830/i830_context.c index 97a9f793fc..1c169e1d33 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 95c2e925e2..6dcaf1febe 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 02c36bec7d..56940e223c 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 b0117210f5..1aa4027096 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 8153828ffc..eabb6084ad 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 <sys/time.h>  #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 a8edf85426..9bd97379ca 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 b61ce6f867..b41957cafc 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 e3d6819d88..d27ac91660 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); -   /* When we render we need to figure out which is the last really enabled -    * tex unit, and put last stage on it -    */ +      /* Handle RGB args */ +      for( i = 0 ; i < numColorArgs ; i++ ) { +	 const int op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR; -   imesa->TexBlendColorPipeNum[unit] = 0; +	 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; +	 } -   /* Build color pipeline */ +	 /* Xor is used so that GL_ONE_MINUS_SRC_COLOR with GL_ZERO +	  * works correctly. +	  */ +	 args_RGB[i] ^= op_rgb[op]; +      } -   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); +      /* Handle A args */ +      for( i = 0 ; i < numAlphaArgs ; i++ ) { +	 const int op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA; -   imesa->TexBlend[unit][used++] = (STATE3D_MAP_BLEND_OP_CMD(unit) | -				    TEXPIPE_ALPHA | -				    ENABLE_TEXOUTPUT_WRT_SEL | -				    TEXOP_OUTPUT_CURRENT | -				    TEXOP_MODIFY_PARMS | -				    ablendop); +	 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; +	 } -   for ( i = 0 ; i < numColorArgs ; i++ ) { -      imesa->TexBlend[unit][used++] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | -				       tex_blend_rgb[i] | -				       args_RGB[i]); -   } +	 /* 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]; +      } -   for ( i = 0 ; i < numAlphaArgs ; i++ ) { -      imesa->TexBlend[unit][used++] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | -				       tex_blend_a[i] | -				       args_A[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 */ +      /* 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]); +      } + +      for ( i = 0 ; i < numAlphaArgs ; i++ ) { +	 imesa->TexBlend[unit][used++] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | +					  tex_blend_a[i] | +					  args_A[i]); +      } -   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]); +      if ( need_constant_color ) { +	 GLubyte r, g, b, a; +	 const GLfloat * const fc = texUnit->EnvColor; -      imesa->TexBlend[unit][used++] = STATE3D_COLOR_FACTOR_CMD(unit); -      imesa->TexBlend[unit][used++] = ((a << 24) | (r << 16) | (g << 8) | b); +	 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<<unit)); +      I830_STATECHANGE( imesa, I830_UPLOAD_TEX_N(unit) );        imesa->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<<unit)); +      I830_STATECHANGE( imesa, I830_UPLOAD_TEX_N(unit) );        t->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<<unit)); +      I830_STATECHANGE( imesa, I830_UPLOAD_TEX_N(unit) );        t->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 addbfff965..6dcaa73f18 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;  } | 
