I noticed that a couple of WebGL demos that use texture compression perform poorly when using LLVMpipe. I patched mesa to decompress the textures during load. This yielded about 4 times the performance of using libtxc_dxtn to sample the compressed textures during rasterization. The patch intercepts calls to glCompressedTexImage2D, decompresses the texture and then calls glTexImage2D with the uncompressed data. The patch is hard coded to take GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE textures and to convert them in to GL_RGBA GL_UNSIGNED_BYTE textures. I've also basically pasted libtxc_dxtn in to src/mesa/main/teximage.c . Obviously this patch isn't production ready but it does illustrate the potential performance win at least in the case of s3tc textures (at the expense of increased memory usage).
I used the following set up:
* Current mesa from git (ba6dcb3c2b8f516b120f591144bf6c3751f0e3f9)
* 64 bit Ubuntu 12.04
* LLVM 3.4 prebuilt binary from from http://llvm.org/releases/
* LLVMpipe built with scons build=release llvmpipe libgl-xlib
* Core 2 Duo E8400
I tested on the following two pages in Firefox 28 (libtxc_dxtn vs my patch):
Simple cube with a compressed texture http://media.tojicode.com/webgl-samples/dds.html
* 40fps 180% CPU without patch
* 60fps 80% CPU with patch
Mozilla Bananabread Arena demo level on https://developer.cdn.mozilla.net/media/uploads/demos/a/z/azakai/3baf4ad7e600cbda06ec46efec5ec3b8/bananabread_1373485124_demo_package/game.html?setup=low&serve (or https://developer.mozilla.org/en/demos/detail/bananabread)
* 6fps without patch
* 20 fps with patch
Created attachment 97645 [details] [review]
Texture decompression patch
Ideally you'd just say you don't support s3tc, and leave it up to the application to not use such textures. I suspect it wouldn't get you very far though today (though I know some apps indeed can deal with this), and you can't actually even do it without deleting (or not installing...) libtxc_dxtn.
If you'd really want to fake s3tc support that way for sw renderers, there's obviously some problems with your implementation:
1) there is a reason why the decode/encode code is not in mesa itself, this doesn't change if you decode the texture as a whole up front. The code admittedly is very inefficient for decompressing complete textures, though nothing would prevent a more efficient whole-block decompression interface.
2) You can't just intercept texstoreimage2d that way, that will give a lot of trouble. You'd also have to catch the texstoresubimage2d calls, and (more complicated) deal with all the other stuff which this affects. E.g. things like getCompressedTexImageARB would more or less require you to store the original image too, or just hope that it won't get called (which is very likely). You'd never get all the error conditions right neither (as compressed textures have a lot of restrictions) though I guess you might not particularly care about these neither. It would probably be cleaner if you'd still treat it as a compressed texture everywhere just with hacked up (and converted) format.
In any case it would need to be configurable too.
As a side note, it would of course be possible to make this code faster for llvmpipe's simd execution (with a different interface).