summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.c6
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.h5
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_maos_arrays.c43
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h24
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_maos_verts.c28
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_state.c167
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_state.h4
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_tcl.c6
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_tcl.h3
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texstate.c113
10 files changed, 299 insertions, 100 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 (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
- /* Need to preconcatenate any active texgen
- * obj/eyeplane matrices:
- */
- _math_matrix_mul_matrix( &rmesa->tmpmat,
+ 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[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;
-
- rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit);
- rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit);
- rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift);
+ 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->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 ));
}