Index: radeon_context.c =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/radeon/radeon_context.c,v retrieving revision 1.43 diff -u -r1.43 radeon_context.c --- radeon_context.c 13 Oct 2005 14:30:20 -0000 1.43 +++ radeon_context.c 13 Oct 2005 18:33:53 -0000 @@ -69,7 +69,7 @@ #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 @@ 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 @@ } 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" ); Index: radeon_context.h =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/radeon/radeon_context.h,v retrieving revision 1.26 diff -u -r1.26 radeon_context.h --- radeon_context.h 13 Oct 2005 14:30:20 -0000 1.26 +++ radeon_context.h 13 Oct 2005 18:33:56 -0000 @@ -264,6 +264,16 @@ #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_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]; Index: radeon_ioctl.c =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/radeon/radeon_ioctl.c,v retrieving revision 1.28 diff -u -r1.28 radeon_ioctl.c --- radeon_ioctl.c 11 Oct 2005 17:55:54 -0000 1.28 +++ radeon_ioctl.c 13 Oct 2005 18:33:58 -0000 @@ -152,6 +152,7 @@ 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); Index: radeon_screen.c =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/radeon/radeon_screen.c,v retrieving revision 1.43 diff -u -r1.43 radeon_screen.c --- radeon_screen.c 13 Oct 2005 14:30:20 -0000 1.43 +++ radeon_screen.c 13 Oct 2005 18:34:03 -0000 @@ -262,6 +262,7 @@ fprintf(stderr, "drm_radeon_getparam_t (RADEON_PARAM_IRQ_NR): %d\n", ret); return NULL; } + screen->drmSupportsCubeMaps = (sPriv->drmMinor >= 15); } } Index: radeon_screen.h =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/radeon/radeon_screen.h,v retrieving revision 1.14 diff -u -r1.14 radeon_screen.h --- radeon_screen.h 4 May 2005 20:11:38 -0000 1.14 +++ radeon_screen.h 13 Oct 2005 18:34:03 -0000 @@ -98,6 +98,7 @@ /* Configuration cache with default values for all contexts */ driOptionCache optionCache; + GLboolean drmSupportsCubeMaps; } radeonScreenRec, *radeonScreenPtr; #endif /* __RADEON_SCREEN_H__ */ Index: radeon_state.c =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/radeon/radeon_state.c,v retrieving revision 1.37 diff -u -r1.37 radeon_state.c --- radeon_state.c 13 Oct 2005 14:30:20 -0000 1.37 +++ radeon_state.c 13 Oct 2005 18:34:07 -0000 @@ -2098,7 +2098,6 @@ } } else { - /* never used currently - no swapping needed at all presumably */ for (i = 0 ; i < 4 ; i++) { *dest++ = src[i]; *dest++ = src[i+4]; Index: radeon_state_init.c =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/radeon/radeon_state_init.c,v retrieving revision 1.16 diff -u -r1.16 radeon_state_init.c --- radeon_state_init.c 13 Oct 2005 14:30:20 -0000 1.16 +++ radeon_state_init.c 13 Oct 2005 18:34:08 -0000 @@ -113,9 +113,13 @@ 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 ) +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 +237,18 @@ 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 +293,12 @@ 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 +510,18 @@ 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 Index: radeon_swtcl.c =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/radeon/radeon_swtcl.c,v retrieving revision 1.24 diff -u -r1.24 radeon_swtcl.c --- radeon_swtcl.c 13 Oct 2005 14:30:20 -0000 1.24 +++ radeon_swtcl.c 13 Oct 2005 18:34:10 -0000 @@ -184,13 +184,18 @@ 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; Index: radeon_tex.c =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/radeon/radeon_tex.c,v retrieving revision 1.15 diff -u -r1.15 radeon_tex.c --- radeon_tex.c 7 Oct 2004 23:30:30 -0000 1.15 +++ radeon_tex.c 13 Oct 2005 18:34:14 -0000 @@ -174,7 +174,24 @@ 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 @@ } 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) ); } Index: radeon_texmem.c =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/radeon/radeon_texmem.c,v retrieving revision 1.12 diff -u -r1.12 radeon_texmem.c --- radeon_texmem.c 25 Aug 2005 03:38:07 -0000 1.12 +++ radeon_texmem.c 13 Oct 2005 18:34:14 -0000 @@ -68,6 +68,7 @@ if ( t == rmesa->state.texture.unit[i].texobj ) { rmesa->state.texture.unit[i].texobj = NULL; rmesa->hw.tex[i].dirty = GL_FALSE; + rmesa->hw.cube[i].dirty = GL_FALSE; } } } @@ -226,7 +227,7 @@ 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; Index: radeon_texstate.c =================================================================== RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/radeon/radeon_texstate.c,v retrieving revision 1.21 diff -u -r1.21 radeon_texstate.c --- radeon_texstate.c 13 Oct 2005 14:30:20 -0000 1.21 +++ radeon_texstate.c 13 Oct 2005 18:34:16 -0000 @@ -153,7 +153,13 @@ /* 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 @@ */ 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 @@ 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 @@ 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<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 +1266,10 @@ 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; }