diff options
| -rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_context.c | 6 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_context.h | 5 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_maos_arrays.c | 43 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h | 24 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_maos_verts.c | 28 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_state.c | 165 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_state.h | 4 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_tcl.c | 6 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_tcl.h | 3 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_texstate.c | 111 | 
10 files changed, 297 insertions, 98 deletions
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index ae9dd35473..abb2c72e79 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -405,10 +405,12 @@ radeonCreateContext( const __GLcontextModes *glVisual,     _math_matrix_ctr( &rmesa->TexGenMatrix[0] );     _math_matrix_ctr( &rmesa->TexGenMatrix[1] ); -   _math_matrix_ctr( &rmesa->tmpmat ); +   _math_matrix_ctr( &rmesa->tmpmat[0] ); +   _math_matrix_ctr( &rmesa->tmpmat[1] );     _math_matrix_set_identity( &rmesa->TexGenMatrix[0] );     _math_matrix_set_identity( &rmesa->TexGenMatrix[1] ); -   _math_matrix_set_identity( &rmesa->tmpmat ); +   _math_matrix_set_identity( &rmesa->tmpmat[0] ); +   _math_matrix_set_identity( &rmesa->tmpmat[1] );     driInitExtensions( ctx, card_extensions, GL_TRUE );     if (rmesa->glCtx->Mesa_DXTn) { diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h index 8c1c70c122..3bd8f6ebc6 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_context.h @@ -753,9 +753,10 @@ struct radeon_context {     GLmatrix TexGenMatrix[RADEON_MAX_TEXTURE_UNITS];     GLboolean recheck_texgen[RADEON_MAX_TEXTURE_UNITS];     GLboolean TexGenNeedNormals[RADEON_MAX_TEXTURE_UNITS]; -   GLuint TexMatEnabled;     GLuint TexGenEnabled; -   GLmatrix tmpmat; +   GLuint NeedTexMatrix; +   GLuint TexMatColSwap; +   GLmatrix tmpmat[RADEON_MAX_TEXTURE_UNITS];     GLuint last_ReallyEnabled;     /* VBI diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c b/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c index 98f66898c7..b5c6f12248 100644 --- a/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c +++ b/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c @@ -387,6 +387,7 @@ static void emit_tex_vector( GLcontext *ctx,     switch (size) {     case 4: emitsize = 3; break; +   case 3: emitsize = 3; break;     default: emitsize = 2; break;     } @@ -416,7 +417,7 @@ static void emit_tex_vector( GLcontext *ctx,        emit_vec8( ctx, rvb, data, stride, count );        break;     case 3: -      emit_vec8( ctx, rvb, data, stride, count ); +      emit_vec12( ctx, rvb, data, stride, count );        break;     case 4:        emit_stq_vec( ctx, rvb, data, stride, count ); @@ -529,38 +530,52 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs )     if (inputs & VERT_BIT_TEX0) {        if (!rmesa->tcl.tex[0].buf) -	 emit_tex_vector( ctx,  -			  &(rmesa->tcl.tex[0]),  +	 emit_tex_vector( ctx, +			  &(rmesa->tcl.tex[0]),  			  (char *)VB->TexCoordPtr[0]->data,  			  VB->TexCoordPtr[0]->size,  			  VB->TexCoordPtr[0]->stride,  			  count ); -      switch( VB->TexCoordPtr[0]->size ) { -      case 4: -	 vtx |= RADEON_TCL_VTX_Q0;  +      vfmt |= RADEON_CP_VC_FRMT_ST0; +      /* assume we need the 3rd coord if texgen is active for r/q OR at least 3 +         coords are submitted. This may not be 100% correct */ +      if ( (VB->TexCoordPtr[0]->size >= 3) { +	 vtx |= RADEON_TCL_VTX_Q0;  	 vfmt |= RADEON_CP_VC_FRMT_Q0; -      default:  -	 vfmt |= RADEON_CP_VC_FRMT_ST0; +      } +      if ( (ctx->Texture.Unit[0].TexGenEnabled & (R_BIT | Q_BIT)) ) +	 vtx |= RADEON_TCL_VTX_Q0; +      else if (VB->TexCoordPtr[0]->size >= 3) { +	 GLuint swaptexmatcol = (VB->TexCoordPtr[0]->size - 3); +	 if ((rmesa->NeedTexMatrix & 1) && +		(swaptexmatcol != (rmesa->TexMatColSwap & 1))) +	    radeonUploadTexMatrix( rmesa, rmesa->tmpmat[0].m, 0, swaptexmatcol ) ;        }        component[nr++] = &rmesa->tcl.tex[0];     }     if (inputs & VERT_BIT_TEX1) {        if (!rmesa->tcl.tex[1].buf) -	 emit_tex_vector( ctx,  -			  &(rmesa->tcl.tex[1]),  +	 emit_tex_vector( ctx, +			  &(rmesa->tcl.tex[1]),  			  (char *)VB->TexCoordPtr[1]->data,  			  VB->TexCoordPtr[1]->size,  			  VB->TexCoordPtr[1]->stride,  			  count ); -      switch( VB->TexCoordPtr[1]->size ) { -      case 4:  +      vfmt |= RADEON_CP_VC_FRMT_ST1; +      if ( (VB->TexCoordPtr[1]->size >= 3) {  	 vtx |= RADEON_TCL_VTX_Q1;  	 vfmt |= RADEON_CP_VC_FRMT_Q1; -      default:  -	 vfmt |= RADEON_CP_VC_FRMT_ST1; +      } +      if ( (ctx->Texture.Unit[1].TexGenEnabled & (R_BIT | Q_BIT)) ) +	 vtx |= RADEON_TCL_VTX_Q1; +      else if (VB->TexCoordPtr[1]->size >= 3) { +	 GLuint swaptexmatcol = (VB->TexCoordPtr[1]->size - 3); +	 if (((rmesa->NeedTexMatrix >> 1) & 1) && +		(swaptexmatcol != ((rmesa->TexMatColSwap >> 1) & 1))) +	    radeonUploadTexMatrix( rmesa, rmesa->tmpmat[1].m, 1, swaptexmatcol ) ;        }        component[nr++] = &rmesa->tcl.tex[1];     } diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h b/src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h index c16234a943..8a07a01cb2 100644 --- a/src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h +++ b/src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h @@ -47,6 +47,7 @@ static void TAG(emit)( GLcontext *ctx,     GLuint tc0_stride, tc1_stride, col_stride, spec_stride, fog_stride;     GLuint tc2_stride, norm_stride;     GLuint fill_tex = 0; +   GLuint rqcoordsnoswap = 0;     GLuint (*coord)[4];     GLuint coord_stride; /* object coordinates */     GLubyte dummy[4]; @@ -65,9 +66,14 @@ static void TAG(emit)( GLcontext *ctx,  	 const GLuint t2 = GET_TEXSOURCE(2);  	 tc2 = (GLuint (*)[4])VB->TexCoordPtr[t2]->data;  	 tc2_stride = VB->TexCoordPtr[t2]->stride; -	 if (DO_PTEX && VB->TexCoordPtr[t2]->size < 4) { +	 if (DO_PTEX && VB->TexCoordPtr[t2]->size < 3) { +	 /* since DO_PTEX is only true when we have 3 or more coords +	    in the first place we don't really need this right? */  	    fill_tex |= (1<<2);  	 } +	 else if (DO_PTEX && VB->TexCoordPtr[t2]->size < 4) { +	    rqcoordsnoswap |= (1<<2); +	 }        } else {  	 tc2 = (GLuint (*)[4])&ctx->Current.Attrib[VERT_ATTRIB_TEX2];  	 tc2_stride = 0; @@ -79,9 +85,12 @@ static void TAG(emit)( GLcontext *ctx,  	 const GLuint t1 = GET_TEXSOURCE(1);  	 tc1 = (GLuint (*)[4])VB->TexCoordPtr[t1]->data;  	 tc1_stride = VB->TexCoordPtr[t1]->stride; -	 if (DO_PTEX && VB->TexCoordPtr[t1]->size < 4) { +	 if (DO_PTEX && VB->TexCoordPtr[t1]->size < 3) {  	    fill_tex |= (1<<1);  	 } +	 else if (DO_PTEX && VB->TexCoordPtr[t1]->size < 4) { +	    rqcoordsnoswap |= (1<<1); +	 }        } else {  	 tc1 = (GLuint (*)[4])&ctx->Current.Attrib[VERT_ATTRIB_TEX1];  	 tc1_stride = 0; @@ -93,9 +102,12 @@ static void TAG(emit)( GLcontext *ctx,  	 const GLuint t0 = GET_TEXSOURCE(0);  	 tc0_stride = VB->TexCoordPtr[t0]->stride;  	 tc0 = (GLuint (*)[4])VB->TexCoordPtr[t0]->data; -	 if (DO_PTEX && VB->TexCoordPtr[t0]->size < 4) { +	 if (DO_PTEX && VB->TexCoordPtr[t0]->size < 3) {  	    fill_tex |= (1<<0);  	 } +	 else if (DO_PTEX && VB->TexCoordPtr[t0]->size < 4) { +	    rqcoordsnoswap |= (1<<0); +	 }        } else {  	 tc0 = (GLuint (*)[4])&ctx->Current.Attrib[VERT_ATTRIB_TEX0];  	 tc0_stride = 0; @@ -213,6 +225,8 @@ static void TAG(emit)( GLcontext *ctx,  	    if (DO_PTEX) {  	       if (fill_tex & (1<<0))  		  v[2].f = 1.0; +	       else if (rqcoordsnoswap & (1<<0)) +		  v[2].ui = tc0[0][2];  	       else  		  v[2].ui = tc0[0][3];  	       if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[2].f); @@ -229,6 +243,8 @@ static void TAG(emit)( GLcontext *ctx,  	    if (DO_PTEX) {  	       if (fill_tex & (1<<1))  		  v[2].f = 1.0; +	       else if (rqcoordsnoswap & (1<<1)) +		  v[2].ui = tc1[0][2];  	       else  		  v[2].ui = tc1[0][3];  	       if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[2].f); @@ -244,6 +260,8 @@ static void TAG(emit)( GLcontext *ctx,  	    if (DO_PTEX) {  	       if (fill_tex & (1<<2))  		  v[2].f = 1.0; +	       else if (rqcoordsnoswap & (1<<2)) +		  v[2].ui = tc2[0][2];  	       else  		  v[2].ui = tc2[0][3];  	       v += 3; diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_verts.c b/src/mesa/drivers/dri/radeon/radeon_maos_verts.c index 8cb08a812a..f3221e60d8 100644 --- a/src/mesa/drivers/dri/radeon/radeon_maos_verts.c +++ b/src/mesa/drivers/dri/radeon/radeon_maos_verts.c @@ -243,7 +243,7 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs )        init_tcl_verts();        firsttime = 0;     } -		      +     if (1) {        req |= RADEON_CP_VC_FRMT_Z;        if (VB->ObjPtr->size == 4) { @@ -254,7 +254,7 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs )     if (inputs & VERT_BIT_NORMAL) {        req |= RADEON_CP_VC_FRMT_N0;     } -    +     if (inputs & VERT_BIT_COLOR0) {        req |= RADEON_CP_VC_FRMT_PKCOLOR;     } @@ -265,20 +265,38 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs )     if (inputs & VERT_BIT_TEX0) {        req |= RADEON_CP_VC_FRMT_ST0; - -      if (VB->TexCoordPtr[0]->size == 4) { +      /* assume we need the 3rd coord if texgen is active for r/q OR at least 3 +         coords are submitted. This may not be 100% correct */ +      if (VB->TexCoordPtr[0]->size >= 3) {  	 req |= RADEON_CP_VC_FRMT_Q0;  	 vtx |= RADEON_TCL_VTX_Q0;        } +      if ( (ctx->Texture.Unit[0].TexGenEnabled & (R_BIT | Q_BIT)) ) +	 vtx |= RADEON_TCL_VTX_Q0; +      else if (VB->TexCoordPtr[0]->size >= 3) { +	 GLuint swaptexmatcol = (VB->TexCoordPtr[0]->size - 3); +	 if ((rmesa->NeedTexMatrix & 1) && +		(swaptexmatcol != (rmesa->TexMatColSwap & 1))) +	    radeonUploadTexMatrix( rmesa, rmesa->tmpmat[0].m, 0, swaptexmatcol ) ; +      }     } +     if (inputs & VERT_BIT_TEX1) {        req |= RADEON_CP_VC_FRMT_ST1; -      if (VB->TexCoordPtr[1]->size == 4) { +      if (VB->TexCoordPtr[1]->size >= 3) {  	 req |= RADEON_CP_VC_FRMT_Q1;  	 vtx |= RADEON_TCL_VTX_Q1;        } +      if ( (ctx->Texture.Unit[1].TexGenEnabled & (R_BIT | Q_BIT)) ) +	 vtx |= RADEON_TCL_VTX_Q1; +      else if (VB->TexCoordPtr[1]->size >= 3) { +	 GLuint swaptexmatcol = (VB->TexCoordPtr[1]->size - 3); +	 if (((rmesa->NeedTexMatrix >> 1) & 1) && +		(swaptexmatcol != ((rmesa->TexMatColSwap >> 1) & 1))) +	    radeonUploadTexMatrix( rmesa, rmesa->tmpmat[1].m, 1, swaptexmatcol ) ; +      }     }     if (vtx != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT]) { diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index 3c7767768b..d99a2f4c20 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -2024,7 +2024,105 @@ static void radeonLightingSpaceChange( GLcontext *ctx )   * Deferred state management - matrices, textures, other?   */ +static void texmat_set_texrect( radeonContextPtr rmesa, +				struct gl_texture_object *tObj, GLuint unit ) +{ +   const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel]; +   _math_matrix_set_identity( &rmesa->tmpmat[unit] ); +   rmesa->tmpmat[unit].m[0] = 1.0 / baseImage->Width; +   rmesa->tmpmat[unit].m[5] = 1.0 / baseImage->Height; + +} + +static void texmat_fixup_texrect( radeonContextPtr rmesa, +				  struct gl_texture_object *tObj, GLuint unit ) +{ +   const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel]; +   GLuint i; +   for (i = 0; i < 4; i++) { +      rmesa->tmpmat[unit].m[i] = rmesa->tmpmat[unit].m[i] / baseImage->Width; +      rmesa->tmpmat[unit].m[i+4] = rmesa->tmpmat[unit].m[i+4] / baseImage->Height; +   }} + + +void radeonUploadTexMatrix( radeonContextPtr rmesa, GLfloat *src, +			    int unit, GLboolean swapcols ) +{ +/* Here's how this works: on r100, only 3 tex coords can be submitted, so the +   vector looks like this probably: (s t r|q 0) (not sure if the last coord +   is hardwired to 0, could be 1 too). Interestingly, it actually looks like +   texgen generates all 4 coords, at least tests with projtex indicated that. +   So: if we need the q coord in the end (solely determined by the texture +   target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row. +   Additionally, if we don't have texgen but 4 tex coords submitted, we swap +   column 3 and 4 (for the 2d / 1d / texrect targets) since the the q coord +   will get submitted in the "wrong", i.e. 3rd, slot. +   If an app submits 3 coords for 2d targets, we assume it is saving on vertex +   size and using the texture matrix to swap the r and q coords around (ut2k3 +   does exactly that), so we don't need the 3rd / 4th column swap - still need +   the 3rd / 4th row swap of course. This will potentially break for apps which +   use TexCoord3x just for fun. Additionally, it will never work if an app uses +   an "advanced" texture matrix and relies on all 4 texcoord inputs to generate +   the maximum needed 3. This seems impossible to do with hw tcl on r100, and +   incredibly hard to detect so we can't just fallback in such a case. Assume +   it never happens... - rs +*/ + +   int idx = TEXMAT_0 + unit; +   float *dest = ((float *)RADEON_DB_STATE( mat[idx] )) + MAT_ELT_0; +   int i; +   struct gl_texture_unit tUnit = rmesa->glCtx->Texture.Unit[unit]; + +   rmesa->TexMatColSwap &= ~(1 << unit); +   if ((tUnit._ReallyEnabled & (TEXTURE_3D_BIT | TEXTURE_CUBE_BIT)) == 0) { +      if (swapcols) { +	 rmesa->TexMatColSwap |= 1 << unit; +	 /* attention some elems are swapped 2 times! */ +	 *dest++ = src[0]; +	 *dest++ = src[4]; +	 *dest++ = src[12]; +	 *dest++ = src[8]; +	 *dest++ = src[1]; +	 *dest++ = src[5]; +	 *dest++ = src[13]; +	 *dest++ = src[9]; +	 *dest++ = src[2]; +	 *dest++ = src[6]; +	 *dest++ = src[15]; +	 *dest++ = src[11]; +	 /* those last 4 are probably never used */ +	 *dest++ = src[3]; +	 *dest++ = src[7]; +	 *dest++ = src[14]; +	 *dest++ = src[10]; +      } +      else { +	 for (i = 0; i < 2; i++) { +	    *dest++ = src[i]; +	    *dest++ = src[i+4]; +	    *dest++ = src[i+8]; +	    *dest++ = src[i+12]; +	 } +	 for (i = 3; i >= 2; i--) { +	    *dest++ = src[i]; +	    *dest++ = src[i+4]; +	    *dest++ = src[i+8]; +	    *dest++ = src[i+12]; +	 } +      } +   } +   else { +      /* never used currently - no swapping needed at all presumably */ +      for (i = 0 ; i < 4 ; i++) { +	 *dest++ = src[i]; +	 *dest++ = src[i+4]; +	 *dest++ = src[i+8]; +	 *dest++ = src[i+12]; +      } +   } +   RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] ); +}  static void upload_matrix( radeonContextPtr rmesa, GLfloat *src, int idx ) @@ -2057,42 +2155,53 @@ static void update_texturematrix( GLcontext *ctx )     GLuint tpc = rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL];     GLuint vs = rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL];     int unit; - -   rmesa->TexMatEnabled = 0; +   GLuint texMatEnabled = 0; +   rmesa->NeedTexMatrix = 0; +   rmesa->TexMatColSwap = 0;     for (unit = 0 ; unit < 2; unit++) { -      if (!ctx->Texture.Unit[unit]._ReallyEnabled) { -      } -      else if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) { -	 GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4; -	  -	 rmesa->TexMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE| -				  RADEON_TEXMAT_0_ENABLE) << unit; +      if (ctx->Texture.Unit[unit]._ReallyEnabled) { +	 GLboolean needMatrix = GL_FALSE; +	 if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) { +	    needMatrix = GL_TRUE; +	    texMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE | +			      RADEON_TEXMAT_0_ENABLE) << unit; -	 if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) { -	    /* Need to preconcatenate any active texgen  -	     * obj/eyeplane matrices: -	     */ -	    _math_matrix_mul_matrix( &rmesa->tmpmat, +	    if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) { +	       /* Need to preconcatenate any active texgen +	        * obj/eyeplane matrices: +	        */ +	       _math_matrix_mul_matrix( &rmesa->tmpmat[unit],  				     ctx->TextureMatrixStack[unit].Top,  				     &rmesa->TexGenMatrix[unit] ); -	    upload_matrix( rmesa, rmesa->tmpmat.m, TEXMAT_0+unit ); +	    } +	    else { +	       _math_matrix_copy( &rmesa->tmpmat[unit], +		  ctx->TextureMatrixStack[unit].Top ); +	    }  	 } -	 else { -	    rmesa->TexMatEnabled |=  -	       (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift; -	    upload_matrix( rmesa, ctx->TextureMatrixStack[unit].Top->m,  -			   TEXMAT_0+unit ); +	 else if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) { +	    _math_matrix_copy( &rmesa->tmpmat[unit], &rmesa->TexGenMatrix[unit] ); +	    needMatrix = GL_TRUE; +	 } +	 if (ctx->Texture.Unit[unit]._ReallyEnabled == TEXTURE_RECT_BIT) { +	    texMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE | +			      RADEON_TEXMAT_0_ENABLE) << unit; +	    if (needMatrix) +	       texmat_fixup_texrect( rmesa, ctx->Texture.Unit[unit]._Current, unit ); +	    else +	       texmat_set_texrect( rmesa, ctx->Texture.Unit[unit]._Current, unit ); +	    needMatrix = GL_TRUE; +	 } +	 if (needMatrix) { +	    rmesa->NeedTexMatrix |= 1 << unit; +	    radeonUploadTexMatrix( rmesa, rmesa->tmpmat[unit].m, unit, +			!ctx->Texture.Unit[unit].TexGenEnabled );  	 } -      } -      else if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) { -	 upload_matrix( rmesa, rmesa->TexGenMatrix[unit].m,  -			TEXMAT_0+unit );        }     } - -   tpc = (rmesa->TexMatEnabled | rmesa->TexGenEnabled); +   tpc = (texMatEnabled | rmesa->TexGenEnabled);     vs &= ~((0xf << RADEON_TCL_TEX_0_OUTPUT_SHIFT) |  	   (0xf << RADEON_TCL_TEX_1_OUTPUT_SHIFT)); @@ -2109,7 +2218,7 @@ static void update_texturematrix( GLcontext *ctx )     if (tpc != rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] ||         vs != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]) { -       +        RADEON_STATECHANGE(rmesa, tcl);        rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = tpc;        rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] = vs; @@ -2188,7 +2297,7 @@ void radeonValidateState( GLcontext *ctx )      */     if (new_state & _NEW_TEXTURE_MATRIX) {        update_texturematrix( ctx ); -   }       +   }     if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) {        update_light( ctx ); diff --git a/src/mesa/drivers/dri/radeon/radeon_state.h b/src/mesa/drivers/dri/radeon/radeon_state.h index c9f5c05cf4..a1afa50007 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.h +++ b/src/mesa/drivers/dri/radeon/radeon_state.h @@ -49,7 +49,9 @@ extern void radeonSetCliprects( radeonContextPtr rmesa );  extern void radeonRecalcScissorRects( radeonContextPtr rmesa );  extern void radeonUpdateViewportOffset( GLcontext *ctx );  extern void radeonUpdateWindow( GLcontext *ctx ); -extern void radeonUpdateDrawBuffer(GLcontext *ctx); +extern void radeonUpdateDrawBuffer( GLcontext *ctx ); +extern void radeonUploadTexMatrix( radeonContextPtr rmesa, GLfloat *src, +				       int unit, GLboolean swapcols );  extern void radeonValidateState( GLcontext *ctx ); diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.c b/src/mesa/drivers/dri/radeon/radeon_tcl.c index b13042d965..fb0f10a862 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_tcl.c @@ -320,6 +320,7 @@ static GLboolean radeon_run_tcl_render( GLcontext *ctx,     for (i = 0 ; i < ctx->Const.MaxTextureUnits; i++) {        if (ctx->Texture.Unit[i]._ReallyEnabled) { +      /* TODO: probably should not emit texture coords when texgen is enabled */  	 if (rmesa->TexGenNeedNormals[i]) {  	    inputs |= VERT_BIT_NORMAL;  	 } @@ -444,10 +445,7 @@ static char *fallbackStrings[] = {     "Texgen unit 0",     "Texgen unit 1",     "Texgen unit 2", -   "User disable", -   "texture rectangle unit 0", -   "texture rectangle unit 1", -   "texture rectangle unit 2" +   "User disable"  }; diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.h b/src/mesa/drivers/dri/radeon/radeon_tcl.h index e292d23037..263b803d62 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tcl.h +++ b/src/mesa/drivers/dri/radeon/radeon_tcl.h @@ -55,9 +55,6 @@ extern void radeonTclFallback( GLcontext *ctx, GLuint bit, GLboolean mode );  #define RADEON_TCL_FALLBACK_TEXGEN_1          0x20 /* texgen, unit 1 */  #define RADEON_TCL_FALLBACK_TEXGEN_2          0x40 /* texgen, unit 2 */  #define RADEON_TCL_FALLBACK_TCL_DISABLE       0x80 /* user disable */ -#define RADEON_TCL_FALLBACK_TEXRECT_0         0x100 /* texture rectangle */ -#define RADEON_TCL_FALLBACK_TEXRECT_1         0x200 /* texture rectangle */ -#define RADEON_TCL_FALLBACK_TEXRECT_2         0x400 /* texture rectangle */  #define RADEON_MAX_TCL_VERTSIZE (15*4) diff --git a/src/mesa/drivers/dri/radeon/radeon_texstate.c b/src/mesa/drivers/dri/radeon/radeon_texstate.c index e12fd41ad9..03324941ba 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texstate.c +++ b/src/mesa/drivers/dri/radeon/radeon_texstate.c @@ -834,7 +834,9 @@ static void import_tex_obj_state( radeonContextPtr rmesa,  static void set_texgen_matrix( radeonContextPtr rmesa,   			       GLuint unit,  			       const GLfloat *s_plane, -			       const GLfloat *t_plane ) +			       const GLfloat *t_plane, +			       const GLfloat *r_plane, +			       const GLfloat *q_plane )  {     rmesa->TexGenMatrix[unit].m[0]  = s_plane[0];     rmesa->TexGenMatrix[unit].m[4]  = s_plane[1]; @@ -846,78 +848,119 @@ static void set_texgen_matrix( radeonContextPtr rmesa,     rmesa->TexGenMatrix[unit].m[9]  = t_plane[2];     rmesa->TexGenMatrix[unit].m[13] = t_plane[3]; +   rmesa->TexGenMatrix[unit].m[2]  = r_plane[0]; +   rmesa->TexGenMatrix[unit].m[6]  = r_plane[1]; +   rmesa->TexGenMatrix[unit].m[10] = r_plane[2]; +   rmesa->TexGenMatrix[unit].m[14] = r_plane[3]; + +   rmesa->TexGenMatrix[unit].m[3]  = q_plane[0]; +   rmesa->TexGenMatrix[unit].m[7]  = q_plane[1]; +   rmesa->TexGenMatrix[unit].m[11] = q_plane[2]; +   rmesa->TexGenMatrix[unit].m[15] = q_plane[3]; +     rmesa->TexGenEnabled |= RADEON_TEXMAT_0_ENABLE << unit;     rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;  } -/* Ignoring the Q texcoord for now. - * - * Returns GL_FALSE if fallback required.   +/* Returns GL_FALSE if fallback required.   */  static GLboolean radeon_validate_texgen( GLcontext *ctx, GLuint unit ) -{   +{     radeonContextPtr rmesa = RADEON_CONTEXT(ctx);     struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];     GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;     GLuint tmp = rmesa->TexGenEnabled; +   static const GLfloat reflect[16] = { +      -1,  0,  0,  0, +       0, -1,  0,  0, +       0,  0,  -1, 0, +       0,  0,  0,  1 }; -   rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit); -   rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit); -   rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift); +   rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE << unit); +   rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE << unit); +   rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK << inputshift);     rmesa->TexGenNeedNormals[unit] = 0; -   if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) == 0) { +   if ((texUnit->TexGenEnabled & (S_BIT|T_BIT|R_BIT|Q_BIT)) == 0) {        /* Disabled, no fallback:         */ -      rmesa->TexGenEnabled |=  -	 (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift; +      rmesa->TexGenEnabled |= +	 (RADEON_TEXGEN_INPUT_TEXCOORD_0 + unit) << inputshift;        return GL_TRUE;     } -   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:  -       */ -      if (RADEON_DEBUG & DEBUG_FALLBACKS)  -	fprintf(stderr, "fallback Q_BIT\n"); -      return GL_FALSE; +   /* the r100 cannot do texgen for some coords and not for others +    * we do not detect such cases (certainly can't do it here) and just +    * ASSUME that when S and T are texgen enabled we do not need other +    * non-texgen enabled coords, no matter if the R and Q bits are texgen +    * enabled. Still check for mixed mode texgen for all coords. +    */ +   else if ( (texUnit->TexGenEnabled & S_BIT) && +	     (texUnit->TexGenEnabled & T_BIT) && +	     (texUnit->GenModeS == texUnit->GenModeT) ) { +      if ( ((texUnit->TexGenEnabled & R_BIT) && +	    (texUnit->GenModeS != texUnit->GenModeR)) || +	   ((texUnit->TexGenEnabled & Q_BIT) && +	    (texUnit->GenModeS != texUnit->GenModeQ)) ) { +	 /* Mixed modes, fallback: +	  */ +	 if (RADEON_DEBUG & DEBUG_FALLBACKS) +	    fprintf(stderr, "fallback mixed texgen\n"); +	 return GL_FALSE; +      } +      rmesa->TexGenEnabled |= RADEON_TEXGEN_TEXMAT_0_ENABLE << unit;     } -   else if ((texUnit->TexGenEnabled & (S_BIT|T_BIT)) != (S_BIT|T_BIT) || -	    texUnit->GenModeS != texUnit->GenModeT) { -      /* Mixed modes, fallback: -       */ -      if (RADEON_DEBUG & DEBUG_FALLBACKS)  -        fprintf(stderr, "fallback mixed texgen\n"); +   else { +   /* some texgen mode not including both S and T bits */ +      if (RADEON_DEBUG & DEBUG_FALLBACKS) +	 fprintf(stderr, "fallback mixed texgen/nontexgen\n");        return GL_FALSE;     } -   else -      rmesa->TexGenEnabled |= RADEON_TEXGEN_TEXMAT_0_ENABLE << unit; + +   if ((texUnit->TexGenEnabled & (R_BIT | Q_BIT)) != 0) { +      /* need this here for vtxfmt presumably. Argh we need to set +         this from way too many places, would be much easier if we could leave +         tcl q coord always enabled as on r200) */ +      RADEON_STATECHANGE( rmesa, tcl ); +      if (unit == 0) +	 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_Q0; +      else +	 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_Q1; +   }     switch (texUnit->GenModeS) {     case GL_OBJECT_LINEAR:        rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_OBJ << inputshift; -      set_texgen_matrix( rmesa, unit,  +      set_texgen_matrix( rmesa, unit,  			 texUnit->ObjectPlaneS, -			 texUnit->ObjectPlaneT); +			 texUnit->ObjectPlaneT, +			 texUnit->ObjectPlaneR, +			 texUnit->ObjectPlaneQ);        break;     case GL_EYE_LINEAR:        rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE << inputshift; -      set_texgen_matrix( rmesa, unit,  +      set_texgen_matrix( rmesa, unit,  			 texUnit->EyePlaneS, -			 texUnit->EyePlaneT); +			 texUnit->EyePlaneT, +			 texUnit->EyePlaneR, +			 texUnit->EyePlaneQ);        break;     case GL_REFLECTION_MAP_NV:        rmesa->TexGenNeedNormals[unit] = GL_TRUE; -      rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_REFLECT<<inputshift; +      rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_REFLECT << inputshift; +      /* TODO: unknown if this is needed/correct */ +      set_texgen_matrix( rmesa, unit, reflect, reflect + 4, +			reflect + 8, reflect + 12 );        break;     case GL_NORMAL_MAP_NV:        rmesa->TexGenNeedNormals[unit] = GL_TRUE; -      rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_NORMAL<<inputshift; +      rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_NORMAL << inputshift;        break;     case GL_SPHERE_MAP: +      /* the mode which everyone uses :-( */     default:        /* Unsupported mode, fallback:         */ @@ -1131,11 +1174,7 @@ static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit )  {     struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; -   TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_TEXRECT_0 << unit, 0 ); -     if ( texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT) ) { -      TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_TEXRECT_0 << unit, 1 ); -        return (enable_tex_rect( ctx, unit ) &&  	      update_tex_common( ctx, unit ));     }  | 
