Texture Caching


I’m having a problem whereby the frame rate drops considerably the first time I “approach” an object with a moderate (2048x2048) texture in my environment. After looking at it from a few different angles, the frame rate seems to pick back up. Can anyone provide any insight on texture caching, and how it may be possible to avoid this initial bottleneck? I’m running with OpenGL on Mac OS X 10.5. Here’s a typical frame where this happens:

Thread Main frame 2715, 171.054 ms (176.093 Hz):
Draw = 164.712 ms
Flush = 0.0276566 ms
Clear = 0.157356 ms
Transfer data = 105.282 ms
Texture = 103.904 ms
Index buffer = 0.387192 ms
Vertex buffer = 0.990868 ms
Make current = 0.184059 ms
window1 = 59.0611 ms
dr_0 = 47.7915 ms
opaque = 46.0024 ms
transparent = 1.75095 ms
dr_1 = 0.141144 ms
unsorted = 0.0810623 ms
transparent = 0 ms
dr_2 = 0.0162125 ms
dr_3 = 0.0715256 ms
transparent = 0.0572205 ms

And a typical frame before/after approaching the object:

Thread Main frame 2712, 5.52368 ms (209.36 Hz):
Draw = 2.26784 ms
Flush = 0.0143051 ms
Clear = 0.0562668 ms
Transfer data = 0 ms
Texture = 0 ms
Index buffer = 0 ms
Vertex buffer = 0 ms
Make current = 0.103951 ms
window1 = 2.09332 ms
dr_0 = 1.79672 ms
opaque = 0.505447 ms
transparent = 1.2722 ms
dr_1 = 0.0686646 ms
unsorted = 0.0486374 ms
transparent = 0 ms
dr_2 = 0.0133514 ms
dr_3 = 0.0581741 ms
transparent = 0.0448227 ms

Thanks as always.

You could try:
when you load your scene up. That will force all the textures under render to be preloaded to the graphics card, even before you come close to the models in question. That way you’ll take the texture load hit at startup time, instead of in the middle of the scene.


Thanks for the suggestion. This seems to have “resolved” the problem as far as pstats notices… all frames except the first now render in <10ms. However, during game play, the frame rate still occasionally drops below 5fps. What could be causing this discrepancy between what pstats is seeing and what’s actually happening?

You observe the frame rate drop below 5 fps, while PStats is simultaneously reporting a frame rate in excess of 100fps (10 ms)?

Wow. It’s hard to imagine what could cause that, unless it’s a problem with network messages getting cached on the wire, which could cause PStats to lag behind the actual events happening onscreen. (But eventually, PStats would catch up, and show the 5fps reading.)

What tool are you using to determine that your frame rate is below 5fps?


Not sure what was going on before, but the slower frames are being spotted by pstats now. (I was just relying on the built-in FPS meter to answer your question, but I’m not sure if that matters anymore). It looks like the bottleneck in Data Transfer is gone as expected, but still exists in drawing the window, e.g.:

Thread Main frame 1970, 83.3445 ms (77.7225 Hz):
Draw = 77.9686 ms
Flush = 0.0286102 ms
Clear = 0.126839 ms
Transfer data = 3.69358 ms
Texture = 0 ms
Index buffer = 1.52206 ms
Vertex buffer = 2.17152 ms
Make current = 0.156403 ms
window1 = 73.9632 ms
dr_0 = 55.541 ms
opaque = 47.0963 ms
transparent = 8.41045 ms
dr_1 = 0.125885 ms
unsorted = 0.0658035 ms
transparent = 0 ms
dr_2 = 0.0152588 ms
dr_3 = 0.0686646 ms
transparent = 0.0553131 ms

But in the very next frame,

Thread Main frame 1971, 6.8121 ms (77.4311 Hz):
Draw = 3.39603 ms
Flush = 0.0190735 ms
Clear = 0.126839 ms
Transfer data = 0 ms
Texture = 0 ms
Index buffer = 0 ms
Vertex buffer = 0 ms
Make current = 0.177383 ms
window1 = 3.07274 ms
dr_0 = 1.9989 ms
opaque = 0.888824 ms
transparent = 1.06907 ms
dr_1 = 0.0762939 ms
unsorted = 0.0534058 ms
transparent = 0 ms
dr_2 = 0.0152588 ms
dr_3 = 0.0629425 ms
transparent = 0.0495911 ms

Do you have any other ideas?

It also seems there’s a correlation between Index buffer and Vertex buffer transfer and the slowdown. Although the transfer itself is fast (<4ms), it seems to always appear along with a slow rendering of the window (up to 100ms).

I looked at the pstats logs some more, and the earlier ones have intermittent “Shutting down connection…” around the time things slow down, then it picks up again as if nothing had happened. The dropped frames often include the ones that are slowly rendered. It shouldn’t be a network issue, since the server and client are running on the same machine. Not sure if this is a clue or not.

Well, I’m not sure that text-stats is really capable of keeping up with the data bandwidth generated by a real application, so it might start to drop behind. If it gets really far behind, the connection will close itself down, which might be what you’re seeing in the logs. I don’t know why it would start up again as if nothing had happened, though.

You should consider using the graphical pstats program instead. On OSX, this has to be compiled as an X application. Use MacPorts to install X and gtk2 for X.

But, to answer the original question, I can only speculate that your graphics driver is doing something complex the first time it actually renders a particular texture. For instance, maybe the texture doesn’t get copied into AGP memory until it is actually rendered. This sort of behavior is highly driver-dependent, though, so you can expect different behavior on different hardware.

Are you sure your graphics card is well-equipped to handle such a large texture? Many cards, although they can render large textures, will render smaller textures much more quickly. You might consider limiting yourself to 1024x1024 or smaller.