Keith Whitwell wrote:
Ian Romanick wrote:
Keith Whitwell wrote:

I'm wondering if this has been thought through. For the test to work, this code fragement will have to be re-evaluated whenever tObj->MinFilter changes, or at least whenever it changes to/from NEAREST or LINEAR.

I don't think the drivers do this at the moment. Correct?

This function was the result of a code refactor. All of the drivers had a bit of code like this in their SetTexImages function. I just pulled the code out of those individual functions are replaced it with a call to driCalculateTextureFirstLastLevel. So, the values of firstLevel and lastLevel may get out-of-date, but they are re-evaluated when they are actually needed. To keep them completely upto date (which I don't think is necessary, we'd have to call driCalculateTextureFirstLastLevel whenever:


1. The texture size changed.
2. MinLod or MaxLod changed.
3. The texture filter changed.

4. Base level or maximum level changed.


Indeed - my point being that I don't think we do call it under (all of) those circumstances.

Right. It's not called from any of those places.


The importance of firstLevel/lastLevel is that they specify which mipmaps to upload, if they aren't correct, how can we have confidence that the right set of mipmaps are on the card?

In all of the drivers, whenever any bit of texture state is changed the entire texture gets invalidated. This results in SetTexImages being called and the correct firstLevel and lastLevel values being calculated.


At the moment, in most drivers, this function doesn't get called unless at least one texture level (t->base.dirty_images[0] != 0) is going to be uploaded - which isn't really what you want to happen every time you change some of that state.

Which will happen. The drivers work now, but they end up doing extra texture uploads. It could be a lot smarter. I've attached a patch to tunnel.c to illustrate this. When it starts up, the min filter is GL_NEAREST, so only the base level should get uploaded to the card. When 'x' is pressed, it switches to GL_LINEAR_MIPMAP_LINEAR. If firstLevel & lastLevel weren't correctly recalcuated, you'd see garbage, but you don't. It's easier to tell if you hit '0' to stop the animation and 'h' to get rid of the help menu.


I'm pretty sure that the i830 driver didn't have the test on tObj->MinFilter, fwiw, possibly due to conform or glean testing done near the end of its development.

None of the drivers had that test until Ville Syrjala discovered it as a bug in the MGA driver.


http://marc.theaimsgroup.com/?l=dri-devel&m=105814616725200&w=2

Index: tunnel.c
===================================================================
RCS file: /cvs/mesa/Mesa/progs/demos/tunnel.c,v
retrieving revision 1.8
diff -u -d -r1.8 tunnel.c
--- tunnel.c    9 May 2001 20:02:28 -0000       1.8
+++ tunnel.c    29 Jan 2004 17:44:26 -0000
@@ -83,8 +83,12 @@
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 
+#if 0
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                   GL_LINEAR_MIPMAP_LINEAR);
+#else
+   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+#endif
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
    glGenTextures(1, &t2id);
@@ -98,8 +102,12 @@
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 
+#if 0
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                   GL_LINEAR_MIPMAP_LINEAR);
+#else
+   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+#endif
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
@@ -209,6 +217,9 @@
    case 'z':
       v -= 0.01;
       break;
+   case '0':
+      v = 0.0;
+      break;
 
 #ifdef XMESA
    case ' ':
@@ -254,6 +265,14 @@
       NiceFog = !NiceFog;
       printf("NiceFog %d\n", NiceFog);
       break;
+   case 'x':
+      glBindTexture(GL_TEXTURE_2D, t1id);
+      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+                     GL_LINEAR_MIPMAP_LINEAR);
+      glBindTexture(GL_TEXTURE_2D, t2id);
+      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+                     GL_LINEAR_MIPMAP_LINEAR);
+      break;
    }
    glutPostRedisplay();
 }

Reply via email to