From cddda524472f813d3abf26a878302b5f28aaeb89 Mon Sep 17 00:00:00 2001 From: odalet Date: Mon, 6 May 2024 10:59:49 +0200 Subject: [PATCH] Added support for Compatibility profile in Wgl and Glx code (#15598) * Added support for Compatibility profile in Wgl and Glx code * Fixes after code review --------- Co-authored-by: Olivier DALET --- src/Avalonia.Native/AvaloniaNativeGlPlatformGraphics.cs | 5 ++++- src/Avalonia.OpenGL/GlConsts.cs | 6 +++--- src/Avalonia.OpenGL/GlVersion.cs | 5 ++++- src/Avalonia.X11/Glx/GlxDisplay.cs | 6 +++++- src/Windows/Avalonia.Win32/OpenGl/WglConsts.cs | 2 ++ src/Windows/Avalonia.Win32/OpenGl/WglDisplay.cs | 9 +++++++-- 6 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/Avalonia.Native/AvaloniaNativeGlPlatformGraphics.cs b/src/Avalonia.Native/AvaloniaNativeGlPlatformGraphics.cs index 16280a90cd..c75f1b19ae 100644 --- a/src/Avalonia.Native/AvaloniaNativeGlPlatformGraphics.cs +++ b/src/Avalonia.Native/AvaloniaNativeGlPlatformGraphics.cs @@ -25,7 +25,10 @@ namespace Avalonia.Native var basic = new GlBasicInfoInterface(display.GetProcAddress); basic.GetIntegerv(GlConsts.GL_MAJOR_VERSION, out major); basic.GetIntegerv(GlConsts.GL_MINOR_VERSION, out minor); - _version = new GlVersion(GlProfileType.OpenGL, major, minor); + basic.GetIntegerv(GlConsts.GL_CONTEXT_PROFILE_MASK, out var profileMask); + var isCompatibilityProfile = (profileMask & GlConsts.GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) == GlConsts.GL_CONTEXT_COMPATIBILITY_PROFILE_BIT; + + _version = new GlVersion(GlProfileType.OpenGL, major, minor, isCompatibilityProfile); glInterface = new GlInterface(_version, (name) => { var rv = _display.GetProcAddress(name); diff --git a/src/Avalonia.OpenGL/GlConsts.cs b/src/Avalonia.OpenGL/GlConsts.cs index 4fbe738ca9..8f53e5a6fa 100644 --- a/src/Avalonia.OpenGL/GlConsts.cs +++ b/src/Avalonia.OpenGL/GlConsts.cs @@ -1282,8 +1282,8 @@ namespace Avalonia.OpenGL // public const int GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8A46; // public const int GL_INVALID_INDEX = -1; // public const int GL_VERSION_3_2 = 1; -// public const int GL_CONTEXT_CORE_PROFILE_BIT = 0x00000001; -// public const int GL_CONTEXT_COMPATIBILITY_PROFILE_BIT = 0x00000002; + public const int GL_CONTEXT_CORE_PROFILE_BIT = 0x00000001; + public const int GL_CONTEXT_COMPATIBILITY_PROFILE_BIT = 0x00000002; // public const int GL_LINES_ADJACENCY = 0x000A; // public const int GL_LINE_STRIP_ADJACENCY = 0x000B; // public const int GL_TRIANGLES_ADJACENCY = 0x000C; @@ -1303,7 +1303,7 @@ namespace Avalonia.OpenGL // public const int GL_MAX_GEOMETRY_INPUT_COMPONENTS = 0x9123; // public const int GL_MAX_GEOMETRY_OUTPUT_COMPONENTS = 0x9124; // public const int GL_MAX_FRAGMENT_INPUT_COMPONENTS = 0x9125; -// public const int GL_CONTEXT_PROFILE_MASK = 0x9126; + public const int GL_CONTEXT_PROFILE_MASK = 0x9126; // public const int GL_DEPTH_CLAMP = 0x864F; // public const int GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION = 0x8E4C; // public const int GL_FIRST_VERTEX_CONVENTION = 0x8E4D; diff --git a/src/Avalonia.OpenGL/GlVersion.cs b/src/Avalonia.OpenGL/GlVersion.cs index 16ed18e45a..2d70fa3ef3 100644 --- a/src/Avalonia.OpenGL/GlVersion.cs +++ b/src/Avalonia.OpenGL/GlVersion.cs @@ -11,12 +11,15 @@ namespace Avalonia.OpenGL public GlProfileType Type { get; } public int Major { get; } public int Minor { get; } + public bool IsCompatibilityProfile { get; } // Only makes sense if Type is OpenGL and Version is >= 3.2 - public GlVersion(GlProfileType type, int major, int minor) + public GlVersion(GlProfileType type, int major, int minor) : this(type, major, minor, false) { } + public GlVersion(GlProfileType type, int major, int minor, bool isCompatibilityProfile) { Type = type; Major = major; Minor = minor; + IsCompatibilityProfile = isCompatibilityProfile; } } } diff --git a/src/Avalonia.X11/Glx/GlxDisplay.cs b/src/Avalonia.X11/Glx/GlxDisplay.cs index 9bcd8f3763..3a0a4026d8 100644 --- a/src/Avalonia.X11/Glx/GlxDisplay.cs +++ b/src/Avalonia.X11/Glx/GlxDisplay.cs @@ -126,7 +126,11 @@ namespace Avalonia.X11.Glx GlxContext Create(GlVersion profile) { var profileMask = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; - if (profile.Type == GlProfileType.OpenGLES) + if (profile.Type == GlProfileType.OpenGL && + profile.IsCompatibilityProfile && + (profile.Major > 3 || profile.Major == 3 && profile.Minor >= 2)) + profileMask = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + else if (profile.Type == GlProfileType.OpenGLES) profileMask = GLX_CONTEXT_ES2_PROFILE_BIT_EXT; var attrs = new int[] diff --git a/src/Windows/Avalonia.Win32/OpenGl/WglConsts.cs b/src/Windows/Avalonia.Win32/OpenGl/WglConsts.cs index 3cb3dc25bb..e83a16aeb3 100644 --- a/src/Windows/Avalonia.Win32/OpenGl/WglConsts.cs +++ b/src/Windows/Avalonia.Win32/OpenGl/WglConsts.cs @@ -7,6 +7,8 @@ namespace Avalonia.Win32.OpenGl public const int WGL_CONTEXT_LAYER_PLANE_ARB = 0x2093; public const int WGL_CONTEXT_FLAGS_ARB = 0x2094; public const int WGL_CONTEXT_PROFILE_MASK_ARB = 0x9126; + public const int WGL_CONTEXT_CORE_PROFILE_BIT_ARB = 0x00000001; + public const int WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB = 0x00000002; public const int WGL_NUMBER_PIXEL_FORMATS_ARB = 0x2000; public const int WGL_DRAW_TO_WINDOW_ARB = 0x2001; diff --git a/src/Windows/Avalonia.Win32/OpenGl/WglDisplay.cs b/src/Windows/Avalonia.Win32/OpenGl/WglDisplay.cs index 85cab1d18e..798c8e7842 100644 --- a/src/Windows/Avalonia.Win32/OpenGl/WglDisplay.cs +++ b/src/Windows/Avalonia.Win32/OpenGl/WglDisplay.cs @@ -126,6 +126,11 @@ namespace Avalonia.Win32.OpenGl IntPtr context; using (shareContext?.Lock()) { + var profileMask = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; + if (version.IsCompatibilityProfile && + (version.Major > 3 || version.Major == 3 && version.Minor >= 2)) + profileMask = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + context = s_wglCreateContextAttribsArb(dc, shareContext?.Handle ?? IntPtr.Zero, new[] { @@ -133,8 +138,8 @@ namespace Avalonia.Win32.OpenGl WGL_CONTEXT_MAJOR_VERSION_ARB, version.Major, // minor WGL_CONTEXT_MINOR_VERSION_ARB, version.Minor, - // core profile - WGL_CONTEXT_PROFILE_MASK_ARB, 1, + // core or compatibility profile + WGL_CONTEXT_PROFILE_MASK_ARB, profileMask, // debug // WGL_CONTEXT_FLAGS_ARB, 1, // end