substituting textures while loading into memory

Started by
12 comments, last by Sneftel 15 years, 9 months ago
Quote:The first holdup for this, assuming it is a valid proposal, is being able to reliably determine if a texture is in the video memory. Given that glAreTexturesResident() does not always work, what other options are there?
None that work reliably. Figure out how much texture memory you have available (you will have to use a platform dependant API), and then only load that much texture data into OpenGL, paging textures in and out as necessary.

This may give you even greater performance gains than you would imagine. Moving data from main memory to the card is pretty darn fast - I would guess that some of the textures not currently on the card are being swapped out by the VM subsystem, which means they have to be swapped back from the disk.

Quote:I do not know if there are canonical solutions for this, but as I said previously I would be interested in exploring the technique of showing a small substitute placeholder texture until I have the large texture available in the video RAM.
The best way to do this is to store your textures in a format like DDS, with pre-calculated mipmaps. Then you can stream in the mipmaps, manipulating GL_TEXTURE_BASE_LEVEL to use only the currently loaded levels.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Advertisement
It seems that people keep suggesting to use pre-compressed DDS files. I don't understand how this changes anything compared to my current situation.

Here is a more detailed outline of what I am doing when creating textures:
I am reading raw .png data from the harddisk and storing it temporarily in the system memory as a "TextureData" object which probably is unique to jogl. I then call a method that converts the format of this data into DXT1 compressed. I then make a standard texture object using this data. This is all done only once when I initialize my program, before I even draw the first frame. My program takes a damn long time to load the textures from the hard disk when starting up. After that it renders nicely at 70 fps, but if I include really high-res images in my program I get "hiccups" as I move around my scene to areas that use textures that aren't currently resident in the card's memory.

The issue is not loading the textures for the first time or compressing them. It is with paging if I understand. OpenGL is apparently swapping textures in and out and it really degrades the usability of the program. Not all of my textures can be stored on the card's memory so it is going somewhere (I don't know if it is the hard disk or system RAM).

To mike: Isn't DXT1 better than DXT5 in terms of memory usage? As near as I can tell, DXT5 uses 8 bits per pixel and DXT1 uses 4. Were you suggesting that I switch to DXT5 or did you not read from before that I was already compressing?


Thanks for the input everyone. It is very kind of you all to offer your thoughts.
Quote:Original post by dsr12
It seems that people keep suggesting to use pre-compressed DDS files. I don't understand how this changes anything compared to my current situation.

It doesn't, but since you are going to have to implement your own paging system, you may as well go for faster disk loading.

Quote:The issue is not loading the textures for the first time or compressing them. It is with paging if I understand. OpenGL is apparently swapping textures in and out and it really degrades the usability of the program. Not all of my textures can be stored on the card's memory so it is going somewhere (I don't know if it is the hard disk or system RAM).
The major problem you have right now is that OpenGL is paging for you, but it isn't paging intelligently. OpenGL knows there are too many textures to fit in VRAM, and it knows which textures are in use, so it just pages out a random selection (probably chosen using LRU, or similar) of unused textures. Then when you move to a new area, OpenGL must suddenly page all the new textures in at once, which results in your slowdowns.

You on the other hand (as the programmer/level designer) know exactly what textures need to be used in each area, so you need to write your own paging system which uses that knowledge to give only the necessary textures for the current area to OpenGL, and to remove them when they are no longer needed.

While you may well end up doing more work paging, you will at least be doing the right work, and you can spread the loading of new textures over several frames, by dint of a little prediction of player movement. You can also do mipmap level streaming to speed things up further.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

PCI Express offers 4 GB/sec sustained one-way transfer. For a 512x512 DXT3 texture, that's about 65 microseconds. There's certainly some extra time lost from overhead, but loading a normal-sized texture from main memory to GPU memory over several frames is not a useful proposition. What is worthwhile is a placeholder texture while the full texture is being streamed from the disk or network, but you don't have to do any fancy footwork for that: just use the placeholder until the texture is loaded into main memory (loading on a separate thread, or otherwise concurrently), then switch. Bottom line: Worry about your total texture set, not whether the textures are resident. These days, that's not a major concern.

This topic is closed to new replies.

Advertisement