summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordok666 <dok666>2003-05-19 21:23:55 +0000
committerdok666 <dok666>2003-05-19 21:23:55 +0000
commit041870e83bff7d56d116cd523c6867dd11a57cd0 (patch)
tree2eb1167563081738ff463853005a47f691684e57
parent2b315c921b57aa78bf23364a4198118288902c7b (diff)
Reject mip maps smaller than 8x8.
Changed bit order in TEXFILTER mip map setting. Use firstLevel/lastLevel calculation from radeon driver, horing tObj->MinLod and tObj->MaxLod. Set max mip map level from 12 to 11 for G400 as doc says mipmap count can be 0 to 10. Still not sure about that, maybe it's just 10? Where is the 12 from?
-rw-r--r--src/mesa/drivers/dri/mga/mga_texstate.c70
-rw-r--r--src/mesa/drivers/dri/mga/mgacontext.h3
-rw-r--r--src/mesa/drivers/dri/mga/mgatexmem.c15
3 files changed, 59 insertions, 29 deletions
diff --git a/src/mesa/drivers/dri/mga/mga_texstate.c b/src/mesa/drivers/dri/mga/mga_texstate.c
index ac4382b32b9..3cd03c6a4d7 100644
--- a/src/mesa/drivers/dri/mga/mga_texstate.c
+++ b/src/mesa/drivers/dri/mga/mga_texstate.c
@@ -65,10 +65,11 @@ mgaSetTexImages( mgaContextPtr mmesa,
GLint totalSize;
GLint width, height;
GLint i;
- GLint lastLevel;
+ GLint firstLevel, lastLevel, numLevels;
GLint log2Width, log2Height;
GLuint txformat = 0;
GLint ofs;
+ GLuint size = 0;
/* Set the hardware texture format
*/
@@ -97,36 +98,63 @@ mgaSetTexImages( mgaContextPtr mmesa,
#endif
- /* We are going to upload all levels that are present, even if
- * later levels wouldn't be used by the current filtering mode. This
- * allows the filtering mode to change without forcing another upload
- * of the images.
+ /* Calculate mipmap offsets and dimensions.
*/
-
- lastLevel = ((MGA_IS_G200(mmesa)) ? G200_TEX_MAXLEVELS : G400_TEX_MAXLEVELS)
- - 1;
-
totalSize = 0;
- for ( i = 0 ; i <= lastLevel ; i++ ) {
+
+ /* Compute which mipmap levels we really want to send to the hardware.
+ * This depends on the base image size, GL_TEXTURE_MIN_LOD,
+ * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
+ * Yes, this looks overly complicated, but it's all needed.
+ */
+ firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5);
+ firstLevel = MAX2(firstLevel, tObj->BaseLevel);
+ lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5);
+ lastLevel = MAX2(lastLevel, tObj->BaseLevel);
+ lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
+ lastLevel = MIN2(lastLevel, tObj->MaxLevel);
+ lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
+
+ numLevels = MIN2( lastLevel - firstLevel + 1,
+ MGA_IS_G200(mmesa) ? G200_TEX_MAXLEVELS : G400_TEX_MAXLEVELS);
+
+ baseImage = tObj->Image[firstLevel];
+
+ for ( i = 0 ; i < numLevels ; i++ ) {
const struct gl_texture_image *texImage;
- texImage = tObj->Image[i];
- if ( texImage == NULL ) {
- lastLevel = i - 1;
+ texImage = tObj->Image[i + firstLevel];
+ if ( !texImage ) {
+ numLevels = i;
break;
}
+ if (i && (texImage->Width < 8 || texImage->Height < 8)) {
+ numLevels = i;
+ break;
+ }
+
+ size = ((MAX2( texImage->Width, 8 ) *
+ MAX2( texImage->Height, 8 ) *
+ baseImage->TexFormat->TexelBytes) + 31) & ~31;
+ if (!size) {
+ numLevels = i;
+ break;
+ }
+
t->offsets[i] = totalSize;
t->base.dirty_images[0] |= (1<<i);
-
- totalSize += ((MAX2( texImage->Width, 8 ) *
- MAX2( texImage->Height, 8 ) *
- baseImage->TexFormat->TexelBytes) + 31) & ~31;
+
+ totalSize += size;
}
- t->base.totalSize = totalSize;
+ lastLevel = firstLevel + numLevels - 1;
+
+ /* save these values */
+ t->firstLevel = firstLevel;
t->lastLevel = lastLevel;
-
+
+ t->base.totalSize = totalSize;
/* setup hardware register values */
t->setup.texctl &= (TMC_tformat_MASK & TMC_tpitch_MASK
@@ -146,8 +174,8 @@ mgaSetTexImages( mgaContextPtr mmesa,
/* FIXME: Is this correct for G200?
*/
t->setup.texfilter &= TF_mapnb_MASK & ~(1U << 18) & ~(0x1ff00);
- t->setup.texfilter |= ((lastLevel & 0x01e) << (TF_mapnb_SHIFT - 1));
- t->setup.texfilter |= ((lastLevel & 0x001) << 18);
+ t->setup.texfilter |= (((numLevels-1) & 0x07) << (TF_mapnb_SHIFT));
+ t->setup.texfilter |= (((numLevels-1) & 0x08) << 15);
/* warp texture registers */
ofs = MGA_IS_G200(mmesa) ? 28 : 11;
diff --git a/src/mesa/drivers/dri/mga/mgacontext.h b/src/mesa/drivers/dri/mga/mgacontext.h
index b214d499041..8feabc4e8a1 100644
--- a/src/mesa/drivers/dri/mga/mgacontext.h
+++ b/src/mesa/drivers/dri/mga/mgacontext.h
@@ -86,7 +86,7 @@ struct mga_texture_object_s;
struct mga_screen_private_s;
#define G200_TEX_MAXLEVELS 5
-#define G400_TEX_MAXLEVELS 12
+#define G400_TEX_MAXLEVELS 11
typedef struct mga_texture_object_s
{
@@ -137,6 +137,7 @@ typedef struct mga_texture_object_s
*/
GLuint offsets[G400_TEX_MAXLEVELS];
+ int firstLevel;
int lastLevel;
int texelBytes;
GLuint age;
diff --git a/src/mesa/drivers/dri/mga/mgatexmem.c b/src/mesa/drivers/dri/mga/mgatexmem.c
index 6015258a1f5..18768881d9f 100644
--- a/src/mesa/drivers/dri/mga/mgatexmem.c
+++ b/src/mesa/drivers/dri/mga/mgatexmem.c
@@ -89,16 +89,17 @@ mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t )
* been hardware accelerated.
*/
static void mgaUploadSubImage( mgaContextPtr mmesa,
- mgaTextureObjectPtr t, GLint level )
+ mgaTextureObjectPtr t, GLint hwlevel )
{
struct gl_texture_image * texImage;
unsigned offset;
unsigned texelBytes;
unsigned length;
+ const int level = hwlevel + t->firstLevel;
- if ( (level < 0)
- || (level >= (MGA_IS_G200(mmesa)
+ if ( (hwlevel < 0)
+ || (hwlevel >= (MGA_IS_G200(mmesa)
? G200_TEX_MAXLEVELS : G400_TEX_MAXLEVELS)) ) {
fprintf( stderr, "[%s:%d] level = %d\n", __FILE__, __LINE__, level );
return;
@@ -120,14 +121,14 @@ static void mgaUploadSubImage( mgaContextPtr mmesa,
/* find the proper destination offset for this level */
- if ( MGA_IS_G200(mmesa) ) {
- offset = (t->base.memBlock->ofs + t->offsets[level]);
+ if (MGA_IS_G200(mmesa) ) {
+ offset = (t->base.memBlock->ofs + t->offsets[hwlevel]);
}
else {
unsigned i;
offset = t->base.memBlock->ofs;
- for ( i = 0 ; i < level ; i++ ) {
+ for ( i = 0 ; i < hwlevel ; i++ ) {
offset += (t->offsets[1] >> (i * 2));
}
@@ -143,7 +144,7 @@ static void mgaUploadSubImage( mgaContextPtr mmesa,
texelBytes = texImage->TexFormat->TexelBytes;
length = texImage->Width * texImage->Height * texelBytes;
- if ( t->base.heap->heapId == MGA_CARD_HEAP ) {
+ if (t->base.heap->heapId == MGA_CARD_HEAP ) {
unsigned tex_offset = 0;
unsigned to_copy;