From b1ebd306bf4fdc4076d3d3daa410b08f477cb4c4 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 16 Oct 2004 03:36:14 +0000 Subject: 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 --- src/mesa/drivers/dri/r200/r200_texstate.c | 239 +++++++++++++++++------------- 1 file changed, 135 insertions(+), 104 deletions(-) (limited to 'src/mesa/drivers/dri/r200/r200_texstate.c') 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<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<TexGenMatrix[unit]), m); _math_matrix_analyse( &(rmesa->TexGenMatrix[unit]) ); rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<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<TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<TexGenInputs &= ~(R200_TEXGEN_INPUT_MASK<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<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<TexGenNeedNormals[unit] = GL_TRUE; - rmesa->TexGenInputs |= R200_TEXGEN_INPUT_SPHERE<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<TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<TexGenEnabled &= ~(R200_TEXGEN_INPUT_MASK<TexGenNeedNormals[unit] = 0; + rmesa->TexGenNeedNormals[unit] = GL_FALSE; rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit); - rmesa->TexGenInputs &= ~(R200_TEXGEN_INPUT_MASK<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; -- cgit v1.2.3