From 2ea2a68254b5aaab7aabff41a045b9b59f9ca1c0 Mon Sep 17 00:00:00 2001 From: Mary Date: Thu, 8 Apr 2021 23:05:24 +0200 Subject: [PATCH] Fix wglGetExtensionsStringARB definition and enforce to realloc result of GetExtensionsString This fix a crash on AMD drivers on Windows caused by the result being in the .rodata, this fixes a deallocation made by .NET managed code --- SPB/Platform/WGL/WGLHelper.cs | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/SPB/Platform/WGL/WGLHelper.cs b/SPB/Platform/WGL/WGLHelper.cs index 26ad8b2..0c644bd 100644 --- a/SPB/Platform/WGL/WGLHelper.cs +++ b/SPB/Platform/WGL/WGLHelper.cs @@ -20,9 +20,11 @@ public static class WGLHelper private static string[] Extensions; - private delegate string wglGetExtensionsString(); + private delegate IntPtr wglGetExtensionsStringARB(IntPtr hdc); + private delegate IntPtr wglGetExtensionsStringEXT(); - private static wglGetExtensionsString GetExtensionsString; + private static wglGetExtensionsStringEXT GetExtensionsStringEXT; + private static wglGetExtensionsStringARB GetExtensionsStringARB; [UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = true)] private delegate bool wglChoosePixelFormatARBDelegate(IntPtr hdc, int[] piAttribIList, float[] pfAttribFList, int nMaxFormats, int[] piFormats, out int nNumFormats); @@ -47,6 +49,23 @@ public static class WGLHelper public static wglGetSwapIntervalEXTDelegate GetSwapInterval { get; private set; } + + private static string GetExtensionsString() + { + IntPtr stringPtr; + + if (GetExtensionsStringARB != null) + { + stringPtr = GetExtensionsStringARB(WGL.GetCurrentDC()); + } + else + { + stringPtr = GetExtensionsStringEXT(); + } + + return Marshal.PtrToStringAnsi(stringPtr); + } + public static IntPtr GetProcAddress(string procName) { IntPtr result = WGL.GetProcAddress(procName); @@ -122,16 +141,8 @@ private static void EnsureInit() throw new PlatformException($"WGL.MakeCurrent failed for dummy context: {Marshal.GetLastWin32Error()}"); } - // Now that we have a context, query everything we need. - - IntPtr getExtensionsPtr = WGL.GetProcAddress("wglGetExtensionsStringEXT"); - - if (getExtensionsPtr == IntPtr.Zero) - { - getExtensionsPtr = WGL.GetProcAddress("wglGetExtensionsStringARB"); - } - - GetExtensionsString = Marshal.GetDelegateForFunctionPointer(getExtensionsPtr); + GetExtensionsStringARB = Marshal.GetDelegateForFunctionPointer(WGL.GetProcAddress("wglGetExtensionsStringARB")); + GetExtensionsStringEXT = Marshal.GetDelegateForFunctionPointer(WGL.GetProcAddress("wglGetExtensionsStringEXT")); Extensions = GetExtensionsString().Split(" ");