WGL: Detect MESA D3D12 driver and request GDI compatibility

This way we get a non-opaque framebuffer / render target

Fixes #6975

References:
  [1] https://gitlab.gnome.org/GNOME/gtk/-/issues/6975
  [2] https://gitlab.freedesktop.org/mesa/mesa/-/issues/11828
This commit is contained in:
Luca Bacci 2024-09-04 17:53:37 +02:00
parent b2394691cc
commit 7559a87e8a
2 changed files with 29 additions and 5 deletions

View File

@ -135,6 +135,7 @@ struct _GdkWin32Display
guint hasWglOMLSyncControl : 1;
guint hasWglARBPixelFormat : 1;
guint hasGlWINSwapHint : 1;
guint wgl_support_gdi : 1;
#ifdef HAVE_EGL
guint hasEglKHRCreateContext : 1;

View File

@ -295,7 +295,8 @@ find_pixel_format_with_defined_swap_flag (HDC hdc,
}
static int
choose_pixel_format_arb_attribs (HDC hdc)
choose_pixel_format_arb_attribs (GdkWin32Display *display_win32,
HDC hdc)
{
const int attribs_base[] = {
WGL_DRAW_TO_WINDOW_ARB,
@ -355,6 +356,10 @@ choose_pixel_format_arb_attribs (HDC hdc)
attribs_init (&attribs, reserved);
attribs_add_static_array (&attribs, attribs_base);
if (display_win32->wgl_support_gdi)
attribs_add (&attribs, WGL_SUPPORT_GDI_ARB, GL_TRUE);
attribs_commit (&attribs);
attribs_add_static_array (&attribs, attribs_ancillary_buffers);
@ -443,12 +448,14 @@ get_distance (PIXELFORMATDESCRIPTOR *pfd)
* outcome by ordering pixel formats in specific ways.
*/
static int
choose_pixel_format_opengl32 (HDC hdc)
choose_pixel_format_opengl32 (GdkWin32Display *display_win32,
HDC hdc)
{
const DWORD skip_flags = PFD_GENERIC_FORMAT |
PFD_GENERIC_ACCELERATED;
const DWORD required_flags = PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL;
PFD_SUPPORT_OPENGL |
(display_win32->wgl_support_gdi ? PFD_SUPPORT_GDI : 0);
struct {
int index;
@ -503,14 +510,14 @@ get_wgl_pfd (HDC hdc,
return 0;
}
best_pf = choose_pixel_format_arb_attribs (hdc);
best_pf = choose_pixel_format_arb_attribs (display_win32, hdc);
/* Go back to the HDC that we were using, since we are done with the dummy HDC and GL Context */
wglMakeCurrent (hdc_current, hglrc_current);
}
else
{
best_pf = choose_pixel_format_opengl32 (hdc);
best_pf = choose_pixel_format_opengl32 (display_win32, hdc);
if (best_pf > 0)
DescribePixelFormat (hdc, best_pf, sizeof (PIXELFORMATDESCRIPTOR), pfd);
@ -587,6 +594,18 @@ create_dummy_gl_window (void)
return hwnd;
}
static bool
check_driver_is_d3d12 (void)
{
const char *vendor = (const char *) glGetString (GL_VENDOR);
const char *renderer = (const char *) glGetString (GL_RENDERER);
return vendor != NULL &&
g_ascii_strncasecmp (vendor, "MICROSOFT", strlen ("MICROSOFT")) == 0 &&
renderer != NULL &&
g_ascii_strncasecmp (renderer, "D3D12", strlen ("D3D12")) == 0;
}
GdkGLContext *
gdk_win32_display_init_wgl (GdkDisplay *display,
GError **error)
@ -639,6 +658,8 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
display_win32->hasGlWINSwapHint =
epoxy_has_gl_extension ("GL_WIN_swap_hint");
display_win32->wgl_support_gdi = check_driver_is_d3d12();
context = g_object_new (GDK_TYPE_WIN32_GL_CONTEXT_WGL,
"display", display,
NULL);
@ -656,6 +677,7 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
GDK_NOTE (OPENGL, g_print ("WGL API version %d.%d found\n"
" - Vendor: %s\n"
" - Renderer: %s\n"
" - GDI compatibility required: %s\n"
" - Checked extensions:\n"
"\t* WGL_ARB_pixel_format: %s\n"
"\t* WGL_ARB_create_context: %s\n"
@ -665,6 +687,7 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
major, minor,
glGetString (GL_VENDOR),
glGetString (GL_RENDERER),
display_win32->wgl_support_gdi ? "yes" : "no",
display_win32->hasWglARBPixelFormat ? "yes" : "no",
display_win32->hasWglARBCreateContext ? "yes" : "no",
display_win32->hasWglEXTSwapControl ? "yes" : "no",