summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/mga
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/mga')
-rw-r--r--src/mesa/drivers/dri/mga/Makefile.X116
-rw-r--r--src/mesa/drivers/dri/mga/mga_texcombine.c647
-rw-r--r--src/mesa/drivers/dri/mga/mga_texstate.c592
-rw-r--r--src/mesa/drivers/dri/mga/mga_xmesa.c110
-rw-r--r--src/mesa/drivers/dri/mga/mga_xmesa.h4
-rw-r--r--src/mesa/drivers/dri/mga/mgacontext.h20
-rw-r--r--src/mesa/drivers/dri/mga/mgaioctl.c3
-rw-r--r--src/mesa/drivers/dri/mga/mgastate.c87
-rw-r--r--src/mesa/drivers/dri/mga/mgatex.c49
-rw-r--r--src/mesa/drivers/dri/mga/mgatex.h2
-rw-r--r--src/mesa/drivers/dri/mga/mgatris.c16
-rw-r--r--src/mesa/drivers/dri/mga/mgavb.c7
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 f816616f2c..cb76983822 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 0000000000..f0664e37cf
--- /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 <syrjala@sci.fi>
+ */
+
+#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 fc1406cab9..5f3e1b1bac 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 16dc349cac..d95c0197eb 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 de349da089..d372abe012 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 7188f6d955..50efe4c817 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 6b50af202a..fc53912af4 100644
--- a/src/mesa/drivers/dri/mga/mgaioctl.c
+++ b/src/mesa/drivers/dri/mga/mgaioctl.c
@@ -26,9 +26,8 @@
* Gareth Hughes <gareth@valinux.com>
*/
/* $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 0d304966d7..29815008be 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 82eccc8149..166bdfc22f 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 282577e9f8..94547e3886 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 054c7f0635..1c193066ff 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 34906865e8..17dde2bba6 100644
--- a/src/mesa/drivers/dri/mga/mgavb.c
+++ b/src/mesa/drivers/dri/mga/mgavb.c
@@ -24,7 +24,7 @@
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
-/* $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;