Browse Source

Add support for the 3rd and 4th texture units. The actual number of

available units is configurable via the texture_units option.
tags/R300_DRIVER_0
Ian Romanick 21 years ago
parent
commit
d81d2aeca8

+ 20
- 15
src/mesa/drivers/dri/i830/i830_context.c View File

@@ -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;

+ 15
- 8
src/mesa/drivers/dri/i830/i830_context.h View File

@@ -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;
};



+ 44
- 5
src/mesa/drivers/dri/i830/i830_debug.c View File

@@ -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);
}
}

+ 15
- 0
src/mesa/drivers/dri/i830/i830_screen.c View File

@@ -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;


+ 6
- 0
src/mesa/drivers/dri/i830/i830_screen.h View File

@@ -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;



+ 63
- 19
src/mesa/drivers/dri/i830/i830_state.c View File

@@ -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;

+ 7
- 14
src/mesa/drivers/dri/i830/i830_texmem.c View File

@@ -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++) {

+ 228
- 215
src/mesa/drivers/dri/i830/i830_texstate.c View File

@@ -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<<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;
}
}

+ 7
- 6
src/mesa/drivers/dri/i830/i830_tris.c View File

@@ -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;
}

Loading…
Cancel
Save