diff --git a/src/Avalonia.OpenGL/OpenGlException.cs b/src/Avalonia.OpenGL/OpenGlException.cs index ede038f962..d7a42c4400 100644 --- a/src/Avalonia.OpenGL/OpenGlException.cs +++ b/src/Avalonia.OpenGL/OpenGlException.cs @@ -50,10 +50,5 @@ namespace Avalonia.OpenGL return new OpenGlException($"{funcName} failed with error 0x{errorCode.ToString("X")}", intErrorCode); } } - - /// - /// Throw helper that is used to allow callers to be inlined. - /// - public static OpenGlException ThrowFormattedException(string funcName, EglInterface egl) => throw GetFormattedEglException(funcName, egl.GetError()); } } diff --git a/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleWin32EglDisplay.cs b/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleWin32EglDisplay.cs index e6a01b300c..892278a60a 100644 --- a/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleWin32EglDisplay.cs +++ b/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleWin32EglDisplay.cs @@ -59,7 +59,6 @@ namespace Avalonia.Win32.OpenGl.Angle var dxgiFactoryGuid = MicroComRuntime.GetGuidFor(typeof(IDXGIFactory1)); DirectXUnmanagedMethods.CreateDXGIFactory1(ref dxgiFactoryGuid, out var pDxgiFactory); IDXGIAdapter1? chosenAdapter = null; - if (pDxgiFactory != null) { using var factory = MicroComRuntime.CreateProxyFor(pDxgiFactory, true); @@ -81,7 +80,7 @@ namespace Avalonia.Win32.OpenGl.Angle } if (adapters.Count == 0) - ThrowNoAdaptersFound(); + throw new OpenGlException("No adapters found"); chosenAdapter = adapters .OrderByDescending(x => @@ -96,17 +95,21 @@ namespace Avalonia.Win32.OpenGl.Angle else { if (factory.EnumAdapters1(0, &pAdapter) != 0) - ThrowNoAdaptersFound(); + throw new OpenGlException("No adapters found"); chosenAdapter = MicroComRuntime.CreateProxyFor(pAdapter, true); } } IntPtr pD3dDevice; using (chosenAdapter) - pD3dDevice = CreateD3D11Device(chosenAdapter, featureLevels); + DirectXUnmanagedMethods.D3D11CreateDevice(chosenAdapter?.GetNativeIntPtr() ?? IntPtr.Zero, + D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_UNKNOWN, + IntPtr.Zero, 0, featureLevels, (uint)featureLevels.Length, + 7, out pD3dDevice, out _, null); + if (pD3dDevice == IntPtr.Zero) - ThrowCannotCreateD3D11Device(); + throw new Win32Exception("Unable to create D3D11 Device"); var d3dDevice = MicroComRuntime.CreateProxyFor(pD3dDevice, true); var angleDevice = IntPtr.Zero; @@ -124,11 +127,11 @@ namespace Avalonia.Win32.OpenGl.Angle { angleDevice = egl.CreateDeviceANGLE(EGL_D3D11_DEVICE_ANGLE, pD3dDevice, null); if (angleDevice == IntPtr.Zero) - OpenGlException.ThrowFormattedException("eglCreateDeviceANGLE", egl); + throw OpenGlException.GetFormattedException("eglCreateDeviceANGLE", egl); display = egl.GetPlatformDisplayExt(EGL_PLATFORM_DEVICE_EXT, angleDevice, null); if (display == IntPtr.Zero) - OpenGlException.ThrowFormattedException("eglGetPlatformDisplayEXT", egl); + throw OpenGlException.GetFormattedException("eglGetPlatformDisplayEXT", egl); var rv = new AngleWin32EglDisplay(display, egl, @@ -152,53 +155,6 @@ namespace Avalonia.Win32.OpenGl.Angle Cleanup(); } } - - // Throwhelpers to aid inlining on rare paths. - void ThrowNoAdaptersFound() => throw new OpenGlException("No adapters found"); - void ThrowCannotCreateD3D11Device() => throw new Win32Exception("Unable to create D3D11 Device"); - } - - /// - /// Creates a D3D11 device for the given adapter. - /// - /// A null pointer on failure, otherwise a device pointer. - private static unsafe IntPtr CreateD3D11Device(IDXGIAdapter1? chosenAdapter, D3D_FEATURE_LEVEL[] featureLevels) - { - // https://learn.microsoft.com/en-us/windows/win32/api/dxgi/ns-dxgi-dxgi_adapter_desc1 - // https://learn.microsoft.com/en-us/windows/win32/api/dxgi/ne-dxgi-dxgi_adapter_flag - var isSoftwareAdapter = (chosenAdapter!.Desc1.Flags & 2) == 1; - var driverType = isSoftwareAdapter ? - D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_WARP : - D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_HARDWARE; - - // HARDWARE or WARP should cover ~99% of use cases. - DirectXUnmanagedMethods.D3D11CreateDevice(chosenAdapter?.GetNativeIntPtr() ?? IntPtr.Zero, - driverType, - IntPtr.Zero, 0, featureLevels, (uint)featureLevels.Length, - 7, out var pD3dDevice, out _, null); - - if (pD3dDevice != IntPtr.Zero) - return pD3dDevice; - - // Otherwise fallback to legacy software device. - DirectXUnmanagedMethods.D3D11CreateDevice(chosenAdapter?.GetNativeIntPtr() ?? IntPtr.Zero, - D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_SOFTWARE, - IntPtr.Zero, 0, featureLevels, (uint)featureLevels.Length, - 7, out pD3dDevice, out _, null); - - if (pD3dDevice != IntPtr.Zero) - return pD3dDevice; - - // As a last resort, try creating an unknown device. - // No consumer machine ought to hit this, the remaining options - // are more so for driver developers debugging/testing, but - // we might as well cover this base. - DirectXUnmanagedMethods.D3D11CreateDevice(chosenAdapter?.GetNativeIntPtr() ?? IntPtr.Zero, - D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_UNKNOWN, - IntPtr.Zero, 0, featureLevels, (uint)featureLevels.Length, - 7, out pD3dDevice, out _, null); - - return pD3dDevice; } private AngleWin32EglDisplay(IntPtr display, EglInterface egl, EglDisplayOptions options, AngleOptions.PlatformApi platformApi) : base(display, options)