From b1ebd306bf4fdc4076d3d3daa410b08f477cb4c4 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 16 Oct 2004 03:36:14 +0000 Subject: [PATCH] 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_context.h | 2 +- src/mesa/drivers/dri/r200/r200_maos_arrays.c | 16 -- src/mesa/drivers/dri/r200/r200_reg.h | 5 + src/mesa/drivers/dri/r200/r200_state.c | 10 +- src/mesa/drivers/dri/r200/r200_state_init.c | 4 +- src/mesa/drivers/dri/r200/r200_swtcl.c | 23 +-- src/mesa/drivers/dri/r200/r200_tcl.c | 34 +--- src/mesa/drivers/dri/r200/r200_texstate.c | 239 +++++++++++++++------------ src/mesa/drivers/dri/r200/r200_vtxfmt.c | 41 +---- src/mesa/drivers/dri/r200/r200_vtxfmt.h | 1 + src/mesa/drivers/dri/r200/r200_vtxfmt_c.c | 160 ++++++++++++------ 11 files changed, 265 insertions(+), 270 deletions(-) diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index 140902c..af07653 100644 --- a/src/mesa/drivers/dri/r200/r200_context.h +++ b/src/mesa/drivers/dri/r200/r200_context.h @@ -845,6 +845,7 @@ struct r200_context { GLuint TclFallback; GLuint Fallback; GLuint NewGLState; + GLuint tnl_index; /* index of bits for last tnl_install_attrs */ /* Vertex buffers */ @@ -889,7 +890,6 @@ struct r200_context { GLuint TexMatEnabled; GLuint TexMatCompSel; GLuint TexGenEnabled; - GLuint TexGenInputs; GLuint TexGenCompSel; GLmatrix tmpmat; diff --git a/src/mesa/drivers/dri/r200/r200_maos_arrays.c b/src/mesa/drivers/dri/r200/r200_maos_arrays.c index 3429cf6..0f8ca30 100644 --- a/src/mesa/drivers/dri/r200/r200_maos_arrays.c +++ b/src/mesa/drivers/dri/r200/r200_maos_arrays.c @@ -344,7 +344,6 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) GLuint vfmt0 = 0, vfmt1 = 0; GLuint count = VB->Count; GLuint i; - GLuint re_cntl; if (1) { if (!rmesa->tcl.obj.buf) @@ -421,12 +420,6 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) component[nr++] = &rmesa->tcl.spec; } - re_cntl = rmesa->hw.set.cmd[SET_RE_CNTL] & ~(R200_VTX_STQ0_D3D | - R200_VTX_STQ1_D3D | - R200_VTX_STQ2_D3D | - R200_VTX_STQ3_D3D | - R200_VTX_STQ4_D3D | - R200_VTX_STQ5_D3D ); for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { if (inputs & (VERT_BIT_TEX0 << i)) { if (!rmesa->tcl.tex[i].buf) @@ -437,20 +430,11 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) VB->TexCoordPtr[i]->stride, count ); - if ( ctx->Texture.Unit[i]._ReallyEnabled == TEXTURE_CUBE_BIT ) { - re_cntl |= R200_VTX_STQ0_D3D << (2 * i); - } - vfmt1 |= VB->TexCoordPtr[i]->size << (i * 3); component[nr++] = &rmesa->tcl.tex[i]; } } - if ( re_cntl != rmesa->hw.set.cmd[SET_RE_CNTL] ) { - R200_STATECHANGE( rmesa, set ); - rmesa->hw.set.cmd[SET_RE_CNTL] = re_cntl; - } - if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] || vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) { R200_STATECHANGE( rmesa, vtx ); diff --git a/src/mesa/drivers/dri/r200/r200_reg.h b/src/mesa/drivers/dri/r200/r200_reg.h index 726be6e..89da699 100644 --- a/src/mesa/drivers/dri/r200/r200_reg.h +++ b/src/mesa/drivers/dri/r200/r200_reg.h @@ -575,6 +575,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define R200_LIGHT_7_SHIFT (16) /* gap */ #define R200_SE_TCL_TEX_PROC_CTL_2 0x22a8 +#define R200_TEXGEN_COMP_MASK (0xf) +#define R200_TEXGEN_COMP_S (0x1) +#define R200_TEXGEN_COMP_T (0x2) +#define R200_TEXGEN_COMP_R (0x4) +#define R200_TEXGEN_COMP_Q (0x8) #define R200_TEXGEN_0_COMP_MASK_SHIFT (0) #define R200_TEXGEN_1_COMP_MASK_SHIFT (4) #define R200_TEXGEN_2_COMP_MASK_SHIFT (8) diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index dd547f9..825c036 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -2138,9 +2138,9 @@ static void update_texturematrix( GLcontext *ctx ) /* Need to preconcatenate any active texgen * obj/eyeplane matrices: */ - _math_matrix_mul_matrix( &rmesa->tmpmat, - &rmesa->TexGenMatrix[unit], - ctx->TextureMatrixStack[unit].Top ); + _math_matrix_mul_matrix( &rmesa->tmpmat, + ctx->TextureMatrixStack[unit].Top, + &rmesa->TexGenMatrix[unit] ); upload_matrix( rmesa, rmesa->tmpmat.m, R200_MTX_TEX0+unit ); } else { @@ -2155,11 +2155,9 @@ static void update_texturematrix( GLcontext *ctx ) } tpc = (rmesa->TexMatEnabled | rmesa->TexGenEnabled); - if (tpc != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0] || - rmesa->TexGenInputs != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1]) { + if (tpc != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0]) { R200_STATECHANGE(rmesa, tcg); rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0] = tpc; - rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] = rmesa->TexGenInputs; } compsel &= ~R200_OUTPUT_TEX_MASK; diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c index 049820b..610706b 100644 --- a/src/mesa/drivers/dri/r200/r200_state_init.c +++ b/src/mesa/drivers/dri/r200/r200_state_init.c @@ -699,7 +699,7 @@ void r200InitState( r200ContextPtr rmesa ) R200_CULL_FRONT_IS_CCW); /* Texgen/Texmat state */ - rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] = 0x0; /* masks??? */ + rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] = 0x00ffffff; rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_3] = ((0 << R200_TEXGEN_0_INPUT_TEX_SHIFT) | (1 << R200_TEXGEN_1_INPUT_TEX_SHIFT) | @@ -717,8 +717,6 @@ void r200InitState( r200ContextPtr rmesa ) (5 << R200_TEXGEN_5_INPUT_SHIFT)); rmesa->hw.tcg.cmd[TCG_TEX_CYL_WRAP_CTL] = 0; - rmesa->TexGenInputs = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1]; - for (i = 0 ; i < 8; i++) { struct gl_light *l = &ctx->Light.Light[i]; diff --git a/src/mesa/drivers/dri/r200/r200_swtcl.c b/src/mesa/drivers/dri/r200/r200_swtcl.c index 66662bb..c40c7d0 100644 --- a/src/mesa/drivers/dri/r200/r200_swtcl.c +++ b/src/mesa/drivers/dri/r200/r200_swtcl.c @@ -64,7 +64,6 @@ static void flush_last_swtcl_prim( r200ContextPtr rmesa ); * Initialization ***********************************************************************/ -#define EMIT_SZ(sz) (EMIT_1F + (sz) - 1) #define EMIT_ATTR( ATTR, STYLE, F0 ) \ do { \ rmesa->swtcl.vertex_attrs[rmesa->swtcl.vertex_attr_count].attrib = (ATTR); \ @@ -145,28 +144,18 @@ static void r200SetVertexFormat( GLcontext *ctx ) for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { if (index & _TNL_BIT_TEX(i)) { GLuint sz = VB->TexCoordPtr[i]->size; - GLuint emit; - - /* r200 doesn't like 4D texcoords (is that true?): - */ - if (sz != 4) { - emit = EMIT_1F + (sz - 1); - } - else { - sz = 3; - emit = EMIT_3F_XYW; - } fmt_1 |= sz << (3 * i); - EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_SZ(sz), 0 ); + EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_1F + sz - 1, 0 ); } } } - if ( (rmesa->hw.vtx.cmd[VTX_VTXFMT_0] != fmt_0) - || (rmesa->hw.vtx.cmd[VTX_VTXFMT_1] != fmt_1) ) { + if ( rmesa->tnl_index != index || + (rmesa->hw.vtx.cmd[VTX_VTXFMT_0] != fmt_0) || + (rmesa->hw.vtx.cmd[VTX_VTXFMT_1] != fmt_1) ) { R200_NEWPRIM(rmesa); R200_STATECHANGE( rmesa, vtx ); rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = fmt_0; @@ -178,6 +167,7 @@ static void r200SetVertexFormat( GLcontext *ctx ) rmesa->swtcl.vertex_attr_count, NULL, 0 ); rmesa->swtcl.vertex_size /= 4; + rmesa->tnl_index = index; } } @@ -214,13 +204,11 @@ void r200ChooseVertexState( GLcontext *ctx ) || (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) { rmesa->swtcl.needproj = GL_TRUE; vte |= R200_VTX_XY_FMT | R200_VTX_Z_FMT; - vte &= ~R200_VTX_W0_FMT; vap |= R200_VAP_FORCE_W_TO_ONE; } else { rmesa->swtcl.needproj = GL_FALSE; vte &= ~(R200_VTX_XY_FMT | R200_VTX_Z_FMT); - vte |= R200_VTX_W0_FMT; vap &= ~R200_VAP_FORCE_W_TO_ONE; } @@ -737,7 +725,6 @@ r200PointsBitmap( GLcontext *ctx, GLint px, GLint py, GLuint vap = rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL]; vte &= ~(R200_VTX_XY_FMT | R200_VTX_Z_FMT); - vte |= R200_VTX_W0_FMT; vap &= ~R200_VAP_FORCE_W_TO_ONE; rmesa->swtcl.vertex_size = 5; diff --git a/src/mesa/drivers/dri/r200/r200_tcl.c b/src/mesa/drivers/dri/r200/r200_tcl.c index 746cdb4..78d16ed 100644 --- a/src/mesa/drivers/dri/r200/r200_tcl.c +++ b/src/mesa/drivers/dri/r200/r200_tcl.c @@ -351,13 +351,10 @@ static void r200_check_tcl_render( GLcontext *ctx, for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { if (ctx->Texture.Unit[unit]._ReallyEnabled) { - if (ctx->Texture.Unit[unit].TexGenEnabled) { - if (rmesa->TexGenNeedNormals[unit]) { - inputs |= VERT_BIT_NORMAL; - } - } else { - inputs |= VERT_BIT_TEX(unit); + if (rmesa->TexGenNeedNormals[unit]) { + inputs |= VERT_BIT_NORMAL; } + inputs |= VERT_BIT_TEX(unit); } } @@ -434,18 +431,6 @@ static void transition_to_swtnl( GLcontext *ctx ) */ R200_STATECHANGE( rmesa, vap ); rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_TCL_ENABLE; - rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_D3D_TEX_DEFAULT; - - R200_STATECHANGE( rmesa, vte ); - rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~R200_VTX_W0_FMT; - - R200_STATECHANGE( rmesa, set ); - rmesa->hw.set.cmd[SET_RE_CNTL] |= (R200_VTX_STQ0_D3D | - R200_VTX_STQ1_D3D | - R200_VTX_STQ2_D3D | - R200_VTX_STQ3_D3D | - R200_VTX_STQ4_D3D | - R200_VTX_STQ5_D3D); } static void transition_to_hwtnl( GLcontext *ctx ) @@ -470,21 +455,10 @@ static void transition_to_hwtnl( GLcontext *ctx ) R200_STATECHANGE( rmesa, vap ); rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_TCL_ENABLE; - rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~(R200_VAP_FORCE_W_TO_ONE | - R200_VAP_D3D_TEX_DEFAULT); + rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_FORCE_W_TO_ONE; R200_STATECHANGE( rmesa, vte ); rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~(R200_VTX_XY_FMT|R200_VTX_Z_FMT); - rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] |= R200_VTX_W0_FMT; - - R200_STATECHANGE( rmesa, set ); - rmesa->hw.set.cmd[SET_RE_CNTL] &= ~(R200_VTX_STQ0_D3D | - R200_VTX_STQ1_D3D | - R200_VTX_STQ2_D3D | - R200_VTX_STQ3_D3D | - R200_VTX_STQ4_D3D | - R200_VTX_STQ5_D3D); - if (R200_DEBUG & DEBUG_FALLBACKS) fprintf(stderr, "R200 end tcl fallback\n"); diff --git a/src/mesa/drivers/dri/r200/r200_texstate.c b/src/mesa/drivers/dri/r200/r200_texstate.c index 57ee245..934ffc1 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; diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt.c b/src/mesa/drivers/dri/r200/r200_vtxfmt.c index bd0003e..7a2fa35 100644 --- a/src/mesa/drivers/dri/r200/r200_vtxfmt.c +++ b/src/mesa/drivers/dri/r200/r200_vtxfmt.c @@ -401,24 +401,6 @@ static void VFMT_FALLBACK_OUTSIDE_BEGIN_END( const char *caller ) * to look-up the table, and a specialized version of GL_CALL that used the * offset number instead of the name. */ -static void dispatch_texcoord( GLuint count, GLfloat * f ) -{ - switch( count ) { - case 3: - GL_CALL(TexCoord3fv)( f ); - break; - case 2: - GL_CALL(TexCoord2fv)( f ); - break; - case 1: - GL_CALL(TexCoord1fv)( f ); - break; - default: - assert( count == 0 ); - break; - } -} - static void dispatch_multitexcoord( GLuint count, GLuint unit, GLfloat * f ) { switch( count ) { @@ -437,7 +419,7 @@ static void dispatch_multitexcoord( GLuint count, GLuint unit, GLfloat * f ) } } -static void VFMT_FALLBACK( const char *caller ) +void VFMT_FALLBACK( const char *caller ) { GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); @@ -663,8 +645,6 @@ static GLboolean check_vtx_fmt( GLcontext *ctx ) GLuint ind1 = 0; GLuint i; GLuint count[R200_MAX_TEXTURE_UNITS]; - GLuint re_cntl; - if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag) return GL_FALSE; @@ -692,26 +672,16 @@ static GLboolean check_vtx_fmt( GLcontext *ctx ) } } - re_cntl = rmesa->hw.set.cmd[SET_RE_CNTL] & ~(R200_VTX_STQ0_D3D | - R200_VTX_STQ1_D3D | - R200_VTX_STQ2_D3D | - R200_VTX_STQ3_D3D | - R200_VTX_STQ4_D3D | - R200_VTX_STQ5_D3D ); for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { count[i] = 0; if (ctx->Texture.Unit[i]._ReallyEnabled) { - if (ctx->Texture.Unit[i].TexGenEnabled) { - if (rmesa->TexGenNeedNormals[i]) { - ind0 |= R200_VTX_N0; - } + if (rmesa->TexGenNeedNormals[i]) { + ind0 |= R200_VTX_N0; } else { switch( ctx->Texture.Unit[i]._ReallyEnabled ) { case TEXTURE_CUBE_BIT: - re_cntl |= R200_VTX_STQ0_D3D << (2 * i); - /* FALLTHROUGH */ case TEXTURE_3D_BIT: count[i] = 3; break; @@ -729,11 +699,6 @@ static GLboolean check_vtx_fmt( GLcontext *ctx ) } } - if ( re_cntl != rmesa->hw.set.cmd[SET_RE_CNTL] ) { - R200_STATECHANGE( rmesa, set ); - rmesa->hw.set.cmd[SET_RE_CNTL] = re_cntl; - } - if (R200_DEBUG & (DEBUG_VFMT|DEBUG_STATE)) fprintf(stderr, "%s: format: 0x%x, 0x%x\n", __FUNCTION__, ind0, ind1 ); diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt.h b/src/mesa/drivers/dri/r200/r200_vtxfmt.h index 39f0a10e4..071a740 100644 --- a/src/mesa/drivers/dri/r200/r200_vtxfmt.h +++ b/src/mesa/drivers/dri/r200/r200_vtxfmt.h @@ -52,6 +52,7 @@ extern void r200VtxfmtMakeCurrent( GLcontext *ctx ); extern void r200VtxfmtUnbindContext( GLcontext *ctx ); extern void r200_copy_to_current( GLcontext *ctx ); +extern void VFMT_FALLBACK( const char *caller ); #define DFN( FUNC, CACHE) \ do { \ diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt_c.c b/src/mesa/drivers/dri/r200/r200_vtxfmt_c.c index 9f40b18..70301af 100644 --- a/src/mesa/drivers/dri/r200/r200_vtxfmt_c.c +++ b/src/mesa/drivers/dri/r200/r200_vtxfmt_c.c @@ -515,66 +515,118 @@ static void r200_Normal3fv( const GLfloat *v ) /* TexCoord */ -#define TEX_to_nF(N, P, S, T, R) \ - static void r200_TexCoord ## N P \ - { \ - GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); \ - GLfloat * const dest = rmesa->vb.texcoordptr[0]; \ - switch( ctx->Texture.Unit[0]._ReallyEnabled ) { \ - case TEXTURE_CUBE_BIT: \ - case TEXTURE_3D_BIT: \ - dest[2] = R; \ - case TEXTURE_2D_BIT: \ - case TEXTURE_RECT_BIT: \ - dest[1] = T; \ - case TEXTURE_1D_BIT: \ - dest[0] = S; \ - } \ +/* \todo maybe (target & 4 ? target & 5 : target & 3) is more save than (target & 7) */ +static void r200_MultiTexCoord1fARB(GLenum target, GLfloat s) +{ + GET_CURRENT_CONTEXT(ctx); + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLint unit = (target & 7); + GLfloat * const dest = rmesa->vb.texcoordptr[unit]; + + switch( ctx->Texture.Unit[unit]._ReallyEnabled ) { + case TEXTURE_CUBE_BIT: + case TEXTURE_3D_BIT: + dest[2] = 0.0; + /* FALLTHROUGH */ + case TEXTURE_2D_BIT: + case TEXTURE_RECT_BIT: + dest[1] = 0.0; + /* FALLTHROUGH */ + case TEXTURE_1D_BIT: + dest[0] = s; } +} -TEX_to_nF( 1f, (GLfloat s), s, 0.0, 0.0 ) -TEX_to_nF( 2f, (GLfloat s, GLfloat t), s, t, 0.0 ) -TEX_to_nF( 3f, (GLfloat s, GLfloat t, GLfloat r), s, t, r ) -TEX_to_nF( 1fv, (const GLfloat * v), v[0], 0.0, 0.0 ) -TEX_to_nF( 2fv, (const GLfloat * v), v[0], v[1], 0.0 ) -TEX_to_nF( 3fv, (const GLfloat * v), v[0], v[1], v[2] ) - - -/* MultiTexcoord - * - * Technically speaking, these functions should subtract GL_TEXTURE0 from - * \c target before masking and using it. The value of GL_TEXTURE0 is 0x84C0, - * which has the low-order 5 bits 0. For all possible valid values of - * \c target. Subtracting GL_TEXTURE0 has the net effect of masking \c target - * with 0x1F. Masking with 0x1F and then masking with 0x07 is redundant, so - * the subtraction has been omitted. - */ +static void r200_MultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t) +{ + GET_CURRENT_CONTEXT(ctx); + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLint unit = (target & 7); + GLfloat * const dest = rmesa->vb.texcoordptr[unit]; -#define MTEX_to_nF(N, P, U, S, T, R) \ - static void r200_MultiTexCoord ## N ## ARB P \ - { \ - GET_CURRENT_CONTEXT(ctx); r200ContextPtr rmesa = R200_CONTEXT(ctx); \ - GLfloat * const dest = rmesa->vb.texcoordptr[U]; \ - switch( ctx->Texture.Unit[U]._ReallyEnabled ) { \ - case TEXTURE_CUBE_BIT: \ - case TEXTURE_3D_BIT: \ - dest[2] = R; \ - case TEXTURE_2D_BIT: \ - case TEXTURE_RECT_BIT: \ - dest[1] = T; \ - case TEXTURE_1D_BIT: \ - dest[0] = S; \ - } \ + switch( ctx->Texture.Unit[unit]._ReallyEnabled ) { + case TEXTURE_CUBE_BIT: + case TEXTURE_3D_BIT: + dest[2] = 0.0; + /* FALLTHROUGH */ + case TEXTURE_2D_BIT: + case TEXTURE_RECT_BIT: + dest[1] = t; + dest[0] = s; + break; + default: + VFMT_FALLBACK(__FUNCTION__); + GL_CALL(MultiTexCoord2fARB)(target, s, t); + return; } +} -/* \todo maybe (target & 4 ? target & 5 : target & 3) is more save than (target & 7) */ -MTEX_to_nF( 1f, (GLenum target, GLfloat s), (target & 7), s, 0.0, 0.0 ) -MTEX_to_nF( 2f, (GLenum target, GLfloat s, GLfloat t), (target & 7), s, t, 0.0 ) -MTEX_to_nF( 3f, (GLenum target, GLfloat s, GLfloat t, GLfloat r), (target & 7), s, t, r ) +static void r200_MultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r) +{ + GET_CURRENT_CONTEXT(ctx); + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLint unit = (target & 7); + GLfloat * const dest = rmesa->vb.texcoordptr[unit]; + + switch( ctx->Texture.Unit[unit]._ReallyEnabled ) { + case TEXTURE_CUBE_BIT: + case TEXTURE_3D_BIT: + dest[2] = r; + dest[1] = t; + dest[0] = s; + break; + default: + VFMT_FALLBACK(__FUNCTION__); + GL_CALL(MultiTexCoord3fARB)(target, s, t, r); + return; + } +} + +static void r200_TexCoord1f(GLfloat s) +{ + r200_MultiTexCoord1fARB(GL_TEXTURE0, s); +} + +static void r200_TexCoord2f(GLfloat s, GLfloat t) +{ + r200_MultiTexCoord2fARB(GL_TEXTURE0, s, t); +} + +static void r200_TexCoord3f(GLfloat s, GLfloat t, GLfloat r) +{ + r200_MultiTexCoord3fARB(GL_TEXTURE0, s, t, r); +} + +static void r200_TexCoord1fv(const GLfloat *v) +{ + r200_MultiTexCoord1fARB(GL_TEXTURE0, v[0]); +} + +static void r200_TexCoord2fv(const GLfloat *v) +{ + r200_MultiTexCoord2fARB(GL_TEXTURE0, v[0], v[1]); +} + +static void r200_TexCoord3fv(const GLfloat *v) +{ + r200_MultiTexCoord3fARB(GL_TEXTURE0, v[0], v[1], v[2]); +} + +static void r200_MultiTexCoord1fvARB(GLenum target, const GLfloat *v) +{ + r200_MultiTexCoord1fARB(target, v[0]); +} + +static void r200_MultiTexCoord2fvARB(GLenum target, const GLfloat *v) +{ + r200_MultiTexCoord2fARB(target, v[0], v[1]); +} + +static void r200_MultiTexCoord3fvARB(GLenum target, const GLfloat *v) +{ + r200_MultiTexCoord3fARB(target, v[0], v[1], v[2]); +} -MTEX_to_nF( 1fv, (GLenum target, const GLfloat *v), (target & 7), v[0], 0.0, 0.0 ) -MTEX_to_nF( 2fv, (GLenum target, const GLfloat *v), (target & 7), v[0], v[1], 0.0 ) -MTEX_to_nF( 3fv, (GLenum target, const GLfloat *v), (target & 7), v[0], v[1], v[2] ) static struct dynfn *lookup( struct dynfn *l, const int *key ) { -- 2.7.4