Flipping buffers takes unreasonably much time.

Started by
11 comments, last by Ingrater 16 years, 11 months ago
Hello, I have this problem where basically everything in my game loop except flipping buffers is done within ~2 milliseconds, but when I flip the buffer with SDL_GL_SwapBuffers() that alone takes ~60ms. Im not that experienced with OpenGL or SDL. Here is the initialization code:
void startGL() {
	if (SDL_Init(SDL_INIT_VIDEO) < 0)
		throw "SDL failed";

	SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

	SDL_SetVideoMode(width, height, 24, SDL_OPENGL);
	SDL_WM_SetCaption("Tank vs Aliens", NULL);


	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();
	glOrtho( 0, width, 0, height, -1, 0 );
	glClearColor( 0.0, 0.0, 0.0, 0.0);
	
	glEnable( GL_TEXTURE_2D );
	
	
	glShadeModel( GL_FLAT );

	
	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();

	checkGlErrors();
}





And here is my game loop where I use my xTimer to time it:


void GameLoop() {


	bool keepOn = true;
	
	while ( keepOn ) {
		xTimer t(1);
		
		glClear( GL_COLOR_BUFFER_BIT );
		glLoadIdentity();

		keepOn = events.checkEvents();

		draw();
		
		std::cout << "t1: " << (int)t.Elapsedms() << " ms.\t";

		xTimer t2(1);
		SDL_GL_SwapBuffers();
		std::cout << "t2: " << (int)t2.Elapsedms() << " ms.\n";
		
		SDL_Delay(2);
	}
}





Here is the requested source code for the drawing.

void draw() {
        glBindTexture(GL_TEXTURE_2D, bugTexture.texture );
	checkGlErrors();
	glBegin( GL_QUADS );
	
	for (int i=0; i<maxBugs; ++i) {
	        /* alot of math where I calculate 
                   x, y, dx1, dx2. The reason I use
                   dx1 and dx2 is to avoid glRotate and glTranslate
                   which have some overhead. */


	        glTexCoord2f(0.0, 0.0);
		glVertex2f( x-dx1, y-dy1 );		//lower left
						
		glTexCoord2f(1.0, 0.0);
		glVertex2f( x+dx2, y+dy2 );		//lower right
		glTexCoord2f(1.0, 1.0);
		glVertex2f( x+dx1, y+dy1 );		//upper right
		glTexCoord2f(0.0, 1.0);
		glVertex2f( x-dx2, y-dy2 );		//upper left
	}
	
	glEnd();
	
	return;
}

The compiled exe can be found here. (121kb) It will print in a command window, the values of the two timers in each loop. My t1 (everything except flippingbuffers) stays around 2-3 ms. But my t2 (only flipping buffers) stays around 60ms. I know this sounds like a hardware thing, but many games work perfectly, and I have the newest graphics drivers. It's an AthlonXP 1800+ with a Radeon 8500le, and 512mb of ram. [Edited by - PureW on May 20, 2007 6:02:40 AM]
Advertisement
Maybe V-Sync ist turned on in your graphics driver, so the swap function waits for the v-sync.
http://3d.benjamin-thaut.de
Quote:Original post by Ingrater
Maybe V-Sync ist turned on in your graphics driver, so the swap function waits for the v-sync.


Nah that's not the problem. If I increase the number of objects to be drawn, the time to flip buffers increase.
[Sorry I was answering the wrong question]
It's not what you're taught, it's what you learn.
You should post your drawing code.
Also on my machine swapping buffers takes 0 ms
http://3d.benjamin-thaut.de
Quote:Original post by Ingrater
You should post your drawing code.
Also on my machine swapping buffers takes 0 ms


I edited my first post and added drawing.

When you say on your machine, did you try my exe, or in
one of your own projects?
I tried your exe.
The drawing code seems fine.
To me this seems to be an ATI OpenGL driver issue again.

How many Bugs are you drawing?
http://3d.benjamin-thaut.de
I'm not entirely sure what 'maxbugs' is, but I'll assume it's a decent amount (ie: a few hundred).

Normal OpenGL calls are asynchronous, that is, they send the data to the GPU, and the rest of the code keeps running. The triangles/quads/etc are NOT drawn at the time they are called.. rather they are drawn when ever it is convenient for the graphics card. Obviously, when you call swapbuffers, you need a completely drawn scene before you can swap to the viewers screen. So, swap buffers waits for the graphics card to finish drawing to the back buffer before it swaps to the screen.

Is this your bottleneck? To check, try putting glFinish() (Which will wait for the graphics card to completely finish drawing the scene before it returns) right before the swapbuffers call and time that, and then have another timer for swapbuffers to see if the time has lowered. Also, i'd recommend stopping the timer right after the call, rather than getting it's elapsed time in std::cout. std::cout can be an expensive call that takes several milliseconds itself.

Hope that helped
~zix
---------------------------------------------------Game Programming Resources, Tutorials, and Multimedia | Free Skyboxes
Quote:Original post by zix99
I'm not entirely sure what 'maxbugs' is, but I'll assume it's a decent amount (ie: a few hundred).

maxBugs is 6000 in the downloadable exe.

Quote:Original post by zix99
Is this your bottleneck? To check, try putting glFinish() (Which will wait for the graphics card to completely finish drawing the scene before it returns) right before the swapbuffers call and time that, and then have another timer for swapbuffers to see if the time has lowered. Also, i'd recommend stopping the timer right after the call, rather than getting it's elapsed time in std::cout. std::cout can be an expensive call that takes several milliseconds itself.

Hope that helped
~zix


Thank you, I didn't know this, I'll try it as soon as I fix an mysterious error that surfaced after transfering the whole project to my other computer.
Someone was right, it was the ati drivers.

I tried it on my new computer, with an Nvidia 6800le card, and I could
render twice that amount, 12000 bugs in 11 ms, with the flip taking 0 ms.

Thank you all!

This topic is closed to new replies.

Advertisement