winex11.drv: Prioritize smaller depth formats when zero depth is requested in X11DRV_wglChoosePixelFormatARB().
Fixes Ancient Cities' black screen on Nvidia. Signed-off-by: Paul Gofman <pgofman@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
bfa3c95611
commit
e392e0ac28
|
@ -1764,6 +1764,62 @@ static void test_swap_control(HDC oldhdc)
|
||||||
wglMakeCurrent(oldhdc, oldctx);
|
wglMakeCurrent(oldhdc, oldctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_wglChoosePixelFormatARB(HDC hdc)
|
||||||
|
{
|
||||||
|
static int attrib_list[] =
|
||||||
|
{
|
||||||
|
WGL_DRAW_TO_WINDOW_ARB, 1,
|
||||||
|
WGL_SUPPORT_OPENGL_ARB, 1,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
PIXELFORMATDESCRIPTOR fmt, last_fmt;
|
||||||
|
BYTE depth, last_depth;
|
||||||
|
UINT format_count;
|
||||||
|
int formats[1024];
|
||||||
|
unsigned int i;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (!pwglChoosePixelFormatARB)
|
||||||
|
{
|
||||||
|
skip("wglChoosePixelFormatARB is not available\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
format_count = 0;
|
||||||
|
res = pwglChoosePixelFormatARB(hdc, attrib_list, NULL, ARRAY_SIZE(formats), formats, &format_count);
|
||||||
|
ok(res, "Got unexpected result %d.\n", res);
|
||||||
|
|
||||||
|
memset(&last_fmt, 0, sizeof(last_fmt));
|
||||||
|
last_depth = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < format_count; ++i)
|
||||||
|
{
|
||||||
|
memset(&fmt, 0, sizeof(fmt));
|
||||||
|
if (!DescribePixelFormat(hdc, formats[i], sizeof(fmt), &fmt)
|
||||||
|
|| (fmt.dwFlags & PFD_GENERIC_FORMAT))
|
||||||
|
{
|
||||||
|
memset(&fmt, 0, sizeof(fmt));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
depth = fmt.cDepthBits;
|
||||||
|
fmt.cDepthBits = 0;
|
||||||
|
fmt.cStencilBits = 0;
|
||||||
|
|
||||||
|
if (memcmp(&fmt, &last_fmt, sizeof(fmt)))
|
||||||
|
{
|
||||||
|
last_fmt = fmt;
|
||||||
|
last_depth = depth;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ok(last_depth <= depth, "Got unexpected depth %u, last_depth %u, i %u, format %u.\n",
|
||||||
|
depth, last_depth, i, formats[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(opengl)
|
START_TEST(opengl)
|
||||||
{
|
{
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
|
@ -1858,6 +1914,7 @@ START_TEST(opengl)
|
||||||
}
|
}
|
||||||
|
|
||||||
test_choosepixelformat();
|
test_choosepixelformat();
|
||||||
|
test_wglChoosePixelFormatARB(hdc);
|
||||||
test_debug_message_callback();
|
test_debug_message_callback();
|
||||||
test_setpixelformat(hdc);
|
test_setpixelformat(hdc);
|
||||||
test_destroy(hdc);
|
test_destroy(hdc);
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "x11drv.h"
|
#include "x11drv.h"
|
||||||
#include "xcomposite.h"
|
#include "xcomposite.h"
|
||||||
#include "winternl.h"
|
#include "winternl.h"
|
||||||
|
#include "wine/heap.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
#ifdef SONAME_LIBGL
|
#ifdef SONAME_LIBGL
|
||||||
|
@ -2486,6 +2487,37 @@ static BOOL X11DRV_wglSetPbufferAttribARB( struct wgl_pbuffer *object, const int
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct choose_pixel_format_arb_format
|
||||||
|
{
|
||||||
|
int format;
|
||||||
|
int original_index;
|
||||||
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
|
int depth, stencil;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int compare_formats(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
/* Order formats so that onscreen formats go first. Then, if no depth bits requested,
|
||||||
|
* prioritize formats with smaller depth within the original sort order with respect to
|
||||||
|
* other attributes. */
|
||||||
|
const struct choose_pixel_format_arb_format *fmt_a = a, *fmt_b = b;
|
||||||
|
BOOL offscreen_a, offscreen_b;
|
||||||
|
|
||||||
|
offscreen_a = fmt_a->format > nb_onscreen_formats;
|
||||||
|
offscreen_b = fmt_b->format > nb_onscreen_formats;
|
||||||
|
|
||||||
|
if (offscreen_a != offscreen_b)
|
||||||
|
return offscreen_a - offscreen_b;
|
||||||
|
if (memcmp(&fmt_a->pfd, &fmt_b->pfd, sizeof(fmt_a->pfd)))
|
||||||
|
return fmt_a->original_index - fmt_b->original_index;
|
||||||
|
if (fmt_a->depth != fmt_b->depth)
|
||||||
|
return fmt_a->depth - fmt_b->depth;
|
||||||
|
if (fmt_a->stencil != fmt_b->stencil)
|
||||||
|
return fmt_a->stencil - fmt_b->stencil;
|
||||||
|
|
||||||
|
return fmt_a->original_index - fmt_b->original_index;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* X11DRV_wglChoosePixelFormatARB
|
* X11DRV_wglChoosePixelFormatARB
|
||||||
*
|
*
|
||||||
|
@ -2494,17 +2526,15 @@ static BOOL X11DRV_wglSetPbufferAttribARB( struct wgl_pbuffer *object, const int
|
||||||
static BOOL X11DRV_wglChoosePixelFormatARB( HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList,
|
static BOOL X11DRV_wglChoosePixelFormatARB( HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList,
|
||||||
UINT nMaxFormats, int *piFormats, UINT *nNumFormats )
|
UINT nMaxFormats, int *piFormats, UINT *nNumFormats )
|
||||||
{
|
{
|
||||||
|
struct choose_pixel_format_arb_format *formats;
|
||||||
|
int it, i, format_count;
|
||||||
|
BYTE depth_bits = 0;
|
||||||
|
GLXFBConfig* cfgs;
|
||||||
|
DWORD dwFlags = 0;
|
||||||
int attribs[256];
|
int attribs[256];
|
||||||
int nAttribs = 0;
|
int nAttribs = 0;
|
||||||
GLXFBConfig* cfgs;
|
|
||||||
int nCfgs = 0;
|
int nCfgs = 0;
|
||||||
int it;
|
|
||||||
int fmt_id;
|
int fmt_id;
|
||||||
int start, end;
|
|
||||||
UINT pfmt_it = 0;
|
|
||||||
int run;
|
|
||||||
int i;
|
|
||||||
DWORD dwFlags = 0;
|
|
||||||
|
|
||||||
TRACE("(%p, %p, %p, %d, %p, %p): hackish\n", hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats);
|
TRACE("(%p, %p, %p, %d, %p, %p): hackish\n", hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats);
|
||||||
if (NULL != pfAttribFList) {
|
if (NULL != pfAttribFList) {
|
||||||
|
@ -2548,6 +2578,10 @@ static BOOL X11DRV_wglChoosePixelFormatARB( HDC hdc, const int *piAttribIList, c
|
||||||
if(piAttribIList[i+1])
|
if(piAttribIList[i+1])
|
||||||
dwFlags |= PFD_SUPPORT_GDI;
|
dwFlags |= PFD_SUPPORT_GDI;
|
||||||
break;
|
break;
|
||||||
|
case WGL_DEPTH_BITS_ARB:
|
||||||
|
depth_bits = piAttribIList[i+1];
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2558,37 +2592,57 @@ static BOOL X11DRV_wglChoosePixelFormatARB( HDC hdc, const int *piAttribIList, c
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loop through all matching formats and check if they are suitable.
|
if (!(formats = heap_alloc(nCfgs * sizeof(*formats))))
|
||||||
* Note that this function should at max return nMaxFormats different formats */
|
|
||||||
for(run=0; run < 2; run++)
|
|
||||||
{
|
{
|
||||||
for (it = 0; it < nCfgs && pfmt_it < nMaxFormats; ++it)
|
ERR("No memory.\n");
|
||||||
|
XFree(cfgs);
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
format_count = 0;
|
||||||
|
for (it = 0; it < nCfgs; ++it)
|
||||||
{
|
{
|
||||||
|
struct choose_pixel_format_arb_format *format;
|
||||||
|
|
||||||
if (pglXGetFBConfigAttrib(gdi_display, cfgs[it], GLX_FBCONFIG_ID, &fmt_id))
|
if (pglXGetFBConfigAttrib(gdi_display, cfgs[it], GLX_FBCONFIG_ID, &fmt_id))
|
||||||
{
|
{
|
||||||
ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
|
ERR("Failed to retrieve FBCONFIG_ID from GLXFBConfig, expect problems.\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* During the first run we only want onscreen formats and during the second only offscreen */
|
for (i = 0; i < nb_pixel_formats; ++i)
|
||||||
start = run == 1 ? nb_onscreen_formats : 0;
|
if (pixel_formats[i].fmt_id == fmt_id)
|
||||||
end = run == 1 ? nb_pixel_formats : nb_onscreen_formats;
|
|
||||||
|
|
||||||
for (i = start; i < end; i++)
|
|
||||||
{
|
|
||||||
if (pixel_formats[i].fmt_id == fmt_id && (pixel_formats[i].dwFlags & dwFlags) == dwFlags)
|
|
||||||
{
|
|
||||||
piFormats[pfmt_it++] = i + 1;
|
|
||||||
TRACE("at %d/%d found FBCONFIG_ID 0x%x (%d)\n",
|
|
||||||
it + 1, nCfgs, fmt_id, i + 1);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
if (i == nb_pixel_formats)
|
||||||
}
|
continue;
|
||||||
|
|
||||||
|
format = &formats[format_count];
|
||||||
|
format->format = i + 1;
|
||||||
|
format->original_index = it;
|
||||||
|
|
||||||
|
memset(&format->pfd, 0, sizeof(format->pfd));
|
||||||
|
if (!describe_pixel_format(format->format, &format->pfd, TRUE))
|
||||||
|
ERR("describe_pixel_format failed, format %d.\n", format->format);
|
||||||
|
|
||||||
|
format->depth = format->pfd.cDepthBits;
|
||||||
|
format->stencil = format->pfd.cStencilBits;
|
||||||
|
if (!depth_bits && !(format->pfd.dwFlags & PFD_GENERIC_FORMAT))
|
||||||
|
{
|
||||||
|
format->pfd.cDepthBits = 0;
|
||||||
|
format->pfd.cStencilBits = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*nNumFormats = pfmt_it;
|
++format_count;
|
||||||
/** free list */
|
}
|
||||||
|
|
||||||
|
qsort(formats, format_count, sizeof(*formats), compare_formats);
|
||||||
|
|
||||||
|
*nNumFormats = min(nMaxFormats, format_count);
|
||||||
|
for (i = 0; i < *nNumFormats; ++i)
|
||||||
|
piFormats[i] = formats[i].format;
|
||||||
|
|
||||||
|
heap_free(formats);
|
||||||
XFree(cfgs);
|
XFree(cfgs);
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue