xHere are a bunch of patches for MGA texturing code.
mga_mipmap.patch:
- Fix tpitch when firstLevel > baseLevel.
- Fix some confusion regarding level vs. hwlevel with dirty_images[0] and
tex size calculation.
- Call mgaUploadSubImage() starting from firstLevel not 0 and make it take
the real level as the argument instead of hwlevel. Eliminates a bunch of
ugly warnings.
I sent this one earlier but no-one picked it up for the dri tree.
It's already in Mesa embedded-2-brach.
mga_accel_rop.patch:
- Make the two remaining LogicOp fallbacks depend on ACCEL_ROP.
It looks like the right thing to do but I maybe wrong...
mga_texwrap.patch:
- Remove misleading comment about supported wrap modes.
- Remove GL_CLAMP_TO_BORDER stuff. Cut'n'paste error?
mga_minfilter.patch
- Min filters GL_NEAREST and GL_LINEAR should use the base level texture.
Probably not the optimal way to solve this but it works ;)
mga_texformat.patch:
- Add MESA_FORMAT_{AL88,A8,L8,I8} for G400.
- G200 doesn't support MESA_FORMAT_YCBCR.
mga_texenv.patch:
- Fix all texenv modes for all texformats on G400.
- Implement GL_DECAL using linear blend mode.
The G400 docs aren't very clear on this subject so I'm not entirely sure
if it will work correctly with multi texturing. Anyone have a good test?
- GL_BLEND suffers from hardware limitations. All three components of Cc
must be equal. Additionally GL_INTENSITY requires that Ac is 0.0 or 1.0.
If Cc!=0.0 (or Ac!=0.0 for GL_INTENSITY) we need both units to get
things done in a single pass.
- Passes glean's texenv test (32bpp and 16bpp). And without fallbacks if I
change the envcolor to comply with the aforementioned restrictions. Also
Quake3 looks ok with the patch ;)
- I also removed the useless MGA_FALLBACK_BORDER_MODE thing. It didn't
print anything since the debug print stopped at the first enabled
fallback bit which was the texture fallback.
--
Ville Syrj�l�
[EMAIL PROTECTED]
http://www.sci.fi/~syrjala/
diff -urN mga.orig/mgastate.c mga/mgastate.c
--- mga.orig/mgastate.c 2003-07-12 22:40:08.000000000 +0300
+++ mga/mgastate.c 2003-07-12 22:39:47.000000000 +0300
@@ -123,9 +123,11 @@
/* BlendEquation sets ColorLogicOpEnabled in an unexpected
* manner.
*/
+#if !defined(ACCEL_ROP)
FALLBACK( ctx, MGA_FALLBACK_LOGICOP,
(ctx->Color.ColorLogicOpEnabled &&
ctx->Color.LogicOp != GL_COPY));
+#endif
}
static void mgaDDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
@@ -900,9 +902,11 @@
/* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
*/
+#if !defined(ACCEL_ROP)
FALLBACK( ctx, MGA_FALLBACK_LOGICOP,
(ctx->Color.ColorLogicOpEnabled &&
ctx->Color.LogicOp != GL_COPY));
+#endif
break;
case GL_DEPTH_TEST:
FLUSH_BATCH( mmesa );
diff -urN mga.orig/mga_texstate.c mga/mga_texstate.c
--- mga.orig/mga_texstate.c 2003-07-12 22:40:08.000000000 +0300
+++ mga/mga_texstate.c 2003-07-12 22:42:30.000000000 +0300
@@ -106,14 +106,17 @@
* GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
* Yes, this looks overly complicated, but it's all needed.
*/
-
- firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5);
- firstLevel = MAX2(firstLevel, tObj->BaseLevel);
- lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5);
- lastLevel = MAX2(lastLevel, tObj->BaseLevel);
- lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
- lastLevel = MIN2(lastLevel, tObj->MaxLevel);
- lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
+ if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
+ firstLevel = lastLevel = tObj->BaseLevel;
+ } else {
+ firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5);
+ firstLevel = MAX2(firstLevel, tObj->BaseLevel);
+ lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5);
+ lastLevel = MAX2(lastLevel, tObj->BaseLevel);
+ lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
+ lastLevel = MIN2(lastLevel, tObj->MaxLevel);
+ lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
+ }
log2Width = tObj->Image[firstLevel]->WidthLog2;
log2Height = tObj->Image[firstLevel]->HeightLog2;
width = tObj->Image[firstLevel]->Width;
diff -urN mga.orig/mgatex.c mga/mgatex.c
--- mga.orig/mgatex.c 2003-07-12 22:40:08.000000000 +0300
+++ mga/mgatex.c 2003-07-12 22:42:45.000000000 +0300
@@ -449,6 +445,7 @@
switch (pname) {
case GL_TEXTURE_MIN_FILTER:
+ driSwapOutTextureObject( (driTextureObject *) t );
case GL_TEXTURE_MAG_FILTER:
FLUSH_BATCH(mmesa);
mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter );
diff -urN mga.orig/mga_texstate.c mga/mga_texstate.c
--- mga.orig/mga_texstate.c 2003-07-12 22:44:37.000000000 +0300
+++ mga/mga_texstate.c 2003-07-12 22:46:49.000000000 +0300
@@ -134,7 +134,7 @@
totalSize = 0;
for ( i = 0 ; i < numLevels ; i++ ) {
- const struct gl_texture_image * const texImage = tObj->Image[i];
+ const struct gl_texture_image * const texImage = tObj->Image[i+firstLevel];
if ( (texImage == NULL)
|| ((i != 0)
@@ -143,10 +143,10 @@
}
t->offsets[i] = totalSize;
- t->base.dirty_images[0] |= (1<<i);
+ t->base.dirty_images[0] |= (1<<(i+firstLevel));
- totalSize += ((MAX2( texImage->Width, 8 ) *
- MAX2( texImage->Height, 8 ) *
+ totalSize += ((texImage->Width *
+ texImage->Height *
baseImage->TexFormat->TexelBytes) + 31) & ~31;
}
@@ -171,7 +171,7 @@
*/
t->setup.texctl |= TMC_tpitchlin_enable;
- t->setup.texctl |= (baseImage->Width & (2048 - 1)) << TMC_tpitchext_SHIFT;
+ t->setup.texctl |= (width & (2048 - 1)) << TMC_tpitchext_SHIFT;
/* G400 specifies the number of mip levels in a strange way. Since there
diff -urN mga.orig/mgatexmem.c mga/mgatexmem.c
--- mga.orig/mgatexmem.c 2003-07-12 22:44:37.000000000 +0300
+++ mga/mgatexmem.c 2003-07-12 22:47:41.000000000 +0300
@@ -89,13 +89,13 @@
* been hardware accelerated.
*/
static void mgaUploadSubImage( mgaContextPtr mmesa,
- mgaTextureObjectPtr t, GLint hwlevel )
+ mgaTextureObjectPtr t, GLint level )
{
struct gl_texture_image * texImage;
unsigned offset;
unsigned texelBytes;
unsigned length;
- const int level = hwlevel + t->firstLevel;
+ const int hwlevel = level - t->firstLevel;
if ( (hwlevel < 0)
@@ -265,7 +265,7 @@
fprintf(stderr, "[%s:%d] dirty_images[0] = 0x%04x\n",
__FILE__, __LINE__, t->base.dirty_images[0] );
- for (i = 0 ; i <= t->lastLevel ; i++) {
+ for (i = t->firstLevel ; i <= t->lastLevel ; i++) {
if ( (t->base.dirty_images[0] & (1U << i)) != 0 ) {
mgaUploadSubImage( mmesa, t, i );
}
diff -urN mga.orig/mga_texstate.c mga/mga_texstate.c
--- mga.orig/mga_texstate.c 2003-07-12 22:51:53.000000000 +0300
+++ mga/mga_texstate.c 2003-07-12 23:20:07.000000000 +0300
@@ -234,14 +234,13 @@
t->setup.texctl2 |= TMC_decalblend_enable;
break;
case GL_BLEND:
- FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
+ t->texenv_fallback = GL_TRUE;
break;
default:
break;
}
}
-
#define MGA_DISABLE 0
#define MGA_REPLACE 1
#define MGA_MODULATE 2
@@ -260,29 +259,160 @@
(0),
/* GL_REPLACE
+ * Cv = Cs
+ * Av = Af
*/
(TD0_color_sel_arg1 |
TD0_alpha_arg2_diffuse |
- TD0_alpha_sel_arg2 ),
+ TD0_alpha_sel_arg2),
/* GL_MODULATE
+ * Cv = Cf Cs
+ * Av = Af
*/
(TD0_color_arg2_diffuse |
TD0_color_sel_mul |
TD0_alpha_arg2_diffuse |
- TD0_alpha_sel_mul),
+ TD0_alpha_sel_arg2),
/* GL_DECAL
+ * Cv = Cs
+ * Av = Af
*/
(TD0_color_sel_arg1 |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_arg2),
- /* GL_BLEND
+ /* GL_BLEND (Cc == 0.0)
+ * Cv = Cf ( 1 - Cs )
+ * Av = Af
+ */
+ (TD0_color_arg1_inv_enable |
+ TD0_color_arg2_diffuse |
+ TD0_color_sel_mul |
+ TD0_alpha_arg2_diffuse |
+ TD0_alpha_sel_arg2),
+
+ /* GL_ADD
+ * Cv = Cf + Cs
+ * Av = Af
+ */
+ (TD0_color_arg2_diffuse |
+ TD0_color_add_add |
+ TD0_color_sel_add |
+ TD0_alpha_arg2_diffuse |
+ TD0_alpha_sel_arg2),
+ },
+
+ /* Unit 1:
+ */
+ {
+ /* Disable combiner stage
*/
(0),
+
+ /* GL_REPLACE
+ * Cv = Cs
+ * Av = Ap
+ */
+ (TD0_color_sel_arg1 |
+ TD0_alpha_arg2_prevstage |
+ TD0_alpha_sel_arg2),
+
+ /* GL_MODULATE
+ * Cv = Cp Cs
+ * Av = Ap
+ */
+ (TD0_color_arg2_prevstage |
+ TD0_color_sel_mul |
+ TD0_alpha_arg2_prevstage |
+ TD0_alpha_sel_arg2),
+
+ /* GL_DECAL
+ * Cv = Cs
+ * Av = Ap
+ */
+ (TD0_color_sel_arg1 |
+ TD0_alpha_arg2_prevstage |
+ TD0_alpha_sel_arg2),
+
+ /* GL_BLEND (Cc == 0.0)
+ * Cv = Cp ( 1 - Cs )
+ * Av = Ap
+ */
+ (TD0_color_arg1_inv_enable |
+ TD0_color_arg2_prevstage |
+ TD0_color_sel_mul |
+ TD0_alpha_arg2_prevstage |
+ TD0_alpha_sel_arg2),
+
+ /* GL_ADD
+ * Cv = Cp + Cs
+ * Av = Ap
+ */
+ (TD0_color_arg2_prevstage |
+ TD0_color_add_add |
+ TD0_color_sel_add |
+ TD0_alpha_arg2_prevstage |
+ TD0_alpha_sel_arg2),
+ },
+};
+
+static const GLuint g400_color_alpha_combine[][MGA_MAX_COMBFUNC] =
+{
+ /* Unit 0:
+ */
+ {
+ /* Disable combiner stage
+ */
+ (0),
+
+ /* GL_REPLACE
+ * Cv = Cs
+ * Av = As
+ */
+ (TD0_color_sel_arg1 |
+ TD0_alpha_sel_arg1),
+
+ /* GL_MODULATE
+ * Cv = Cf Cs
+ * Av = Af As
+ */
+ (TD0_color_arg2_diffuse |
+ TD0_color_sel_mul |
+ TD0_alpha_arg2_diffuse |
+ TD0_alpha_sel_mul),
+
+ /* GL_DECAL
+ * tmp = Cf ( 1 - As )
+ * Cv = tmp + Cs As
+ * Av = Af
+ */
+ (TD0_color_arg2_diffuse |
+ TD0_color_alpha_currtex |
+ TD0_color_alpha1inv_enable |
+ TD0_color_arg1mul_alpha1 |
+ TD0_color_blend_enable |
+ TD0_color_arg1add_mulout |
+ TD0_color_arg2add_mulout |
+ TD0_color_add_add |
+ TD0_color_sel_add |
+ TD0_alpha_arg2_diffuse |
+ TD0_alpha_sel_arg2),
+
+ /* GL_BLEND (Cc == 0.0)
+ * Cv = Cf ( 1 - Cs )
+ * Av = Af As
+ */
+ (TD0_color_arg1_inv_enable |
+ TD0_color_arg2_diffuse |
+ TD0_color_sel_mul |
+ TD0_alpha_arg2_diffuse |
+ TD0_alpha_sel_mul),
/* GL_ADD
+ * Cv = Cf + Cs
+ * Av = Af As
*/
(TD0_color_arg2_diffuse |
TD0_color_add_add |
@@ -299,33 +429,53 @@
(0),
/* GL_REPLACE
+ * Cv = Cs
+ * Av = As
*/
(TD0_color_sel_arg1 |
- TD0_alpha_arg2_diffuse |
- TD0_alpha_sel_arg2 ),
+ TD0_alpha_sel_arg1),
/* GL_MODULATE
+ * Cv = Cp Cs
+ * Av = Ap As
*/
(TD0_color_arg2_prevstage |
- TD0_color_alpha_prevstage |
TD0_color_sel_mul |
TD0_alpha_arg2_prevstage |
TD0_alpha_sel_mul),
/* GL_DECAL
+ * tmp = Cp ( 1 - As )
+ * Cv = tmp + Cs As
+ * Av = Ap
*/
- (TD0_color_sel_arg1 |
+ (TD0_color_arg2_prevstage |
+ TD0_color_alpha_currtex |
+ TD0_color_alpha1inv_enable |
+ TD0_color_arg1mul_alpha1 |
+ TD0_color_blend_enable |
+ TD0_color_arg1add_mulout |
+ TD0_color_arg2add_mulout |
+ TD0_color_add_add |
+ TD0_color_sel_add |
TD0_alpha_arg2_prevstage |
- TD0_alpha_sel_arg2 ),
+ TD0_alpha_sel_arg2),
- /* GL_BLEND
+ /* GL_BLEND (Cc == 0.0)
+ * Cv = Cp ( 1 - Cs )
+ * Av = Ap As
*/
- (0),
+ (TD0_color_arg1_inv_enable |
+ TD0_color_arg2_prevstage |
+ TD0_color_sel_mul |
+ TD0_alpha_arg2_prevstage |
+ TD0_alpha_sel_mul),
/* GL_ADD
+ * Cv = Cp + Cs
+ * Av = Ap As
*/
(TD0_color_arg2_prevstage |
- TD0_color_alpha_prevstage |
TD0_color_add_add |
TD0_color_sel_add |
TD0_alpha_arg2_prevstage |
@@ -343,20 +493,25 @@
(0),
/* GL_REPLACE
+ * Cv = Cf
+ * Av = As
*/
- (TD0_color_sel_arg2 |
- TD0_color_arg2_diffuse |
- TD0_alpha_sel_arg1 ),
+ (TD0_color_arg2_diffuse |
+ TD0_color_sel_arg2 |
+ TD0_alpha_sel_arg1),
/* GL_MODULATE
- * FIXME: Is this correct?
+ * Cv = Cf
+ * Av = Af As
*/
(TD0_color_arg2_diffuse |
- TD0_color_sel_mul |
+ TD0_color_sel_arg2 |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_mul),
- /* GL_DECAL
+ /* GL_DECAL (undefined)
+ * Cv = Cf
+ * Av = Af
*/
(TD0_color_arg2_diffuse |
TD0_color_sel_arg2 |
@@ -364,16 +519,20 @@
TD0_alpha_sel_arg2),
/* GL_BLEND
+ * Cv = Cf
+ * Av = Af As
*/
(TD0_color_arg2_diffuse |
- TD0_color_sel_mul |
+ TD0_color_sel_arg2 |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_mul),
/* GL_ADD
+ * Cv = Cf
+ * Av = Af As
*/
(TD0_color_arg2_diffuse |
- TD0_color_sel_mul |
+ TD0_color_sel_arg2 |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_mul),
},
@@ -386,21 +545,25 @@
(0),
/* GL_REPLACE
+ * Cv = Cp
+ * Av = As
*/
- (TD0_color_sel_arg2 |
- TD0_color_arg2_diffuse |
- TD0_alpha_sel_arg1 ),
+ (TD0_color_arg2_prevstage |
+ TD0_color_sel_arg2 |
+ TD0_alpha_sel_arg1),
/* GL_MODULATE
- * FIXME: Is this correct?
+ * Cv = Cp
+ * Av = Ap As
*/
(TD0_color_arg2_prevstage |
- TD0_color_alpha_prevstage |
- TD0_color_sel_mul |
+ TD0_color_sel_arg2 |
TD0_alpha_arg2_prevstage |
TD0_alpha_sel_mul),
- /* GL_DECAL
+ /* GL_DECAL (undefined)
+ * Cv = Cp
+ * Av = Ap
*/
(TD0_color_arg2_prevstage |
TD0_color_sel_arg2 |
@@ -408,21 +571,26 @@
TD0_alpha_sel_arg2),
/* GL_BLEND
+ * Cv = Cp
+ * Av = Ap As
*/
- (TD0_color_arg2_diffuse |
- TD0_color_sel_mul |
- TD0_alpha_arg2_diffuse |
+ (TD0_color_arg2_prevstage |
+ TD0_color_sel_arg2 |
+ TD0_alpha_arg2_prevstage |
TD0_alpha_sel_mul),
/* GL_ADD
+ * Cv = Cp
+ * Av = Ap As
*/
(TD0_color_arg2_prevstage |
- TD0_color_sel_mul |
+ TD0_color_sel_arg2 |
TD0_alpha_arg2_prevstage |
TD0_alpha_sel_mul),
},
};
+
static void mgaUpdateTextureEnvG400( GLcontext *ctx, GLuint unit )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
@@ -430,6 +598,7 @@
const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
const struct gl_texture_object *tObj = texUnit->_Current;
GLuint *reg = ((GLuint *)&mmesa->setup.tdualstage0 + unit);
+ mgaTextureObjectPtr t;
GLenum format;
if ( tObj != ctx->Texture.Unit[source].Current2D || !tObj )
@@ -437,127 +606,232 @@
format = tObj->Image[tObj->BaseLevel]->Format;
+ t = (mgaTextureObjectPtr) tObj->DriverData;
+
switch (ctx->Texture.Unit[source].EnvMode) {
case GL_REPLACE:
- if (format == GL_RGB || format == GL_LUMINANCE) {
- *reg = g400_color_combine[unit][MGA_REPLACE];
- }
- else if (format == GL_ALPHA) {
+ if (format == GL_ALPHA) {
*reg = g400_alpha_combine[unit][MGA_REPLACE];
- }
- else {
- *reg = (TD0_color_sel_arg1 |
- TD0_alpha_sel_arg1 );
+ } else if (format == GL_RGB || format == GL_LUMINANCE) {
+ *reg = g400_color_combine[unit][MGA_REPLACE];
+ } else {
+ *reg = g400_color_alpha_combine[unit][MGA_REPLACE];
}
break;
case GL_MODULATE:
- *reg = g400_color_combine[unit][MGA_MODULATE];
+ if (format == GL_ALPHA) {
+ *reg = g400_alpha_combine[unit][MGA_MODULATE];
+ } else if (format == GL_RGB || format == GL_LUMINANCE) {
+ *reg = g400_color_combine[unit][MGA_MODULATE];
+ } else {
+ *reg = g400_color_alpha_combine[unit][MGA_MODULATE];
+ }
break;
+
case GL_DECAL:
if (format == GL_RGB) {
- *reg = g400_color_combine[unit][MGA_DECAL];
+ *reg = g400_color_combine[unit][MGA_DECAL];
+ } else if (format == GL_RGBA) {
+ *reg = g400_color_alpha_combine[unit][MGA_DECAL];
+ if (ctx->Texture._EnabledUnits != 0x03) {
+ /* Linear blending mode needs dual texturing enabled */
+ *(reg+1) = (TD0_color_arg2_prevstage |
+ TD0_color_sel_arg2 |
+ TD0_alpha_arg2_prevstage |
+ TD0_alpha_sel_arg2);
+ mmesa->dualtex_env = GL_TRUE;
+ }
+ } else {
+ /* Undefined */
+ *reg = g400_alpha_combine[unit][MGA_DECAL];
}
- else if ( format == GL_RGBA ) {
-#if 0
+ break;
+
+ case GL_ADD:
+ if (format == GL_ALPHA) {
+ *reg = g400_alpha_combine[unit][MGA_ADD];
+ } else if (format == GL_RGB || format == GL_LUMINANCE) {
+ *reg = g400_color_combine[unit][MGA_ADD];
+ } else if (format == GL_RGBA || format == GL_LUMINANCE_ALPHA) {
+ *reg = g400_color_alpha_combine[unit][MGA_ADD];
+ } else if (format == GL_INTENSITY) {
+ /* Cv = Cf + Cs
+ * Av = Af + As
+ */
if (unit == 0) {
- /* this doesn't work */
*reg = (TD0_color_arg2_diffuse |
- TD0_color_alpha_currtex |
- TD0_color_alpha2inv_enable |
- TD0_color_arg2mul_alpha2 |
- TD0_color_arg1mul_alpha1 |
- TD0_color_blend_enable |
- TD0_color_arg1add_mulout |
- TD0_color_arg2add_mulout |
TD0_color_add_add |
- TD0_color_sel_mul |
+ TD0_color_sel_add |
TD0_alpha_arg2_diffuse |
- TD0_alpha_sel_arg2 );
- }
- else {
+ TD0_alpha_add_enable |
+ TD0_alpha_sel_add);
+ } else {
*reg = (TD0_color_arg2_prevstage |
- TD0_color_alpha_currtex |
- TD0_color_alpha2inv_enable |
- TD0_color_arg2mul_alpha2 |
- TD0_color_arg1mul_alpha1 |
TD0_color_add_add |
TD0_color_sel_add |
TD0_alpha_arg2_prevstage |
- TD0_alpha_sel_arg2 );
+ TD0_alpha_add_enable |
+ TD0_alpha_sel_add);
}
-#else
- /* s/w fallback, pretty sure we can't do in h/w */
- FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
- if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK )
- fprintf( stderr, "FALLBACK: GL_DECAL RGBA texture, unit=%d\n",
- unit );
-#endif
- }
- else {
- *reg = g400_alpha_combine[unit][MGA_DECAL];
}
break;
- case GL_ADD:
- if (format == GL_INTENSITY) {
- if (unit == 0) {
- *reg = ( TD0_color_arg2_diffuse |
- TD0_color_add_add |
- TD0_color_sel_add |
- TD0_alpha_arg2_diffuse |
- TD0_alpha_add_enable |
- TD0_alpha_sel_add);
- }
- else {
- *reg = ( TD0_color_arg2_prevstage |
- TD0_color_add_add |
- TD0_color_sel_add |
- TD0_alpha_arg2_prevstage |
- TD0_alpha_add_enable |
- TD0_alpha_sel_add);
- }
- }
- else if (format == GL_ALPHA) {
- *reg = g400_alpha_combine[unit][MGA_ADD];
- }
- else {
- *reg = g400_color_combine[unit][MGA_ADD];
- }
- break;
-
case GL_BLEND:
if (format == GL_ALPHA) {
- *reg = g400_alpha_combine[unit][MGA_BLEND];
- }
- else {
- FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
- if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK )
- fprintf( stderr, "FALLBACK: GL_BLEND envcolor=0x%08x\n",
- mmesa->envcolor );
-
- /* Do singletexture GL_BLEND with 'all ones' env-color
- * by using both texture units. Multitexture gl_blend
- * is a fallback.
+ *reg = g400_alpha_combine[unit][MGA_BLEND];
+ } else {
+ /* Hardware limitations:
+ * All three components of Cc must be equal.
+ * Also for GL_INTENSITY Ac must be either 0.0 or 1.0.
+ * If Cc != 0.0 (or Ac != 0.0 for GL_INTENSITY) we need both
+ * texture units to pull this off in a single pass.
*/
- if (unit == 0) {
- /* Part 1: R1 = Rf ( 1 - Rt )
- * A1 = Af At
- */
- *reg = ( TD0_color_arg2_diffuse |
- TD0_color_arg1_inv_enable |
- TD0_color_sel_mul |
- TD0_alpha_arg2_diffuse |
- TD0_alpha_sel_arg1);
+ if (mmesa->blend_flags & MGA_BLEND_RGB_ZERO) {
+ if (format == GL_RGB || format == GL_LUMINANCE) {
+ *reg = g400_color_combine[unit][MGA_BLEND];
+ } else if (format == GL_RGBA || format == GL_LUMINANCE_ALPHA) {
+ *reg = g400_color_alpha_combine[unit][MGA_BLEND];
+ } else if (format == GL_INTENSITY) {
+ if (mmesa->blend_flags & MGA_BLEND_ALPHA_ZERO) {
+ /* Cv = Cf ( 1 - Cs )
+ * Av = Af ( 1 - As )
+ */
+ if (unit == 0) {
+ *reg = (TD0_color_arg1_inv_enable |
+ TD0_color_arg2_diffuse |
+ TD0_color_sel_mul |
+ TD0_alpha_arg1_inv_enable |
+ TD0_alpha_arg2_diffuse |
+ TD0_alpha_sel_mul);
+ } else {
+ *reg = (TD0_color_arg1_inv_enable |
+ TD0_color_arg2_prevstage |
+ TD0_color_sel_mul |
+ TD0_alpha_arg1_inv_enable |
+ TD0_alpha_arg2_prevstage |
+ TD0_alpha_sel_mul);
+ }
+ } else if (mmesa->blend_flags & MGA_BLEND_ALPHA_ONE &&
+ ctx->Texture._EnabledUnits != 0x03) {
+ /* C1 = Cf ( 1 - Cs )
+ * A1 = Af ( 1 - As )
+ */
+ *reg = (TD0_color_arg1_inv_enable |
+ TD0_color_arg2_diffuse |
+ TD0_color_sel_mul |
+ TD0_alpha_arg1_inv_enable |
+ TD0_alpha_arg2_diffuse |
+ TD0_alpha_sel_mul);
+ /* Cv = C1
+ * Av = A1 + As
+ */
+ *(reg+1) = (TD0_color_arg2_prevstage |
+ TD0_color_sel_arg2 |
+ TD0_alpha_arg2_prevstage |
+ TD0_alpha_add_enable |
+ TD0_alpha_sel_add);
+ mmesa->dualtex_env = GL_TRUE;
+ } else {
+ t->texenv_fallback = GL_TRUE;
+ }
+ }
+ } else if (mmesa->blend_flags & MGA_BLEND_RGB_EQUAL &&
+ ctx->Texture._EnabledUnits != 0x03) {
+ if (format == GL_RGB || format == GL_LUMINANCE) {
+ /* C1 = Cf ( 1 - Cs )
+ * A1 = Af
+ */
+ *reg = (TD0_color_arg1_inv_enable |
+ TD0_color_arg2_diffuse |
+ TD0_color_sel_mul |
+ TD0_alpha_arg2_diffuse |
+ TD0_alpha_sel_arg2);
+ /* Cv = C1 + Cc Cs
+ * Av = A1
+ */
+ *(reg+1) = (TD0_color_arg2_prevstage |
+ TD0_color_alpha_fcol |
+ TD0_color_arg2mul_alpha2 |
+ TD0_color_arg1add_mulout |
+ TD0_color_add_add |
+ TD0_color_sel_add |
+ TD0_alpha_arg2_prevstage |
+ TD0_alpha_sel_arg2);
+ mmesa->dualtex_env = GL_TRUE;
+ } else if (format == GL_RGBA || format == GL_LUMINANCE_ALPHA) {
+ /* C1 = Cf ( 1 - Cs )
+ * A1 = Af As
+ */
+ *reg = (TD0_color_arg1_inv_enable |
+ TD0_color_arg2_diffuse |
+ TD0_color_sel_mul |
+ TD0_alpha_arg2_diffuse |
+ TD0_alpha_sel_mul);
+ /* Cv = C1 + Cc Cs
+ * Av = A1
+ */
+ *(reg+1) = (TD0_color_arg2_prevstage |
+ TD0_color_alpha_fcol |
+ TD0_color_arg2mul_alpha2 |
+ TD0_color_arg1add_mulout |
+ TD0_color_add_add |
+ TD0_color_sel_add |
+ TD0_alpha_arg2_prevstage |
+ TD0_alpha_sel_arg2);
+ mmesa->dualtex_env = GL_TRUE;
+ } else if (format == GL_INTENSITY) {
+ if (mmesa->blend_flags & MGA_BLEND_ALPHA_ZERO) {
+ /* C1 = Cf ( 1 - Cs )
+ * A1 = Af ( 1 - As )
+ */
+ *reg = (TD0_color_arg1_inv_enable |
+ TD0_color_arg2_diffuse |
+ TD0_color_sel_mul |
+ TD0_alpha_arg1_inv_enable |
+ TD0_alpha_arg2_diffuse |
+ TD0_alpha_sel_mul);
+ /* Cv = C1 + Cc Cs
+ * Av = A1
+ */
+ *(reg+1) = (TD0_color_arg2_prevstage |
+ TD0_color_alpha_fcol |
+ TD0_color_arg2mul_alpha2 |
+ TD0_color_arg1add_mulout |
+ TD0_color_add_add |
+ TD0_color_sel_add |
+ TD0_alpha_arg2_prevstage |
+ TD0_alpha_sel_arg2);
+ mmesa->dualtex_env = GL_TRUE;
+ } else if (mmesa->blend_flags & MGA_BLEND_ALPHA_ONE) {
+ /* C1 = Cf ( 1 - Cs )
+ * A1 = Af ( 1 - As )
+ */
+ *reg = (TD0_color_arg1_inv_enable |
+ TD0_color_arg2_diffuse |
+ TD0_color_sel_mul |
+ TD0_alpha_arg1_inv_enable |
+ TD0_alpha_arg2_diffuse |
+ TD0_alpha_sel_mul);
+ /* Cv = C1 + Cc Cs
+ * Av = A1 + As
+ */
+ *(reg+1) = (TD0_color_arg2_prevstage |
+ TD0_color_alpha_fcol |
+ TD0_color_arg2mul_alpha2 |
+ TD0_color_arg1add_mulout |
+ TD0_color_add_add |
+ TD0_color_sel_add |
+ TD0_alpha_arg2_prevstage |
+ TD0_alpha_add_enable |
+ TD0_alpha_sel_add);
+ mmesa->dualtex_env = GL_TRUE;
+ } else {
+ t->texenv_fallback = GL_TRUE;
+ }
+ }
} else {
- /* Part 2: R2 = R1 + Rt
- * A2 = A1
- */
- *reg = ( TD0_color_arg2_prevstage |
- TD0_color_add_add |
- TD0_color_sel_add |
- TD0_alpha_arg2_prevstage |
- TD0_alpha_sel_arg2);
+ t->texenv_fallback = GL_TRUE;
}
}
break;
@@ -566,7 +840,6 @@
}
}
-
static void disable_tex( GLcontext *ctx, int unit )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
@@ -582,7 +855,7 @@
mmesa->CurrentTexObj[unit] = NULL;
}
- if ( unit != 0 ) {
+ if ( unit != 0 && !mmesa->dualtex_env) {
mmesa->setup.tdualstage1 = mmesa->setup.tdualstage0;
}
@@ -658,6 +931,8 @@
t->setup.texctl2 |= TMC_dualtex_enable;
}
+ t->texenv_fallback = GL_FALSE;
+
/* FIXME: The Radeon has some cached state so that it can avoid calling
* FIXME: UpdateTextureEnv in some cases. Is that possible here?
*/
@@ -694,8 +969,7 @@
mmesa->setup.dwgctl |= DC_opcod_texture_trap;
mmesa->dirty |= MGA_UPLOAD_CONTEXT | (MGA_UPLOAD_TEX0 << unit);
- FALLBACK( ctx, MGA_FALLBACK_BORDER_MODE, t->border_fallback );
- return !t->border_fallback;
+ return !t->border_fallback && !t->texenv_fallback;
}
@@ -727,6 +1001,7 @@
GLboolean ok;
unsigned i;
+ mmesa->dualtex_env = GL_FALSE;
/* This works around a quirk with the MGA hardware. If only OpenGL
* TEXTURE1 is enabled, then the hardware TEXTURE0 must be used. The
diff -urN mga.orig/mgacontext.h mga/mgacontext.h
--- mga.orig/mgacontext.h 2003-07-12 22:51:53.000000000 +0300
+++ mga/mgacontext.h 2003-07-12 23:20:16.000000000 +0300
@@ -59,7 +59,6 @@
#define MGA_FALLBACK_RENDERMODE 0x10
#define MGA_FALLBACK_STENCIL 0x20
#define MGA_FALLBACK_DEPTH 0x40
-#define MGA_FALLBACK_BORDER_MODE 0x80
/* Use the templated vertex formats:
@@ -78,10 +77,12 @@
-/* Reasons why the GL_BLEND fallback mightn't work:
+/* GL_BLEND has some limitations:
*/
-#define MGA_BLEND_ENV_COLOR 0x1
-#define MGA_BLEND_MULTITEX 0x2
+#define MGA_BLEND_RGB_ZERO 0x1
+#define MGA_BLEND_RGB_EQUAL 0x2
+#define MGA_BLEND_ALPHA_ZERO 0x4
+#define MGA_BLEND_ALPHA_ONE 0x8
struct mga_texture_object_s;
struct mga_screen_private_s;
@@ -150,6 +151,10 @@
* to fallback for GL_CLAMP_TO_BORDER.
*/
GLboolean border_fallback;
+ /* Depending on multitexturing and environment color GL_BLEND may need
+ * to fallback to software.
+ */
+ GLboolean texenv_fallback;
} mgaTextureObject_t;
struct mga_hw_state {
@@ -203,10 +208,11 @@
struct gl_client_array UbyteColor;
struct gl_client_array UbyteSecondaryColor;
- /* Support for limited GL_BLEND fallback
+ /* Support for GL_DECAL and GL_BLEND
*/
unsigned int blend_flags;
unsigned int envcolor;
+ GLboolean dualtex_env;
/* Rasterization state
*/
diff -urN mga.orig/mgastate.c mga/mgastate.c
--- mga.orig/mgastate.c 2003-07-12 22:51:53.000000000 +0300
+++ mga/mgastate.c 2003-07-12 23:19:30.000000000 +0300
@@ -1057,7 +1057,11 @@
sizeof(sarea->TexState[1]));
}
- if ( (sarea->TexState[0].texctl2 & TMC_borderen_MASK) !=
+ if (mmesa->dualtex_env) {
+ sarea->TexState[0].texctl2 |= TMC_dualtex_enable;
+ memcpy( &sarea->TexState[1], &sarea->TexState[0],
+ sizeof(sarea->TexState[0]) );
+ } else if ( (sarea->TexState[0].texctl2 & TMC_borderen_MASK) !=
(sarea->TexState[1].texctl2 & TMC_borderen_MASK) ) {
const int borderen = sarea->TexState[1].texctl2 & ~TMC_borderen_MASK;
@@ -1233,6 +1237,10 @@
mmesa->setup.tdualstage1 = 0;
mmesa->setup.fcol = 0;
mmesa->dirty |= MGA_UPLOAD_CONTEXT;
+
+ mmesa->envcolor = 0;
+ mmesa->blend_flags = MGA_BLEND_RGB_ZERO | MGA_BLEND_ALPHA_ZERO;
+ mmesa->dualtex_env = GL_FALSE;
}
diff -urN mga.orig/mgatex.c mga/mgatex.c
--- mga.orig/mgatex.c 2003-07-12 22:51:53.000000000 +0300
+++ mga/mgatex.c 2003-07-12 23:00:49.000000000 +0300
@@ -333,24 +333,30 @@
GLuint envColor;
UNCLAMPED_FLOAT_TO_RGBA_CHAN( c, texUnit->EnvColor );
- envColor = mgaPackColor( mmesa->mgaScreen->cpp, c[0], c[1], c[2], c[3] );
- mmesa->envcolor = PACK_COLOR_8888( c[3], c[0], c[1], c[2] );
+ envColor = PACK_COLOR_8888( c[3], c[0], c[1], c[2] );
- if (mmesa->setup.fcol != envColor) {
+ if (mmesa->envcolor != envColor) {
+ mmesa->envcolor = envColor;
+
+ /* We use the alpha part of the register for R,G,B
+ * which is why all three components must be equal.
+ */
+ envColor = PACK_COLOR_8888( c[0], c[0], c[0], c[0] );
FLUSH_BATCH(mmesa);
mmesa->setup.fcol = envColor;
mmesa->dirty |= MGA_UPLOAD_CONTEXT;
- mmesa->blend_flags &= ~MGA_BLEND_ENV_COLOR;
+ mmesa->blend_flags = 0;
- /* Actually just require all four components to be
- * equal. This permits a single-pass GL_BLEND.
- *
- * More complex multitexture/multipass fallbacks
- * for blend can be done later.
- */
- if (mmesa->envcolor != 0x0 && mmesa->envcolor != 0xffffffff)
- mmesa->blend_flags |= MGA_BLEND_ENV_COLOR;
+ if ((mmesa->envcolor & 0xffffff) == 0x0)
+ mmesa->blend_flags |= MGA_BLEND_RGB_ZERO;
+ else if ((mmesa->envcolor & 0xffffff) == (envColor & 0xffffff))
+ mmesa->blend_flags |= MGA_BLEND_RGB_EQUAL;
+
+ if ((mmesa->envcolor >> 24) == 0x0)
+ mmesa->blend_flags |= MGA_BLEND_ALPHA_ZERO;
+ else if ((mmesa->envcolor >> 24) == 0xff)
+ mmesa->blend_flags |= MGA_BLEND_ALPHA_ONE;
}
break;
}
diff -urN mga.orig/mga_texstate.c mga/mga_texstate.c
--- mga.orig/mga_texstate.c 2003-07-12 22:48:26.000000000 +0300
+++ mga/mga_texstate.c 2003-07-12 22:51:08.000000000 +0300
@@ -52,6 +52,10 @@
[MESA_FORMAT_RGB565] = TMC_tformat_tw16 | TMC_takey_1 | TMC_tamask_0,
[MESA_FORMAT_ARGB4444] = TMC_tformat_tw12 | TMC_takey_1 | TMC_tamask_0,
[MESA_FORMAT_ARGB1555] = TMC_tformat_tw15 | TMC_takey_1 | TMC_tamask_0,
+ [MESA_FORMAT_AL88] = TMC_tformat_tw8al | TMC_takey_1 | TMC_tamask_0,
+ [MESA_FORMAT_A8] = TMC_tformat_tw8a | TMC_takey_1 | TMC_tamask_0,
+ [MESA_FORMAT_L8] = TMC_tformat_tw8a | TMC_takey_1 | TMC_tamask_0,
+ [MESA_FORMAT_I8] = TMC_tformat_tw8a | TMC_takey_1 | TMC_tamask_0,
[MESA_FORMAT_CI8] = TMC_tformat_tw8 | TMC_takey_1 | TMC_tamask_0,
[MESA_FORMAT_YCBCR] = TMC_tformat_tw422uyvy | TMC_takey_1 | TMC_tamask_0,
[MESA_FORMAT_YCBCR_REV] = TMC_tformat_tw422 | TMC_takey_1 | TMC_tamask_0,
@@ -81,6 +85,10 @@
case MESA_FORMAT_RGB565: txformat = TMC_tformat_tw16; break;
case MESA_FORMAT_ARGB4444: txformat = TMC_tformat_tw12; break;
case MESA_FORMAT_ARGB1555: txformat = TMC_tformat_tw15; break;
+ case MESA_FORMAT_AL88: txformat = TMC_tformat_tw8al; break;
+ case MESA_FORMAT_A8: txformat = TMC_tformat_tw8a; break;
+ case MESA_FORMAT_L8: txformat = TMC_tformat_tw8a; break;
+ case MESA_FORMAT_I8: txformat = TMC_tformat_tw8a; break;
case MESA_FORMAT_CI8: txformat = TMC_tformat_tw8; break;
case MESA_FORMAT_YCBCR: txformat = TMC_tformat_tw422uyvy; break;
case MESA_FORMAT_YCBCR_REV: txformat = TMC_tformat_tw422; break;
diff -urN mga.orig/mgatex.c mga/mgatex.c
--- mga.orig/mgatex.c 2003-07-12 22:48:26.000000000 +0300
+++ mga/mgatex.c 2003-07-12 22:50:11.000000000 +0300
@@ -219,7 +219,7 @@
case GL_ALPHA16:
case GL_COMPRESSED_ALPHA:
/* FIXME: This will report incorrect component sizes... */
- return &_mesa_texformat_argb4444;
+ return MGA_IS_G400(mmesa) ? &_mesa_texformat_a8 : &_mesa_texformat_argb4444;
case 1:
case GL_LUMINANCE:
@@ -229,7 +229,7 @@
case GL_LUMINANCE16:
case GL_COMPRESSED_LUMINANCE:
/* FIXME: This will report incorrect component sizes... */
- return &_mesa_texformat_rgb565;
+ return MGA_IS_G400(mmesa) ? &_mesa_texformat_l8 : &_mesa_texformat_rgb565;
case 2:
case GL_LUMINANCE_ALPHA:
@@ -241,7 +241,7 @@
case GL_LUMINANCE16_ALPHA16:
case GL_COMPRESSED_LUMINANCE_ALPHA:
/* FIXME: This will report incorrect component sizes... */
- return &_mesa_texformat_argb4444;
+ return MGA_IS_G400(mmesa) ? &_mesa_texformat_al88 : &_mesa_texformat_argb4444;
case GL_INTENSITY:
case GL_INTENSITY4:
@@ -250,11 +250,12 @@
case GL_INTENSITY16:
case GL_COMPRESSED_INTENSITY:
/* FIXME: This will report incorrect component sizes... */
- return &_mesa_texformat_argb4444;
+ return MGA_IS_G400(mmesa) ? &_mesa_texformat_i8 : &_mesa_texformat_argb4444;
case GL_YCBCR_MESA:
- if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
- type == GL_UNSIGNED_BYTE)
+ if (MGA_IS_G400(mmesa) &&
+ (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
+ type == GL_UNSIGNED_BYTE))
return &_mesa_texformat_ycbcr;
else
return &_mesa_texformat_ycbcr_rev;
diff -urN mga.orig/mgatex.c mga/mgatex.c
--- mga.orig/mgatex.c 2003-07-12 22:40:08.000000000 +0300
+++ mga/mgatex.c 2003-07-12 22:41:03.000000000 +0300
@@ -47,7 +47,6 @@
/**
* Set the texture wrap modes.
- * Currently, only \c GL_REPEAT and \c GL_CLAMP are supported.
*
* \param t Texture object whose wrap modes are to be set
* \param swrap Wrap mode for the \a s texture coordinate
@@ -74,9 +73,6 @@
t->setup.texctl |= TMC_clampu_enable;
is_clamp_to_edge = GL_TRUE;
break;
- case GL_CLAMP_TO_BORDER:
- t->setup.texctl |= TMC_clampu_enable;
- break;
default:
_mesa_problem(NULL, "bad S wrap mode in %s", __FUNCTION__);
}