Hi Ken,
The problem you explain is indeed strange. I have never encountered this issue with opengl32 before. I tried to find a bug in the test, but didn't really see anything strange. If your theory about wglCreateContext being needed to 'heat things up' is true, maybe it has to do with ICD loading.
Assuming you picked a pixel format, which requires the hw vendor's ICD, I believe wglCreateContext kicks of driver initialization unless it is done implicitly at an earlier stage (something happens for sure earlier for pixel format enumeration). Various ICD provided functions like the ICD version of wglGetProcAddress are loaded at time and I wouldn't be surprised if that is also when they hook up the ICD versions of MakeCurrent, CreateContext, SetPixelFormat, GetPixelFormat and others. Just a wild guess.
Thanks, Roderick
On Wed, Feb 12, 2014 at 6:46 AM, Ken Thomases ken@codeweavers.com wrote:
Hi,
I have been working on refining a d3d9 test patch I recently submitted < http://source.winehq.org/patches/data/102263%3E and noticed a strange behavior when running on a real Windows machine. I'm wondering if anybody is familiar with it or can check my reasoning.
The strange behavior is that a failed call to wglCreateContext() must be done before SetPixelFormat() will work properly. The call to wglCreateContext() has to fail because it can't succeed until SetPixelFormat() has been done. And yet it still seems to be necessary.
My test does the following sequence:
CreateWindowA() GetDC() ChoosePixelFormat() SetPixelFormat() GetPixelFormat()
This seems fairly simple, straightforward, and commonplace. Although everything through the SetPixelFormat() indicates success, the GetPixelFormat() call still returns 0. This causes the test to be skipped. This happened on the testbot, but I assumed that was caused by the VM's display driver. However, when I got the chance to try on a real Windows machine, it happened there, too.
I looked around to see if the same sort of thing is done elsewhere in Wine. It's done in the opengl32 tests in test_setpixelformat() < http://source.winehq.org/source/dlls/opengl32/tests/opengl.c#L254%3E and it works there, both on the testbot and the Windows machine.
So, then I figured it must be working in those tests because of stuff that is done beforehand. I disabled most of the opengl32 tests other than test_setpixelformat(). That was testbot job < https://newtestbot.winehq.org/JobDetails.pl?Key=4751%3E and it still passed on the testbot and real Windows.
I then disabled the expected-to-fail call to wglCreateContext() that is done in the test main entry function (START_TEST(opengl)). Once that is disabled, test_setpixelformat() starts failing in the same way as my d3d9 test. That is testbot job < https://newtestbot.winehq.org/JobDetails.pl?Key=4752%3E.
So, can it really be that a failed call to wglCreateContext() is necessary before SetPixelFormat() will work properly?
One thing that I haven't had the chance to test yet is whether a wglCreateContext() call _after_ SetPixelFormat() will cause a subsequent GetPixelFormat() to return the right format. That is, perhaps SetPixelFormat() has worked and the pixel format is remembered, but it's only "realized" once wglCreateContext() is called. And GetPixelFormat() only returns realized pixel formats.
Also, it's possible that it's sufficient to call any opengl32 function and not wglCreateContext() specifically. (ChoosePixelFormat(), SetPixelFormat(), and GetPixelFormat() are gdi32 functions.)
In any case, that would mean that my d3d9 test will have to link with opengl32 and call one of its functions.
-Ken