[PATCH v2 0/5] MR10103: win32u, opengl: Misc opengl fixes.
-- v2: opengl32: Also bind default framebuffer in pop_default_fbo(). win32u: Don't present new drawable in context_sync_drawables(). opengl32: Create compatibility context in wrap_wglCreateContext(). https://gitlab.winehq.org/wine/wine/-/merge_requests/10103
From: Paul Gofman <pgofman@codeweavers.com> --- dlls/win32u/opengl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 4a1e40f6f0d..48debd72204 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -2736,6 +2736,8 @@ static void display_funcs_init(void) display_funcs.p_context_destroy = win32u_context_destroy; display_funcs.p_context_reset = win32u_context_reset; + register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_multisample" ); + register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_pixel_format" ); display_funcs.p_wglChoosePixelFormatARB = (void *)1; /* never called */ display_funcs.p_wglGetPixelFormatAttribfvARB = (void *)1; /* never called */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10103
From: Paul Gofman <pgofman@codeweavers.com> --- dlls/win32u/opengl.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 48debd72204..5bb07d9e434 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -1874,9 +1874,9 @@ static BOOL context_sync_drawables( struct opengl_context *context, HDC draw_hdc return ret; } -static void push_internal_context( struct opengl_context *context, HDC hdc, int format ) +static void push_internal_context( struct opengl_context *context, struct opengl_drawable *drawable, int format ) { - TRACE( "context %p, hdc %p\n", context, hdc ); + TRACE( "context %p, drawable %s\n", context, debugstr_opengl_drawable( drawable )); if (!context->internal_context) { @@ -1884,7 +1884,7 @@ static void push_internal_context( struct opengl_context *context, HDC hdc, int if (!context->internal_context) ERR( "Failed to create internal context\n" ); } - driver_funcs->p_make_current( context->draw, context->read, context->internal_context ); + driver_funcs->p_make_current( drawable, drawable, context->internal_context ); } static void pop_internal_context( struct opengl_context *context ) @@ -2170,11 +2170,12 @@ static BOOL win32u_wglBindTexImageARB( HPBUFFERARB client_pbuffer, int buffer ) return ret; funcs->p_glGetIntegerv( binding_from_target( pbuffer->texture_target ), &prev_texture ); - push_internal_context( NtCurrentTeb()->glContext, pbuffer->hdc, format ); + push_internal_context( NtCurrentTeb()->glContext, pbuffer->drawable, format ); /* Make sure that the prev_texture is set as the current texture state isn't shared * between contexts. After that copy the pbuffer texture data. */ funcs->p_glBindTexture( pbuffer->texture_target, prev_texture ); + funcs->p_glReadBuffer( source ); funcs->p_glCopyTexImage2D( pbuffer->texture_target, 0, pbuffer->texture_format, 0, 0, pbuffer->width, pbuffer->height, 0 ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10103
From: Paul Gofman <pgofman@codeweavers.com> --- dlls/opengl32/unix_wgl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 315aa3cee27..fa377b89f96 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -1528,7 +1528,13 @@ HGLRC wrap_wglCreateContextAttribsARB( TEB *teb, HDC hdc, HGLRC client_shared, c HGLRC wrap_wglCreateContext( TEB *teb, HDC hdc, HGLRC client_context ) { - return wrap_wglCreateContextAttribsARB( teb, hdc, NULL, NULL, client_context ); + static const int attribs[] = + { + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, + 0, 0, + }; + + return wrap_wglCreateContextAttribsARB( teb, hdc, NULL, attribs, client_context ); } BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC draw_hdc, HDC read_hdc, HGLRC client_context ) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10103
From: Paul Gofman <pgofman@codeweavers.com> --- dlls/win32u/opengl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 5bb07d9e434..2bc88631adc 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -1852,7 +1852,7 @@ static BOOL context_sync_drawables( struct opengl_context *context, HDC draw_hdc if (new_read != new_draw) opengl_drawable_set_context( new_draw, context ); opengl_drawable_flush( new_read, new_read->interval, 0 ); - opengl_drawable_flush( new_draw, new_draw->interval, GL_FLUSH_PRESENT ); + opengl_drawable_flush( new_draw, new_draw->interval, 0 ); } if (ret) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10103
From: Paul Gofman <pgofman@codeweavers.com> So if the drawable is switched from framebuffer drawable default FBO is properly restored. --- dlls/opengl32/unix_wgl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index fa377b89f96..6d73b1cd735 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -1680,8 +1680,8 @@ void pop_default_fbo( TEB *teb ) RECT rect; if (!(ctx = get_current_context( teb, &draw, &read ))) return; - if (!ctx->draw_fbo && draw->draw_fbo) funcs->p_glBindFramebuffer( GL_DRAW_FRAMEBUFFER, draw->draw_fbo ); - if (!ctx->read_fbo && read->read_fbo) funcs->p_glBindFramebuffer( GL_READ_FRAMEBUFFER, read->read_fbo ); + if (!ctx->draw_fbo) funcs->p_glBindFramebuffer( GL_DRAW_FRAMEBUFFER, draw->draw_fbo ); + if (!ctx->read_fbo) funcs->p_glBindFramebuffer( GL_READ_FRAMEBUFFER, read->read_fbo ); if (!ctx->has_viewport && draw->draw_fbo && draw->client) { NtUserGetClientRect( draw->client->hwnd, &rect, NtUserGetDpiForWindow( draw->client->hwnd ) ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10103
v2: - rename "win32u: Create compatibility EGL context if no attribs specified." to "opengl32: Create compatibility context in wrap_wglCreateContext().", -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10103#note_129650
Rémi Bernon (@rbernon) commented about dlls/win32u/opengl.c:
display_funcs.p_context_destroy = win32u_context_destroy; display_funcs.p_context_reset = win32u_context_reset;
+ register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_multisample" );
Should we check for GL_ARB_multisample as the winemac driver does? This could be done in init_device_info maybe, where we create contexts (it needs to check that the initialized device is the display device one). -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10103#note_129684
On Sat Feb 14 09:03:08 2026 +0000, Rémi Bernon wrote:
Should we check for GL_ARB_multisample as the winemac driver does? This could be done in init_device_info maybe, where we create contexts (it needs to check that the initialized device is the display device one). Well, I am struggling to find it specified entirely clearly, but I think those are different things. WGL_ARB_multisample is a WSI thing, it is responsible for supporting corresponding visual / pixel format queries (e. g., WGL_SAMPLES_ARB pixel format attrib). On GLX there is direct equivalent GLX_ARB_multisample (giving, e. g., GLX_SAMPLES_ARB). It looks like on EGL those are supported unconditionally (like EGL_SAMPLES_ARB) and that what Wine does. Then, GL_ARB_multisample is GL rendering driver extension, allowing using multisampling in GL rendering commands. So I think there is no equivalent. So it seems to me that from format correctness standpoint we don't have reasons to disable WGL_ARB_multisample even if GL_ARB_multisample is somehow not avaialable.
This distinction also makes it not entirely straightforward: GL_ one are specific for device while WGL_ extensions are not. So maybe we can keep it straightforward and simpler in this case and just enable WGL_ARB_multisample, as we enable unconditionally the functionality under exactly this? Note that if the extension is supported, it doesn't mean that multisample is supported: the system may in theory still not be giving any multisampled visual configs. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10103#note_129695
On Sat Feb 14 16:10:44 2026 +0000, Paul Gofman wrote:
Well, I am struggling to find it specified entirely clearly, but I think those are different things. WGL_ARB_multisample is a WSI thing, it is responsible for supporting corresponding visual / pixel format queries (e. g., WGL_SAMPLES_ARB pixel format attrib). On GLX there is direct equivalent GLX_ARB_multisample (giving, e. g., GLX_SAMPLES_ARB). It looks like on EGL those are supported unconditionally (like EGL_SAMPLES_ARB) and that what Wine does. Then, GL_ARB_multisample is GL rendering driver extension, allowing using multisampling in GL rendering commands. So I think there is no equivalent. So it seems to me that from format correctness standpoint we don't have reasons to disable WGL_ARB_multisample even if GL_ARB_multisample is somehow not avaialable. This distinction also makes it not entirely straightforward: GL_ one are specific for device while WGL_ extensions are not. So maybe we can keep it straightforward and simpler in this case and just enable WGL_ARB_multisample, as we enable unconditionally the functionality under exactly this? Note that if the extension is supported, it doesn't mean that multisample is supported: the system may in theory still not be giving any multisampled visual configs. Important correction in the text above; 'EGL_SAMPLES_ARB' -> 'EGL_SAMPLES' (the difference reflects the fact that support for that constant in corresponding query is not optional and does not depend on any extension).
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10103#note_129696
On Sat Feb 14 16:12:28 2026 +0000, Paul Gofman wrote:
Important correction in the text above; 'EGL_SAMPLES_ARB' -> 'EGL_SAMPLES' (the difference reflects the fact that support for that constant in corresponding query is not optional and does not depend on any extension). And while I don't know much of macdrv details, I looked up this part in winemac.drv and I have a guess why it is checked there. winemac generates (simulates?) all the pixel formats / visuals itself (there is no mac WSI direct equivalent), and multisample variants are generated based on 'renderer' properties, while whether renderer supports multisampling or not is controlled by GL render's GL_ extension. That is different from EGL / GLX, where, similar to WGL, the pixel formats / visuals / config are obtained from the system. Where GLX needs GLX_ARB_multisample to support multisampled visuals at all, while EGL always supports that.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10103#note_129706
This merge request was approved by Rémi Bernon. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10103
participants (3)
-
Paul Gofman -
Paul Gofman (@gofman) -
Rémi Bernon (@rbernon)