* Ian Romanick <idr@us.ibm.com>
* Keith Whitwell <keithw@tungstengraphics.com>
*/
-/* $XFree86:$ */
-#include "mm.h"
+#include <stdlib.h>
+#include "main/mm.h"
#include "mgacontext.h"
#include "mgatex.h"
#include "mgaregs.h"
#include "mgatris.h"
#include "mgaioctl.h"
-#include "context.h"
-#include "enums.h"
-#include "macros.h"
-#include "imports.h"
+#include "main/context.h"
+#include "main/enums.h"
+#include "main/macros.h"
+#include "main/imports.h"
-#include "simple_list.h"
-#include "texformat.h"
+#include "main/simple_list.h"
+#include "main/texformat.h"
#define MGA_USE_TABLE_FOR_FORMAT
#ifdef MGA_USE_TABLE_FOR_FORMAT
#define TMC_nr_tformat (MESA_FORMAT_YCBCR_REV + 1)
static const unsigned TMC_tformat[ TMC_nr_tformat ] =
{
- [MESA_FORMAT_ARGB8888] = TMC_tformat_tw32 | TMC_takey_1 | TMC_tamask_0,
- [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_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,
+ [MESA_FORMAT_ARGB8888] = TMC_tformat_tw32,
+ [MESA_FORMAT_RGB565] = TMC_tformat_tw16,
+ [MESA_FORMAT_ARGB4444] = TMC_tformat_tw12,
+ [MESA_FORMAT_ARGB1555] = TMC_tformat_tw15,
+ [MESA_FORMAT_AL88] = TMC_tformat_tw8al,
+ [MESA_FORMAT_I8] = TMC_tformat_tw8a,
+ [MESA_FORMAT_CI8] = TMC_tformat_tw8 ,
+ [MESA_FORMAT_YCBCR] = TMC_tformat_tw422uyvy,
+ [MESA_FORMAT_YCBCR_REV] = TMC_tformat_tw422,
};
#endif
const struct gl_texture_object * tObj )
{
mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData;
- struct gl_texture_image *baseImage = tObj->Image[ tObj->BaseLevel ];
+ struct gl_texture_image *baseImage = tObj->Image[0][ tObj->BaseLevel ];
GLint totalSize;
GLint width, height;
GLint i;
- GLint firstLevel, lastLevel, numLevels;
+ GLint numLevels;
GLint log2Width, log2Height;
GLuint txformat = 0;
GLint ofs;
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;
#endif /* MGA_USE_TABLE_FOR_FORMAT */
- if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
- /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
- */
-
- firstLevel = lastLevel = tObj->BaseLevel;
+ driCalculateTextureFirstLastLevel( (driTextureObject *) t );
+ if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
+ log2Width = 0;
+ log2Height = 0;
} else {
- /* Compute which mipmap levels we really want to send to the hardware.
- * This depends on the base image size, GL_TEXTURE_MIN_LOD,
- * 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 */
+ log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;
+ log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;
}
- log2Width = tObj->Image[firstLevel]->WidthLog2;
- log2Height = tObj->Image[firstLevel]->HeightLog2;
- width = tObj->Image[firstLevel]->Width;
- height = tObj->Image[firstLevel]->Height;
+ width = tObj->Image[0][t->base.firstLevel]->Width;
+ height = tObj->Image[0][t->base.firstLevel]->Height;
- numLevels = MIN2( lastLevel - firstLevel + 1,
+ numLevels = MIN2( t->base.lastLevel - t->base.firstLevel + 1,
MGA_IS_G200(mmesa) ? G200_TEX_MAXLEVELS : G400_TEX_MAXLEVELS);
totalSize = 0;
for ( i = 0 ; i < numLevels ; i++ ) {
- const struct gl_texture_image * const texImage = tObj->Image[i+firstLevel];
+ const struct gl_texture_image * const texImage =
+ tObj->Image[0][ i + t->base.firstLevel ];
+ int size;
- if ( (texImage == NULL)
- || ((i != 0)
- && ((texImage->Width < 8) || (texImage->Height < 8))) ) {
+ if (texImage == NULL)
break;
- }
+
+ size = texImage->Width * texImage->Height *
+ _mesa_get_format_bytes(baseImage->TexFormat->MesaFormat);
t->offsets[i] = totalSize;
t->base.dirty_images[0] |= (1<<i);
- totalSize += ((MAX2( texImage->Width, 8 ) *
- MAX2( texImage->Height, 8 ) *
- baseImage->TexFormat->TexelBytes) + 31) & ~31;
- }
+ /* All mipmaps must be 32-byte aligned */
+ totalSize += (size + 31) & ~31;
- numLevels = i;
- lastLevel = firstLevel + numLevels - 1;
+ /* Since G400 calculates the offsets in hardware
+ * it can't handle more than one < 32 byte mipmap.
+ *
+ * Further testing has indicated that it can't
+ * handle any < 32 byte mipmaps.
+ */
+ if (MGA_IS_G400( mmesa ) && size <= 32) {
+ i++;
+ break;
+ }
+ }
/* save these values */
- t->base.firstLevel = firstLevel;
- t->base.lastLevel = lastLevel;
-
+ numLevels = i;
+ t->base.lastLevel = t->base.firstLevel + numLevels - 1;
t->base.totalSize = totalSize;
/* setup hardware register values */
*/
t->setup.texctl |= TMC_tpitchlin_enable;
- t->setup.texctl |= (width & (2048 - 1)) << TMC_tpitchext_SHIFT;
+ t->setup.texctl |= MGA_FIELD( TMC_tpitchext, width & (2048 - 1) );
/* G400 specifies the number of mip levels in a strange way. Since there
- * are up to 12 levels, it requires 4 bits. Three of the bits are at the
+ * are up to 11 levels, it requires 4 bits. Three of the bits are at the
* high end of TEXFILTER. The other bit is in the middle. Weird.
*/
-
+ numLevels--;
t->setup.texfilter &= TF_mapnb_MASK & TF_mapnbhigh_MASK & TF_reserved_MASK;
- t->setup.texfilter |= (((numLevels-1) & 0x07) << (TF_mapnb_SHIFT));
- t->setup.texfilter |= (((numLevels-1) & 0x08) << (TF_mapnbhigh_SHIFT - 3));
+ t->setup.texfilter |= MGA_FIELD( TF_mapnb, numLevels & 0x7 );
+ t->setup.texfilter |= MGA_FIELD( TF_mapnbhigh, (numLevels >> 3) & 0x1 );
/* warp texture registers */
ofs = MGA_IS_G200(mmesa) ? 28 : 11;
static void mgaUpdateTextureEnvG200( GLcontext *ctx, GLuint unit )
{
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
struct gl_texture_object *tObj = ctx->Texture.Unit[0]._Current;
- mgaTextureObjectPtr t;
+ mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData;
+ GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
- if (!tObj || !tObj->DriverData)
+ if (tObj != ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX] &&
+ tObj != ctx->Texture.Unit[0].CurrentTex[TEXTURE_RECT_INDEX])
return;
- t = (mgaTextureObjectPtr)tObj->DriverData;
- t->setup.texctl2 &= ~TMC_decalblend_enable;
+ t->setup.texctl &= ~TMC_tmodulate_enable;
+ t->setup.texctl2 &= ~(TMC_decalblend_enable |
+ TMC_idecal_enable |
+ TMC_decaldis_enable);
switch (ctx->Texture.Unit[0].EnvMode) {
case GL_REPLACE:
- t->setup.texctl &= ~TMC_tmodulate_enable;
+ if (format == GL_ALPHA)
+ t->setup.texctl2 |= TMC_idecal_enable;
+
+ if (format == GL_RGB || format == GL_LUMINANCE)
+ mmesa->hw.alpha_sel = AC_alphasel_diffused;
+ else
+ mmesa->hw.alpha_sel = AC_alphasel_fromtex;
break;
+
case GL_MODULATE:
t->setup.texctl |= TMC_tmodulate_enable;
+
+ if (format == GL_ALPHA)
+ t->setup.texctl2 |= (TMC_idecal_enable |
+ TMC_decaldis_enable);
+
+ if (format == GL_RGB || format == GL_LUMINANCE)
+ mmesa->hw.alpha_sel = AC_alphasel_diffused;
+ else
+ mmesa->hw.alpha_sel = AC_alphasel_modulated;
break;
+
case GL_DECAL:
- t->setup.texctl &= ~TMC_tmodulate_enable;
- t->setup.texctl2 |= TMC_decalblend_enable;
+ if (format == GL_RGB || format == GL_RGBA)
+ t->setup.texctl2 |= TMC_decalblend_enable;
+ else
+ t->setup.texctl2 |= TMC_idecal_enable;
+
+ mmesa->hw.alpha_sel = AC_alphasel_diffused;
break;
+
case GL_BLEND:
- FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
+ if (format == GL_ALPHA) {
+ t->setup.texctl2 |= TMC_idecal_enable;
+ mmesa->hw.alpha_sel = AC_alphasel_modulated;
+ } else {
+ t->texenv_fallback = GL_TRUE;
+ }
break;
+
default:
break;
}
}
-#define MGA_DISABLE 0
-#define MGA_REPLACE 1
-#define MGA_MODULATE 2
-#define MGA_DECAL 3
-#define MGA_BLEND 4
-#define MGA_ADD 5
-#define MGA_MAX_COMBFUNC 6
+#define MGA_REPLACE 0
+#define MGA_MODULATE 1
+#define MGA_DECAL 2
+#define MGA_ADD 3
+#define MGA_MAX_COMBFUNC 4
static const GLuint g400_color_combine[][MGA_MAX_COMBFUNC] =
{
/* Unit 0:
*/
{
- /* Disable combiner stage
- */
- (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
- */
- (0),
-
/* 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_mul),
+ TD0_alpha_sel_arg2),
},
/* Unit 1:
*/
{
- /* Disable combiner stage
- */
- (0),
-
/* GL_REPLACE
+ * Cv = Cs
+ * Av = Ap
*/
(TD0_color_sel_arg1 |
- TD0_alpha_arg2_diffuse |
- TD0_alpha_sel_arg2 ),
+ TD0_alpha_arg2_prevstage |
+ TD0_alpha_sel_arg2),
/* GL_MODULATE
+ * Cv = Cp Cs
+ * Av = Ap
*/
(TD0_color_arg2_prevstage |
- TD0_color_alpha_prevstage |
TD0_color_sel_mul |
TD0_alpha_arg2_prevstage |
- TD0_alpha_sel_mul),
+ TD0_alpha_sel_arg2),
/* GL_DECAL
+ * Cv = Cs
+ * Av = Ap
*/
(TD0_color_sel_arg1 |
TD0_alpha_arg2_prevstage |
- TD0_alpha_sel_arg2 ),
-
- /* GL_BLEND
- */
- (0),
+ TD0_alpha_sel_arg2),
/* GL_ADD
+ * Cv = Cp + Cs
+ * Av = Ap
*/
(TD0_color_arg2_prevstage |
- TD0_color_alpha_prevstage |
TD0_color_add_add |
TD0_color_sel_add |
TD0_alpha_arg2_prevstage |
- TD0_alpha_sel_mul),
+ TD0_alpha_sel_arg2),
},
};
-static const GLuint g400_alpha_combine[][MGA_MAX_COMBFUNC] =
+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_arg2 |
- TD0_color_arg2_diffuse |
- TD0_alpha_sel_arg1 ),
+ (TD0_color_sel_arg1 |
+ TD0_alpha_sel_arg1),
/* GL_MODULATE
- * FIXME: Is this correct?
+ * 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_sel_arg2 |
+ 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
+ /* GL_ADD
+ * Cv = Cf + Cs
+ * Av = Af As
*/
(TD0_color_arg2_diffuse |
+ TD0_color_add_add |
+ TD0_color_sel_add |
+ TD0_alpha_arg2_diffuse |
+ TD0_alpha_sel_mul),
+ },
+
+ /* Unit 1:
+ */
+ {
+ /* GL_REPLACE
+ * Cv = Cs
+ * Av = As
+ */
+ (TD0_color_sel_arg1 |
+ TD0_alpha_sel_arg1),
+
+ /* GL_MODULATE
+ * Cv = Cp Cs
+ * Av = Ap As
+ */
+ (TD0_color_arg2_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_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),
+
+ /* GL_ADD
+ * Cv = Cp + Cs
+ * Av = Ap As
+ */
+ (TD0_color_arg2_prevstage |
+ TD0_color_add_add |
+ TD0_color_sel_add |
+ TD0_alpha_arg2_prevstage |
+ TD0_alpha_sel_mul),
+ },
+};
+
+static const GLuint g400_alpha_combine[][MGA_MAX_COMBFUNC] =
+{
+ /* Unit 0:
+ */
+ {
+ /* GL_REPLACE
+ * Cv = Cf
+ * Av = As
+ */
+ (TD0_color_arg2_diffuse |
+ TD0_color_sel_arg2 |
+ TD0_alpha_sel_arg1),
+
+ /* GL_MODULATE
+ * Cv = Cf
+ * Av = Af As
+ */
+ (TD0_color_arg2_diffuse |
+ TD0_color_sel_arg2 |
TD0_alpha_arg2_diffuse |
TD0_alpha_sel_mul),
+ /* GL_DECAL (undefined)
+ * Cv = Cf
+ * Av = Af
+ */
+ (TD0_color_arg2_diffuse |
+ TD0_color_sel_arg2 |
+ TD0_alpha_arg2_diffuse |
+ TD0_alpha_sel_arg2),
+
/* 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),
},
/* Unit 1:
*/
{
- /* Disable combiner stage
- */
- (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 |
TD0_alpha_arg2_prevstage |
TD0_alpha_sel_arg2),
- /* GL_BLEND
- */
- (TD0_color_arg2_diffuse |
- TD0_color_sel_mul |
- TD0_alpha_arg2_diffuse |
- 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 GLboolean mgaUpdateTextureEnvBlend( 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];
+ const struct gl_texture_object *tObj = texUnit->_Current;
+ GLuint *reg = ((GLuint *)&mmesa->setup.tdualstage0 + unit);
+ GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
+
+ *reg = 0;
+
+ if (format == GL_ALPHA) {
+ /* Cv = Cf */
+ *reg |= (TD0_color_arg2_diffuse |
+ TD0_color_sel_arg2);
+ /* Av = Af As */
+ *reg |= (TD0_alpha_arg2_diffuse |
+ TD0_alpha_sel_mul);
+ return GL_TRUE;
+ }
+
+ /* C1 = Cf ( 1 - Cs ) */
+ *reg |= (TD0_color_arg1_inv_enable |
+ TD0_color_arg2_diffuse |
+ TD0_color_sel_mul);
+
+ if (format == GL_RGB || format == GL_LUMINANCE) {
+ /* A1 = Af */
+ *reg |= (TD0_alpha_arg2_diffuse |
+ TD0_alpha_sel_arg2);
+ } else
+ if (format == GL_RGBA || format == GL_LUMINANCE_ALPHA) {
+ /* A1 = Af As */
+ *reg |= (TD0_alpha_arg2_diffuse |
+ TD0_alpha_sel_mul);
+ } else
+ if (format == GL_INTENSITY) {
+ /* A1 = Af ( 1 - As ) */
+ *reg |= (TD0_alpha_arg1_inv_enable |
+ TD0_alpha_arg2_diffuse |
+ TD0_alpha_sel_mul);
+ }
+
+ if (RGB_ZERO(mmesa->envcolor[source]) &&
+ (format != GL_INTENSITY || ALPHA_ZERO(mmesa->envcolor[source])))
+ return GL_TRUE; /* all done */
+
+ if (ctx->Texture._EnabledUnits == 0x03)
+ return GL_FALSE; /* need both units */
+
+ mmesa->force_dualtex = GL_TRUE;
+ reg = &mmesa->setup.tdualstage1;
+ *reg = 0;
+
+ if (RGB_ZERO(mmesa->envcolor[source])) {
+ /* Cv = C1 */
+ *reg |= (TD0_color_arg2_prevstage |
+ TD0_color_sel_arg2);
+ } else
+ if (RGB_ONE(mmesa->envcolor[source])) {
+ /* Cv = C1 + Cs */
+ *reg |= (TD0_color_arg2_prevstage |
+ TD0_color_add_add |
+ TD0_color_sel_add);
+ } else
+ if (RGBA_EQUAL(mmesa->envcolor[source])) {
+ /* Cv = C1 + Cc Cs */
+ *reg |= (TD0_color_arg2_prevstage |
+ TD0_color_alpha_fcol |
+ TD0_color_arg2mul_alpha2 |
+ TD0_color_arg1add_mulout |
+ TD0_color_add_add |
+ TD0_color_sel_add);
+
+ mmesa->setup.fcol = mmesa->envcolor[source];
+ } else {
+ return GL_FALSE;
+ }
+
+ if (format != GL_INTENSITY || ALPHA_ZERO(mmesa->envcolor[source])) {
+ /* Av = A1 */
+ *reg |= (TD0_alpha_arg2_prevstage |
+ TD0_alpha_sel_arg2);
+ } else
+ if (ALPHA_ONE(mmesa->envcolor[source])) {
+ /* Av = A1 + As */
+ *reg |= (TD0_alpha_arg2_prevstage |
+ TD0_alpha_add_enable |
+ TD0_alpha_sel_add);
+ } else {
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
static void mgaUpdateTextureEnvG400( GLcontext *ctx, GLuint unit )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
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);
- GLenum format;
+ mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData;
+ GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
- if ( tObj != ctx->Texture.Unit[source].Current2D || !tObj )
+ if (tObj != ctx->Texture.Unit[source].CurrentTex[TEXTURE_2D_INDEX] &&
+ tObj != ctx->Texture.Unit[source].CurrentTex[TEXTURE_RECT_INDEX])
return;
- format = tObj->Image[tObj->BaseLevel]->Format;
-
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->force_dualtex = 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);
- } 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);
- }
- }
+ if (!mgaUpdateTextureEnvBlend(ctx, unit))
+ t->texenv_fallback = GL_TRUE;
+ break;
+
+ case GL_COMBINE:
+ 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 );
mmesa->CurrentTexObj[unit] = NULL;
}
- if ( unit != 0 ) {
+ if ( unit != 0 && !mmesa->force_dualtex ) {
mmesa->setup.tdualstage1 = mmesa->setup.tdualstage0;
}
mmesa->dirty |= MGA_UPLOAD_CONTEXT | (MGA_UPLOAD_TEX0 << unit);
}
-static GLboolean enable_tex_2d( GLcontext *ctx, int unit )
+static GLboolean enable_tex( GLcontext *ctx, int unit )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
const int source = mmesa->tmu_source[unit];
mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData;
/* Fallback if there's a texture border */
- if ( tObj->Image[tObj->BaseLevel]->Border > 0 ) {
+ if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) {
return GL_FALSE;
}
mmesa->setup.tdualstage1 = mmesa->setup.tdualstage0;
}
- t->setup.texctl2 &= TMC_dualtex_MASK;
- if (ctx->Texture._EnabledUnits == 0x03) {
- 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?
mgaUpdateTextureEnvG400( ctx, unit );
} else {
- mmesa->hw.alpha_sel = 0;
- switch (ctx->Texture.Unit[0].EnvMode) {
- case GL_DECAL:
- mmesa->hw.alpha_sel |= AC_alphasel_diffused;
- case GL_REPLACE:
- mmesa->hw.alpha_sel |= AC_alphasel_fromtex;
- break;
- case GL_BLEND:
- case GL_MODULATE:
- mmesa->hw.alpha_sel |= AC_alphasel_modulated;
- break;
- default:
- break;
- }
-
mgaUpdateTextureEnvG200( ctx, unit );
}
- mmesa->setup.dwgctl &= DC_opcod_MASK;
- mmesa->setup.dwgctl |= DC_opcod_texture_trap;
+ t->setup.texctl2 &= TMC_dualtex_MASK;
+ if (ctx->Texture._EnabledUnits == 0x03 || mmesa->force_dualtex) {
+ t->setup.texctl2 |= TMC_dualtex_enable;
+ }
+
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;
}
const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
- if ( texUnit->_ReallyEnabled == TEXTURE_2D_BIT) {
- return(enable_tex_2d( ctx, unit ) &&
+ if ( texUnit->_ReallyEnabled == TEXTURE_2D_BIT ||
+ texUnit->_ReallyEnabled == TEXTURE_RECT_BIT ) {
+ return(enable_tex( ctx, unit ) &&
update_tex_common( ctx, unit ));
}
else if ( texUnit->_ReallyEnabled ) {
GLboolean ok;
unsigned i;
+ mmesa->force_dualtex = GL_FALSE;
+ mmesa->fcol_used = 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
}
FALLBACK( ctx, MGA_FALLBACK_TEXTURE, !ok );
-
- /* FIXME: I believe that ChooseVertexState should be called here instead of
- * FIXME: in mgaDDValidateState.
- */
}