diff options
Diffstat (limited to 'src/mesa/drivers/dri/mga')
-rw-r--r-- | src/mesa/drivers/dri/mga/Makefile.X11 | 6 | ||||
-rw-r--r-- | src/mesa/drivers/dri/mga/mga_texcombine.c | 647 | ||||
-rw-r--r-- | src/mesa/drivers/dri/mga/mga_texstate.c | 592 | ||||
-rw-r--r-- | src/mesa/drivers/dri/mga/mga_xmesa.c | 110 | ||||
-rw-r--r-- | src/mesa/drivers/dri/mga/mga_xmesa.h | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/mga/mgacontext.h | 20 | ||||
-rw-r--r-- | src/mesa/drivers/dri/mga/mgaioctl.c | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/mga/mgastate.c | 87 | ||||
-rw-r--r-- | src/mesa/drivers/dri/mga/mgatex.c | 49 | ||||
-rw-r--r-- | src/mesa/drivers/dri/mga/mgatex.h | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/mga/mgatris.c | 16 | ||||
-rw-r--r-- | src/mesa/drivers/dri/mga/mgavb.c | 7 |
12 files changed, 1237 insertions, 306 deletions
diff --git a/src/mesa/drivers/dri/mga/Makefile.X11 b/src/mesa/drivers/dri/mga/Makefile.X11 index f816616f2cf..cb769838227 100644 --- a/src/mesa/drivers/dri/mga/Makefile.X11 +++ b/src/mesa/drivers/dri/mga/Makefile.X11 @@ -1,4 +1,4 @@ -# $Id: Makefile.X11,v 1.4 2003/10/20 02:17:33 jonsmirl Exp $ +# $Id: Makefile.X11,v 1.5 2003/10/21 06:05:41 jonsmirl Exp $ # Mesa 3-D graphics library # Version: 5.0 @@ -31,7 +31,8 @@ DRIVER_SOURCES = mgadd.c \ ../common/mm.c \ ../common/utils.c \ ../common/texmem.c \ - ../common/vblank.c + ../common/vblank.c \ + ../common/xmlconfig.c FULL_DRIVER_SOURCES = \ mgapixel.c \ @@ -39,6 +40,7 @@ FULL_DRIVER_SOURCES = \ mgatex.c \ mgatexmem.c \ mga_texstate.c \ + mga_texcombine.c \ mgavb.c \ mga_xmesa.c diff --git a/src/mesa/drivers/dri/mga/mga_texcombine.c b/src/mesa/drivers/dri/mga/mga_texcombine.c new file mode 100644 index 00000000000..f0664e37cfa --- /dev/null +++ b/src/mesa/drivers/dri/mga/mga_texcombine.c @@ -0,0 +1,647 @@ +/* + * Copyright (c) 2003 Ville Syrjala + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Ville Syrjala <[email protected]> + */ + +#include "glheader.h" + +#include "mgacontext.h" +#include "mgatex.h" +#include "mgaregs.h" + +/* + * GL_ARB_texture_env_combine + * GL_EXT_texture_env_combine + * GL_ARB_texture_env_crossbar + * GL_ATI_texture_env_combine3 + */ + +#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: + case GL_MODULATE_ADD_ATI: + case GL_MODULATE_SIGNED_ADD_ATI: + case GL_MODULATE_SUBTRACT_ATI: + 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; + default: + return GL_FALSE; + } + + 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; + } + } + + switch (texUnit->CombineModeRGB) { + case GL_MODULATE_ADD_ATI: + case GL_MODULATE_SIGNED_ADD_ATI: + /* Special handling for ATI_texture_env_combine3. + * If Arg1 == Arg0 or Arg1 == Arg2 we can use arg1 or arg2 as input for + * both multiplier and adder. + */ + /* Arg1 == arg1 */ + if (arg1[1] == arg1[0]) { + if ((arg1[1] | arg2[2]) != ARG_DISABLE) { + *reg |= arg1[1] | arg2[2]; + args[0] = MGA_ARG1; args[1] = MGA_ARG1; args[2] = MGA_ARG2; + break; + } else + if ((arg1[1] | alpha[2]) != ARG_DISABLE) { + *reg |= arg1[1] | alpha[2]; + args[0] = MGA_ARG1; args[1] = MGA_ARG1; args[2] = MGA_ALPHA; + break; + } + } + if (arg1[1] == arg1[2]) { + if ((arg1[1] | arg2[0]) != ARG_DISABLE) { + *reg |= arg1[1] | arg2[0]; + args[0] = MGA_ARG2; args[1] = MGA_ARG1; args[2] = MGA_ARG1; + break; + } else + if ((arg1[1] | alpha[0]) != ARG_DISABLE) { + *reg |= arg1[1] | alpha[0]; + args[0] = MGA_ALPHA; args[1] = MGA_ARG1; args[2] = MGA_ARG1; + break; + } + } + /* fallthrough */ + case GL_MODULATE_SUBTRACT_ATI: + /* Arg1 == arg2 */ + if (arg2[1] == arg2[0]) { + if ((arg2[1] | arg1[2]) != ARG_DISABLE) { + *reg |= arg2[1] | arg1[2]; + args[0] = MGA_ARG2; args[1] = MGA_ARG2; args[2] = MGA_ARG1; + break; + } else + if ((arg2[1] | alpha[2]) != ARG_DISABLE) { + *reg |= arg2[1] | alpha[2]; + args[0] = MGA_ARG2; args[1] = MGA_ARG2; args[2] = MGA_ALPHA; + break; + } + } + if (arg2[1] == arg2[2]) { + if ((arg2[1] | arg1[0]) != ARG_DISABLE) { + *reg |= arg2[1] | arg1[0]; + args[0] = MGA_ARG1; args[1] = MGA_ARG2; args[2] = MGA_ARG2; + break; + } else + if ((arg2[1] | alpha[0]) != ARG_DISABLE) { + *reg |= arg2[1] | alpha[0]; + args[0] = MGA_ALPHA; args[1] = MGA_ARG2; args[2] = MGA_ARG2; + break; + } + } + /* fallthrough */ + default: + /* Find working combo of arg1, arg2 and alpha. + * + * Keep the Arg0 != alpha cases first 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 good for + * GL_ADD, GL_ADD_SIGNED, GL_SUBTRACT since we can't get alpha to the + * adder. + * + * Keep the Arg1 == alpha cases last for GL_MODULATE_ADD_ATI, + * GL_MODULATE_SIGNED_ADD_ATI. Again because we can't get alpha to the + * adder. + * + * GL_MODULATE_SUBTRACT_ATI needs special treatment since it requires + * that Arg1 == arg2. This requirement clashes with those of other modes. + */ + 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 && + texUnit->CombineModeRGB != GL_MODULATE_SUBTRACT_ATI) { + *reg |= arg1[1] | arg2[0] | alpha[2]; + args[0] = MGA_ARG2; args[1] = MGA_ARG1; args[2] = MGA_ALPHA; + } else + if ((arg1[1] | arg2[2] | alpha[0]) != ARG_DISABLE && + texUnit->CombineModeRGB != GL_MODULATE_SUBTRACT_ATI) { + *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 + 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 { + /* 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_SIGNED: + *reg |= TD0_color_addbias_enable; + /* fallthrough */ + 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_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 this bit. + */ + *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 */ + *(reg+1) = (TD0_color_arg2_prevstage | + TD0_color_sel_arg2 | + TD0_alpha_arg2_prevstage | + TD0_alpha_sel_arg2); + 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; + case GL_MODULATE_SIGNED_ADD_ATI: + *reg |= TD0_color_addbias_enable; + /* fallthrough */ + case GL_MODULATE_ADD_ATI: + if (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); + + if (args[1] == args[0] || args[1] == args[2]) { + *reg |= TD0_color_arg1add_mulout; + if (args[0] == MGA_ALPHA || args[2] == MGA_ALPHA) + *reg |= TD0_color_arg1mul_alpha1; + + if (args[1] == MGA_ARG1) { + /* Swap adder arguments */ + *reg ^= (TD0_color_arg1add_mulout | + TD0_color_arg2add_mulout); + if (args[0] == MGA_ALPHA || args[2] == MGA_ALPHA) { + /* Swap multiplier arguments */ + *reg ^= (TD0_color_arg1mul_alpha1 | + TD0_color_arg2mul_alpha2); + } + } + } else { + *reg |= (TD0_color_arg2mul_alpha2 | + TD0_color_arg1add_mulout); + + if (args[1] == MGA_ARG1) { + /* Swap arguments */ + *reg ^= (TD0_color_arg1mul_alpha1 | + TD0_color_arg2mul_alpha2 | + TD0_color_arg1add_mulout | + TD0_color_arg2add_mulout); + } + } + break; + case GL_MODULATE_SUBTRACT_ATI: + if (args[1] != MGA_ARG2) { + /* Can't swap arguments */ + 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[1] == args[0] || args[1] == args[2]) { + *reg |= TD0_color_arg1add_mulout; + if (args[0] == MGA_ALPHA || args[2] == MGA_ALPHA) + *reg |= TD0_color_arg1mul_alpha1; + } else { + *reg |= (TD0_color_arg2mul_alpha2 | + TD0_color_arg1add_mulout); + } + 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; + default: + return GL_FALSE; + } + + 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_SIGNED: + *reg |= TD0_alpha_addbias_enable; + /* fallthrough */ + 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_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; +} + + diff --git a/src/mesa/drivers/dri/mga/mga_texstate.c b/src/mesa/drivers/dri/mga/mga_texstate.c index fc1406cab9e..5f3e1b1bacc 100644 --- a/src/mesa/drivers/dri/mga/mga_texstate.c +++ b/src/mesa/drivers/dri/mga/mga_texstate.c @@ -52,6 +52,8 @@ static const unsigned TMC_tformat[ TMC_nr_tformat ] = [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, @@ -67,7 +69,7 @@ mgaSetTexImages( mgaContextPtr mmesa, GLint totalSize; GLint width, height; GLint i; - GLint firstLevel, lastLevel, numLevels; + GLint numLevels; GLint log2Width, log2Height; GLuint txformat = 0; GLint ofs; @@ -81,6 +83,8 @@ mgaSetTexImages( mgaContextPtr mmesa, 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; @@ -101,39 +105,21 @@ mgaSetTexImages( mgaContextPtr mmesa, #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; - } 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 */ - } + driCalculateTextureFirstLastLevel( (driTextureObject *) t ); + log2Width = tObj->Image[t->base.firstLevel]->WidthLog2; + log2Height = tObj->Image[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[t->base.firstLevel]->Width; + height = tObj->Image[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[ i + t->base.firstLevel ]; if ( (texImage == NULL) || ((i != 0) @@ -149,13 +135,9 @@ mgaSetTexImages( mgaContextPtr mmesa, baseImage->TexFormat->TexelBytes) + 31) & ~31; } - numLevels = i; - lastLevel = firstLevel + numLevels - 1; - /* 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 */ @@ -225,7 +207,7 @@ static void mgaUpdateTextureEnvG200( GLcontext *ctx, GLuint unit ) 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; @@ -251,29 +233,160 @@ static const GLuint g400_color_combine[][MGA_MAX_COMBFUNC] = (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 +403,53 @@ static const GLuint g400_color_combine[][MGA_MAX_COMBFUNC] = (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 +467,25 @@ static const GLuint g400_alpha_combine[][MGA_MAX_COMBFUNC] = (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 +493,20 @@ static const GLuint g400_alpha_combine[][MGA_MAX_COMBFUNC] = 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 +519,25 @@ static const GLuint g400_alpha_combine[][MGA_MAX_COMBFUNC] = (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 +545,20 @@ static const GLuint g400_alpha_combine[][MGA_MAX_COMBFUNC] = 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,143 +571,236 @@ static void mgaUpdateTextureEnvG400( GLcontext *ctx, GLuint 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); + mgaTextureObjectPtr t; GLenum format; - if ( tObj != ctx->Texture.Unit[source].Current2D || !tObj ) + if ( !tObj || + (tObj != ctx->Texture.Unit[source].Current2D && + tObj != ctx->Texture.Unit[source].CurrentRect) ) return; 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 +816,7 @@ static void disable_tex( GLcontext *ctx, int unit ) mmesa->CurrentTexObj[unit] = NULL; } - if ( unit != 0 ) { + if ( unit != 0 && !mmesa->dualtex_env ) { mmesa->setup.tdualstage1 = mmesa->setup.tdualstage0; } @@ -586,7 +829,7 @@ static void disable_tex( GLcontext *ctx, int unit ) 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]; @@ -649,6 +892,14 @@ static GLboolean update_tex_common( GLcontext *ctx, int unit ) 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 +931,10 @@ static GLboolean update_tex_common( GLcontext *ctx, int unit ) 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; } @@ -697,8 +945,9 @@ static GLboolean updateTextureUnit( GLcontext *ctx, int unit ) 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 ) { @@ -718,6 +967,7 @@ void mgaUpdateTextureState( GLcontext *ctx ) 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 @@ -740,8 +990,4 @@ void mgaUpdateTextureState( GLcontext *ctx ) } FALLBACK( ctx, MGA_FALLBACK_TEXTURE, !ok ); - - /* FIXME: I believe that ChooseVertexState should be called here instead of - * FIXME: in mgaDDValidateState. - */ } diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c index 16dc349cace..d95c0197ebb 100644 --- a/src/mesa/drivers/dri/mga/mga_xmesa.c +++ b/src/mesa/drivers/dri/mga/mga_xmesa.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c,v 1.18 2002/12/16 16:18:52 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c,v 1.19 2003/03/26 20:43:49 tsi Exp $ */ /* * Copyright 2000-2001 VA Linux Systems, Inc. * All Rights Reserved. @@ -56,11 +56,23 @@ #include "utils.h" #include "vblank.h" -#include "dri_util.h" + #ifndef _SOLO #include "glxextensions.h" #endif +/* MGA configuration + */ +#include "xmlpool.h" + +const char __driConfigOptions[] = +DRI_CONF_BEGIN + DRI_CONF_SECTION_PERFORMANCE + DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) + DRI_CONF_SECTION_END +DRI_CONF_END; +const GLuint __driNConfigOptions = 1; + #ifndef MGA_DEBUG int MGA_DEBUG = 0; #endif @@ -97,7 +109,7 @@ mgaInitDriver(__DRIscreenPrivate *sPriv) &gp, sizeof(gp)); if (ret) { fprintf(stderr, "drmMgaGetParam (MGA_PARAM_IRQ_NR): %d\n", ret); - free(mgaScreen); + FREE(mgaScreen); sPriv->private = NULL; return GL_FALSE; } @@ -105,23 +117,26 @@ mgaInitDriver(__DRIscreenPrivate *sPriv) mgaScreen->linecomp_sane = (sPriv->ddxMajor > 1) || (sPriv->ddxMinor > 1) || ((sPriv->ddxMinor == 1) && (sPriv->ddxPatch > 0)); -#ifndef _SOLO - if ( ! mgaScreen->linecomp_sane ) { - PFNGLXDISABLEEXTENSIONPROC glx_disable_extension; +#ifndef _SOLO + if ( driCompareGLXAPIVersion( 20030813 ) >= 0 ) { + PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = + (PFNGLXSCRENABLEEXTENSIONPROC) glXGetProcAddress( (const GLubyte *) "__glXScrEnableExtension" ); + void * const psc = sPriv->psc->screenConfigs; - glx_disable_extension = (PFNGLXDISABLEEXTENSIONPROC) - glXGetProcAddress( "__glXDisableExtension" ); + if ( glx_enable_extension != NULL ) { + if ( mgaScreen->linecomp_sane ) { + (*glx_enable_extension)( psc, "GLX_SGI_swap_control" ); + (*glx_enable_extension)( psc, "GLX_SGI_video_sync" ); + (*glx_enable_extension)( psc, "GLX_MESA_swap_control" ); + } - if ( glx_disable_extension != NULL ) { - (*glx_disable_extension)( "GLX_SGI_swap_control" ); - (*glx_disable_extension)( "GLX_SGI_video_sync" ); - (*glx_disable_extension)( "GLX_MESA_swap_control" ); + (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" ); } } #endif if (serverInfo->chipset != MGA_CARD_TYPE_G200 && serverInfo->chipset != MGA_CARD_TYPE_G400) { - free(mgaScreen); + FREE(mgaScreen); sPriv->private = NULL; __driUtilMessage("Unrecognized chipset"); return GL_FALSE; @@ -168,7 +183,7 @@ mgaInitDriver(__DRIscreenPrivate *sPriv) mgaScreen->agp.size, (drmAddress *)&mgaScreen->agp.map) != 0) { - free(mgaScreen); + Xfree(mgaScreen); sPriv->private = NULL; __driUtilMessage("Couldn't map agp region"); return GL_FALSE; @@ -194,7 +209,7 @@ mgaInitDriver(__DRIscreenPrivate *sPriv) serverInfo->agpTextureSize, (drmAddress *)&mgaScreen->texVirtual[MGA_AGP_HEAP]) != 0) { - free(mgaScreen); + FREE(mgaScreen); sPriv->private = NULL; __driUtilMessage("Couldn't map agptexture region"); return GL_FALSE; @@ -214,13 +229,16 @@ mgaInitDriver(__DRIscreenPrivate *sPriv) mgaScreen->bufs = drmMapBufs(sPriv->fd); if (!mgaScreen->bufs) { /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/ - free(mgaScreen); + FREE(mgaScreen); sPriv->private = NULL; __driUtilMessage("Couldn't map dma buffers"); return GL_FALSE; } mgaScreen->sarea_priv_offset = serverInfo->sarea_priv_offset; + /* parse information in __driConfigOptions */ + driParseOptionInfo (&mgaScreen->optionCache); + return GL_TRUE; } @@ -234,7 +252,11 @@ mgaDestroyScreen(__DRIscreenPrivate *sPriv) fprintf(stderr, "mgaDestroyScreen\n"); /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/ - free(mgaScreen); + + /* free all option information */ + driDestroyOptionInfo (&mgaScreen->optionCache); + + FREE(mgaScreen); sPriv->private = NULL; } @@ -263,6 +285,10 @@ static const char * const g400_extensions[] = "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_ATI_texture_env_combine3", "GL_EXT_texture_edge_clamp", "GL_SGIS_texture_edge_clamp", #if defined (MESA_packed_depth_stencil) @@ -286,6 +312,7 @@ static const char * const card_extensions[] = "GL_MESA_ycbcr_texture", "GL_SGIS_generate_mipmap", "GL_SGIS_texture_lod", + "GL_NV_texture_rectangle", NULL }; @@ -353,6 +380,10 @@ mgaCreateContext( const __GLcontextModes *mesaVis, mmesa->sarea = (void *)saPriv; mmesa->glBuffer = NULL; + /* Parse configuration files */ + driParseConfigFiles (&mmesa->optionCache, &mgaScreen->optionCache, + sPriv->myNum, "mga"); + (void) memset( mmesa->texture_heaps, 0, sizeof( mmesa->texture_heaps ) ); make_empty_list( & mmesa->swapped ); @@ -388,10 +419,10 @@ mgaCreateContext( const __GLcontextModes *mesaVis, mmesa->nr_heaps, & ctx->Const, 4, - 11, /* max 2D texture size is 1024x1024 */ + 11, /* max 2D texture size is 2048x2048 */ 0, /* 3D textures unsupported. */ 0, /* cube textures unsupported. */ - 0, /* texture rectangles unsupported. */ + 11, /* max texture rect size is 2048x2048 */ maxlevels, GL_FALSE ); @@ -487,14 +518,15 @@ mgaCreateContext( const __GLcontextModes *mesaVis, mmesa->vblank_flags = ((mmesa->mgaScreen->irq == 0) || !mmesa->mgaScreen->linecomp_sane) - ? VBLANK_FLAG_NO_IRQ : driGetDefaultVBlankFlags(); + ? VBLANK_FLAG_NO_IRQ : driGetDefaultVBlankFlags(&mmesa->optionCache); #ifndef _SOLO - mmesa->get_ust = (PFNGLXGETUSTPROC) glXGetProcAddress( "__glXGetUST" ); - if ( mmesa->get_ust == NULL ) -#endif - { + mmesa->get_ust = (PFNGLXGETUSTPROC) glXGetProcAddress( (const GLubyte *) "__glXGetUST" ); + if ( mmesa->get_ust == NULL ) { mmesa->get_ust = get_ust_nop; } +#else + mmesa->get_ust = get_ust_nop; +#endif (*mmesa->get_ust)( & mmesa->swap_ust ); @@ -541,6 +573,9 @@ mgaDestroyContext(__DRIcontextPrivate *driContextPriv) } } + /* free the option cache */ + driDestroyOptionCache (&mmesa->optionCache); + FREE(mmesa); } @@ -614,6 +649,7 @@ mgaMakeCurrent(__DRIcontextPrivate *driContextPriv, mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate; if (mmesa->driDrawable != driDrawPriv) { + driDrawableInitVBlank( driDrawPriv, mmesa->vblank_flags ); mmesa->driDrawable = driDrawPriv; mmesa->dirty = ~0; mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK); @@ -695,7 +731,7 @@ static const struct __DriverAPIRec mgaAPI = { * The __driCreateScreen name is the symbol that libGL.so fetches. * Return: pointer to a __DRIscreenPrivate. */ -#ifndef _SOLO +#ifndef _SOLO void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, int numConfigs, __GLXvisualConfig *config) { @@ -714,30 +750,6 @@ void *__driCreateScreen(struct DRIDriverRec *driver, #endif -#ifndef _SOLO -/* This function is called by libGL.so as soon as libGL.so is loaded. - * This is where we'd register new extension functions with the dispatcher. - */ -void -__driRegisterExtensions( void ) -{ - PFNGLXENABLEEXTENSIONPROC glx_enable_extension; - - - if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) { - glx_enable_extension = (PFNGLXENABLEEXTENSIONPROC) - glXGetProcAddress( "__glXEnableExtension" ); - - if ( glx_enable_extension != NULL ) { - (*glx_enable_extension)( "GLX_SGI_swap_control", GL_FALSE ); - (*glx_enable_extension)( "GLX_SGI_video_sync", GL_FALSE ); - (*glx_enable_extension)( "GLX_MESA_swap_control", GL_FALSE ); - (*glx_enable_extension)( "GLX_MESA_swap_frame_usage", GL_FALSE ); - } - } -} -#endif - /** * Get information about previous buffer swaps. */ diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.h b/src/mesa/drivers/dri/mga/mga_xmesa.h index de349da0895..d372abe0120 100644 --- a/src/mesa/drivers/dri/mga/mga_xmesa.h +++ b/src/mesa/drivers/dri/mga/mga_xmesa.h @@ -36,6 +36,7 @@ #include "mtypes.h" #include "mgaregs.h" #include "mga_common.h" +#include "xmlconfig.h" typedef struct mga_screen_private_s { @@ -78,6 +79,9 @@ typedef struct mga_screen_private_s { drmRegion primary; drmRegion buffers; unsigned int sarea_priv_offset; + + /* Configuration cache with default values for all contexts */ + driOptionCache optionCache; } mgaScreenPrivate; diff --git a/src/mesa/drivers/dri/mga/mgacontext.h b/src/mesa/drivers/dri/mga/mgacontext.h index 7188f6d9552..50efe4c817f 100644 --- a/src/mesa/drivers/dri/mga/mgacontext.h +++ b/src/mesa/drivers/dri/mga/mgacontext.h @@ -38,6 +38,7 @@ #include "mga_sarea.h" #include "texmem.h" #include "macros.h" +#include "xmlconfig.h" #define MGA_SET_FIELD(reg,mask,val) reg = ((reg) & (mask)) | ((val) & ~(mask)) #define MGA_FIELD(field,val) (((val) << (field ## _SHIFT)) & ~(field ## _MASK)) @@ -79,10 +80,12 @@ typedef void (*mga_point_func)( mgaContextPtr, mgaVertex * ); -/* 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; @@ -149,6 +152,10 @@ typedef struct mga_texture_object_s * 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 { @@ -202,10 +209,11 @@ struct mga_context_t { 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 */ @@ -299,6 +307,10 @@ struct mga_context_t { __DRIscreenPrivate *driScreen; struct mga_screen_private_s *mgaScreen; MGASAREAPrivPtr sarea; + + /* Configuration cache + */ + driOptionCache optionCache; }; #define MGA_CONTEXT(ctx) ((mgaContextPtr)(ctx->DriverCtx)) diff --git a/src/mesa/drivers/dri/mga/mgaioctl.c b/src/mesa/drivers/dri/mga/mgaioctl.c index 6b50af202a8..fc53912af4c 100644 --- a/src/mesa/drivers/dri/mga/mgaioctl.c +++ b/src/mesa/drivers/dri/mga/mgaioctl.c @@ -26,9 +26,8 @@ * Gareth Hughes <[email protected]> */ /* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaioctl.c,v 1.16 2002/12/16 16:18:52 dawes Exp $ */ - -#include <sched.h> #include <errno.h> +#include <sched.h> #include "mtypes.h" #include "macros.h" diff --git a/src/mesa/drivers/dri/mga/mgastate.c b/src/mesa/drivers/dri/mga/mgastate.c index 0d304966d7e..29815008be9 100644 --- a/src/mesa/drivers/dri/mga/mgastate.c +++ b/src/mesa/drivers/dri/mga/mgastate.c @@ -401,7 +401,7 @@ static void mgaDDColorMask(GLcontext *ctx, */ static int mgaStipples[16] = { - 0xffff1, /* See above note */ + 0xffff, 0xa5a5, 0x5a5a, 0xa0a0, @@ -425,9 +425,6 @@ static int mgaStipples[16] = { * * \param ctx GL rendering context to be affected * \param mask Pointer to the 32x32 stipple mask - * - * \note the fully opaque pattern (0xffff) has been disabled in order - * to work around a conformance issue. */ static void mgaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) @@ -492,8 +489,7 @@ static void updateSpecularLighting( GLcontext *ctx ) mgaContextPtr mmesa = MGA_CONTEXT(ctx); unsigned int specen; - specen = (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR && - ctx->Light.Enabled) ? TMC_specen_enable : 0; + specen = (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) ? TMC_specen_enable : 0; if ( specen != mmesa->hw.specen ) { mmesa->hw.specen = specen; @@ -519,14 +515,6 @@ static void mgaDDLightModelfv(GLcontext *ctx, GLenum pname, } -static void mgaDDShadeModel(GLcontext *ctx, GLenum mode) -{ - /* FIXME: This used to FLUSH_BATCH and set MGA_NEW_TEXTURE in new_state, - * FIXME: so I'm not sure what to do here now. - */ -} - - /* ============================================================= * Stencil */ @@ -671,6 +659,12 @@ static void mgaDDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail, case GL_DECR: stencilctl |= SC_szpassop_decrsat; break; + case GL_INCR_WRAP: + stencilctl |= SC_szpassop_incr; + break; + case GL_DECR_WRAP: + stencilctl |= SC_szpassop_decr; + break; case GL_INVERT: stencilctl |= SC_szpassop_invert; break; @@ -826,8 +820,10 @@ void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers ) else mgaXMesaSetBackClipRects( mmesa ); +#ifndef _SOLO + sarea->req_drawable = driDrawable->draw; sarea->req_draw_buffer = mmesa->draw_buffer; - +#endif mgaUpdateClipping( mmesa->glCtx ); mgaCalcViewport( mmesa->glCtx ); @@ -888,6 +884,11 @@ static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state) mgaContextPtr mmesa = MGA_CONTEXT( ctx ); switch(cap) { + case GL_LIGHTING: + case GL_COLOR_SUM_EXT: + FLUSH_BATCH( mmesa ); + updateSpecularLighting( ctx ); + break; case GL_ALPHA_TEST: FLUSH_BATCH( mmesa ); mmesa->hw.alpha_func_enable = (state) ? ~0 : 0; @@ -1034,25 +1035,24 @@ void mgaEmitHwStateLocked( mgaContextPtr mmesa ) } if ((mmesa->dirty & MGA_UPLOAD_TEX0) && mmesa->CurrentTexObj[0]) { - mmesa->CurrentTexObj[0]->setup.texctl2 &= ~TMC_specen_enable; - mmesa->CurrentTexObj[0]->setup.texctl2 |= mmesa->hw.specen; - memcpy(&sarea->TexState[0], &mmesa->CurrentTexObj[0]->setup, sizeof(sarea->TexState[0])); } if ((mmesa->dirty & MGA_UPLOAD_TEX1) && mmesa->CurrentTexObj[1]) { - mmesa->CurrentTexObj[1]->setup.texctl2 &= ~TMC_specen_enable; - mmesa->CurrentTexObj[1]->setup.texctl2 |= mmesa->hw.specen; - memcpy(&sarea->TexState[1], &mmesa->CurrentTexObj[1]->setup, 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], @@ -1070,15 +1070,10 @@ void mgaEmitHwStateLocked( mgaContextPtr mmesa ) mmesa->sarea->dirty |= mmesa->dirty; mmesa->dirty &= MGA_UPLOAD_CLIPRECTS; - /* This is a bit of a hack but seems to be the best place to ensure - * that separate specular is disabled when not needed. - */ - if (ctx->Texture._EnabledUnits == 0 || - !ctx->Light.Enabled || - ctx->Light.Model.ColorControl == GL_SINGLE_COLOR) { - sarea->TexState[0].texctl2 &= ~TMC_specen_enable; - sarea->TexState[1].texctl2 &= ~TMC_specen_enable; - } + sarea->TexState[0].texctl2 &= ~TMC_specen_enable; + sarea->TexState[1].texctl2 &= ~TMC_specen_enable; + sarea->TexState[0].texctl2 |= mmesa->hw.specen; + sarea->TexState[1].texctl2 |= mmesa->hw.specen; } @@ -1089,21 +1084,21 @@ void mgaEmitHwStateLocked( mgaContextPtr mmesa ) static void mgaDDValidateState( GLcontext *ctx ) { mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - int new_state = mmesa->NewGLState; - FLUSH_BATCH( mmesa ); - if (mmesa->NewGLState & _MGA_NEW_RASTERSETUP) { - mgaChooseVertexState( ctx ); + if (mmesa->NewGLState & _NEW_TEXTURE) { + mgaUpdateTextureState(ctx); } - if (mmesa->NewGLState & _MGA_NEW_RENDERSTATE) { - mgaChooseRenderState( ctx ); - } + if (!mmesa->Fallback) { + if (mmesa->NewGLState & _MGA_NEW_RASTERSETUP) { + mgaChooseVertexState( ctx ); + } - if (new_state & _NEW_TEXTURE) { - mgaUpdateTextureState(ctx); + if (mmesa->NewGLState & _MGA_NEW_RENDERSTATE) { + mgaChooseRenderState( ctx ); + } } mmesa->NewGLState = 0; @@ -1186,13 +1181,14 @@ void mgaInitState( mgaContextPtr mmesa ) break; } + mmesa->hw.blend_func = AC_src_one | AC_dst_zero; mmesa->hw.zmode = DC_zmode_zlt | DC_atype_zi; mmesa->hw.stencil = (0x0ff << S_smsk_SHIFT) | (0x0ff << S_swtmsk_SHIFT); mmesa->hw.stencilctl = SC_smode_salways | SC_sfailop_keep | SC_szfailop_keep | SC_szpassop_keep; mmesa->hw.stencil_enable = 0; - mmesa->hw.cull = _CULL_NEGATIVE; - mmesa->hw.cull_dualtex = _CULL_POSITIVE; + mmesa->hw.cull = _CULL_DISABLE; + mmesa->hw.cull_dualtex = _CULL_DISABLE; mmesa->hw.specen = 0; mmesa->setup.dwgctl = (DC_opcod_trap | @@ -1227,6 +1223,10 @@ void mgaInitState( mgaContextPtr mmesa ) 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; } @@ -1243,7 +1243,6 @@ void mgaDDInitStateFuncs( GLcontext *ctx ) ctx->Driver.DepthMask = mgaDDDepthMask; ctx->Driver.Fogfv = mgaDDFogfv; ctx->Driver.Scissor = mgaDDScissor; - ctx->Driver.ShadeModel = mgaDDShadeModel; ctx->Driver.CullFace = mgaDDCullFaceFrontFace; ctx->Driver.FrontFace = mgaDDCullFaceFrontFace; ctx->Driver.ColorMask = mgaDDColorMask; diff --git a/src/mesa/drivers/dri/mga/mgatex.c b/src/mesa/drivers/dri/mga/mgatex.c index 82eccc81498..166bdfc22f3 100644 --- a/src/mesa/drivers/dri/mga/mgatex.c +++ b/src/mesa/drivers/dri/mga/mgatex.c @@ -221,7 +221,7 @@ mgaChooseTextureFormat( GLcontext *ctx, GLint internalFormat, 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: @@ -231,7 +231,7 @@ mgaChooseTextureFormat( GLcontext *ctx, GLint internalFormat, 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_al88 : &_mesa_texformat_rgb565; case 2: case GL_LUMINANCE_ALPHA: @@ -243,7 +243,7 @@ mgaChooseTextureFormat( GLcontext *ctx, GLint internalFormat, 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: @@ -252,7 +252,7 @@ mgaChooseTextureFormat( GLcontext *ctx, GLint internalFormat, 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) && @@ -309,6 +309,7 @@ mgaAllocTexObj( struct gl_texture_object *tObj ) | TF_uvoffset_OGL); t->border_fallback = GL_FALSE; + t->texenv_fallback = GL_FALSE; make_empty_list( & t->base ); @@ -328,31 +329,31 @@ static void mgaDDTexEnv( GLcontext *ctx, GLenum target, struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; mgaContextPtr mmesa = MGA_CONTEXT(ctx); - 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; + + 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; + } - /* 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 >> 24) == 0x0) { + mmesa->blend_flags |= MGA_BLEND_ALPHA_ZERO; + } else if ((mmesa->envcolor >> 24) == 0xff) { + mmesa->blend_flags |= MGA_BLEND_ALPHA_ONE; + } } break; } @@ -445,8 +446,9 @@ mgaDDTexParameter( GLcontext *ctx, GLenum target, * to do anything now */ - if ( (t == NULL) - || (target != GL_TEXTURE_2D) ) { + if ( (t == NULL) || + (target != GL_TEXTURE_2D && + target != GL_TEXTURE_RECTANGLE_NV) ) { return; } @@ -492,7 +494,8 @@ static void mgaDDBindTexture( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj ) { - if ( target == GL_TEXTURE_2D ) { + if ( target == GL_TEXTURE_2D || + target == GL_TEXTURE_RECTANGLE_NV ) { if ( tObj->DriverData == NULL ) { mgaAllocTexObj( tObj ); } @@ -547,5 +550,7 @@ mgaDDInitTextureFuncs( GLcontext *ctx ) ctx->Driver.TexEnv = mgaDDTexEnv; ctx->Driver.TexParameter = mgaDDTexParameter; - driInitTextureObjects( ctx, & mmesa->swapped, DRI_TEXMGR_DO_TEXTURE_2D ); + driInitTextureObjects( ctx, & mmesa->swapped, + (DRI_TEXMGR_DO_TEXTURE_2D | + DRI_TEXMGR_DO_TEXTURE_RECT) ); } diff --git a/src/mesa/drivers/dri/mga/mgatex.h b/src/mesa/drivers/dri/mga/mgatex.h index 282577e9f80..94547e38862 100644 --- a/src/mesa/drivers/dri/mga/mgatex.h +++ b/src/mesa/drivers/dri/mga/mgatex.h @@ -46,4 +46,6 @@ void mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t ); void mgaDDInitTextureFuncs( GLcontext *ctx ); +GLboolean mgaUpdateTextureEnvCombine( GLcontext *ctx, int unit ); + #endif diff --git a/src/mesa/drivers/dri/mga/mgatris.c b/src/mesa/drivers/dri/mga/mgatris.c index 054c7f0635d..1c193066ff3 100644 --- a/src/mesa/drivers/dri/mga/mgatris.c +++ b/src/mesa/drivers/dri/mga/mgatris.c @@ -676,8 +676,7 @@ static void mgaFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, #define POINT_FALLBACK (DD_POINT_SMOOTH) #define LINE_FALLBACK (DD_LINE_SMOOTH | DD_LINE_STIPPLE) #define TRI_FALLBACK (DD_TRI_SMOOTH | DD_TRI_UNFILLED) -#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK| \ - DD_TRI_STIPPLE) +#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK) #define ANY_RASTER_FLAGS (DD_FLATSHADE|DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET| \ DD_TRI_UNFILLED) @@ -688,7 +687,7 @@ void mgaChooseRenderState(GLcontext *ctx) GLuint flags = ctx->_TriangleCaps; GLuint index = 0; - if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) { + if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS|DD_TRI_STIPPLE)) { if (flags & ANY_RASTER_FLAGS) { if (flags & DD_TRI_LIGHT_TWOSIDE) index |= MGA_TWOSIDE_BIT; if (flags & DD_TRI_OFFSET) index |= MGA_OFFSET_BIT; @@ -713,9 +712,11 @@ void mgaChooseRenderState(GLcontext *ctx) if (flags & TRI_FALLBACK) mmesa->draw_tri = mga_fallback_tri; - if ((flags & DD_TRI_STIPPLE) && !mmesa->haveHwStipple) - mmesa->draw_tri = mga_fallback_tri; - + index |= MGA_FALLBACK_BIT; + } + + if ((flags & DD_TRI_STIPPLE) && !mmesa->haveHwStipple) { + mmesa->draw_tri = mga_fallback_tri; index |= MGA_FALLBACK_BIT; } } @@ -782,10 +783,9 @@ void mgaRasterPrimitive( GLcontext *ctx, GLenum prim, GLuint hwprim ) if (ctx->Polygon.StippleFlag && mmesa->haveHwStipple) { mmesa->dirty |= MGA_UPLOAD_CONTEXT; + mmesa->setup.dwgctl &= ~(0xf<<20); if (mmesa->raster_primitive == GL_TRIANGLES) mmesa->setup.dwgctl |= mmesa->poly_stipple; - else - mmesa->setup.dwgctl &= ~(0xf<<20); } } diff --git a/src/mesa/drivers/dri/mga/mgavb.c b/src/mesa/drivers/dri/mga/mgavb.c index 34906865e8d..17dde2bba60 100644 --- a/src/mesa/drivers/dri/mga/mgavb.c +++ b/src/mesa/drivers/dri/mga/mgavb.c @@ -24,7 +24,7 @@ * Authors: * Keith Whitwell <[email protected]> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgavb.c,v 1.14 2002/10/30 12:51:36 alanh Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgavb.c,v 1.15 2003/03/26 20:43:49 tsi Exp $ */ #include "mgacontext.h" #include "mgavb.h" @@ -340,6 +340,9 @@ void mgaCheckTexSizes( GLcontext *ctx ) tnl->Driver.Render.Interp = setup_tab[mmesa->SetupIndex].interp; tnl->Driver.Render.CopyPV = setup_tab[mmesa->SetupIndex].copy_pv; } + if (mmesa->Fallback) { + tnl->Driver.Render.Start(ctx); + } } } @@ -456,7 +459,7 @@ void mgaInitVB( GLcontext *ctx ) mgaContextPtr mmesa = MGA_CONTEXT(ctx); GLuint size = TNL_CONTEXT(ctx)->vb.Size; - mmesa->verts = ALIGN_MALLOC(size * sizeof(mgaVertex), 32); + mmesa->verts = (GLubyte *)ALIGN_MALLOC(size * sizeof(mgaVertex), 32); { static int firsttime = 1; |