wglChoosePixelFormatARB for MSAA very slow

Started by
12 comments, last by Florian22222 10 years ago

I am using the tutorial from NeHe Productions http://nehe.gamedev.net/tutorial/fullscreen_antialiasing/16008/ on how to enable MSAA on a gl context.

It all works fine, but the funciton call to wglChoosePixelFormatARB() is very, very slow.

Usually takes about 2-3 second(my pc is a gaming pc, so it should run muchf faster).

Does anyone know why this function is so slow and is there a workaround/solution?

Advertisement

What graphics card are you using, and are the drivers up to date? Also, do you have a small piece of code that emulates it - I'll happily run it my system and report the timing.

If you review the spec for WGL_ARB_pixel_format you'll see that it makes no promises about speed, and notes that the returned list of valid formats is going to be in a device-dependent order. That tells you that the driver must (1) go through each supported pixel format, (2) test it to see if it meets your criteria (and GL doesn't specify how this test is done), (3) assign a score to it, and (4) sort the list by this score to return them.

The key one here is (2) test it to see if it meets your criteria - becuase GL doesn't specify what tests are done, how they're done, etc, drivers are perfectly free to do anything up to and including a mode change to see if a format is good. Having a "gaming PC" shouldn't give you an expectation that this process is going to be fast: a mode change is always going to be slow, even if it's not a mode change it may be something else extensive (and remember - GL doesn't specify so it's device-dependent), and you may even have a lot of formats that match your criteria, so that's a lot of formats that must be tested.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

What do you mean by "what graphics are you using"?

I updated my graphics card driver and it didnt change anything in the time.

I have no small demo unfortunately its all incorporated in my engine. I just let a friend test it on his computer and there without Visual Studio it takes about 1-2 seconds(a bit faster than when i run it from visual studio).

EDIT: Just read the second answer. Is there any workaround for this?

What do you mean by "what graphics are you using"?

I updated my graphics card driver and it didnt change anything in the time.

NVIDIA? AMD? Intel? Something else? And which model?

I have no small demo unfortunately its all incorporated in my engine. I just let a friend test it on his computer and there without Visual Studio it takes about 1-2 seconds(a bit faster than when i run it from visual studio).

EDIT: Just read the second answer. Is there any workaround for this?

I'm not aware of one but I'm not aware that one is necessary. Setting a display mode isn't a performance-critical part of any engine. If you're changing display modes so often that it becomes one, you have a design problem that you should fix.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

I have an NVIDIA GeForce GTX 560 Ti.

Well yes its not a performance-critical part of my engine, yet it bugs me to have this delay in there after starting...

Sorry - I meant graphics card. It does seem unusually slow - as mhagain suggested, you're probably picking a pixel format that returns a large number of potential matches.

Are you specifying WGL_FULL_ACCELERATION_ARB, WGL_SWAP_EXCHANGE_ARB, WGL_TYPE_RGBA_ARB etc? These should reduce the number of matches.

Adding


WGL_SWAP_EXCHANGE_ARB,WGL_SWAP_EXCHANGE_ARB,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
to the iAttributes array actually makes the whole thing run slower than before.
Here's the full iAttributes array without the 2 additions:

int iAttributes[] =
	{
		WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
		WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
		WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
		WGL_COLOR_BITS_ARB,24,
		WGL_ALPHA_BITS_ARB,8,
		WGL_DEPTH_BITS_ARB,16,
		WGL_STENCIL_BITS_ARB,0,
		WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
		WGL_SAMPLE_BUFFERS_ARB,1,
		WGL_SAMPLES_ARB,16,

		0,0
	};

There is no comprehensible reason why it is so excessively slow other than the reason given by mhagain: the specification makes no promises about speed.

Typically, the implementation will have around 150-200 formats available, so in order to take 2-3 seconds, it would have to spend an entire 10-15 milliseconds matching a single format. For comparing a dozen or so values against a list of capabilities, that is... a... lot. Even if you add half a millisecond on top to sort the list of 10-12 formats that match the minimum required specs.

My suspicion is that it's slow not only because the task is complicated, but also because it loads DLLs and fires up the shader compiler, etc. At least on my system, the second call is significantly faster than the first. Also, merely enumerating (without making the driver choose one) formats is slow already. On my system, the driver always chooses the first hit, too. Of course it may look different on a different system.

You can make it slightly faster if you use GetPixelFormat instead of ChoosePixelFormat to enumerate them one by one, look at the caps, and stop as soon as you've found one that you're happy with. It's still quite slow, however.

Caching the format's integer identifier (would have to verify at the next run though, in case hardware or driver gets updated) is something I haven't tried, but this might actually work. Other than that, I'm afraid you'll simply have to live with the fact that it takes a moment to come up.

My 560Ti, driver 335.23, takes 4.5ms in debug build and 3.4ms in release build using the attributes you posted above.

Also, the nNumFormats variable in wglChoosePixelFormatARB returns 4 matches.

Edit to add that those timings are after rebooting my machine.

This topic is closed to new replies.

Advertisement