Fixes ClaDun X2 missing rendering parts on AMD. The GL game uses stencil and requests pixel format with depth 16, stencil 8. On Wine / AMD that ends up with 16x0 format as there is no 16x8 advertised (16x0 only) and depth takes absolute priority. On the same Windows machine I see both 16x0 and 16x8 formats, but when 16x8 is requested 24x8 is returned (and 16x0 if 16x0 is requested).
That currently works under Wine / Nvidia because there is no 16 bit depth formats advertised at all and it ends up with 24x8 without this patch.
-- v2: opengl32/tests: Add more tests for ChoosePixelFormat(). opengl32: Prioritize stencil check over depth check in wglChoosePixelFormat().
From: Paul Gofman pgofman@codeweavers.com
Patch by Matteo Bruni.
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/opengl32/wgl.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index bd7f7d22e98..49f1e4700b4 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -564,27 +564,27 @@ INT WINAPI wglChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR* ppfd) continue; } } - if (ppfd->cDepthBits && !(ppfd->dwFlags & PFD_DEPTH_DONTCARE)) + if (ppfd->cStencilBits) { - if (((ppfd->cDepthBits > best.cDepthBits) && (format.cDepthBits > best.cDepthBits)) || - ((format.cDepthBits >= ppfd->cDepthBits) && (format.cDepthBits < best.cDepthBits))) + if (((ppfd->cStencilBits > best.cStencilBits) && (format.cStencilBits > best.cStencilBits)) || + ((format.cStencilBits >= ppfd->cStencilBits) && (format.cStencilBits < best.cStencilBits))) goto found;
- if (best.cDepthBits != format.cDepthBits) + if (best.cStencilBits != format.cStencilBits) { - TRACE( "depth mismatch for iPixelFormat=%d\n", i ); + TRACE( "stencil mismatch for iPixelFormat=%d\n", i ); continue; } } - if (ppfd->cStencilBits) + if (ppfd->cDepthBits && !(ppfd->dwFlags & PFD_DEPTH_DONTCARE)) { - if (((ppfd->cStencilBits > best.cStencilBits) && (format.cStencilBits > best.cStencilBits)) || - ((format.cStencilBits >= ppfd->cStencilBits) && (format.cStencilBits < best.cStencilBits))) + if (((ppfd->cDepthBits > best.cDepthBits) && (format.cDepthBits > best.cDepthBits)) || + ((format.cDepthBits >= ppfd->cDepthBits) && (format.cDepthBits < best.cDepthBits))) goto found;
- if (best.cStencilBits != format.cStencilBits) + if (best.cDepthBits != format.cDepthBits) { - TRACE( "stencil mismatch for iPixelFormat=%d\n", i ); + TRACE( "depth mismatch for iPixelFormat=%d\n", i ); continue; } }
From: Paul Gofman pgofman@codeweavers.com
Test extended by Matteo Bruni. --- dlls/opengl32/tests/opengl.c | 55 ++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+)
diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index 8b0e70ccf9c..f05bb09d4b6 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -342,6 +342,61 @@ static void test_choosepixelformat(void) pfd.cDepthBits = 0; pfd.cStencilBits = 0; pfd.dwFlags &= ~PFD_DEPTH_DONTCARE; + + pfd.cDepthBits = 16; + ok( test_pfd(&pfd, &ret_fmt), "depth 16 failed.\n" ); + ok( ret_fmt.cDepthBits >= 16, "Got unexpected cDepthBits %u.\n", ret_fmt.cDepthBits ); + pfd.cDepthBits = 0; + + pfd.cDepthBits = 16; + pfd.cStencilBits = 8; + ok( test_pfd(&pfd, &ret_fmt), "depth 16, stencil 8 failed.\n" ); + ok( ret_fmt.cDepthBits >= 16, "Got unexpected cDepthBits %u.\n", ret_fmt.cDepthBits ); + ok( ret_fmt.cStencilBits == 8, "Got unexpected cStencilBits %u.\n", ret_fmt.cStencilBits ); + pfd.cDepthBits = 0; + pfd.cStencilBits = 0; + + pfd.cDepthBits = 8; + pfd.cStencilBits = 8; + ok( test_pfd(&pfd, &ret_fmt), "depth 8, stencil 8 failed.\n" ); + ok( ret_fmt.cDepthBits >= 8, "Got unexpected cDepthBits %u.\n", ret_fmt.cDepthBits ); + ok( ret_fmt.cStencilBits == 8, "Got unexpected cStencilBits %u.\n", ret_fmt.cStencilBits ); + pfd.cDepthBits = 0; + pfd.cStencilBits = 0; + + pfd.cDepthBits = 24; + pfd.cStencilBits = 8; + ok( test_pfd(&pfd, &ret_fmt), "depth 24, stencil 8 failed.\n" ); + ok( ret_fmt.cDepthBits >= 24, "Got unexpected cDepthBits %u.\n", ret_fmt.cDepthBits ); + ok( ret_fmt.cStencilBits == 8, "Got unexpected cStencilBits %u.\n", ret_fmt.cStencilBits ); + pfd.cDepthBits = 0; + pfd.cStencilBits = 0; + + pfd.cDepthBits = 32; + pfd.cStencilBits = 8; + ok( test_pfd(&pfd, &ret_fmt), "depth 32, stencil 8 failed.\n" ); + ok( ret_fmt.cDepthBits >= 24, "Got unexpected cDepthBits %u.\n", ret_fmt.cDepthBits ); + ok( ret_fmt.cStencilBits == 8, "Got unexpected cStencilBits %u.\n", ret_fmt.cStencilBits ); + pfd.cDepthBits = 0; + pfd.cStencilBits = 0; + + pfd.cDepthBits = 32; + ok( test_pfd(&pfd, &ret_fmt), "depth 32, stencil 8 failed.\n" ); + ok( ret_fmt.cDepthBits >= 24, "Got unexpected cDepthBits %u.\n", ret_fmt.cDepthBits ); + ok( !ret_fmt.cStencilBits, "Got unexpected cStencilBits %u.\n", ret_fmt.cStencilBits ); + pfd.cDepthBits = 0; + + pfd.cStencilBits = 8; + ok( test_pfd(&pfd, &ret_fmt), "depth 32, stencil 8 failed.\n" ); + ok( ret_fmt.cStencilBits == 8, "Got unexpected cStencilBits %u.\n", ret_fmt.cStencilBits ); + pfd.cStencilBits = 0; + + pfd.cDepthBits = 1; + pfd.cStencilBits = 8; + ok( test_pfd(&pfd, &ret_fmt), "depth 32, stencil 8 failed.\n" ); + ok( ret_fmt.cStencilBits == 8, "Got unexpected cStencilBits %u.\n", ret_fmt.cStencilBits ); + pfd.cStencilBits = 0; + pfd.cDepthBits = 0; }
static void WINAPI gl_debug_message_callback(GLenum source, GLenum type, GLuint id, GLenum severity,
v2: - Used Matteo's version (which checks for stencil before depth instead of fixing up request paramaters); - Split off tests in a separate patch.
This merge request was approved by Matteo Bruni.
I don't know that basically approving my own patches adds a lot of value, but...