[PATCH v3 0/1] MR10241: opengl32: Recognize more glHint attributes.
And store only present attributes in context_attributes[]. -- v3: opengl32: Recognize more glHint attributes. https://gitlab.winehq.org/wine/wine/-/merge_requests/10241
From: Paul Gofman <pgofman@codeweavers.com> And store only present attributes in context_attributes[]. --- dlls/opengl32/tests/opengl.c | 19 +++++++++++++ dlls/opengl32/unix_wgl.c | 53 ++++++++++++++++++++++++++++-------- 2 files changed, 61 insertions(+), 11 deletions(-) diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index e0fc1ae1426..ca77784b991 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -1166,7 +1166,13 @@ static void test_setpixelformat(HDC winhdc) static void test_sharelists(HDC winhdc) { BOOL res, nvidia, amd, source_current, source_sharing, dest_current, dest_sharing; + const char *extensions = (const char*)glGetString(GL_EXTENSIONS); HGLRC source, dest, other; + BOOL ms_hint_supported; + + ms_hint_supported = gl_extension_supported(extensions, "GL_NV_multisample_filter_hint"); + if (!ms_hint_supported) + skip("GL_NV_multisample_filter_hint is not supported.\n"); res = wglShareLists(NULL, NULL); ok(!res, "Sharing display lists for no contexts passed!\n"); @@ -1211,8 +1217,15 @@ static void test_sharelists(HDC winhdc) glDisable(GL_DITHER); glDepthFunc(GL_LESS); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); + glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); + glHint(GL_FOG_HINT, GL_NICEST); + if (ms_hint_supported) + glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST); glShadeModel(GL_SMOOTH); glClearColor(0.1, 0.2, 0.3, 1.0); + } if (source_sharing) { @@ -1237,6 +1250,12 @@ static void test_sharelists(HDC winhdc) glEnable(GL_DITHER); glDepthFunc(GL_GREATER); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); + glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); + glHint(GL_FOG_HINT, GL_NICEST); + if (ms_hint_supported) + glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST); glShadeModel(GL_FLAT); glClearColor(0.3, 0.2, 0.1, 1.0); } diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 1d0c995e7fe..6243b403878 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -109,6 +109,11 @@ struct color_buffer_state struct hint_state { GLenum perspective_correction; + GLenum point_smooth; + GLenum line_smooth; + GLenum polygon_smooth; + GLenum fog; + GLenum multisample_nv; }; struct buffers @@ -222,6 +227,7 @@ static struct context *get_current_context( TEB *teb, struct opengl_drawable **d struct context_attribute_desc { + GLenum name; GLbitfield bit; unsigned short offset; unsigned short size; @@ -229,7 +235,7 @@ struct context_attribute_desc static struct context_attribute_desc context_attributes[] = { -#define CONTEXT_ATTRIBUTE_DESC(bit, name, field) [name] = { bit, offsetof(struct context, field), sizeof(((struct context *)0)->field) } +#define CONTEXT_ATTRIBUTE_DESC(bit, name, field) { name, bit, offsetof(struct context, field), sizeof(((struct context *)0)->field) } CONTEXT_ATTRIBUTE_DESC( GL_COLOR_BUFFER_BIT, GL_COLOR_CLEAR_VALUE, color_buffer.clear_color ), CONTEXT_ATTRIBUTE_DESC( GL_DEPTH_BUFFER_BIT, GL_DEPTH_FUNC, depth_buffer.depth_func ), CONTEXT_ATTRIBUTE_DESC( GL_ENABLE_BIT, GL_CULL_FACE, enable.cull_face ), @@ -239,6 +245,11 @@ static struct context_attribute_desc context_attributes[] = CONTEXT_ATTRIBUTE_DESC( GL_ENABLE_BIT, GL_LIGHTING, enable.lighting ), CONTEXT_ATTRIBUTE_DESC( GL_ENABLE_BIT, GL_NORMALIZE, enable.normalize ), CONTEXT_ATTRIBUTE_DESC( GL_HINT_BIT, GL_PERSPECTIVE_CORRECTION_HINT, hint.perspective_correction ), + CONTEXT_ATTRIBUTE_DESC( GL_HINT_BIT, GL_POINT_SMOOTH_HINT, hint.point_smooth ), + CONTEXT_ATTRIBUTE_DESC( GL_HINT_BIT, GL_LINE_SMOOTH_HINT, hint.line_smooth ), + CONTEXT_ATTRIBUTE_DESC( GL_HINT_BIT, GL_POLYGON_SMOOTH_HINT, hint.polygon_smooth ), + CONTEXT_ATTRIBUTE_DESC( GL_HINT_BIT, GL_FOG_HINT, hint.fog ), + CONTEXT_ATTRIBUTE_DESC( GL_HINT_BIT, GL_MULTISAMPLE_FILTER_HINT_NV, hint.multisample_nv ), CONTEXT_ATTRIBUTE_DESC( GL_LIGHTING_BIT, GL_LIGHT_MODEL_AMBIENT, lighting.model.ambient ), CONTEXT_ATTRIBUTE_DESC( GL_LIGHTING_BIT, GL_LIGHT_MODEL_TWO_SIDE, lighting.model.two_side ), CONTEXT_ATTRIBUTE_DESC( GL_LIGHTING_BIT, GL_SHADE_MODEL, lighting.shade_model ), @@ -246,22 +257,36 @@ static struct context_attribute_desc context_attributes[] = #undef CONTEXT_ATTRIBUTE_DESC }; -/* GL constants used as indexes should be small, make sure size is reasonable */ -C_ASSERT( sizeof(context_attributes) <= 64 * 1024 ); +static int compare_context_attributes( const void *v1, const void *v2 ) +{ + const struct context_attribute_desc *a1 = v1, *a2 = v2; + + return (int)a1->name - (int)a2->name; +}; void set_context_attribute( TEB *teb, GLenum name, const void *value, size_t size ) { + struct context_attribute_desc key = { .name = name }; + const struct context_attribute_desc *desc; struct context *ctx; - GLbitfield bit; if (!(ctx = get_current_context( teb, NULL, NULL ))) return; - if (name >= ARRAY_SIZE(context_attributes) || !(bit = context_attributes[name].bit)) bit = -1 /* unsupported */; - else if (size && size != context_attributes[name].size) ERR( "Invalid state attrib %#x parameter size %#zx\n", name, size ); - else memcpy( (char *)ctx + context_attributes[name].offset, value, context_attributes[name].size ); - - if (bit == -1 && ctx->used != -1) WARN( "Unsupported attribute on context %p\n", ctx ); - ctx->used |= bit; + if ((desc = bsearch( &key, context_attributes, ARRAY_SIZE(context_attributes), sizeof(*context_attributes), + compare_context_attributes ))) + { + if (size && size != desc->size) ERR( "Invalid state attrib %#x parameter size %#zx\n", name, size ); + else + { + memcpy( (char *)ctx + desc->offset, value, desc->size ); + ctx->used |= desc->bit; + } + } + else + { + if (ctx->used != -1) WARN( "Unsupported attribute on context %p/%p\n", teb->glCurrentRC, ctx ); + ctx->used |= -1; + } } static BOOL copy_context_attributes( TEB *teb, HGLRC client_dst, struct context *dst, @@ -326,7 +351,12 @@ static BOOL copy_context_attributes( TEB *teb, HGLRC client_dst, struct context } if (mask & GL_HINT_BIT) { - funcs->p_glHint( GL_PERSPECTIVE_CORRECTION_HINT, src->hint.perspective_correction ); + if (src->hint.perspective_correction) funcs->p_glHint( GL_PERSPECTIVE_CORRECTION_HINT, src->hint.perspective_correction ); + if (src->hint.point_smooth) funcs->p_glHint( GL_POINT_SMOOTH_HINT, src->hint.perspective_correction ); + if (src->hint.line_smooth) funcs->p_glHint( GL_LINE_SMOOTH_HINT, src->hint.perspective_correction ); + if (src->hint.polygon_smooth) funcs->p_glHint( GL_POLYGON_SMOOTH_HINT, src->hint.perspective_correction ); + if (src->hint.fog) funcs->p_glHint( GL_FOG_HINT, src->hint.perspective_correction ); + if (src->hint.multisample_nv) funcs->p_glHint( GL_MULTISAMPLE_FILTER_HINT_NV, src->hint.multisample_nv ); dst->hint = src->hint; } if (mask & GL_LIGHTING_BIT) @@ -2022,6 +2052,7 @@ NTSTATUS process_attach( void *args ) zero_bits = (ULONG_PTR)info.HighestUserAddress | 0x7fffffff; } + qsort( context_attributes, ARRAY_SIZE(context_attributes), sizeof(*context_attributes), compare_context_attributes ); return STATUS_SUCCESS; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10241
On Wed Mar 4 15:11:32 2026 +0000, Rémi Bernon wrote:
Would be nice to check that the hints are preserved here and below for dest context. I don't know how to fetch those hints from GL, it is probably not possible. That's probably the reason the existing GL_PERSPECTIVE_CORRECTION_HINT is not checked? Checking that can only be done through rendering, and reliably checking the effect is not that obvious, and it is not given that the implementation won't just ignore some hints. Looks like a bit of overdo?
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10241#note_131280
On Wed Mar 4 15:17:59 2026 +0000, Paul Gofman wrote:
I don't know how to fetch those hints from GL, it is probably not possible. That's probably the reason the existing GL_PERSPECTIVE_CORRECTION_HINT is not checked? Checking that can only be done through rendering, and reliably checking the effect is not that obvious, and it is not given that the implementation won't just ignore some hints. Looks like a bit of overdo? Oh sorry, actually glGetIntegerv() can fetch those under the same names, it is absence of reference to glGet in glHint docs and absence of the check for existing GL_PERSPECTIVE_CORRECTION_HINT that tripped me.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10241#note_131281
participants (2)
-
Paul Gofman -
Paul Gofman (@gofman)