X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmesa%2Fdrivers%2Fdri%2Fradeon%2Fradeon_texstate.c;h=3c28d70e3765dfcf480d8febac217fbfbf7edc01;hb=b584b0728d3a001a142f76dde22f9e8ed7d2dd16;hp=16682b1f64925e03a70363f2c277438737748b15;hpb=bb1dcb4fadb86ba89eeb2ba5e0ade3ead219ef67;p=mesa.git diff --git a/src/mesa/drivers/dri/radeon/radeon_texstate.c b/src/mesa/drivers/dri/radeon/radeon_texstate.c index 16682b1f649..3c28d70e376 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texstate.c +++ b/src/mesa/drivers/dri/radeon/radeon_texstate.c @@ -1,4 +1,3 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_texstate.c,v 1.6 2002/12/16 16:18:59 dawes Exp $ */ /************************************************************************** Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and @@ -34,15 +33,17 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * Gareth Hughes */ -#include "glheader.h" -#include "imports.h" -#include "colormac.h" -#include "context.h" -#include "macros.h" -#include "texformat.h" -#include "enums.h" +#include "main/glheader.h" +#include "main/imports.h" +#include "main/colormac.h" +#include "main/context.h" +#include "main/macros.h" +#include "main/texformat.h" +#include "main/texobj.h" +#include "main/enums.h" #include "radeon_context.h" +#include "radeon_mipmap_tree.h" #include "radeon_state.h" #include "radeon_ioctl.h" #include "radeon_swtcl.h" @@ -50,39 +51,62 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_tcl.h" +#define RADEON_TXFORMAT_A8 RADEON_TXFORMAT_I8 +#define RADEON_TXFORMAT_L8 RADEON_TXFORMAT_I8 #define RADEON_TXFORMAT_AL88 RADEON_TXFORMAT_AI88 #define RADEON_TXFORMAT_YCBCR RADEON_TXFORMAT_YVYU422 #define RADEON_TXFORMAT_YCBCR_REV RADEON_TXFORMAT_VYUY422 +#define RADEON_TXFORMAT_RGB_DXT1 RADEON_TXFORMAT_DXT1 +#define RADEON_TXFORMAT_RGBA_DXT1 RADEON_TXFORMAT_DXT1 +#define RADEON_TXFORMAT_RGBA_DXT3 RADEON_TXFORMAT_DXT23 +#define RADEON_TXFORMAT_RGBA_DXT5 RADEON_TXFORMAT_DXT45 #define _COLOR(f) \ [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, 0 } +#define _COLOR_REV(f) \ + [ MESA_FORMAT_ ## f ## _REV ] = { RADEON_TXFORMAT_ ## f, 0 } #define _ALPHA(f) \ [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 } +#define _ALPHA_REV(f) \ + [ MESA_FORMAT_ ## f ## _REV ] = { RADEON_TXFORMAT_ ## f | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 } #define _YUV(f) \ [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, RADEON_YUV_TO_RGB } #define _INVALID(f) \ [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 } -#define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_YCBCR_REV) \ +#define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \ && (tx_table[f].format != 0xffffffff) ) -static const struct { +struct tx_table { GLuint format, filter; -} -tx_table[] = +}; + +static const struct tx_table tx_table[] = { _ALPHA(RGBA8888), + _ALPHA_REV(RGBA8888), _ALPHA(ARGB8888), - _INVALID(RGB888), + _ALPHA_REV(ARGB8888), + [ MESA_FORMAT_RGB888 ] = { RADEON_TXFORMAT_ARGB8888, 0 }, _COLOR(RGB565), + _COLOR_REV(RGB565), _ALPHA(ARGB4444), + _ALPHA_REV(ARGB4444), _ALPHA(ARGB1555), + _ALPHA_REV(ARGB1555), _ALPHA(AL88), - _INVALID(A8), - _INVALID(L8), - _COLOR(I8), + _ALPHA_REV(AL88), + _ALPHA(A8), + _COLOR(L8), + _ALPHA(I8), _INVALID(CI8), _YUV(YCBCR), _YUV(YCBCR_REV), + _INVALID(RGB_FXT1), + _INVALID(RGBA_FXT1), + _COLOR(RGB_DXT1), + _ALPHA(RGBA_DXT1), + _ALPHA(RGBA_DXT3), + _ALPHA(RGBA_DXT5), }; #undef _COLOR @@ -100,37 +124,46 @@ tx_table[] = * \param tObj GL texture object whose images are to be posted to * hardware state. */ -static void radeonSetTexImages( radeonContextPtr rmesa, +#if 0 +static void radeonSetTexImages( r100ContextPtr rmesa, struct gl_texture_object *tObj ) { radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData; const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel]; - GLint curOffset; - GLint i; + GLint curOffset, blitWidth; + GLint i, texelBytes; GLint numLevels; GLint log2Width, log2Height, log2Depth; /* Set the hardware texture format */ - - t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK | - RADEON_TXFORMAT_ALPHA_IN_MAP); - t->pp_txfilter &= ~RADEON_YUV_TO_RGB; - - if ( VALID_FORMAT( baseImage->TexFormat->MesaFormat ) ) { - t->pp_txformat |= tx_table[ baseImage->TexFormat->MesaFormat ].format; - t->pp_txfilter |= tx_table[ baseImage->TexFormat->MesaFormat ].filter; - } - else { - _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__); - return; + if ( !t->image_override ) { + t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK | + RADEON_TXFORMAT_ALPHA_IN_MAP); + t->pp_txfilter &= ~RADEON_YUV_TO_RGB; + + if ( VALID_FORMAT( baseImage->TexFormat->MesaFormat ) ) { + t->pp_txformat |= tx_table[ baseImage->TexFormat->MesaFormat ].format; + t->pp_txfilter |= tx_table[ baseImage->TexFormat->MesaFormat ].filter; + } + else { + _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__); + return; + } } + texelBytes = baseImage->TexFormat->TexelBytes; /* 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; @@ -144,6 +177,34 @@ static void radeonSetTexImages( radeonContextPtr rmesa, * memory organized as a rectangle of width BLIT_WIDTH_BYTES. */ curOffset = 0; + blitWidth = BLIT_WIDTH_BYTES; + t->tile_bits = 0; + + /* figure out if this texture is suitable for tiling. */ + if (texelBytes && (tObj->Target != GL_TEXTURE_RECTANGLE_NV)) { + if (rmesa->texmicrotile && (baseImage->Height > 1)) { + /* allow 32 (bytes) x 1 mip (which will use two times the space + the non-tiled version would use) max if base texture is large enough */ + if ((numLevels == 1) || + (((baseImage->Width * texelBytes / baseImage->Height) <= 32) && + (baseImage->Width * texelBytes > 64)) || + ((baseImage->Width * texelBytes / baseImage->Height) <= 16)) { + /* R100 has two microtile bits (only the txoffset reg, not the blitter) + weird: X2 + OPT: 32bit correct, 16bit completely hosed + X2: 32bit correct, 16bit correct + OPT: 32bit large mips correct, small mips hosed, 16bit completely hosed */ + t->tile_bits |= RADEON_TXO_MICRO_TILE_X2 /*| RADEON_TXO_MICRO_TILE_OPT*/; + } + } + if ((baseImage->Width * texelBytes >= 256) && (baseImage->Height >= 16)) { + /* R100 disables macro tiling only if mip width is smaller than 256 bytes, and not + in the case if height is smaller than 16 (not 100% sure), as does the r200, + so need to disable macro tiling in that case */ + if ((numLevels == 1) || ((baseImage->Width * texelBytes / baseImage->Height) <= 4)) { + t->tile_bits |= RADEON_TXO_MACRO_TILE; + } + } + } for (i = 0; i < numLevels; i++) { const struct gl_texture_image *texImage; @@ -155,31 +216,61 @@ static void radeonSetTexImages( radeonContextPtr rmesa, /* find image size in bytes */ if (texImage->IsCompressed) { - size = texImage->CompressedSize; + /* need to calculate the size AFTER padding even though the texture is + submitted without padding. + Only handle pot textures currently - don't know if npot is even possible, + size calculation would certainly need (trivial) adjustments. + Align (and later pad) to 32byte, not sure what that 64byte blit width is + good for? */ + if ((t->pp_txformat & RADEON_TXFORMAT_FORMAT_MASK) == RADEON_TXFORMAT_DXT1) { + /* RGB_DXT1/RGBA_DXT1, 8 bytes per block */ + if ((texImage->Width + 3) < 8) /* width one block */ + size = texImage->CompressedSize * 4; + else if ((texImage->Width + 3) < 16) + size = texImage->CompressedSize * 2; + else size = texImage->CompressedSize; + } + else /* DXT3/5, 16 bytes per block */ + if ((texImage->Width + 3) < 8) + size = texImage->CompressedSize * 2; + else size = texImage->CompressedSize; } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) { - size = ((texImage->Width * texImage->TexFormat->TexelBytes + 63) - & ~63) * texImage->Height; + size = ((texImage->Width * texelBytes + 63) & ~63) * texImage->Height; + } + else if (t->tile_bits & RADEON_TXO_MICRO_TILE_X2) { + /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned, + though the actual offset may be different (if texture is less than + 32 bytes width) to the untiled case */ + int w = (texImage->Width * texelBytes * 2 + 31) & ~31; + size = (w * ((texImage->Height + 1) / 2)) * texImage->Depth; + blitWidth = MAX2(texImage->Width, 64 / texelBytes); } else { - int w = texImage->Width * texImage->TexFormat->TexelBytes; - if (w < 32) - w = 32; - size = w * texImage->Height * texImage->Depth; + int w = (texImage->Width * texelBytes + 31) & ~31; + size = w * texImage->Height * texImage->Depth; + blitWidth = MAX2(texImage->Width, 64 / texelBytes); } assert(size > 0); - /* Align to 32-byte offset. It is faster to do this unconditionally * (no branch penalty). */ curOffset = (curOffset + 0x1f) & ~0x1f; - t->image[0][i].x = curOffset % BLIT_WIDTH_BYTES; - t->image[0][i].y = curOffset / BLIT_WIDTH_BYTES; - t->image[0][i].width = MIN2(size, BLIT_WIDTH_BYTES); - t->image[0][i].height = size / t->image[0][i].width; + if (texelBytes) { + t->image[0][i].x = curOffset; /* fix x and y coords up later together with offset */ + t->image[0][i].y = 0; + t->image[0][i].width = MIN2(size / texelBytes, blitWidth); + t->image[0][i].height = (size / texelBytes) / t->image[0][i].width; + } + else { + t->image[0][i].x = curOffset % BLIT_WIDTH_BYTES; + t->image[0][i].y = curOffset / BLIT_WIDTH_BYTES; + t->image[0][i].width = MIN2(size, BLIT_WIDTH_BYTES); + t->image[0][i].height = size / t->image[0][i].width; + } #if 0 /* for debugging only and only applicable to non-rectangle targets */ @@ -203,6 +294,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; @@ -210,10 +317,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)); @@ -221,17 +345,19 @@ static void radeonSetTexImages( radeonContextPtr rmesa, * requires 64-byte aligned pitches, and we may/may not need the * blitter. NPOT only! */ - if (baseImage->IsCompressed) - t->pp_txpitch = (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63); - else - t->pp_txpitch = ((tObj->Image[0][t->base.firstLevel]->Width * baseImage->TexFormat->TexelBytes) + 63) & ~(63); - t->pp_txpitch -= 32; + if ( !t->image_override ) { + if (baseImage->IsCompressed) + t->pp_txpitch = (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63); + else + t->pp_txpitch = ((tObj->Image[0][t->base.firstLevel]->Width * texelBytes) + 63) & ~(63); + t->pp_txpitch -= 32; + } - t->dirty_state = TEX_ALL; + t->dirty_state = R100_TEX_ALL; /* FYI: radeonUploadTexImages( rmesa, t ); used to be called here */ } - +#endif /* ================================================================ @@ -380,9 +506,16 @@ do { \ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit ) { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + r100ContextPtr rmesa = R100_CONTEXT(ctx); const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; GLuint color_combine, alpha_combine; + const GLuint color_combine0 = RADEON_COLOR_ARG_A_ZERO | RADEON_COLOR_ARG_B_ZERO + | RADEON_COLOR_ARG_C_CURRENT_COLOR | RADEON_BLEND_CTL_ADD + | RADEON_SCALE_1X | RADEON_CLAMP_TX; + const GLuint alpha_combine0 = RADEON_ALPHA_ARG_A_ZERO | RADEON_ALPHA_ARG_B_ZERO + | RADEON_ALPHA_ARG_C_CURRENT_ALPHA | RADEON_BLEND_CTL_ADD + | RADEON_SCALE_1X | RADEON_CLAMP_TX; + /* texUnit->_Current can be NULL if and only if the texture unit is * not actually enabled. @@ -391,26 +524,24 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit ) || (texUnit->_Current != NULL) ); if ( RADEON_DEBUG & DEBUG_TEXTURE ) { - fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, ctx, unit ); + fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, (void *)ctx, unit ); } /* Set the texture environment state. Isn't this nice and clean? * The chip will automagically set the texture alpha to 0xff when - * the texture format does not include an alpha component. This + * the texture format does not include an alpha component. This * reduces the amount of special-casing we have to do, alpha-only - * textures being a notable exception. + * textures being a notable exception. Doesn't work for luminance + * textures realized with I8 and ALPHA_IN_MAP not set neither (on r100). + */ + /* Don't cache these results. */ + rmesa->state.texture.unit[unit].format = 0; + rmesa->state.texture.unit[unit].envMode = 0; + if ( !texUnit->_ReallyEnabled ) { - /* Don't cache these results. - */ - rmesa->state.texture.unit[unit].format = 0; - rmesa->state.texture.unit[unit].envMode = 0; - color_combine = RADEON_COLOR_ARG_A_ZERO | RADEON_COLOR_ARG_B_ZERO - | RADEON_COLOR_ARG_C_CURRENT_COLOR | RADEON_BLEND_CTL_ADD - | RADEON_SCALE_1X | RADEON_CLAMP_TX; - alpha_combine = RADEON_ALPHA_ARG_A_ZERO | RADEON_ALPHA_ARG_B_ZERO - | RADEON_ALPHA_ARG_C_CURRENT_ALPHA | RADEON_BLEND_CTL_ADD - | RADEON_SCALE_1X | RADEON_CLAMP_TX; + color_combine = color_combine0; + alpha_combine = alpha_combine0; } else { GLuint color_arg[3], alpha_arg[3]; @@ -420,22 +551,21 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit ) GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB; GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA; - /* Don't cache these results. - */ - rmesa->state.texture.unit[unit].format = 0; - rmesa->state.texture.unit[unit].envMode = 0; - /* Step 1: * Extract the color and alpha combine function arguments. */ for ( i = 0 ; i < numColorArgs ; i++ ) { - const GLuint op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR; + const GLint op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR; + const GLuint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i]; assert(op >= 0); assert(op <= 3); - switch ( texUnit->_CurrentCombine->SourceRGB[i] ) { + switch ( srcRGBi ) { case GL_TEXTURE: - color_arg[i] = radeon_texture_color[op][unit]; + if (texUnit->_Current->Image[0][0]->_BaseFormat == GL_ALPHA) + color_arg[i] = radeon_zero_color[op]; + else + color_arg[i] = radeon_texture_color[op][unit]; break; case GL_CONSTANT: color_arg[i] = radeon_tfactor_color[op]; @@ -452,18 +582,35 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit ) case GL_ONE: color_arg[i] = radeon_zero_color[op+1]; break; + case GL_TEXTURE0: + case GL_TEXTURE1: + case GL_TEXTURE2: { + GLuint txunit = srcRGBi - GL_TEXTURE0; + if (ctx->Texture.Unit[txunit]._Current->Image[0][0]->_BaseFormat == GL_ALPHA) + color_arg[i] = radeon_zero_color[op]; + else + /* implement ogl 1.4/1.5 core spec here, not specification of + * GL_ARB_texture_env_crossbar (which would require disabling blending + * instead of undefined results when referencing not enabled texunit) */ + color_arg[i] = radeon_texture_color[op][txunit]; + } + break; default: return GL_FALSE; } } for ( i = 0 ; i < numAlphaArgs ; i++ ) { - const GLuint op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA; + const GLint op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA; + const GLuint srcAi = texUnit->_CurrentCombine->SourceA[i]; assert(op >= 0); assert(op <= 1); - switch ( texUnit->_CurrentCombine->SourceA[i] ) { + switch ( srcAi ) { case GL_TEXTURE: - alpha_arg[i] = radeon_texture_alpha[op][unit]; + if (texUnit->_Current->Image[0][0]->_BaseFormat == GL_LUMINANCE) + alpha_arg[i] = radeon_zero_alpha[op+1]; + else + alpha_arg[i] = radeon_texture_alpha[op][unit]; break; case GL_CONSTANT: alpha_arg[i] = radeon_tfactor_alpha[op]; @@ -480,6 +627,16 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit ) case GL_ONE: alpha_arg[i] = radeon_zero_alpha[op+1]; break; + case GL_TEXTURE0: + case GL_TEXTURE1: + case GL_TEXTURE2: { + GLuint txunit = srcAi - GL_TEXTURE0; + if (ctx->Texture.Unit[txunit]._Current->Image[0][0]->_BaseFormat == GL_LUMINANCE) + alpha_arg[i] = radeon_zero_alpha[op+1]; + else + alpha_arg[i] = radeon_texture_alpha[op][txunit]; + } + break; default: return GL_FALSE; } @@ -542,7 +699,6 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit ) * 1.3) does. */ RGBshift = 0; - Ashift = 0; /* FALLTHROUGH */ case GL_DOT3_RGB: @@ -555,7 +711,11 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit ) } RGBshift += 2; - Ashift = RGBshift; + if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT) + || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ) { + /* is it necessary to set this or will it be ignored anyway? */ + Ashift = RGBshift; + } color_combine = (RADEON_COLOR_ARG_C_ZERO | RADEON_BLEND_CTL_DOT3 | @@ -686,6 +846,44 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit ) return GL_TRUE; } +void radeonSetTexOffset(__DRIcontext * pDRICtx, GLint texname, + unsigned long long offset, GLint depth, GLuint pitch) +{ + r100ContextPtr rmesa = pDRICtx->driverPrivate; + struct gl_texture_object *tObj = + _mesa_lookup_texture(rmesa->radeon.glCtx, texname); + radeonTexObjPtr t; + + if (tObj == NULL) + return; + + t = (radeonTexObjPtr) tObj->DriverData; + + t->image_override = GL_TRUE; + + if (!offset) + return; + + t->pp_txoffset = offset; + t->pp_txpitch = pitch - 32; + + switch (depth) { + case 32: + t->pp_txformat = tx_table[MESA_FORMAT_ARGB8888].format; + t->pp_txfilter |= tx_table[MESA_FORMAT_ARGB8888].filter; + break; + case 24: + default: + t->pp_txformat = tx_table[MESA_FORMAT_RGB888].format; + t->pp_txfilter |= tx_table[MESA_FORMAT_RGB888].filter; + break; + case 16: + t->pp_txformat = tx_table[MESA_FORMAT_RGB565].format; + t->pp_txfilter |= tx_table[MESA_FORMAT_RGB565].filter; + break; + } +} + #define TEXOBJ_TXFILTER_MASK (RADEON_MAX_MIP_LEVEL_MASK | \ RADEON_MIN_FILTER_MASK | \ RADEON_MAG_FILTER_MASK | \ @@ -705,12 +903,16 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit ) RADEON_TXFORMAT_CUBIC_MAP_ENABLE | \ RADEON_TXFORMAT_NON_POWER2) - -static void import_tex_obj_state( radeonContextPtr rmesa, +#if 0 +static void import_tex_obj_state( r100ContextPtr rmesa, int unit, radeonTexObjPtr texobj ) { - GLuint *cmd = RADEON_DB_STATE( tex[unit] ); +/* do not use RADEON_DB_STATE to avoid stale texture caches */ + uint32_t *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0]; + GLuint se_coord_fmt = rmesa->hw.set.cmd[SET_SE_COORDFMT]; + + RADEON_STATECHANGE( rmesa, tex[unit] ); cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK; cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK; @@ -718,128 +920,193 @@ 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) { 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] ); + se_coord_fmt |= RADEON_VTX_ST0_NONPARAMETRIC << unit; + } + else { + se_coord_fmt &= ~(RADEON_VTX_ST0_NONPARAMETRIC << unit); + + if (texobj->base.tObj->Target == GL_TEXTURE_CUBE_MAP) { + int *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0]; + GLuint bytesPerFace = texobj->base.totalSize / 6; + ASSERT(texobj->base.totalSize % 6 == 0); + + RADEON_STATECHANGE( rmesa, cube[unit] ); + 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 */ + cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset + 5 * bytesPerFace; /* back */ + } + } + + if (se_coord_fmt != rmesa->hw.set.cmd[SET_SE_COORDFMT]) { + RADEON_STATECHANGE( rmesa, set ); + rmesa->hw.set.cmd[SET_SE_COORDFMT] = se_coord_fmt; } texobj->dirty_state &= ~(1<TexGenEnabled |= RADEON_TEXMAT_0_ENABLE<TexGenMatrix[unit].m[0] = s_plane[0]; - rmesa->TexGenMatrix[unit].m[4] = s_plane[1]; - rmesa->TexGenMatrix[unit].m[8] = s_plane[2]; - rmesa->TexGenMatrix[unit].m[12] = s_plane[3]; - - rmesa->TexGenMatrix[unit].m[1] = t_plane[0]; - rmesa->TexGenMatrix[unit].m[5] = t_plane[1]; - rmesa->TexGenMatrix[unit].m[9] = t_plane[2]; - rmesa->TexGenMatrix[unit].m[13] = t_plane[3]; - rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; - } + rmesa->TexGenMatrix[unit].m[0] = s_plane[0]; + rmesa->TexGenMatrix[unit].m[4] = s_plane[1]; + rmesa->TexGenMatrix[unit].m[8] = s_plane[2]; + rmesa->TexGenMatrix[unit].m[12] = s_plane[3]; + + rmesa->TexGenMatrix[unit].m[1] = t_plane[0]; + rmesa->TexGenMatrix[unit].m[5] = t_plane[1]; + 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->radeon.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); +{ + r100ContextPtr rmesa = R100_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<TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<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: - */ - 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: - */ - /* 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 ); + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_Q_BIT(unit); + } 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<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<TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_NORMAL << inputshift; break; case GL_SPHERE_MAP: + /* the mode which everyone uses :-( */ default: /* Unsupported mode, fallback: */ - /* fprintf(stderr, "fallback unsupported texgen\n"); */ + if (RADEON_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "fallback GL_SPHERE_MAP\n"); return GL_FALSE; } if (tmp != rmesa->TexGenEnabled) { - rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; + rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX; } return GL_TRUE; } - +#if 0 static void disable_tex( GLcontext *ctx, int unit ) { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + r100ContextPtr rmesa = R100_CONTEXT(ctx); if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_TCL_VTX_ST0 | - RADEON_TCL_VTX_Q0); - break; - case 1: - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_TCL_VTX_ST1 | - RADEON_TCL_VTX_Q1); - break; - default: - break; - } - + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_ST_BIT(unit) | + RADEON_Q_BIT(unit)); - if (rmesa->TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0<radeon.TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0<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; @@ -891,7 +1154,7 @@ static void disable_tex( GLcontext *ctx, int unit ) if (tmp != rmesa->TexGenEnabled) { rmesa->recheck_texgen[unit] = GL_TRUE; - rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; + rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX; } } } @@ -899,7 +1162,7 @@ static void disable_tex( GLcontext *ctx, int unit ) static GLboolean enable_tex_2d( GLcontext *ctx, int unit ) { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + r100ContextPtr rmesa = R100_CONTEXT(ctx); struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; struct gl_texture_object *tObj = texUnit->_Current; radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData; @@ -917,16 +1180,58 @@ static GLboolean enable_tex_2d( GLcontext *ctx, int unit ) RADEON_FIREVERTICES( rmesa ); radeonSetTexImages( rmesa, tObj ); radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 ); - if ( !t->base.memBlock ) + if ( !t->base.memBlock && !t->image_override ) return GL_FALSE; } return GL_TRUE; } +static GLboolean enable_tex_cube( GLcontext *ctx, int unit ) +{ + r100ContextPtr rmesa = R100_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); + r100ContextPtr rmesa = R100_CONTEXT(ctx); struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; struct gl_texture_object *tObj = texUnit->_Current; radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData; @@ -942,7 +1247,8 @@ static GLboolean enable_tex_rect( GLcontext *ctx, int unit ) RADEON_FIREVERTICES( rmesa ); radeonSetTexImages( rmesa, tObj ); radeonUploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 ); - if ( !t->base.memBlock /* && !rmesa->prefer_gart_client_texturing FIXME */ ) { + if ( !t->base.memBlock && + !t->image_override /* && !rmesa->prefer_gart_client_texturing FIXME */ ) { fprintf(stderr, "%s: upload failed\n", __FUNCTION__); return GL_FALSE; } @@ -954,7 +1260,7 @@ static GLboolean enable_tex_rect( GLcontext *ctx, int unit ) static GLboolean update_tex_common( GLcontext *ctx, int unit ) { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + r100ContextPtr rmesa = R100_CONTEXT(ctx); struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; struct gl_texture_object *tObj = texUnit->_Current; radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData; @@ -965,6 +1271,9 @@ static GLboolean update_tex_common( GLcontext *ctx, int unit ) fprintf(stderr, "%s: border\n", __FUNCTION__); return GL_FALSE; } + /* yuv conversion only works in first unit */ + if (unit != 0 && (t->pp_txfilter & RADEON_YUV_TO_RGB)) + return GL_FALSE; /* Update state if this is a different texture object to last * time. @@ -995,26 +1304,25 @@ static GLboolean update_tex_common( GLcontext *ctx, int unit ) RADEON_STATECHANGE( rmesa, tcl ); - if (unit == 0) - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_ST0; - else - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_ST1; + rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_ST_BIT(unit); rmesa->recheck_texgen[unit] = GL_TRUE; } if (t->dirty_state & (1<radeon.NewGLState |= _NEW_TEXTURE_MATRIX; } if (rmesa->recheck_texgen[unit]) { GLboolean fallback = !radeon_validate_texgen( ctx, unit ); TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<recheck_texgen[unit] = 0; - rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; + rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX; } - format = tObj->Image[0][tObj->BaseLevel]->Format; + format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat; if ( rmesa->state.texture.unit[unit].format != format || rmesa->state.texture.unit[unit].envMode != texUnit->EnvMode ) { rmesa->state.texture.unit[unit].format = format; @@ -1027,18 +1335,93 @@ static GLboolean update_tex_common( GLcontext *ctx, int unit ) FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback ); return !t->border_fallback; } +#endif + +/** + * Compute the cached hardware register values for the given texture object. + * + * \param rmesa Context pointer + * \param t the r300 texture object + */ +static void setup_hardware_state(r100ContextPtr rmesa, radeonTexObj *t) +{ + const struct gl_texture_image *firstImage = + t->base.Image[0][t->mt->firstLevel]; + GLint log2Width, log2Height, log2Depth, texelBytes; + + log2Width = firstImage->WidthLog2; + log2Height = firstImage->HeightLog2; + log2Depth = firstImage->DepthLog2; + texelBytes = firstImage->TexFormat->TexelBytes; + + if (!t->image_override) { + if (VALID_FORMAT(firstImage->TexFormat->MesaFormat)) { + const struct tx_table *table = tx_table; + + t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK | + RADEON_TXFORMAT_ALPHA_IN_MAP); + t->pp_txfilter &= ~RADEON_YUV_TO_RGB; + + // t->pp_txformat |= table[ firstImage->TexFormat->MesaFormat ].format; + // t->pp_txfilter |= table[ firstImage->TexFormat->MesaFormat ].filter; + } else { + _mesa_problem(NULL, "unexpected texture format in %s", + __FUNCTION__); + return; + } + } + + t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK; + t->pp_txfilter |= (t->mt->lastLevel - t->mt->firstLevel) << RADEON_MAX_MIP_LEVEL_SHIFT; + + t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK | + RADEON_TXFORMAT_HEIGHT_MASK | + 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)); + + t->tile_bits = 0; + + if (t->base.Target == GL_TEXTURE_CUBE_MAP) { + ASSERT(log2Width == log2Height); + t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_F5_WIDTH_SHIFT) | + (log2Height << RADEON_TXFORMAT_F5_HEIGHT_SHIFT) | + /* don't think we need this bit, if it exists at all - fglrx does not set it */ + (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 = (((firstImage->Width - 1) << RADEON_TEX_USIZE_SHIFT) + | ((firstImage->Height - 1) << RADEON_TEX_VSIZE_SHIFT)); + if ( !t->image_override ) { + if (firstImage->IsCompressed) + t->pp_txpitch = (firstImage->Width + 63) & ~(63); + else + t->pp_txpitch = ((firstImage->Width * texelBytes) + 63) & ~(63); + t->pp_txpitch -= 32; + } + if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) { + t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2; + } + +} +#if 0 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 )); } @@ -1046,6 +1429,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; } @@ -1054,17 +1441,25 @@ static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit ) return GL_TRUE; } } +#endif + +static GLboolean radeonUpdateTextureUnit( GLcontext *ctx, int unit ) +{ + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + +} void radeonUpdateTextureState( GLcontext *ctx ) { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + r100ContextPtr rmesa = R100_CONTEXT(ctx); GLboolean ok; ok = (radeonUpdateTextureUnit( ctx, 0 ) && - radeonUpdateTextureUnit( ctx, 1 )); + radeonUpdateTextureUnit( ctx, 1 ) && + radeonUpdateTextureUnit( ctx, 2 )); FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, !ok ); - if (rmesa->TclFallback) + if (rmesa->radeon.TclFallback) radeonChooseVertexState( ctx ); }