Slow texture lookups ... or is it?

Hi everyone! This is my first post, so feel free to “educate” me if I break some sort of etiquette. :slight_smile:

I have (among other things) in my application a VBO that contains around 12000 textured triangles. The VBO is rendered without culling (for a reason) and without lighting and I am using the fixed pipeline. The problem is - not a big surprise here - performance: with only 12000 triangles the frame rate should be extremely high, but I only get results between 80 FPS (when camera is facing away from VBO) to 21 FPS (worst-case scenario when camera is viewing the VBO).

First thing I suspected was that am I fill-rate-bound: after all the there are LOTS of overlapping triangles which is not helped by the fact that the texture which is used for the triangles contain lots of holes (alpha channel). I reduced the resolution of the application window from 800x600 to 800x60 and my framerate went to 200+ FPS as I expected.

Not knowing what to do as I can not replace the texture nor the geometry, I tried using a simplified shader to render the VBO just to see how fast it would go with an extremely simplified pipeline. I expected it to be very slow, but to my surprise I got over 60 FPS constantly (only relevant parts of the dummy shader in included here):

void main()
{
	// just doing some random stuff with the pixels
	if(mod(texture_coordinate.x*100.0,20.0)<5.0){
		gl_FragColor=vec4(
					texture_coordinate.x,
					texture_coordinate.y,
					1.0,
					1.0
		);
	} else {
		// "simulates" the holes in the texture
		discard;
	}
}

As that was fast enough for me, the next thing I did was to run the scene with this shader:

void main()
{
	vec4 color=texture2D(texture, texture_coordinate);
	if(texture_coordinate.y<0.8){
		gl_FragColor=vec4(1.0);
	} else {
		discard;
	}
}

I got identical performance (over 60 FPS) but that’s not surprising because I guess that the unused “color=textured2D” gets optimized away. So next thing I tested was:

void main()
{
	vec4 color=texture2D(texture, texture_coordinate);
	if(texture_coordinate.y<0.8){
		gl_FragColor=vec4(color.r,1.0,1.0,1.0);
	} else {
		discard;
	}
}

…and got 21 FPS.

So, texture lookups seem to be slow. If I remove texture lookups (with a simplified shader or using fixed pipeline without TEXTURE_2D) the frame rate skyrockets. As soon as I enable texturing (using only one texture, no multitextring) VBO performs poorly. What could I do to increase the performance? The texture used by VBO is 1024x1024 GL_BGRA,GL_UNSIGNED_BYTE texture with the following:


glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

I am rendering to FBO but I guess that doesn’t make any difference. My guess is that there’s a really simple basic thingy I’ve missed (perhaps not even texture related)… I posted this to the beginners-section for a reason :slight_smile:

Most probably you need to know more, so feel free to ask. Thanks in advance!

Give it a try with mipmaps !
They are more texture-cache friendly, each time the minifiaction is needed :
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
Trilinear mipmaps (GL_LINEAR_MIPMAP_LINEAR) is nicer to the eye but a bit more costly.

What is your hardware/OS by the way ?

That sounds very logical.

…testing…

I tried it with mipmaps and got good performance! Used a shader like this to make things simple (I have 8 bits of alpha in the textures but actually I only require 1 bit alpha):


{
	vec4 color=texture2D(texture, texture_coordinate);
	if(color.a>0.5){
		gl_FragColor=vec4(color.rgb,1.0);
	} else {
		discard;
	}
}

I’m now getting 60+ FPS even in the worst case scenario.

…still… 60-80 FPS … I wonder if I still have something wrong since rendering so few triangles per frame should give me lots more frames. Or am I just expecting too much? (I’m running this on ATI Radeon HD 3600, on Vista).

I guess the texturing is “as fast as it can be” now but is there anything I could do to increase fill rate, considering that the app runs much faster when the application window is smaller?

well with v-sync turned off you should be getting like 500 or more FPS.

Just the fact that your getting 3 times the performance by using mipmapping is very suspect, i can’t help to feel that something else is wrong here.

Double monitor ? Software acceleration ? Indeed with such hardware you should get much better performance.

I am rendering to FBO but I guess that doesn’t make any difference

Just try doing classic rendering to the framebuffer, so you will not have to guess :slight_smile: