summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Scheidegger <[email protected]>2005-10-15 23:45:53 +0000
committerRoland Scheidegger <[email protected]>2005-10-15 23:45:53 +0000
commit247f3b3e81fffa86c50531070fab573e26ffb452 (patch)
tree7656b736e6faf1b4d31722752c0634927f23c17c
parentccf13781319b5b9d7ba306728f74b4ae2d099ad0 (diff)
enable cube maps on radeon (#2241 on bugzilla). No vtxfmt code yet (just generates vfmt fallback). Code by Andreas Stenglein, some small adjustments by me.
-rw-r--r--docs/VERSIONS1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.c6
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.h11
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_ioctl.c1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_maos_arrays.c4
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_maos_verts.c3
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.c1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.h1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_state.c1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_state_init.c37
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_swtcl.c11
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_tex.c21
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texmem.c3
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texstate.c120
14 files changed, 202 insertions, 19 deletions
diff --git a/docs/VERSIONS b/docs/VERSIONS
index 315fd3ddbc6..58ec9edff25 100644
--- a/docs/VERSIONS
+++ b/docs/VERSIONS
@@ -1383,6 +1383,7 @@ Mesa Version History
- GL_EXT_timer_query extension
- r200: add support for GL_ATI_fragment_shader
- added fast XOR-mode line drawing optimization
+ - radeon: add support for all 3 tmus and cube maps
Changes:
- removed GL_HP_occlusion_test (use GL_ARB_occlusion_query instead)
Bug fixes:
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c
index 9ab6e676780..a1e3582415c 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_context.c
@@ -69,7 +69,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define need_GL_EXT_secondary_color
#include "extension_helper.h"
-#define DRIVER_DATE "20051008"
+#define DRIVER_DATE "20051013"
#include "vblank.h"
#include "utils.h"
@@ -338,7 +338,7 @@ radeonCreateContext( const __GLcontextModes *glVisual,
4,
11, /* max 2D texture size is 2048x2048 */
0, /* 3D textures unsupported. */
- 0, /* cube textures unsupported. */
+ 9, /* \todo: max cube texture size seems to be 512x512(x6) */
11, /* max rect texture size is 2048x2048. */
12,
GL_FALSE );
@@ -412,6 +412,8 @@ radeonCreateContext( const __GLcontextModes *glVisual,
}
driInitExtensions( ctx, card_extensions, GL_TRUE );
+ if (rmesa->radeonScreen->drmSupportsCubeMaps)
+ _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" );
if (rmesa->glCtx->Mesa_DXTn) {
_mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
_mesa_enable_extension( ctx, "GL_S3_s3tc" );
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h
index 09bb96861ee..d6dc9c46ed4 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.h
+++ b/src/mesa/drivers/dri/radeon/radeon_context.h
@@ -264,6 +264,16 @@ struct radeon_state_atom {
#define TXR_PP_TEX_PITCH 2 /* 0x1d08, 0x1d10 for NPOT! */
#define TXR_STATE_SIZE 3
+#define CUBE_CMD_0 0
+#define CUBE_PP_CUBIC_FACES 1
+#define CUBE_CMD_1 2
+#define CUBE_PP_CUBIC_OFFSET_0 3
+#define CUBE_PP_CUBIC_OFFSET_1 4
+#define CUBE_PP_CUBIC_OFFSET_2 5
+#define CUBE_PP_CUBIC_OFFSET_3 6
+#define CUBE_PP_CUBIC_OFFSET_4 7
+#define CUBE_STATE_SIZE 8
+
#define ZBS_CMD_0 0
#define ZBS_SE_ZBIAS_FACTOR 1
#define ZBS_SE_ZBIAS_CONSTANT 2
@@ -415,6 +425,7 @@ struct radeon_hw_state {
struct radeon_state_atom tcl;
struct radeon_state_atom msc;
struct radeon_state_atom tex[3];
+ struct radeon_state_atom cube[3];
struct radeon_state_atom zbs;
struct radeon_state_atom mtl;
struct radeon_state_atom mat[6];
diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c
index 1cf5340b9cb..37a619c2450 100644
--- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c
@@ -152,6 +152,7 @@ void radeonSetUpAtomList( radeonContextPtr rmesa )
for (i = 0; i < mtu; ++i) {
insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.tex[i]);
insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.txr[i]);
+ insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.cube[i]);
}
insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.zbs);
insert_at_tail(&rmesa->hw.atomlist, &rmesa->hw.mtl);
diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c b/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c
index 1602464011a..76ad1f3cd4b 100644
--- a/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c
+++ b/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c
@@ -542,13 +542,13 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs )
/* 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[unit]->size >= 3) {
- /* tcl_vtx and vc_frmt values are identical */
vtx |= RADEON_Q_BIT(unit);
vfmt |= RADEON_Q_BIT(unit);
}
if ( (ctx->Texture.Unit[unit].TexGenEnabled & (R_BIT | Q_BIT)) )
vtx |= RADEON_Q_BIT(unit);
- else if (VB->TexCoordPtr[unit]->size >= 3) {
+ else if ((VB->TexCoordPtr[unit]->size >= 3) &&
+ ((ctx->Texture.Unit[unit]._ReallyEnabled & (TEXTURE_CUBE_BIT)) == 0)) {
GLuint swaptexmatcol = (VB->TexCoordPtr[unit]->size - 3);
if (((rmesa->NeedTexMatrix >> unit) & 1) &&
(swaptexmatcol != ((rmesa->TexMatColSwap >> unit) & 1)))
diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_verts.c b/src/mesa/drivers/dri/radeon/radeon_maos_verts.c
index 57aa90321cf..24e681c8c09 100644
--- a/src/mesa/drivers/dri/radeon/radeon_maos_verts.c
+++ b/src/mesa/drivers/dri/radeon/radeon_maos_verts.c
@@ -352,7 +352,8 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs )
}
if ( (ctx->Texture.Unit[unit].TexGenEnabled & (R_BIT | Q_BIT)) )
vtx |= RADEON_Q_BIT(unit);
- else if (VB->TexCoordPtr[unit]->size >= 3) {
+ else if ((VB->TexCoordPtr[unit]->size >= 3) &&
+ ((ctx->Texture.Unit[unit]._ReallyEnabled & (TEXTURE_CUBE_BIT)) == 0)) {
GLuint swaptexmatcol = (VB->TexCoordPtr[unit]->size - 3);
if (((rmesa->NeedTexMatrix >> unit) & 1) &&
(swaptexmatcol != ((rmesa->TexMatColSwap >> unit) & 1)))
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index c79f406f68a..9a552c2c120 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -262,6 +262,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_IRQ_NR): %d\n", ret);
return NULL;
}
+ screen->drmSupportsCubeMaps = (sPriv->drmMinor >= 15);
}
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.h b/src/mesa/drivers/dri/radeon/radeon_screen.h
index b9cbeaac335..0bf88d98416 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.h
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.h
@@ -98,6 +98,7 @@ typedef struct {
/* Configuration cache with default values for all contexts */
driOptionCache optionCache;
+ GLboolean drmSupportsCubeMaps;
} radeonScreenRec, *radeonScreenPtr;
#endif /* __RADEON_SCREEN_H__ */
diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c
index a79fefee502..28033881c5e 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state.c
+++ b/src/mesa/drivers/dri/radeon/radeon_state.c
@@ -2098,7 +2098,6 @@ void radeonUploadTexMatrix( radeonContextPtr rmesa,
}
}
else {
- /* never used currently - no swapping needed at all presumably */
for (i = 0 ; i < 4 ; i++) {
*dest++ = src[i];
*dest++ = src[i+4];
diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c
index 7e7dc0f7823..6e538a29732 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state_init.c
+++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c
@@ -113,9 +113,14 @@ static GLboolean check_##NM( GLcontext *ctx ) \
CHECK( always, GL_TRUE )
+CHECK( never, GL_FALSE )
CHECK( tex0, ctx->Texture.Unit[0]._ReallyEnabled )
CHECK( tex1, ctx->Texture.Unit[1]._ReallyEnabled )
-CHECK( tex2, ctx->Texture.Unit[2]._ReallyEnabled )
+/* need this for the cubic_map on disabled unit 2 bug, maybe r100 only? */
+CHECK( tex2, ctx->Texture._EnabledUnits )
+CHECK( cube0, (ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_CUBE_BIT))
+CHECK( cube1, (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_CUBE_BIT))
+CHECK( cube2, (ctx->Texture.Unit[2]._ReallyEnabled & TEXTURE_CUBE_BIT))
CHECK( fog, ctx->Fog.Enabled )
TCL_CHECK( tcl, GL_TRUE )
TCL_CHECK( tcl_tex0, ctx->Texture.Unit[0]._ReallyEnabled )
@@ -233,6 +238,18 @@ void radeonInitState( radeonContextPtr rmesa )
ALLOC_STATE( tex[0], tex0, TEX_STATE_SIZE, "TEX/tex-0", 0 );
ALLOC_STATE( tex[1], tex1, TEX_STATE_SIZE, "TEX/tex-1", 0 );
ALLOC_STATE( tex[2], tex2, TEX_STATE_SIZE, "TEX/tex-2", 0 );
+ if (rmesa->radeonScreen->drmSupportsCubeMaps)
+ {
+ ALLOC_STATE( cube[0], cube0, CUBE_STATE_SIZE, "CUBE/cube-0", 0 );
+ ALLOC_STATE( cube[1], cube1, CUBE_STATE_SIZE, "CUBE/cube-1", 0 );
+ ALLOC_STATE( cube[2], cube2, CUBE_STATE_SIZE, "CUBE/cube-2", 0 );
+ }
+ else
+ {
+ ALLOC_STATE( cube[0], never, CUBE_STATE_SIZE, "CUBE/cube-0", 0 );
+ ALLOC_STATE( cube[1], never, CUBE_STATE_SIZE, "CUBE/cube-1", 0 );
+ ALLOC_STATE( cube[2], never, CUBE_STATE_SIZE, "CUBE/cube-2", 0 );
+ }
ALLOC_STATE( mat[0], tcl, MAT_STATE_SIZE, "MAT/modelproject", 1 );
ALLOC_STATE( mat[1], tcl_eyespace_or_fog, MAT_STATE_SIZE, "MAT/modelview", 1 );
ALLOC_STATE( mat[2], tcl_eyespace_or_lighting, MAT_STATE_SIZE, "MAT/it-modelview", 1 );
@@ -277,6 +294,12 @@ void radeonInitState( radeonContextPtr rmesa )
rmesa->hw.tex[1].cmd[TEX_CMD_1] = cmdpkt(RADEON_EMIT_PP_BORDER_COLOR_1);
rmesa->hw.tex[2].cmd[TEX_CMD_0] = cmdpkt(RADEON_EMIT_PP_TXFILTER_2);
rmesa->hw.tex[2].cmd[TEX_CMD_1] = cmdpkt(RADEON_EMIT_PP_BORDER_COLOR_2);
+ rmesa->hw.cube[0].cmd[CUBE_CMD_0] = cmdpkt(RADEON_EMIT_PP_CUBIC_FACES_0);
+ rmesa->hw.cube[0].cmd[CUBE_CMD_1] = cmdpkt(RADEON_EMIT_PP_CUBIC_OFFSETS_T0);
+ rmesa->hw.cube[1].cmd[CUBE_CMD_0] = cmdpkt(RADEON_EMIT_PP_CUBIC_FACES_1);
+ rmesa->hw.cube[1].cmd[CUBE_CMD_1] = cmdpkt(RADEON_EMIT_PP_CUBIC_OFFSETS_T1);
+ rmesa->hw.cube[2].cmd[CUBE_CMD_0] = cmdpkt(RADEON_EMIT_PP_CUBIC_FACES_2);
+ rmesa->hw.cube[2].cmd[CUBE_CMD_1] = cmdpkt(RADEON_EMIT_PP_CUBIC_OFFSETS_T2);
rmesa->hw.zbs.cmd[ZBS_CMD_0] = cmdpkt(RADEON_EMIT_SE_ZBIAS_FACTOR);
rmesa->hw.tcl.cmd[TCL_CMD_0] = cmdpkt(RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT);
rmesa->hw.mtl.cmd[MTL_CMD_0] =
@@ -488,6 +511,18 @@ void radeonInitState( radeonContextPtr rmesa )
RADEON_SCALE_1X |
RADEON_CLAMP_TX);
rmesa->hw.tex[i].cmd[TEX_PP_TFACTOR] = 0;
+
+ rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_FACES] = 0;
+ rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_0] =
+ rmesa->radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP];
+ rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_1] =
+ rmesa->radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP];
+ rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_2] =
+ rmesa->radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP];
+ rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_3] =
+ rmesa->radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP];
+ rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_4] =
+ rmesa->radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP];
}
/* Can only add ST1 at the time of doing some multitex but can keep
diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.c b/src/mesa/drivers/dri/radeon/radeon_swtcl.c
index 7200f71ef6b..7a97cf0ce60 100644
--- a/src/mesa/drivers/dri/radeon/radeon_swtcl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.c
@@ -184,13 +184,18 @@ static void radeonSetVertexFormat( GLcontext *ctx )
switch (sz) {
case 1:
case 2:
- case 3:
EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_2F,
radeon_cp_vc_frmts[i][0] );
break;
+ case 3:
case 4:
- EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_3F_XYW,
- radeon_cp_vc_frmts[i][1] );
+ if (ctx->Texture.Unit[i]._ReallyEnabled & (TEXTURE_CUBE_BIT) ) {
+ EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_3F,
+ radeon_cp_vc_frmts[i][1] );
+ } else {
+ EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_3F_XYW,
+ radeon_cp_vc_frmts[i][1] );
+ }
break;
default:
continue;
diff --git a/src/mesa/drivers/dri/radeon/radeon_tex.c b/src/mesa/drivers/dri/radeon/radeon_tex.c
index c466af868c4..46ca86bde26 100644
--- a/src/mesa/drivers/dri/radeon/radeon_tex.c
+++ b/src/mesa/drivers/dri/radeon/radeon_tex.c
@@ -174,7 +174,24 @@ static void radeonSetTexFilter( radeonTexObjPtr t, GLenum minf, GLenum magf )
t->pp_txfilter &= ~(RADEON_MIN_FILTER_MASK | RADEON_MAG_FILTER_MASK);
- if ( anisotropy == RADEON_MAX_ANISO_1_TO_1 ) {
+ /* r100 chips can't handle mipmaps/aniso for cubemap/volume textures */
+ if ( t->base.tObj->Target == GL_TEXTURE_CUBE_MAP ) {
+ switch ( minf ) {
+ case GL_NEAREST:
+ case GL_NEAREST_MIPMAP_NEAREST:
+ case GL_NEAREST_MIPMAP_LINEAR:
+ t->pp_txfilter |= RADEON_MIN_FILTER_NEAREST;
+ break;
+ case GL_LINEAR:
+ case GL_LINEAR_MIPMAP_NEAREST:
+ case GL_LINEAR_MIPMAP_LINEAR:
+ t->pp_txfilter |= RADEON_MIN_FILTER_LINEAR;
+ break;
+ default:
+ break;
+ }
+ }
+ else if ( anisotropy == RADEON_MAX_ANISO_1_TO_1 ) {
switch ( minf ) {
case GL_NEAREST:
t->pp_txfilter |= RADEON_MIN_FILTER_NEAREST;
@@ -774,7 +791,7 @@ static void radeonBindTexture( GLcontext *ctx, GLenum target,
}
assert( (target != GL_TEXTURE_1D && target != GL_TEXTURE_2D &&
- target != GL_TEXTURE_RECTANGLE_NV) ||
+ target != GL_TEXTURE_RECTANGLE_NV && target != GL_TEXTURE_CUBE_MAP) ||
(texObj->DriverData != NULL) );
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_texmem.c b/src/mesa/drivers/dri/radeon/radeon_texmem.c
index 3943afcde0b..e2766713b2f 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texmem.c
+++ b/src/mesa/drivers/dri/radeon/radeon_texmem.c
@@ -67,7 +67,6 @@ radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t )
for ( i = 0 ; i < rmesa->glCtx->Const.MaxTextureUnits ; i++ ) {
if ( t == rmesa->state.texture.unit[i].texobj ) {
rmesa->state.texture.unit[i].texobj = NULL;
- rmesa->hw.tex[i].dirty = GL_FALSE;
}
}
}
@@ -226,7 +225,7 @@ static void uploadSubImage( radeonContextPtr rmesa, radeonTexObjPtr t,
imageWidth = texImage->Width;
imageHeight = texImage->Height;
- offset = t->bufAddr;
+ offset = t->bufAddr + t->base.totalSize * face / 6;
if ( RADEON_DEBUG & (DEBUG_TEXTURE|DEBUG_IOCTL) ) {
GLint imageX = 0;
diff --git a/src/mesa/drivers/dri/radeon/radeon_texstate.c b/src/mesa/drivers/dri/radeon/radeon_texstate.c
index fe5445bf626..ccf08850c2a 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texstate.c
+++ b/src/mesa/drivers/dri/radeon/radeon_texstate.c
@@ -153,7 +153,13 @@ static void radeonSetTexImages( radeonContextPtr rmesa,
/* Compute which mipmap levels we really want to send to the hardware.
*/
- driCalculateTextureFirstLastLevel( (driTextureObject *) t );
+ if (tObj->Target != GL_TEXTURE_CUBE_MAP)
+ driCalculateTextureFirstLastLevel( (driTextureObject *) t );
+ else {
+ /* r100 can't handle mipmaps for cube/3d textures, so don't waste
+ memory for them */
+ t->base.firstLevel = t->base.lastLevel = tObj->BaseLevel;
+ }
log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;
log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;
log2Depth = tObj->Image[0][t->base.firstLevel]->DepthLog2;
@@ -284,6 +290,22 @@ static void radeonSetTexImages( radeonContextPtr rmesa,
*/
t->base.totalSize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
+ /* Setup remaining cube face blits, if needed */
+ if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
+ const GLuint faceSize = t->base.totalSize;
+ GLuint face;
+ /* reuse face 0 x/y/width/height - just update the offset when uploading */
+ for (face = 1; face < 6; face++) {
+ for (i = 0; i < numLevels; i++) {
+ t->image[face][i].x = t->image[0][i].x;
+ t->image[face][i].y = t->image[0][i].y;
+ t->image[face][i].width = t->image[0][i].width;
+ t->image[face][i].height = t->image[0][i].height;
+ }
+ }
+ t->base.totalSize = 6 * faceSize; /* total texmem needed */
+ }
+
/* Hardware state:
*/
t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK;
@@ -291,10 +313,27 @@ static void radeonSetTexImages( radeonContextPtr rmesa,
t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK |
RADEON_TXFORMAT_HEIGHT_MASK |
- RADEON_TXFORMAT_CUBIC_MAP_ENABLE);
+ RADEON_TXFORMAT_CUBIC_MAP_ENABLE |
+ RADEON_TXFORMAT_F5_WIDTH_MASK |
+ RADEON_TXFORMAT_F5_HEIGHT_MASK);
t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) |
(log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT));
+ if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
+ assert(log2Width == log2Height);
+ t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_F5_WIDTH_SHIFT) |
+ (log2Height << RADEON_TXFORMAT_F5_HEIGHT_SHIFT) |
+ (RADEON_TXFORMAT_CUBIC_MAP_ENABLE));
+ t->pp_cubic_faces = ((log2Width << RADEON_FACE_WIDTH_1_SHIFT) |
+ (log2Height << RADEON_FACE_HEIGHT_1_SHIFT) |
+ (log2Width << RADEON_FACE_WIDTH_2_SHIFT) |
+ (log2Height << RADEON_FACE_HEIGHT_2_SHIFT) |
+ (log2Width << RADEON_FACE_WIDTH_3_SHIFT) |
+ (log2Height << RADEON_FACE_HEIGHT_3_SHIFT) |
+ (log2Width << RADEON_FACE_WIDTH_4_SHIFT) |
+ (log2Height << RADEON_FACE_HEIGHT_4_SHIFT));
+ }
+
t->pp_txsize = (((tObj->Image[0][t->base.firstLevel]->Width - 1) << 0) |
((tObj->Image[0][t->base.firstLevel]->Height - 1) << 16));
@@ -816,15 +855,33 @@ static void import_tex_obj_state( radeonContextPtr rmesa,
cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK;
cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset;
cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
- RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tex[unit] );
- if (texobj->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
+ if (texobj->base.tObj->Target == GL_TEXTURE_CUBE_MAP) {
+ GLuint *cube_cmd = RADEON_DB_STATE( cube[unit] );
+ GLuint bytesPerFace = texobj->base.totalSize / 6;
+ ASSERT(texobj->totalSize % 6 == 0);
+
+ cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
+ /* dont know if this setup conforms to OpenGL..
+ * at least it matches the behavior of mesa software renderer
+ */
+ cube_cmd[CUBE_PP_CUBIC_OFFSET_0] = texobj->pp_txoffset; /* right */
+ cube_cmd[CUBE_PP_CUBIC_OFFSET_1] = texobj->pp_txoffset + 1 * bytesPerFace; /* left */
+ cube_cmd[CUBE_PP_CUBIC_OFFSET_2] = texobj->pp_txoffset + 2 * bytesPerFace; /* top */
+ cube_cmd[CUBE_PP_CUBIC_OFFSET_3] = texobj->pp_txoffset + 3 * bytesPerFace; /* bottom */
+ cube_cmd[CUBE_PP_CUBIC_OFFSET_4] = texobj->pp_txoffset + 4 * bytesPerFace; /* front */
+ RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.cube[unit] );
+ cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset + 5 * bytesPerFace; /* back */
+ }
+ else if (texobj->base.tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
GLuint *txr_cmd = RADEON_DB_STATE( txr[unit] );
txr_cmd[TXR_PP_TEX_SIZE] = texobj->pp_txsize; /* NPOT only! */
txr_cmd[TXR_PP_TEX_PITCH] = texobj->pp_txpitch; /* NPOT only! */
RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.txr[unit] );
}
+ RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tex[unit] );
+
texobj->dirty_state &= ~(1<<unit);
}
@@ -1002,7 +1059,14 @@ static void disable_tex( GLcontext *ctx, int unit )
rmesa->recheck_texgen[unit] = GL_TRUE;
}
-
+ if (rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) {
+ /* this seems to be a genuine (r100 only?) hw bug. Need to remove the
+ cubic_map bit on unit 2 when the unit is disabled, otherwise every
+ 2nd (2d) mipmap on unit 0 will be broken (may not be needed for other
+ units, better be safe than sorry though).*/
+ RADEON_STATECHANGE( rmesa, tex[unit] );
+ rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &= ~RADEON_TXFORMAT_CUBIC_MAP_ENABLE;
+ }
{
GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
@@ -1050,6 +1114,48 @@ static GLboolean enable_tex_2d( GLcontext *ctx, int unit )
return GL_TRUE;
}
+static GLboolean enable_tex_cube( GLcontext *ctx, int unit )
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ struct gl_texture_object *tObj = texUnit->_Current;
+ radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
+ GLuint face;
+
+ /* Need to load the 2d images associated with this unit.
+ */
+ if (t->pp_txformat & RADEON_TXFORMAT_NON_POWER2) {
+ t->pp_txformat &= ~RADEON_TXFORMAT_NON_POWER2;
+ for (face = 0; face < 6; face++)
+ t->base.dirty_images[face] = ~0;
+ }
+
+ ASSERT(tObj->Target == GL_TEXTURE_CUBE_MAP);
+
+ if ( t->base.dirty_images[0] || t->base.dirty_images[1] ||
+ t->base.dirty_images[2] || t->base.dirty_images[3] ||
+ t->base.dirty_images[4] || t->base.dirty_images[5] ) {
+ /* flush */
+ RADEON_FIREVERTICES( rmesa );
+ /* layout memory space, once for all faces */
+ radeonSetTexImages( rmesa, tObj );
+ }
+
+ /* upload (per face) */
+ for (face = 0; face < 6; face++) {
+ if (t->base.dirty_images[face]) {
+ radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, face );
+ }
+ }
+
+ if ( !t->base.memBlock ) {
+ /* texmem alloc failed, use s/w fallback */
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
static GLboolean enable_tex_rect( GLcontext *ctx, int unit )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
@@ -1167,6 +1273,10 @@ static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit )
return (enable_tex_2d( ctx, unit ) &&
update_tex_common( ctx, unit ));
}
+ else if ( texUnit->_ReallyEnabled & (TEXTURE_CUBE_BIT) ) {
+ return (enable_tex_cube( ctx, unit ) &&
+ update_tex_common( ctx, unit ));
+ }
else if ( texUnit->_ReallyEnabled ) {
return GL_FALSE;
}