This patch implements these extensions:
GL_ARB_texture_env_combine
GL_EXT_texture_env_combine
GL_ARB_texture_env_crossbar
G400 or better needed obviously.
My older texenv stuff is included with a slight modification. Since I
can't easily play with FCOL like I did before GL_BLEND has some more
restricions. Now both Cc and Ac must be either 0.0 or 1.0. I could
still add a Cc==Ac case which would work with other formats except
GL_INTENSITY.
Also I had to change GL_ALPHA and GL_LUMINANCE to use TW8AL format since
TW8A behaves like GL_INTENSITY and now it's possible to specify
SRC_ALPHA operand for GL_LUMINANCE and so on. I'm hoping Mesa will take
care of fillning the unused component with 0.0 or 1.0...
I made the mapping between OpenGL args and hw args flexible. This way
it doesn't matter in which order the user specifies the arguments.
Hw can't support dot3 stuff. Also RGB_SCALE and ALPHA_SCALE only work
fully with GL_MODULATE. GL_REPLACE can't support this at all the others
support only a value of 1.
So far I've only tested with an emboss bumpmapping sample from ATI. Good
news is that it looks ok :) It uses GL_MODULATE, GL_REPLACE and
GL_ADD_SIGNED. Are there any other good tests I could try?
PS.
I use Mesa embedded-2-branch as my working copy so I made the changes
to dri sources manually. Hopefully I got all of them...
--
Ville Syrj�l�
[EMAIL PROTECTED]
http://www.sci.fi/~syrjala/
Index: Imakefile.inc
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/mga/Imakefile.inc,v
retrieving revision 1.6
diff -u -r1.6 Imakefile.inc
--- Imakefile.inc 30 Apr 2003 01:50:40 -0000 1.6
+++ Imakefile.inc 3 Aug 2003 16:07:23 -0000
@@ -43,6 +43,7 @@
$(MESADRVMGABUILDDIR)mgatex.c \
$(MESADRVMGABUILDDIR)mgatexmem.c \
$(MESADRVMGABUILDDIR)mga_texstate.c \
+ $(MESADRVMGABUILDDIR)mga_texcombine.c \
$(MESADRVMGABUILDDIR)mgatris.c \
$(MESADRVMGABUILDDIR)mgavb.c \
$(MESADRVMGABUILDDIR)mga_xmesa.c \
@@ -56,6 +57,7 @@
$(MESADRVMGABUILDDIR)mgatex.o \
$(MESADRVMGABUILDDIR)mgatexmem.o \
$(MESADRVMGABUILDDIR)mga_texstate.o \
+ $(MESADRVMGABUILDDIR)mga_texcombine.o \
$(MESADRVMGABUILDDIR)mgatris.o \
$(MESADRVMGABUILDDIR)mgavb.o \
$(MESADRVMGABUILDDIR)mga_xmesa.o
@@ -69,6 +71,7 @@
$(MESADRVMGABUILDDIR)unshared/mgatex.o \
$(MESADRVMGABUILDDIR)unshared/mgatexmem.o \
$(MESADRVMGABUILDDIR)unshared/mga_texstate.o \
+ $(MESADRVMGABUILDDIR)unshared/mga_texcombine.o \
$(MESADRVMGABUILDDIR)unshared/mgatris.o \
$(MESADRVMGABUILDDIR)unshared/mgavb.o \
$(MESADRVMGABUILDDIR)unshared/mga_xmesa.o
@@ -82,6 +85,7 @@
$(MESADRVMGABUILDDIR)debugger/mgatex.o \
$(MESADRVMGABUILDDIR)debugger/mgatexmem.o \
$(MESADRVMGABUILDDIR)debugger/mga_texstate.o \
+ $(MESADRVMGABUILDDIR)debugger/mga_texcombine.o \
$(MESADRVMGABUILDDIR)debugger/mgatris.o \
$(MESADRVMGABUILDDIR)debugger/mgavb.o \
$(MESADRVMGABUILDDIR)debugger/mga_xmesa.o
@@ -95,6 +99,7 @@
$(MESADRVMGABUILDDIR)profiled/mgatex.o \
$(MESADRVMGABUILDDIR)profiled/mgatexmem.o \
$(MESADRVMGABUILDDIR)profiled/mga_texstate.o \
+ $(MESADRVMGABUILDDIR)profiled/mga_texcombine.o \
$(MESADRVMGABUILDDIR)profiled/mgatris.o \
$(MESADRVMGABUILDDIR)profiled/mgavb.o \
$(MESADRVMGABUILDDIR)profiled/mga_xmesa.o
@@ -109,6 +114,7 @@
LinkSourceFile(mgatex.c, $(MESADRVSRCDIR)/mga)
LinkSourceFile(mgatexmem.c, $(MESADRVSRCDIR)/mga)
LinkSourceFile(mga_texstate.c, $(MESADRVSRCDIR)/mga)
+LinkSourceFile(mga_texcombine.c, $(MESADRVSRCDIR)/mga)
LinkSourceFile(mgatris.c, $(MESADRVSRCDIR)/mga)
LinkSourceFile(mgavb.c, $(MESADRVSRCDIR)/mga)
LinkSourceFile(mga_xmesa.c, $(MESADRVSRCDIR)/mga)
Index: mga_texstate.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/mga/mga_texstate.c,v
retrieving revision 1.9
diff -u -r1.9 mga_texstate.c
--- mga_texstate.c 25 Jul 2003 00:24:53 -0000 1.9
+++ mga_texstate.c 3 Aug 2003 16:07:23 -0000
@@ -52,6 +52,8 @@
[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_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 +83,8 @@
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_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;
@@ -251,29 +255,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 |
@@ -290,33 +425,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 |
@@ -334,20 +489,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 |
@@ -355,16 +515,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),
},
@@ -377,21 +541,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 |
@@ -399,16 +567,20 @@
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),
},
@@ -421,6 +593,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 )
@@ -428,136 +601,226 @@
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.
- */
- 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);
+ *reg = g400_alpha_combine[unit][MGA_BLEND];
+ } else {
+ 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_ONE &&
+ 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 + Cs
+ * Av = A1
+ */
+ *(reg+1) = (TD0_color_arg2_prevstage |
+ 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 + Cs
+ * Av = A1
+ */
+ *(reg+1) = (TD0_color_arg2_prevstage |
+ 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 + Cs
+ * Av = A1
+ */
+ *(reg+1) = (TD0_color_arg2_prevstage |
+ 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 + Cs
+ * Av = A1 + As
+ */
+ *(reg+1) = (TD0_color_arg2_prevstage |
+ 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;
+ case GL_COMBINE_EXT:
+ if (!mgaUpdateTextureEnvCombine(ctx, unit))
+ t->texenv_fallback = GL_TRUE;
+ break;
default:
break;
}
}
-
static void disable_tex( GLcontext *ctx, int unit )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
@@ -573,7 +836,7 @@
mmesa->CurrentTexObj[unit] = NULL;
}
- if ( unit != 0 ) {
+ if ( unit != 0 && !mmesa->dualtex_env ) {
mmesa->setup.tdualstage1 = mmesa->setup.tdualstage0;
}
@@ -649,6 +912,14 @@
t->setup.texctl2 |= TMC_dualtex_enable;
}
+ t->texenv_fallback = GL_FALSE;
+
+ /* Set this before mgaUpdateTextureEnvG400() since
+ * GL_ARB_texture_env_crossbar may have to disable texturing.
+ */
+ mmesa->setup.dwgctl &= DC_opcod_MASK;
+ mmesa->setup.dwgctl |= DC_opcod_texture_trap;
+
/* FIXME: The Radeon has some cached state so that it can avoid calling
* FIXME: UpdateTextureEnv in some cases. Is that possible here?
*/
@@ -680,13 +951,10 @@
mgaUpdateTextureEnvG200( ctx, unit );
}
-
- mmesa->setup.dwgctl &= DC_opcod_MASK;
- 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;
}
@@ -718,6 +986,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
Index: mga_xmesa.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c,v
retrieving revision 1.54
diff -u -r1.54 mga_xmesa.c
--- mga_xmesa.c 25 Jun 2003 17:13:46 -0000 1.54
+++ mga_xmesa.c 3 Aug 2003 16:07:25 -0000
@@ -259,6 +259,9 @@
"GL_ARB_multitexture",
"GL_ARB_texture_env_add",
"GL_EXT_texture_env_add",
+ "GL_ARB_texture_env_combine",
+ "GL_EXT_texture_env_combine",
+ "GL_ARB_texture_env_crossbar",
"GL_EXT_texture_edge_clamp",
"GL_SGIS_texture_edge_clamp",
#if defined (MESA_packed_depth_stencil)
Index: mgacontext.h
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/mga/mgacontext.h,v
retrieving revision 1.26
diff -u -r1.26 mgacontext.h
--- mgacontext.h 22 Jul 2003 04:54:31 -0000 1.26
+++ mgacontext.h 3 Aug 2003 16:07:25 -0000
@@ -78,10 +78,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_ONE 0x2
+#define MGA_BLEND_ALPHA_ZERO 0x4
+#define MGA_BLEND_ALPHA_ONE 0x8
struct mga_texture_object_s;
struct mga_screen_private_s;
@@ -148,6 +150,10 @@
* to fallback for GL_CLAMP_TO_BORDER.
*/
GLboolean border_fallback;
+ /* Depending on multitxturing and environment color
+ * GL_BLEND may have to be a software fallback.
+ */
+ GLboolean texenv_fallback;
} mgaTextureObject_t;
struct mga_hw_state {
@@ -201,10 +207,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
*/
Index: mgastate.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/mga/mgastate.c,v
retrieving revision 1.41
diff -u -r1.41 mgastate.c
--- mgastate.c 23 Jul 2003 13:40:07 -0000 1.41
+++ mgastate.c 3 Aug 2003 16:07:26 -0000
@@ -1053,8 +1053,13 @@
sizeof(sarea->TexState[1]));
}
- if ( (sarea->TexState[0].texctl2 & TMC_borderen_MASK) !=
- (sarea->TexState[1].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]) );
+ mmesa->dirty |= MGA_UPLOAD_TEX1|MGA_UPLOAD_TEX0;
+ } 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;
memcpy( &sarea->TexState[1], &sarea->TexState[0],
@@ -1229,6 +1234,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;
}
Index: mgatex.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/mga/mgatex.c,v
retrieving revision 1.49
diff -u -r1.49 mgatex.c
--- mgatex.c 25 Jul 2003 07:42:21 -0000 1.49
+++ mgatex.c 3 Aug 2003 16:07:27 -0000
@@ -220,7 +220,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_al88 : &_mesa_texformat_argb4444;
case 1:
case GL_LUMINANCE:
@@ -230,7 +230,8 @@
case GL_LUMINANCE16:
case GL_COMPRESSED_LUMINANCE:
/* FIXME: This will report incorrect component sizes... */
- return &_mesa_texformat_rgb565;
+ return
+ return MGA_IS_G400(mmesa) ? &_mesa_texformat_al88 : &_mesa_texformat_rgb565;
case 2:
case GL_LUMINANCE_ALPHA:
@@ -242,7 +243,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:
@@ -251,7 +252,7 @@
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 (MGA_IS_G400(mmesa) &&
@@ -331,27 +332,28 @@
switch( pname ) {
case GL_TEXTURE_ENV_COLOR: {
GLubyte c[4];
- 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] );
- if (mmesa->setup.fcol != envColor) {
+ if (mmesa->setup.fcol != mmesa->envcolor) {
FLUSH_BATCH(mmesa);
- mmesa->setup.fcol = envColor;
+ mmesa->setup.fcol = mmesa->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) == 0xffffff) {
+ mmesa->blend_flags |= MGA_BLEND_RGB_ONE;
+ }
+
+ 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;
}
Index: mgatex.h
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/mga/mgatex.h,v
retrieving revision 1.13
diff -u -r1.13 mgatex.h
--- mgatex.h 30 Apr 2003 01:50:43 -0000 1.13
+++ mgatex.h 3 Aug 2003 16:07:27 -0000
@@ -46,4 +46,6 @@
void mgaDDInitTextureFuncs( GLcontext *ctx );
+GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit );
+
#endif
#include "glheader.h"
#include "imports.h"
#include "colormac.h"
#include "context.h"
#include "enums.h"
#include "macros.h"
#include "mmath.h"
#include "texformat.h"
#include "mga_xmesa.h"
#include "mgastate.h"
#include "mgaioctl.h"
#include "mgatex.h"
#include "mgaregs.h"
/* GL_EXT_texture_env_combine support
*/
#define ARG_DISABLE 0xffffffff
#define MGA_ARG1 0
#define MGA_ARG2 1
#define MGA_ALPHA 2
GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
const int source = mmesa->tmu_source[unit];
const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
GLuint *reg = ((GLuint *)&mmesa->setup.tdualstage0 + unit);
GLuint numColorArgs = 0, numAlphaArgs = 0;
GLuint arg1[3], arg2[3], alpha[3];
int args[3];
int i;
switch (texUnit->CombineModeRGB) {
case GL_REPLACE:
numColorArgs = 1;
break;
case GL_MODULATE:
case GL_ADD:
case GL_ADD_SIGNED:
case GL_SUBTRACT:
numColorArgs = 2;
break;
case GL_INTERPOLATE:
numColorArgs = 3;
break;
default:
return GL_FALSE;
}
switch (texUnit->CombineModeA) {
case GL_REPLACE:
numAlphaArgs = 1;
break;
case GL_MODULATE:
case GL_ADD:
case GL_ADD_SIGNED:
case GL_SUBTRACT:
numAlphaArgs = 2;
break;
default:
return GL_FALSE;
}
/* Start fresh :) */
*reg = 0;
/* COLOR */
for (i = 0; i < 3; i++) {
arg1[i] = 0;
arg2[i] = 0;
alpha[i] = 0;
}
for (i = 0;i < numColorArgs; i++) {
switch (texUnit->CombineSourceRGB[i]) {
case GL_TEXTURE:
arg1[i] |= 0;
arg2[i] |= ARG_DISABLE;
alpha[i] |= TD0_color_alpha_currtex;
break;
case GL_TEXTURE0:
if (source == 0) {
arg1[i] |= 0;
arg2[i] |= ARG_DISABLE;
alpha[i] |= TD0_color_alpha_currtex;
} else {
if (ctx->Texture._EnabledUnits != 0x03) {
/* disable texturing */
mmesa->setup.dwgctl &= DC_opcod_MASK;
mmesa->setup.dwgctl |= DC_opcod_trap;
mmesa->hw.alpha_sel = AC_alphasel_diffused;
/* return GL_TRUE since we don't need a fallback */
return GL_TRUE;
}
arg1[i] |= ARG_DISABLE;
arg2[i] |= ARG_DISABLE;
alpha[i] |= TD0_color_alpha_prevtex;
}
break;
case GL_TEXTURE1:
if (source == 0) {
if (ctx->Texture._EnabledUnits != 0x03) {
/* disable texturing */
mmesa->setup.dwgctl &= DC_opcod_MASK;
mmesa->setup.dwgctl |= DC_opcod_trap;
mmesa->hw.alpha_sel = AC_alphasel_diffused;
/* return GL_TRUE since we don't need a fallback */
return GL_TRUE;
}
arg1[i] |= ARG_DISABLE;
/* G400 specs.(TDUALSTAGE0) */
arg2[i] |= TD0_color_arg2_prevstage;
alpha[i] |= TD0_color_alpha_prevstage;
} else {
arg1[i] |= 0;
arg2[i] |= ARG_DISABLE;
alpha[i] |= TD0_color_alpha_currtex;
}
break;
case GL_CONSTANT:
arg1[i] |= ARG_DISABLE;
arg2[i] |= TD0_color_arg2_fcol;
alpha[i] |= TD0_color_alpha_fcol;
break;
case GL_PRIMARY_COLOR:
arg1[i] |= ARG_DISABLE;
/* G400 specs.(TDUALSTAGE1) */
if (unit == 0 || (mmesa->setup.tdualstage0 &
((TD0_color_sel_mul & TD0_color_sel_add) |
(TD0_alpha_sel_mul & TD0_alpha_sel_add)))) {
arg2[i] |= TD0_color_arg2_diffuse;
alpha[i] |= TD0_color_alpha_diffuse;
} else {
arg2[i] |= ARG_DISABLE;
alpha[i] |= ARG_DISABLE;
}
break;
case GL_PREVIOUS:
arg1[i] |= ARG_DISABLE;
if (unit == 0) {
arg2[i] |= TD0_color_arg2_diffuse;
alpha[i] |= TD0_color_alpha_diffuse;
} else {
arg2[i] |= TD0_color_arg2_prevstage;
alpha[i] |= TD0_color_alpha_prevstage;
}
break;
}
switch (texUnit->CombineOperandRGB[i]) {
case GL_SRC_COLOR:
arg1[i] |= 0;
arg2[i] |= 0;
alpha[i] |= ARG_DISABLE;
break;
case GL_ONE_MINUS_SRC_COLOR:
arg1[i] |= TD0_color_arg1_inv_enable;
arg2[i] |= TD0_color_arg2_inv_enable;
alpha[i] |= ARG_DISABLE;
break;
case GL_SRC_ALPHA:
arg1[i] |= TD0_color_arg1_replicatealpha_enable;
arg2[i] |= TD0_color_arg2_replicatealpha_enable;
alpha[i] |= 0;
break;
case GL_ONE_MINUS_SRC_ALPHA:
arg1[i] |= (TD0_color_arg1_replicatealpha_enable |
TD0_color_arg1_inv_enable);
arg2[i] |= (TD0_color_arg2_replicatealpha_enable |
TD0_color_arg2_inv_enable);
alpha[i] |= (TD0_color_alpha1inv_enable |
TD0_color_alpha2inv_enable);
break;
}
}
/* Find working combo of arg1, arg2 and alpha.
*
* Keep the Arg0 == alpha cases last since there's
* no way to get alpha out by itself (GL_REPLACE).
*
* Keep the Arg2 == alpha cases first because only alpha has the
* capabilities to function as Arg2 (GL_INTERPOLATE).
* Also we can't get alpha to the adder so keep it away from Arg0 and Arg1
* for as long as possible (GL_ADD,GL_ADD_SIGNED,GL_SUBTRACT).
*/
if ((arg1[0] | arg2[1] | alpha[2]) != ARG_DISABLE) {
*reg |= arg1[0] | arg2[1] | alpha[2];
args[0] = MGA_ARG1; args[1] = MGA_ARG2; args[2] = MGA_ALPHA;
} else
if ((arg1[1] | arg2[0] | alpha[2]) != ARG_DISABLE) {
*reg |= arg1[1] | arg2[0] | alpha[2];
args[0] = MGA_ARG2; args[1] = MGA_ARG1; args[2] = MGA_ALPHA;
} else
if (!(arg1[0] | arg2[2] | alpha[1]) != ARG_DISABLE) {
*reg |= arg1[0] | arg2[2] | alpha[1];
args[0] = MGA_ARG1; args[1] = MGA_ALPHA; args[2] = MGA_ARG2;
} else
if (!(arg1[2] | arg2[0] | alpha[1]) != ARG_DISABLE) {
*reg |= arg1[2] | arg2[0] | alpha[1];
args[0] = MGA_ARG2; args[1] = MGA_ALPHA; args[2] = MGA_ARG1;
} else
if (!(arg1[1] | arg2[2] | alpha[0]) != ARG_DISABLE) {
*reg |= arg1[1] | arg2[2] | alpha[0];
args[0] = MGA_ALPHA; args[1] = MGA_ARG1; args[2] = MGA_ARG2;
} else
if (!(arg1[2] | arg2[1] | alpha[0]) != ARG_DISABLE) {
*reg |= arg1[2] | arg2[1] | alpha[0];
args[0] = MGA_ALPHA; args[1] = MGA_ARG2; args[2] = MGA_ARG1;
} else {
/* nothing suitable */
return GL_FALSE;
}
switch (texUnit->CombineModeRGB) {
case GL_REPLACE:
if (texUnit->CombineScaleShiftRGB) {
return GL_FALSE;
}
if (args[0] == MGA_ARG1) {
*reg |= TD0_color_sel_arg1;
} else if (args[0] == MGA_ARG2) {
*reg |= TD0_color_sel_arg2;
} else if (args[0] == MGA_ALPHA) {
/* Can't get alpha out by itself */
return GL_FALSE;
}
break;
case GL_MODULATE:
if (texUnit->CombineScaleShiftRGB == 1) {
*reg |= TD0_color_modbright_2x;
} else if (texUnit->CombineScaleShiftRGB == 2) {
*reg |= TD0_color_modbright_4x;
}
*reg |= TD0_color_sel_mul;
if (args[0] == MGA_ALPHA || args[1] == MGA_ALPHA) {
if (args[0] == MGA_ARG1 || args[1] == MGA_ARG1) {
*reg |= TD0_color_arg2mul_alpha2;
} else if (args[0] == MGA_ARG2 || args[1] == MGA_ARG2) {
*reg |= TD0_color_arg1mul_alpha1;
}
}
break;
case GL_ADD:
if (args[0] == MGA_ALPHA || args[1] == MGA_ALPHA){
/* Can't get alpha to the adder */
return GL_FALSE;
}
if (texUnit->CombineScaleShiftRGB == 1) {
*reg |= TD0_color_add2x_enable;
} else if (texUnit->CombineScaleShiftRGB == 2) {
return GL_FALSE;
}
*reg |= (TD0_color_add_add |
TD0_color_sel_add);
break;
case GL_ADD_SIGNED:
if (args[0] == MGA_ALPHA || args[1] == MGA_ALPHA){
/* Can't get alpha to the adder */
return GL_FALSE;
}
if (texUnit->CombineScaleShiftRGB == 1) {
*reg |= TD0_color_add2x_enable;
} else if (texUnit->CombineScaleShiftRGB == 2) {
return GL_FALSE;
}
*reg |= (TD0_color_addbias_enable |
TD0_color_add_add |
TD0_color_sel_add);
break;
case GL_INTERPOLATE:
if (args[2] != MGA_ALPHA) {
/* Only alpha can function as Arg2 */
return GL_FALSE;
}
if (texUnit->CombineScaleShiftRGB == 1) {
*reg |= TD0_color_add2x_enable;
} else if (texUnit->CombineScaleShiftRGB == 2) {
return GL_FALSE;
}
*reg |= (TD0_color_arg1mul_alpha1 |
TD0_color_blend_enable |
TD0_color_arg1add_mulout |
TD0_color_arg2add_mulout |
TD0_color_add_add |
TD0_color_sel_add);
/* Have to do this with xor since GL_ONE_MINUS_SRC_ALPHA may have
* already touched these bits.
*/
*reg ^= TD0_color_alpha1inv_enable;
if (args[0] == MGA_ARG2) {
/* Swap arguments */
*reg ^= (TD0_color_arg1mul_alpha1 |
TD0_color_arg2mul_alpha2 |
TD0_color_alpha1inv_enable |
TD0_color_alpha2inv_enable);
}
if (ctx->Texture._EnabledUnits != 0x03) {
/* Linear blending mode needs dualtex enabled */
mmesa->dualtex_env = GL_TRUE;
}
break;
case GL_SUBTRACT:
if (args[0] == MGA_ALPHA || args[1] == MGA_ALPHA) {
/* Can't get alpha to the adder */
return GL_FALSE;
}
if (texUnit->CombineScaleShiftRGB == 1) {
*reg |= TD0_color_add2x_enable;
} else if (texUnit->CombineScaleShiftRGB == 2) {
return GL_FALSE;
}
*reg |= (TD0_color_add_sub |
TD0_color_sel_add);
if (args[0] == MGA_ARG2) {
/* Swap arguments */
*reg ^= (TD0_color_arg1_inv_enable |
TD0_color_arg2_inv_enable);
}
break;
}
/* ALPHA */
for (i = 0; i < 2; i++) {
arg1[i] = 0;
arg2[i] = 0;
}
for (i = 0; i < numAlphaArgs; i++) {
switch (texUnit->CombineSourceA[i]) {
case GL_TEXTURE:
arg1[i] |= 0;
arg2[i] |= ARG_DISABLE;
break;
case GL_TEXTURE0:
if (source == 0) {
arg1[i] |= 0;
arg2[i] |= ARG_DISABLE;
} else {
if (ctx->Texture._EnabledUnits != 0x03) {
/* disable texturing */
mmesa->setup.dwgctl &= DC_opcod_MASK;
mmesa->setup.dwgctl |= DC_opcod_trap;
mmesa->hw.alpha_sel = AC_alphasel_diffused;
/* return GL_TRUE since we don't need a fallback */
return GL_TRUE;
}
arg1[i] |= ARG_DISABLE;
arg2[i] |= TD0_alpha_arg2_prevtex;
}
break;
case GL_TEXTURE1:
if (source == 0) {
if (ctx->Texture._EnabledUnits != 0x03) {
/* disable texturing */
mmesa->setup.dwgctl &= DC_opcod_MASK;
mmesa->setup.dwgctl |= DC_opcod_trap;
mmesa->hw.alpha_sel = AC_alphasel_diffused;
/* return GL_TRUE since we don't need a fallback */
return GL_TRUE;
}
arg1[i] |= ARG_DISABLE;
/* G400 specs.(TDUALSTAGE0) */
arg2[i] |= TD0_alpha_arg2_prevstage;
} else {
arg1[i] |= 0;
arg2[i] |= ARG_DISABLE;
}
break;
case GL_CONSTANT:
arg1[i] |= ARG_DISABLE;
arg2[i] |= TD0_alpha_arg2_fcol;
break;
case GL_PRIMARY_COLOR:
arg1[i] |= ARG_DISABLE;
/* G400 specs.(TDUALSTAGE1) */
if (unit == 0 || (mmesa->setup.tdualstage0 &
((TD0_color_sel_mul & TD0_color_sel_add) |
(TD0_alpha_sel_mul & TD0_alpha_sel_add)))) {
arg2[i] |= TD0_alpha_arg2_diffuse;
} else {
arg2[i] |= ARG_DISABLE;
}
break;
case GL_PREVIOUS:
arg1[i] |= ARG_DISABLE;
if (unit == 0) {
arg2[i] |= TD0_alpha_arg2_diffuse;
} else {
arg2[i] |= TD0_alpha_arg2_prevstage;
}
break;
}
switch (texUnit->CombineOperandA[i]) {
case GL_SRC_ALPHA:
arg1[i] |= 0;
arg2[i] |= 0;
break;
case GL_ONE_MINUS_SRC_ALPHA:
arg1[i] |= TD0_alpha_arg1_inv_enable;
arg2[i] |= TD0_alpha_arg2_inv_enable;
break;
}
}
/* Find a working combo of arg1 and arg2 */
if ((arg1[0] | arg2[1]) != ARG_DISABLE) {
*reg |= arg1[0] | arg2[1];
args[0] = MGA_ARG1; args[1] = MGA_ARG2;
} else
if ((arg1[1] | arg2[0]) != ARG_DISABLE) {
*reg |= arg1[1] | arg2[0];
args[0] = MGA_ARG2; args[1] = MGA_ARG1;
} else {
/* nothing suitable */
return GL_FALSE;
}
switch (texUnit->CombineModeA) {
case GL_REPLACE:
if (texUnit->CombineScaleShiftA) {
return GL_FALSE;
}
if (args[0] == MGA_ARG1){
*reg |= TD0_alpha_sel_arg1;
} else if (args[0] == MGA_ARG2) {
*reg |= TD0_alpha_sel_arg2;
}
break;
case GL_MODULATE:
if (texUnit->CombineScaleShiftA == 1) {
*reg |= TD0_alpha_modbright_2x;
} else if (texUnit->CombineScaleShiftA == 2) {
*reg |= TD0_alpha_modbright_4x;
}
*reg |= TD0_alpha_sel_mul;
break;
case GL_ADD:
if (texUnit->CombineScaleShiftA == 1) {
*reg |= TD0_alpha_add2x_enable;
} else if (texUnit->CombineScaleShiftA == 2) {
return GL_FALSE;
}
*reg |= (TD0_alpha_add_enable |
TD0_alpha_sel_add);
break;
case GL_ADD_SIGNED:
if (texUnit->CombineScaleShiftA == 1) {
*reg |= TD0_alpha_add2x_enable;
} else if (texUnit->CombineScaleShiftA == 2) {
return GL_FALSE;
}
*reg |= (TD0_alpha_addbias_enable |
TD0_alpha_add_enable |
TD0_alpha_sel_add);
break;
case GL_INTERPOLATE:
/* fallback */
return GL_FALSE;
case GL_SUBTRACT:
if (texUnit->CombineScaleShiftA == 1) {
*reg |= TD0_alpha_add2x_enable;
} else if (texUnit->CombineScaleShiftA == 2) {
return GL_FALSE;
}
*reg |= (TD0_alpha_add_disable |
TD0_alpha_sel_add);
if (args[0] == MGA_ARG2) {
/* Swap arguments */
*reg ^= (TD0_alpha_arg1_inv_enable |
TD0_alpha_arg2_inv_enable);
}
break;
}
return GL_TRUE;
}