diff options
author | Eric Anholt <[email protected]> | 2004-10-16 03:36:14 +0000 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2004-10-16 03:36:14 +0000 |
commit | b1ebd306bf4fdc4076d3d3daa410b08f477cb4c4 (patch) | |
tree | e815feb8221211e716d664be7093e5f344efcf3d | |
parent | a1af92877d3d91886cf01be9e6c65311960e3baf (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
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_context.h | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_maos_arrays.c | 16 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_reg.h | 5 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_state.c | 10 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_state_init.c | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_swtcl.c | 23 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_tcl.c | 34 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_texstate.c | 239 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_vtxfmt.c | 41 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_vtxfmt.h | 1 | ||||
-rw-r--r-- | 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 140902c356b..af07653244c 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 3429cf6400d..0f8ca3048ed 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 726be6ef8fd..89da699bdb6 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 dd547f9957a..825c036e272 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 049820b3cb7..610706bd318 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 66662bb4d03..c40c7d09dbd 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 746cdb4778a..78d16ed0f3b 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 57ee245ee90..934ffc13493 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; diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt.c b/src/mesa/drivers/dri/r200/r200_vtxfmt.c index bd0003e127e..7a2fa35d44f 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 39f0a10e4eb..071a74082ff 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 9f40b18c9d2..70301afb04e 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 ) { |