Browse Source

Win32/ARM64: let GraphicsAdapterSelectionCallback see unfiltered adapters and warn on Adreno WARP fallback (#21695)

* win32: let GraphicsAdapterSelectionCallback see unfiltered adapters on ARM64

The ARM64 Adreno blocklist in AngleWin32EglDisplay removed every Adreno
adapter from the list before it was handed to GraphicsAdapterSelectionCallback,
so an application had no way to opt back into hardware acceleration and no
indication that WARP (the Microsoft Basic Render Driver) was being forced.

Stop mutating the adapter list. The blocklist now only moves the *default*
selection to the first non-Adreno adapter when no callback is supplied, and
logs a warning about the CPU-usage impact and the available workarounds. When
a callback is present it receives the full, unfiltered adapter list and its
choice is used as-is.

As a side effect this also removes a latent IndexOutOfRange: the old code
could empty the list when every enumerated adapter was Adreno.

Refs #21689

* Update src/Windows/Avalonia.Win32/OpenGl/Angle/AngleWin32EglDisplay.cs

Co-authored-by: Max Katz <maxkatz6@outlook.com>

---------

Co-authored-by: nickna <nick@nassiri.xyz>
Co-authored-by: Max Katz <maxkatz6@outlook.com>
pull/21710/head
Nick Nassiri 3 months ago
committed by GitHub
parent
commit
bfa2319e77
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 30
      src/Windows/Avalonia.Win32/OpenGl/Angle/AngleWin32EglDisplay.cs

30
src/Windows/Avalonia.Win32/OpenGl/Angle/AngleWin32EglDisplay.cs

@ -4,6 +4,7 @@ using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Avalonia.Logging;
using Avalonia.OpenGL;
using Avalonia.OpenGL.Angle;
using Avalonia.OpenGL.Egl;
@ -95,19 +96,28 @@ namespace Avalonia.Win32.OpenGl.Angle
if (adapters.Count == 0)
throw new OpenGlException("No adapters found");
if (applyArmAdrenoBlacklist && adapters.Count > 1)
{
for (var c = adapters.Count - 1; c >= 0; c--)
if (adapters[c].desc.Description?.Contains("adreno") == true)
{
adapters[c].adapter.Dispose();
adapters.RemoveAt(c);
}
}
// The Adreno blacklist (see #10405) now only moves the *default* selection away
// from Adreno GPUs - it no longer hides adapters from the selection callback, so
// an application can deliberately opt back into hardware acceleration.
var chosenAdapterIndex = 0;
if (selectionCallback != null)
{
chosenAdapterIndex = selectionCallback(adapters.Select(a => a.desc).ToArray());
}
else if (applyArmAdrenoBlacklist && adapters.Count > 1)
{
var firstNonAdreno = adapters.FindIndex(a => a.desc.Description?.Contains("adreno") != true);
if (firstNonAdreno > 0)
{
chosenAdapterIndex = firstNonAdreno;
Logger.TryGet(LogEventLevel.Warning, "OpenGL")?.Log(null,
"ARM64 Adreno GPU detected; the Adreno rendering blocklist is forcing a " +
"fallback to '{FallbackAdapter}' (typically a software renderer). Set " +
"Win32PlatformOptions.GraphicsAdapterSelectionCallback to choose an adapter " +
"explicitly, or switch Win32PlatformOptions.RenderingMode to Vulkan or Wgl.",
adapters[firstNonAdreno].desc.Description);
}
}
chosenAdapter = adapters[chosenAdapterIndex].adapter.CloneReference();

Loading…
Cancel
Save