summaryrefslogtreecommitdiff
path: root/xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c
diff options
context:
space:
mode:
Diffstat (limited to 'xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c')
-rw-r--r--xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c503
1 files changed, 421 insertions, 82 deletions
diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c
index f66f589cd..a52969d33 100644
--- a/xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c
+++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c,v 1.3 2002/09/16 18:05:21 eich Exp $ */
+/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c,v 1.6 2002/12/16 16:18:59 dawes Exp $ */
/**************************************************************************
Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
@@ -34,21 +34,21 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-#include "radeon_context.h"
-#include "radeon_state.h"
-#include "radeon_ioctl.h"
-#include "radeon_vb.h"
-#include "radeon_tex.h"
-
+#include "glheader.h"
+#include "imports.h"
#include "colormac.h"
#include "context.h"
#include "enums.h"
#include "macros.h"
-#include "mem.h"
-#include "mmath.h"
-#include "simple_list.h"
#include "texformat.h"
+#include "radeon_context.h"
+#include "radeon_state.h"
+#include "radeon_ioctl.h"
+#include "radeon_swtcl.h"
+#include "radeon_tex.h"
+#include "radeon_tcl.h"
+
static void radeonSetTexImages( radeonContextPtr rmesa,
struct gl_texture_object *tObj )
@@ -228,6 +228,8 @@ static void radeonSetTexImages( radeonContextPtr rmesa,
t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) |
(log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT));
+ t->dirty_state = TEX_ALL;
+
radeonUploadTexImages( rmesa, t );
}
@@ -660,6 +662,19 @@ static GLuint radeon_previous_color[] =
RADEON_COLOR_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
};
+/* GL_ZERO table - indices 0-3
+ * GL_ONE table - indices 1-4
+ */
+static GLuint radeon_zero_color[] =
+{
+ RADEON_COLOR_ARG_A_ZERO,
+ RADEON_COLOR_ARG_A_ZERO | RADEON_COMP_ARG_A,
+ RADEON_COLOR_ARG_A_ZERO,
+ RADEON_COLOR_ARG_A_ZERO | RADEON_COMP_ARG_A,
+ RADEON_COLOR_ARG_A_ZERO
+};
+
+
/* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
*/
static GLuint radeon_texture_alpha[][RADEON_MAX_TEXTURE_UNITS] =
@@ -694,6 +709,16 @@ static GLuint radeon_previous_alpha[] =
RADEON_ALPHA_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
};
+/* GL_ZERO table - indices 0-1
+ * GL_ONE table - indices 1-2
+ */
+static GLuint radeon_zero_alpha[] =
+{
+ RADEON_ALPHA_ARG_A_ZERO,
+ RADEON_ALPHA_ARG_A_ZERO | RADEON_COMP_ARG_A,
+ RADEON_ALPHA_ARG_A_ZERO
+};
+
/* Extract the arg from slot A, shift it into the correct argument slot
* and set the corresponding complement bit.
@@ -723,7 +748,7 @@ do { \
* Texture unit state management
*/
-static void radeonUpdateTextureEnv( GLcontext *ctx, int unit )
+static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
@@ -733,9 +758,9 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit )
GLuint color_arg[3], alpha_arg[3];
GLuint i, numColorArgs = 0, numAlphaArgs = 0;
- if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) {
- fprintf( stderr, "%s( %p, %d ) format=%s\n",__FUNCTION__,
- (void*)ctx, unit, _mesa_lookup_enum_by_nr( format ) );
+ if ( RADEON_DEBUG & DEBUG_TEXTURE ) {
+ fprintf( stderr, "%s( %p, %d ) format=%s\n", __FUNCTION__,
+ ctx, unit, _mesa_lookup_enum_by_nr( format ) );
}
/* Set the texture environment state. Isn't this nice and clean?
@@ -764,7 +789,7 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit )
break;
case GL_COLOR_INDEX:
default:
- return;
+ return GL_FALSE;
}
break;
@@ -787,7 +812,7 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit )
break;
case GL_COLOR_INDEX:
default:
- return;
+ return GL_FALSE;
}
break;
@@ -807,7 +832,7 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit )
break;
case GL_COLOR_INDEX:
default:
- return;
+ return GL_FALSE;
}
break;
@@ -830,7 +855,7 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit )
break;
case GL_COLOR_INDEX:
default:
- return;
+ return GL_FALSE;
}
break;
@@ -853,7 +878,7 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit )
break;
case GL_COLOR_INDEX:
default:
- return;
+ return GL_FALSE;
}
break;
@@ -872,16 +897,22 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit )
break;
case GL_MODULATE:
case GL_ADD:
- case GL_ADD_SIGNED_EXT:
+ case GL_ADD_SIGNED:
+ case GL_SUBTRACT:
+ case GL_DOT3_RGB:
+ case GL_DOT3_RGBA:
case GL_DOT3_RGB_EXT:
case GL_DOT3_RGBA_EXT:
numColorArgs = 2;
break;
- case GL_INTERPOLATE_EXT:
+ case GL_INTERPOLATE:
+ case GL_MODULATE_ADD_ATI:
+ case GL_MODULATE_SIGNED_ADD_ATI:
+ case GL_MODULATE_SUBTRACT_ATI:
numColorArgs = 3;
break;
default:
- return;
+ return GL_FALSE;
}
switch ( texUnit->CombineModeA ) {
@@ -890,14 +921,18 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit )
break;
case GL_MODULATE:
case GL_ADD:
- case GL_ADD_SIGNED_EXT:
+ case GL_ADD_SIGNED:
+ case GL_SUBTRACT:
numAlphaArgs = 2;
break;
- case GL_INTERPOLATE_EXT:
+ case GL_INTERPOLATE:
+ case GL_MODULATE_ADD_ATI:
+ case GL_MODULATE_SIGNED_ADD_ATI:
+ case GL_MODULATE_SUBTRACT_ATI:
numAlphaArgs = 3;
break;
default:
- return;
+ return GL_FALSE;
}
/* Step 1:
@@ -911,17 +946,23 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit )
case GL_TEXTURE:
color_arg[i] = radeon_texture_color[op][unit];
break;
- case GL_CONSTANT_EXT:
+ case GL_CONSTANT:
color_arg[i] = radeon_tfactor_color[op];
break;
- case GL_PRIMARY_COLOR_EXT:
+ case GL_PRIMARY_COLOR:
color_arg[i] = radeon_primary_color[op];
break;
- case GL_PREVIOUS_EXT:
+ case GL_PREVIOUS:
color_arg[i] = radeon_previous_color[op];
break;
+ case GL_ZERO:
+ color_arg[i] = radeon_zero_color[op];
+ break;
+ case GL_ONE:
+ color_arg[i] = radeon_zero_color[op+1];
+ break;
default:
- return;
+ return GL_FALSE;
}
}
@@ -933,17 +974,23 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit )
case GL_TEXTURE:
alpha_arg[i] = radeon_texture_alpha[op][unit];
break;
- case GL_CONSTANT_EXT:
+ case GL_CONSTANT:
alpha_arg[i] = radeon_tfactor_alpha[op];
break;
- case GL_PRIMARY_COLOR_EXT:
+ case GL_PRIMARY_COLOR:
alpha_arg[i] = radeon_primary_alpha[op];
break;
- case GL_PREVIOUS_EXT:
+ case GL_PREVIOUS:
alpha_arg[i] = radeon_previous_alpha[op];
break;
+ case GL_ZERO:
+ alpha_arg[i] = radeon_zero_alpha[op];
+ break;
+ case GL_ONE:
+ alpha_arg[i] = radeon_zero_alpha[op+1];
+ break;
default:
- return;
+ return GL_FALSE;
}
}
@@ -973,7 +1020,7 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit )
RADEON_COLOR_ARG( 0, A );
RADEON_COLOR_ARG( 1, C );
break;
- case GL_ADD_SIGNED_EXT:
+ case GL_ADD_SIGNED:
color_combine = (RADEON_COLOR_ARG_B_ZERO |
RADEON_COMP_ARG_B |
RADEON_BLEND_CTL_ADDSIGNED |
@@ -981,13 +1028,31 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit )
RADEON_COLOR_ARG( 0, A );
RADEON_COLOR_ARG( 1, C );
break;
- case GL_INTERPOLATE_EXT:
+ case GL_SUBTRACT:
+ color_combine = (RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_SUBTRACT |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, A );
+ RADEON_COLOR_ARG( 1, C );
+ break;
+ case GL_INTERPOLATE:
color_combine = (RADEON_BLEND_CTL_BLEND |
RADEON_CLAMP_TX);
RADEON_COLOR_ARG( 0, B );
RADEON_COLOR_ARG( 1, A );
RADEON_COLOR_ARG( 2, C );
break;
+
+ case GL_DOT3_RGB:
+ case GL_DOT3_RGBA:
+ if ( texUnit->CombineScaleShiftRGB
+ != (RADEON_SCALE_1X >> RADEON_SCALE_SHIFT) )
+ {
+ return GL_FALSE;
+ }
+ /* FALLTHROUGH */
+
case GL_DOT3_RGB_EXT:
case GL_DOT3_RGBA_EXT:
color_combine = (RADEON_COLOR_ARG_C_ZERO |
@@ -996,8 +1061,30 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit )
RADEON_COLOR_ARG( 0, A );
RADEON_COLOR_ARG( 1, B );
break;
+
+ case GL_MODULATE_ADD_ATI:
+ color_combine = (RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, A );
+ RADEON_COLOR_ARG( 1, C );
+ RADEON_COLOR_ARG( 2, B );
+ break;
+ case GL_MODULATE_SIGNED_ADD_ATI:
+ color_combine = (RADEON_BLEND_CTL_ADDSIGNED |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, A );
+ RADEON_COLOR_ARG( 1, C );
+ RADEON_COLOR_ARG( 2, B );
+ break;
+ case GL_MODULATE_SUBTRACT_ATI:
+ color_combine = (RADEON_BLEND_CTL_SUBTRACT |
+ RADEON_CLAMP_TX);
+ RADEON_COLOR_ARG( 0, A );
+ RADEON_COLOR_ARG( 1, C );
+ RADEON_COLOR_ARG( 2, B );
+ break;
default:
- return;
+ return GL_FALSE;
}
switch ( texUnit->CombineModeA ) {
@@ -1023,7 +1110,7 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit )
RADEON_ALPHA_ARG( 0, A );
RADEON_ALPHA_ARG( 1, C );
break;
- case GL_ADD_SIGNED_EXT:
+ case GL_ADD_SIGNED:
alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
RADEON_COMP_ARG_B |
RADEON_BLEND_CTL_ADDSIGNED |
@@ -1031,31 +1118,64 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit )
RADEON_ALPHA_ARG( 0, A );
RADEON_ALPHA_ARG( 1, C );
break;
- case GL_INTERPOLATE_EXT:
+ case GL_SUBTRACT:
+ alpha_combine = (RADEON_COLOR_ARG_B_ZERO |
+ RADEON_COMP_ARG_B |
+ RADEON_BLEND_CTL_SUBTRACT |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, A );
+ RADEON_ALPHA_ARG( 1, C );
+ break;
+ case GL_INTERPOLATE:
alpha_combine = (RADEON_BLEND_CTL_BLEND |
RADEON_CLAMP_TX);
RADEON_ALPHA_ARG( 0, B );
RADEON_ALPHA_ARG( 1, A );
RADEON_ALPHA_ARG( 2, C );
break;
+
+ case GL_MODULATE_ADD_ATI:
+ alpha_combine = (RADEON_BLEND_CTL_ADD |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, A );
+ RADEON_ALPHA_ARG( 1, C );
+ RADEON_ALPHA_ARG( 2, B );
+ break;
+ case GL_MODULATE_SIGNED_ADD_ATI:
+ alpha_combine = (RADEON_BLEND_CTL_ADDSIGNED |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, A );
+ RADEON_ALPHA_ARG( 1, C );
+ RADEON_ALPHA_ARG( 2, B );
+ break;
+ case GL_MODULATE_SUBTRACT_ATI:
+ alpha_combine = (RADEON_BLEND_CTL_SUBTRACT |
+ RADEON_CLAMP_TX);
+ RADEON_ALPHA_ARG( 0, A );
+ RADEON_ALPHA_ARG( 1, C );
+ RADEON_ALPHA_ARG( 2, B );
+ break;
default:
- return;
+ return GL_FALSE;
}
- if ( texUnit->CombineModeRGB == GL_DOT3_RGB_EXT ) {
+ if ( (texUnit->CombineModeRGB == GL_DOT3_RGB_EXT)
+ || (texUnit->CombineModeRGB == GL_DOT3_RGB_ARB) ) {
alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE;
}
/* Step 3:
- * Apply the scale factor. The EXT extension has a somewhat
- * unnecessary restriction that the scale must be 4x. The ARB
- * extension will likely drop this and we can just apply the
- * scale factors regardless.
+ * Apply the scale factor. The EXT version of the DOT3 extension does
+ * not support the scale factor, but the ARB version (and the version in
+ * OpenGL 1.3) does. The catch is that the Radeon only supports a 1X
+ * multiplier in hardware w/the ARB version.
*/
if ( texUnit->CombineModeRGB != GL_DOT3_RGB_EXT &&
- texUnit->CombineModeRGB != GL_DOT3_RGBA_EXT ) {
- color_combine |= (texUnit->CombineScaleShiftRGB << 21);
- alpha_combine |= (texUnit->CombineScaleShiftA << 21);
+ texUnit->CombineModeRGB != GL_DOT3_RGBA_EXT &&
+ texUnit->CombineModeRGB != GL_DOT3_RGB &&
+ texUnit->CombineModeRGB != GL_DOT3_RGBA ) {
+ color_combine |= (texUnit->CombineScaleShiftRGB << RADEON_SCALE_SHIFT);
+ alpha_combine |= (texUnit->CombineScaleShiftA << RADEON_SCALE_SHIFT);
}
else
{
@@ -1068,57 +1188,227 @@ static void radeonUpdateTextureEnv( GLcontext *ctx, int unit )
break;
default:
- return;
+ return GL_FALSE;
}
- if ( rmesa->state.hw.texture[unit].pp_txcblend != color_combine ||
- rmesa->state.hw.texture[unit].pp_txablend != alpha_combine ) {
- RADEON_STATECHANGE( rmesa, (RADEON_UPLOAD_TEX0 << unit) );
- rmesa->state.hw.texture[unit].pp_txcblend = color_combine;
- rmesa->state.hw.texture[unit].pp_txablend = alpha_combine;
+ if ( rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] != color_combine ||
+ rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] != alpha_combine ) {
+ RADEON_STATECHANGE( rmesa, tex[unit] );
+ rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] = color_combine;
+ rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] = alpha_combine;
}
+
+ return GL_TRUE;
}
-static void radeonUpdateTextureUnit( GLcontext *ctx, int unit )
+#define TEXOBJ_TXFILTER_MASK (RADEON_MAX_MIP_LEVEL_MASK | \
+ RADEON_MIN_FILTER_MASK | \
+ RADEON_MAG_FILTER_MASK | \
+ RADEON_MAX_ANISO_MASK | \
+ RADEON_CLAMP_S_MASK | \
+ RADEON_CLAMP_T_MASK)
+
+#define TEXOBJ_TXFORMAT_MASK (RADEON_TXFORMAT_WIDTH_MASK | \
+ RADEON_TXFORMAT_HEIGHT_MASK | \
+ RADEON_TXFORMAT_FORMAT_MASK | \
+ RADEON_TXFORMAT_ALPHA_IN_MAP)
+
+
+static void import_tex_obj_state( radeonContextPtr rmesa,
+ int unit,
+ radeonTexObjPtr texobj )
{
+ GLuint *cmd = RADEON_DB_STATE( tex[unit] );
+
+ cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK;
+ cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
+ cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK;
+ cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK;
+ cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset;
+ cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
+ texobj->dirty_state &= ~(1<<unit);
+
+ RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tex[unit] );
+}
+
+
+
+
+static void set_texgen_matrix( radeonContextPtr rmesa,
+ GLuint unit,
+ GLfloat *s_plane,
+ GLfloat *t_plane )
+{
+ static const GLfloat scale_identity[4] = { 1,1,1,1 };
+
+ if (!TEST_EQ_4V( s_plane, scale_identity) ||
+ !(TEST_EQ_4V( t_plane, scale_identity))) {
+ rmesa->TexGenEnabled |= RADEON_TEXMAT_0_ENABLE<<unit;
+ rmesa->TexGenMatrix[unit].m[0] = s_plane[0];
+ rmesa->TexGenMatrix[unit].m[4] = s_plane[1];
+ rmesa->TexGenMatrix[unit].m[8] = s_plane[2];
+ rmesa->TexGenMatrix[unit].m[12] = s_plane[3];
+
+ rmesa->TexGenMatrix[unit].m[1] = t_plane[0];
+ rmesa->TexGenMatrix[unit].m[5] = t_plane[1];
+ rmesa->TexGenMatrix[unit].m[9] = t_plane[2];
+ rmesa->TexGenMatrix[unit].m[13] = t_plane[3];
+ rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
+ }
+}
+
+/* Ignoring the Q texcoord for now.
+ *
+ * Returns GL_FALSE if fallback required.
+ */
+static GLboolean radeon_validate_texgen( GLcontext *ctx, GLuint unit )
+{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
+ GLuint tmp = rmesa->TexGenEnabled;
+
+ rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit);
+ rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit);
+ rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift);
+ rmesa->TexGenNeedNormals[unit] = 0;
+
+ if (0)
+ fprintf(stderr, "%s unit %d cleared texgenEnabled %x\n", __FUNCTION__,
+ unit, rmesa->TexGenEnabled);
+
+ if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) == 0) {
+ /* Disabled, no fallback:
+ */
+ rmesa->TexGenEnabled |=
+ (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
+ return GL_TRUE;
+ }
+ else if (texUnit->TexGenEnabled & Q_BIT) {
+ /* Very easy to do this, in fact would remove a fallback case
+ * elsewhere, but I haven't done it yet... Fallback:
+ */
+ fprintf(stderr, "fallback Q_BIT\n");
+ return GL_FALSE;
+ }
+ else if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) != (S_BIT|T_BIT) ||
+ texUnit->GenModeS != texUnit->GenModeT) {
+ /* Mixed modes, fallback:
+ */
+/* fprintf(stderr, "fallback mixed texgen\n"); */
+ return GL_FALSE;
+ }
+ else
+ rmesa->TexGenEnabled |= RADEON_TEXGEN_TEXMAT_0_ENABLE << unit;
+
+ switch (texUnit->GenModeS) {
+ case GL_OBJECT_LINEAR:
+ rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_OBJ << inputshift;
+ set_texgen_matrix( rmesa, unit,
+ texUnit->ObjectPlaneS,
+ texUnit->ObjectPlaneT);
+ break;
+
+ case GL_EYE_LINEAR:
+ rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE << inputshift;
+ set_texgen_matrix( rmesa, unit,
+ texUnit->EyePlaneS,
+ texUnit->EyePlaneT);
+ break;
- if ( texUnit->_ReallyEnabled & (TEXTURE0_1D|TEXTURE0_2D) ) {
+ case GL_REFLECTION_MAP_NV:
+ rmesa->TexGenNeedNormals[unit] = GL_TRUE;
+ rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_REFLECT<<inputshift;
+ break;
+
+ case GL_NORMAL_MAP_NV:
+ rmesa->TexGenNeedNormals[unit] = GL_TRUE;
+ rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_NORMAL<<inputshift;
+ break;
+
+ case GL_SPHERE_MAP:
+ default:
+ /* Unsupported mode, fallback:
+ */
+ /* fprintf(stderr, "fallback unsupported texgen\n"); */
+ return GL_FALSE;
+ }
+
+ if (tmp != rmesa->TexGenEnabled) {
+ rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
+ }
+
+/* fprintf(stderr, "%s unit %d texgenEnabled %x\n", __FUNCTION__, */
+/* unit, rmesa->TexGenEnabled); */
+ return GL_TRUE;
+}
+
+
+
+
+static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+
+/* fprintf(stderr, "%s\n", __FUNCTION__); */
+
+ if ( texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) {
struct gl_texture_object *tObj = texUnit->_Current;
radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
- GLuint flag = RADEON_UPLOAD_TEX0 << unit;
GLenum format;
/* Fallback if there's a texture border */
- if ( tObj->Image[tObj->BaseLevel]->Border > 0 ) {
- FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE );
- return;
- }
+ if ( tObj->Image[tObj->BaseLevel]->Border > 0 )
+ return GL_FALSE;
/* Upload teximages (not pipelined)
*/
if ( t->dirty_images ) {
RADEON_FIREVERTICES( rmesa );
radeonSetTexImages( rmesa, tObj );
- if ( !t->memBlock ) {
- FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE );
- return;
- }
+ /* Fallback if we can't upload:
+ */
+ if ( !t->memBlock )
+ return GL_FALSE;
}
/* Update state if this is a different texture object to last
* time.
*/
if ( rmesa->state.texture.unit[unit].texobj != t ) {
- if ( rmesa->state.texture.unit[unit].texobj == NULL ) {
- RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT );
- rmesa->state.hw.context.pp_cntl |= (RADEON_TEX_0_ENABLE |
- RADEON_TEX_BLEND_0_ENABLE)<<unit;
- }
- RADEON_STATECHANGE( rmesa, flag );
rmesa->state.texture.unit[unit].texobj = t;
- radeonUpdateTexLRU( rmesa, t ); /* done too often */
+ t->dirty_state |= 1<<unit;
+ radeonUpdateTexLRU( rmesa, t ); /* XXX: should be locked! */
+ }
+
+
+ /* Newly enabled?
+ */
+ if ( !(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<unit))) {
+ RADEON_STATECHANGE( rmesa, ctx );
+ rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=
+ (RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit;
+
+ RADEON_STATECHANGE( rmesa, tcl );
+
+ if (unit == 0)
+ rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_ST0;
+ else
+ rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_ST1;
+
+ rmesa->recheck_texgen[unit] = GL_TRUE;
+ }
+
+ if (t->dirty_state & (1<<unit)) {
+ import_tex_obj_state( rmesa, unit, t );
+ }
+
+ if (rmesa->recheck_texgen[unit]) {
+ GLboolean fallback = !radeon_validate_texgen( ctx, unit );
+ TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), fallback);
+ rmesa->recheck_texgen[unit] = 0;
+ rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
}
format = tObj->Image[tObj->BaseLevel]->Format;
@@ -1126,27 +1416,76 @@ static void radeonUpdateTextureUnit( GLcontext *ctx, int unit )
rmesa->state.texture.unit[unit].envMode != texUnit->EnvMode ) {
rmesa->state.texture.unit[unit].format = format;
rmesa->state.texture.unit[unit].envMode = texUnit->EnvMode;
- radeonUpdateTextureEnv( ctx, unit );
+ if ( ! radeonUpdateTextureEnv( ctx, unit ) ) {
+ return GL_FALSE;
+ }
}
}
else if ( texUnit->_ReallyEnabled ) {
- FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE );
- return;
+ /* 3d textures, etc:
+ */
+ return GL_FALSE;
}
- else {
+ else if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<unit)) {
/* Texture unit disabled */
rmesa->state.texture.unit[unit].texobj = 0;
- rmesa->state.hw.dirty &= ~(RADEON_UPLOAD_TEX0 << unit);
- RADEON_STATECHANGE( rmesa, RADEON_UPLOAD_CONTEXT );
- rmesa->state.hw.context.pp_cntl &= ~((RADEON_TEX_0_ENABLE |
- RADEON_TEX_BLEND_0_ENABLE) << unit);
+ RADEON_STATECHANGE( rmesa, ctx );
+ rmesa->hw.ctx.cmd[CTX_PP_CNTL] &=
+ ~((RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit);
+
+ RADEON_STATECHANGE( rmesa, tcl );
+ switch (unit) {
+ case 0:
+ rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_TCL_VTX_ST0 |
+ RADEON_TCL_VTX_Q0);
+ break;
+ case 1:
+ rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_TCL_VTX_ST1 |
+ RADEON_TCL_VTX_Q1);
+ break;
+ default:
+ break;
+ }
+
+
+ if (rmesa->TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0<<unit)) {
+ TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
+ rmesa->recheck_texgen[unit] = GL_TRUE;
+ }
+
+
+
+ {
+ GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
+ GLuint tmp = rmesa->TexGenEnabled;
+
+ rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit);
+ rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit);
+ rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift);
+ rmesa->TexGenNeedNormals[unit] = 0;
+ rmesa->TexGenEnabled |=
+ (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
+
+ if (tmp != rmesa->TexGenEnabled) {
+ rmesa->recheck_texgen[unit] = GL_TRUE;
+ rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
+ }
+ }
}
+
+ return GL_TRUE;
}
void radeonUpdateTextureState( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, GL_FALSE );
- radeonUpdateTextureUnit( ctx, 0 );
- radeonUpdateTextureUnit( ctx, 1 );
+ GLboolean ok;
+
+ ok = (radeonUpdateTextureUnit( ctx, 0 ) &&
+ radeonUpdateTextureUnit( ctx, 1 ));
+
+ FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, !ok );
+
+ if (rmesa->TclFallback)
+ radeonChooseVertexState( ctx );
}