nvidia drivers and SetPixelFormat

I have developed software on a GeForce3 with drivers 30.82 and all works well. I have upgraded to a GeForce4 and ran into problems.
The wglMakeCurrent call takes way too long (~20ms). All other calls, drawing and glReadPixels, take the same amount of time as they used to. What happened?

As a fix, I tried to upgrade to drivers 40.72 and 43.45 and SetPixelFormat fails even though the PixelFormatDescriptor as filled out by DescribePixelFormat after it describes the format chosen by choosePixelFormat is exactly the same. Don’t the new drivers support at least as many formats as they used to? Why would ChoosePixelFormat return a format type that would then fail in SetPixelFormat? Any help would be greatly appreciated.

Thanks,
Alon

Might be easier if you show your code for pixelformat init and choose and describe, etc. It seems as though on my system, it never fails, but won’t give me exactly what I want all of the time… chooses best fit.

Here’s the code - I’m trying to create a context that renders to a pbuffer on the card. Everything I do is offscreen. This same code works fine with driver ver 30.82 but now fails. BTW, I’m happy to stick with ver 30.82 with the GeForce4 if I can solve the wglMakeCurrent slow down.

	int pfd_options = PFD_SUPPORT_OPENGL;
	PIXELFORMATDESCRIPTOR pfd =
	{
		sizeof(PIXELFORMATDESCRIPTOR),
		1,
		pfd_options,
		PFD_TYPE_RGBA,
		32,
		0, 0, 0, 0, 0, 0,
		0,
		0,
		0,
		0, 0, 0, 0,
		0,
		8,
		0,
		PFD_MAIN_PLANE,
		0,
		0, 0, 0
	};

	//Get default device context
	m_hdc = GetDC(NULL);
	if(m_hdc == NULL)
	{
		AfxMessageBox("bad GetDC");
	}

	//Choose pix format - returns closest approximation to what we ask 
	//for as detailed by pfd
	int	pixelFormat;
	pixelFormat = ChoosePixelFormat(m_hdc, &pfd);
	if(pixelFormat == 0)
	{
		AfxMessageBox("bad pixel format chosen");
	}

	DescribePixelFormat(m_hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);

	//Attempt to set our device to the pix format we just found
	if(SetPixelFormat(m_hdc, pixelFormat, &pfd) == FALSE) {
			AfxMessageBox("bad pixel format set");
	} 

	//Create a rendering context to associate with our DC
	m_hRc = wglCreateContext(m_hdc);	
	if(m_hRc == NULL)
	{
		AfxMessageBox("bad rendering context created");
	}

BTW, I also noticed that the PFD_DRAW_TO_WINDOW flag seems to be set on the chosen format even though I want on offscreen rendering and don’t specify it(requested flags = 32, chosen flags = 52). It seems odd that this worked before. If I choose PFD_DRAW_TO_BITMAP to try to counteract it, it results in using software rendering which means no on-card pbuffer. Any other flag I should specify to get it to work?
My process for creating the context (which I gleaned from other sources) is to create a regular context, use that to verify available extensions, and then do a wglCreatePBufferARB - I skipped over the wgl stuff that comes later b/c the first part about creating the regular context seems critical before even worrying about the second part.

[This message has been edited by Alon (edited 04-17-2003).]

Okay, I think I know what your problem may be… maybe. I was debugging the code and never let it exit naturally, so I assume VC automatically undid whatever may have been done. I dunno. ANyway, I let it go through once and now I am getting the same problem. Add wglDeleteContext at the close of your app so it will get rid of the context from the screen HDC. Also, does the app have a window of its own? If so, try to use that HDC. I don’t know how safe it is to use the screen’s HDC. ANyway, I think that the context remains and therefore will not accept a new context. You’ll probably have to reboot because the HDC returned by GetDC(NULL) is not constant and I couldn’t get rid of it.

If that’s not it, try stepping through your app and watch how the pfd changes with each call. Especially the first time you run it after you reboot. It should work that first time through if not the next. However, it could be a problem with GF4 and the new drivers so someone with a GF4 will probably need to test it for you.

[This message has been edited by shinpaughp (edited 04-17-2003).]

While it was a good catch on the release part (I did in fact forget to release the context), that unfortunately wasn’t the problem. It doesn’t work, even from the first time I run it after booting. The pixel format is the same every time, regardless of card - GF3 or GF4 - and regardless of driver version. I am running this from some abstracted thread that tries to render GL stuff and do glReadPixels so I end up with a frame of data - no windows, no displays. That’s the reason I have to use GetDC(NULL) - Perhaps 30.82 is okay with this but not recent drivers? I’m also still curious about the slow down for wglMakeCurrent on GF4 using the 30.82 drivers which worked well on GF3 (still exists despite my fix to releasing the context)…
(btw, thanks much for the help)

Why not use PFD_DRAW_TO_BITMAP instead. Should do what you want… draws to memory not a window. Otherwise, I dunno…

Can’t - I still need to render to a pbuffer on the card and PFD_DRAW_TO_BITMAP only gives me software rendering if that flag is set in the pixel format. I did just check the error code (GetLastError) when setPixelFormat fails with the new driver though - 3221684230 - never seen anything like it and can’t find any record of a code like that. Thanks again for the help.

I had to do that in a program, and I set the PFD_DRAW_TO_WINDOW and PFD_DOUBLEBUFFER flags, but I only used the back buffer, so there was mothing on the screen. Prehaps it is the solution…

[This message has been edited by Acheum (edited 04-18-2003).]

You should be able to use gluErrorString to give you a description of the error code.

Sorry I couldn’t be more help. I had thought someone else might pop in and help out, but…

I haven’t yet figured out the SetPixelFormat failure but I did finally sort of figure out the wglMakeCurrent slow down. We were using an Asus board with a GeForce4 chip and it comes with drivers that offer either the standard nvidia whql drivers, or the Asus “enhanced” drivers. The manufacturer was nice enough to pre-install the Asus drivers which are now apparently buggy. MakeCurrent now works as expected after uninstalling those and choosing the standard nvidia drivers offered on the CD (31.04 I think). It would be nice though to upgrade to version 43.45 if anyone knew why SetPixelFormat fails on a valid format returned by ChoosePixelFormat with the latest drivers…