diff options
Diffstat (limited to 'src/mesa/drivers/dri/r200/r200_texstate.c')
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_texstate.c | 239 |
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; |