summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/r200/r200_texstate.c
diff options
context:
space:
mode:
authorEric Anholt <anholt@FreeBSD.org>2004-10-16 03:36:14 +0000
committerEric Anholt <anholt@FreeBSD.org>2004-10-16 03:36:14 +0000
commitb1ebd306bf4fdc4076d3d3daa410b08f477cb4c4 (patch)
treee815feb8221211e716d664be7093e5f344efcf3d /src/mesa/drivers/dri/r200/r200_texstate.c
parenta1af92877d3d91886cf01be9e6c65311960e3baf (diff)
Add code to support projective texturing and fix mixed enabling of texture
coordinate generation. Original code by Roland Schiedegger, with changes by myself. While here, ensure that the swtcl path does tnl_install_attrs enough when fog/specular are being (en/dis)abled. Notable effects: - projtex test works with TCL and is closer with swtcl (Bugzilla #1461) - 8/9 squares work in texgenmix instead of 3. - texcyl "reflect" mode works (GL_SPHERE_MAP is now a fallback -- unclear if the hardware can actually support it). - flickering in doom3 replaced by just plain darkness. - blocktube fixed (Bugzilla #984) - fixes stex3d
Diffstat (limited to 'src/mesa/drivers/dri/r200/r200_texstate.c')
-rw-r--r--src/mesa/drivers/dri/r200/r200_texstate.c239
1 files changed, 135 insertions, 104 deletions
diff --git a/src/mesa/drivers/dri/r200/r200_texstate.c b/src/mesa/drivers/dri/r200/r200_texstate.c
index 57ee245ee9..934ffc1349 100644
--- a/src/mesa/drivers/dri/r200/r200_texstate.c
+++ b/src/mesa/drivers/dri/r200/r200_texstate.c
@@ -293,6 +293,12 @@ static void r200SetTexImages( r200ContextPtr rmesa,
(log2Width << R200_FACE_WIDTH_4_SHIFT) |
(log2Height << R200_FACE_HEIGHT_4_SHIFT));
}
+ else {
+ /* If we don't in fact send enough texture coordinates, q will be 1,
+ * making TEXCOORD_PROJ act like TEXCOORD_NONPROJ (Right?)
+ */
+ t->pp_txformat_x |= R200_TEXCOORD_PROJ;
+ }
t->pp_txsize = (((tObj->Image[0][t->base.firstLevel]->Width - 1) << 0) |
((tObj->Image[0][t->base.firstLevel]->Height - 1) << 16));
@@ -836,71 +842,42 @@ static void import_tex_obj_state( r200ContextPtr rmesa,
}
-
-
static void set_texgen_matrix( r200ContextPtr rmesa,
GLuint unit,
const GLfloat *s_plane,
const GLfloat *t_plane,
- const GLfloat *r_plane )
+ const GLfloat *r_plane,
+ const GLfloat *q_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) ||
- !TEST_EQ_4V( r_plane, scale_identity)) {
- rmesa->TexGenEnabled |= R200_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];
-
- /* NOTE: r_plane goes in the 4th row, not 3rd! */
- rmesa->TexGenMatrix[unit].m[3] = r_plane[0];
- rmesa->TexGenMatrix[unit].m[7] = r_plane[1];
- rmesa->TexGenMatrix[unit].m[11] = r_plane[2];
- rmesa->TexGenMatrix[unit].m[15] = r_plane[3];
+ GLfloat m[16];
- rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
- }
-}
+ m[0] = s_plane[0];
+ m[4] = s_plane[1];
+ m[8] = s_plane[2];
+ m[12] = s_plane[3];
-/* Need this special matrix to get correct reflection map coords */
-static void
-set_texgen_reflection_matrix( r200ContextPtr rmesa, GLuint unit )
-{
- static const GLfloat m[16] = {
- -1, 0, 0, 0,
- 0, -1, 0, 0,
- 0, 0, 0, -1,
- 0, 0, -1, 0 };
- _math_matrix_loadf( &(rmesa->TexGenMatrix[unit]), m);
- _math_matrix_analyse( &(rmesa->TexGenMatrix[unit]) );
- rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit;
-}
+ m[1] = t_plane[0];
+ m[5] = t_plane[1];
+ m[9] = t_plane[2];
+ m[13] = t_plane[3];
+
+ m[2] = r_plane[0];
+ m[6] = r_plane[1];
+ m[10] = r_plane[2];
+ m[14] = r_plane[3];
+
+ m[3] = q_plane[0];
+ m[7] = q_plane[1];
+ m[11] = q_plane[2];
+ m[15] = q_plane[3];
-/* Need this special matrix to get correct normal map coords */
-static void
-set_texgen_normal_map_matrix( r200ContextPtr rmesa, GLuint unit )
-{
- static const GLfloat m[16] = {
- 1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 0, 1,
- 0, 0, 1, 0 };
_math_matrix_loadf( &(rmesa->TexGenMatrix[unit]), m);
_math_matrix_analyse( &(rmesa->TexGenMatrix[unit]) );
rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit;
}
-/* Ignoring the Q texcoord for now.
- *
+/*
* Returns GL_FALSE if fallback required.
*/
static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit )
@@ -908,98 +885,130 @@ static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit )
r200ContextPtr rmesa = R200_CONTEXT(ctx);
const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
GLuint inputshift = R200_TEXGEN_0_INPUT_SHIFT + unit*4;
- GLuint tmp = rmesa->TexGenEnabled;
+ GLuint tgi, tgcm;
+ GLuint mode = 0;
+ GLboolean mixed_fallback = GL_FALSE;
+ static const GLfloat I[16] = {
+ 1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1 };
+ static const GLfloat reflect[16] = {
+ -1, 0, 0, 0,
+ 0, -1, 0, 0,
+ 0, 0, -1, 0,
+ 0, 0, 0, 1 };
rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit);
rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit);
- rmesa->TexGenInputs &= ~(R200_TEXGEN_INPUT_MASK<<inputshift);
- rmesa->TexGenNeedNormals[unit] = 0;
+ rmesa->TexGenNeedNormals[unit] = GL_FALSE;
+ tgi = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] & ~(R200_TEXGEN_INPUT_MASK <<
+ inputshift);
+ tgcm = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] & ~(R200_TEXGEN_COMP_MASK <<
+ (unit * 4));
if (0)
fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit);
- if ((texUnit->TexGenEnabled & (S_BIT|T_BIT|R_BIT)) == 0) {
- /* Disabled, no fallback:
- */
- rmesa->TexGenInputs |=
- (R200_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
- return GL_TRUE;
+ if (texUnit->TexGenEnabled & S_BIT) {
+ mode = texUnit->GenModeS;
+ } else {
+ tgcm |= R200_TEXGEN_COMP_S << (unit * 4);
}
- 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;
+
+ if (texUnit->TexGenEnabled & T_BIT) {
+ if (texUnit->GenModeT != mode)
+ mixed_fallback = GL_TRUE;
+ } else {
+ tgcm |= R200_TEXGEN_COMP_T << (unit * 4);
}
- else if (texUnit->TexGenEnabled == (S_BIT|T_BIT) &&
- texUnit->GenModeS == texUnit->GenModeT) {
- /* OK */
- rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit;
- /* continue */
+
+ if (texUnit->TexGenEnabled & R_BIT) {
+ if (texUnit->GenModeR != mode)
+ mixed_fallback = GL_TRUE;
+ } else {
+ tgcm |= R200_TEXGEN_COMP_R << (unit * 4);
}
- else if (texUnit->TexGenEnabled == (S_BIT|T_BIT|R_BIT) &&
- texUnit->GenModeS == texUnit->GenModeT &&
- texUnit->GenModeT == texUnit->GenModeR) {
- /* OK */
- rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit;
- /* continue */
+
+ if (texUnit->TexGenEnabled & Q_BIT) {
+ if (texUnit->GenModeQ != mode)
+ mixed_fallback = GL_TRUE;
+ } else {
+ tgcm |= R200_TEXGEN_COMP_Q << (unit * 4);
}
- else {
- /* Mixed modes, fallback:
- */
- /* fprintf(stderr, "fallback mixed texgen\n"); */
+
+ if (mixed_fallback) {
+ if (R200_DEBUG & DEBUG_FALLBACKS)
+ fprintf(stderr, "fallback mixed texgen, 0x%x (0x%x 0x%x 0x%x 0x%x)\n",
+ texUnit->TexGenEnabled, texUnit->GenModeS, texUnit->GenModeT,
+ texUnit->GenModeR, texUnit->GenModeQ);
return GL_FALSE;
}
- rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit;
-
- switch (texUnit->GenModeS) {
+ switch (mode) {
case GL_OBJECT_LINEAR:
- rmesa->TexGenInputs |= R200_TEXGEN_INPUT_OBJ << inputshift;
+ tgi |= R200_TEXGEN_INPUT_OBJ << inputshift;
set_texgen_matrix( rmesa, unit,
- texUnit->ObjectPlaneS,
- texUnit->ObjectPlaneT,
- texUnit->ObjectPlaneR);
+ (texUnit->TexGenEnabled & S_BIT) ? texUnit->ObjectPlaneS : I,
+ (texUnit->TexGenEnabled & T_BIT) ? texUnit->ObjectPlaneT : I + 4,
+ (texUnit->TexGenEnabled & R_BIT) ? texUnit->ObjectPlaneR : I + 8,
+ (texUnit->TexGenEnabled & Q_BIT) ? texUnit->ObjectPlaneQ : I + 12);
break;
case GL_EYE_LINEAR:
- rmesa->TexGenInputs |= R200_TEXGEN_INPUT_EYE << inputshift;
+ tgi |= R200_TEXGEN_INPUT_EYE << inputshift;
set_texgen_matrix( rmesa, unit,
- texUnit->EyePlaneS,
- texUnit->EyePlaneT,
- texUnit->EyePlaneR);
+ (texUnit->TexGenEnabled & S_BIT) ? texUnit->EyePlaneS : I,
+ (texUnit->TexGenEnabled & T_BIT) ? texUnit->EyePlaneT : I + 4,
+ (texUnit->TexGenEnabled & R_BIT) ? texUnit->EyePlaneR : I + 8,
+ (texUnit->TexGenEnabled & Q_BIT) ? texUnit->EyePlaneQ : I + 12);
break;
case GL_REFLECTION_MAP_NV:
rmesa->TexGenNeedNormals[unit] = GL_TRUE;
- rmesa->TexGenInputs |= R200_TEXGEN_INPUT_EYE_REFLECT<<inputshift;
- set_texgen_reflection_matrix(rmesa, unit);
+ tgi |= R200_TEXGEN_INPUT_EYE_REFLECT<<inputshift;
+ set_texgen_matrix( rmesa, unit,
+ (texUnit->TexGenEnabled & S_BIT) ? reflect : I,
+ (texUnit->TexGenEnabled & T_BIT) ? reflect + 4 : I + 4,
+ (texUnit->TexGenEnabled & R_BIT) ? reflect + 8 : I + 8,
+ I + 12);
break;
case GL_NORMAL_MAP_NV:
rmesa->TexGenNeedNormals[unit] = GL_TRUE;
- rmesa->TexGenInputs |= R200_TEXGEN_INPUT_EYE_NORMAL<<inputshift;
- set_texgen_normal_map_matrix(rmesa, unit);
+ tgi |= R200_TEXGEN_INPUT_EYE_NORMAL<<inputshift;
break;
case GL_SPHERE_MAP:
rmesa->TexGenNeedNormals[unit] = GL_TRUE;
- rmesa->TexGenInputs |= R200_TEXGEN_INPUT_SPHERE<<inputshift;
+ tgi |= R200_TEXGEN_INPUT_SPHERE<<inputshift;
+ /* GL_SPHERE_MAP doesn't appear to work. */
+ return GL_FALSE;
+
+ case 0:
+ /* All texgen units were disabled, so just pass coords through. */
+ tgi |= unit << inputshift;
break;
default:
/* Unsupported mode, fallback:
*/
- /* fprintf(stderr, "fallback unsupported texgen\n"); */
+ if (R200_DEBUG & DEBUG_FALLBACKS)
+ fprintf(stderr, "fallback unsupported texgen, %d\n",
+ texUnit->GenModeS);
return GL_FALSE;
}
+ rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit;
rmesa->TexGenCompSel |= R200_OUTPUT_TEX_0 << unit;
- if (tmp != rmesa->TexGenEnabled) {
- rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
+ if (tgi != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] ||
+ tgcm != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2])
+ {
+ R200_STATECHANGE(rmesa, tcg);
+ rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] = tgi;
+ rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] = tgcm;
}
return GL_TRUE;
@@ -1042,15 +1051,12 @@ static void disable_tex( GLcontext *ctx, int unit )
{
- GLuint inputshift = R200_TEXGEN_0_INPUT_SHIFT + unit*4;
GLuint tmp = rmesa->TexGenEnabled;
rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit);
rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit);
- rmesa->TexGenEnabled &= ~(R200_TEXGEN_INPUT_MASK<<inputshift);
- rmesa->TexGenNeedNormals[unit] = 0;
+ rmesa->TexGenNeedNormals[unit] = GL_FALSE;
rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
- rmesa->TexGenInputs &= ~(R200_TEXGEN_INPUT_MASK<<inputshift);
if (tmp != rmesa->TexGenEnabled) {
rmesa->recheck_texgen[unit] = GL_TRUE;
@@ -1060,6 +1066,22 @@ static void disable_tex( GLcontext *ctx, int unit )
}
}
+static void set_re_cntl_d3d( GLcontext *ctx, int unit, GLboolean use_d3d )
+{
+ r200ContextPtr rmesa = R200_CONTEXT(ctx);
+
+ GLuint re_cntl;
+
+ re_cntl = rmesa->hw.set.cmd[SET_RE_CNTL] & ~(R200_VTX_STQ0_D3D << (2 * unit));
+ if (use_d3d)
+ re_cntl |= R200_VTX_STQ0_D3D << (2 * unit);
+
+ if ( re_cntl != rmesa->hw.set.cmd[SET_RE_CNTL] ) {
+ R200_STATECHANGE( rmesa, set );
+ rmesa->hw.set.cmd[SET_RE_CNTL] = re_cntl;
+ }
+}
+
static GLboolean enable_tex_2d( GLcontext *ctx, int unit )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
@@ -1084,6 +1106,8 @@ static GLboolean enable_tex_2d( GLcontext *ctx, int unit )
return GL_FALSE;
}
+ set_re_cntl_d3d( ctx, unit, GL_FALSE );
+
return GL_TRUE;
}
@@ -1118,6 +1142,8 @@ static GLboolean enable_tex_3d( GLcontext *ctx, int unit )
return GL_FALSE;
}
+ set_re_cntl_d3d( ctx, unit, GL_TRUE );
+
return GL_TRUE;
}
#endif
@@ -1161,6 +1187,8 @@ static GLboolean enable_tex_cube( GLcontext *ctx, int unit )
return GL_FALSE;
}
+ set_re_cntl_d3d( ctx, unit, GL_TRUE );
+
return GL_TRUE;
}
@@ -1186,6 +1214,8 @@ static GLboolean enable_tex_rect( GLcontext *ctx, int unit )
return GL_FALSE;
}
+ set_re_cntl_d3d( ctx, unit, GL_FALSE );
+
return GL_TRUE;
}
@@ -1230,6 +1260,7 @@ static GLboolean update_tex_common( GLcontext *ctx, int unit )
R200_TEX_BLEND_0_ENABLE) << unit;
R200_STATECHANGE( rmesa, vtx );
+ rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3);
rmesa->recheck_texgen[unit] = GL_TRUE;