mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-04 04:50:11 +01:00
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.
This commit is contained in:
parent
ccf1378131
commit
247f3b3e81
14 changed files with 202 additions and 19 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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" );
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ typedef struct {
|
|||
|
||||
/* Configuration cache with default values for all contexts */
|
||||
driOptionCache optionCache;
|
||||
GLboolean drmSupportsCubeMaps;
|
||||
} radeonScreenRec, *radeonScreenPtr;
|
||||
|
||||
#endif /* __RADEON_SCREEN_H__ */
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue