mirror of
https://github.com/godotengine/godot-angle-static.git
synced 2026-01-06 02:09:55 +03:00
Vulkan: add workaround for VK_EXT_full_screen_exclusive on AMD
On outdated (but recent) AMD drivers, the Windows-only Vulkan extension VK_EXT_full_screen_exclusive appeared to be implicitly enabled and set to VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT mode. Even though ANGLE did not enable or interact with this extension at all, the driver was incorrectly returning VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT error codes on various swapchain operations when the full screen window focus was lost (i.e. alt-tab out and back in). Naturally, ANGLE was not expecting these error codes and did not know how to handle them. Depending on where the errors occurred, ANGLE might crash or retry creating the swapchain repeatedly. Treating the unexpected VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT error code as VK_ERROR_OUT_OF_DATE_KHR/VK_SUBOPTIMAL_KHR was not sufficient, because the driver would repeat the error on every swapchain operation, apparently expecting the error to be handled by a vkAcquireFullScreenExclusiveModeEXT call (even though that would make no sense, since the extension was not enabled). The incorrect driver behavior was reported to AMD and was fixed in recent driver releases. The earliest driver I've tested and know to be working is AMD's Adrenaline driver version 23.5.2 (VkPhysicalDeviceProperties calls this driverVersion 2.0.262/0x800106). The last known bad version was 0x8000e9. The simplest workaround on these older AMD graphics drivers is to explicitly enable the extension, but set it to VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT mode. On newer drivers we do not need to do anything with the extension and can ignore it. Bug: angleproject:8215 Change-Id: I7c58d47a0350f4b0bc1a77f200c1e2f72fcde8d8 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4627279 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Charlie Lao <cclao@google.com>
This commit is contained in:
committed by
Angle LUCI CQ
parent
c23029d2fe
commit
ac263582dd
@@ -1215,6 +1215,20 @@ struct FeaturesVk : FeatureSetBase
|
||||
&members, "http://anglebug.com/8162"
|
||||
};
|
||||
|
||||
FeatureInfo supportsFullScreenExclusive = {
|
||||
"supportsFullScreenExclusive",
|
||||
FeatureCategory::VulkanFeatures,
|
||||
"VkDevice supports the VK_EXT_full_screen_exclusive extension",
|
||||
&members, "http://anglebug.com/8215"
|
||||
};
|
||||
|
||||
FeatureInfo forceDisableFullScreenExclusive = {
|
||||
"forceDisableFullScreenExclusive",
|
||||
FeatureCategory::VulkanWorkarounds,
|
||||
"Device needs VK_EXT_full_screen_exclusive explicitly disabled",
|
||||
&members, "http://anglebug.com/8215"
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
inline FeaturesVk::FeaturesVk() = default;
|
||||
|
||||
@@ -1312,6 +1312,22 @@
|
||||
"Limit sample count to 2 to save memory on low end devices."
|
||||
],
|
||||
"issue": "http://anglebug.com/8162"
|
||||
},
|
||||
{
|
||||
"name": "supports_full_screen_exclusive",
|
||||
"category": "Features",
|
||||
"description": [
|
||||
"VkDevice supports the VK_EXT_full_screen_exclusive extension"
|
||||
],
|
||||
"issue": "http://anglebug.com/8215"
|
||||
},
|
||||
{
|
||||
"name": "force_disable_full_screen_exclusive",
|
||||
"category": "Workarounds",
|
||||
"description": [
|
||||
"Device needs VK_EXT_full_screen_exclusive explicitly disabled"
|
||||
],
|
||||
"issue": "http://anglebug.com/8215"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2597,6 +2597,7 @@ void RendererVk::queryDeviceExtensionFeatures(const vk::ExtensionNameList &devic
|
||||
// - VK_EXT_external_memory_dma_buf
|
||||
// - VK_EXT_image_drm_format_modifier
|
||||
// - VK_EXT_blend_operation_advanced
|
||||
// - VK_EXT_full_screen_exclusive
|
||||
//
|
||||
void RendererVk::enableDeviceExtensionsNotPromoted(
|
||||
const vk::ExtensionNameList &deviceExtensionNames)
|
||||
@@ -2847,6 +2848,17 @@ void RendererVk::enableDeviceExtensionsNotPromoted(
|
||||
mEnabledDeviceExtensions.push_back(VK_EXT_LEGACY_DITHERING_EXTENSION_NAME);
|
||||
vk::AddToPNextChain(&mEnabledFeatures, &mDitheringFeatures);
|
||||
}
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINDOWS)
|
||||
// We only need the VK_EXT_full_screen_exclusive extension if we are opting
|
||||
// out of it via VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT (i.e. working
|
||||
// around driver bugs).
|
||||
if (getFeatures().supportsFullScreenExclusive.enabled &&
|
||||
getFeatures().forceDisableFullScreenExclusive.enabled)
|
||||
{
|
||||
mEnabledDeviceExtensions.push_back(VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// See comment above appendDeviceExtensionFeaturesPromotedTo11. Additional extensions are enabled
|
||||
@@ -3983,6 +3995,22 @@ void RendererVk::initFeatures(DisplayVk *displayVk,
|
||||
&mFeatures, supportsExternalMemoryFd,
|
||||
ExtensionFound(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, deviceExtensionNames));
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINDOWS)
|
||||
ANGLE_FEATURE_CONDITION(
|
||||
&mFeatures, supportsFullScreenExclusive,
|
||||
ExtensionFound(VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME, deviceExtensionNames));
|
||||
|
||||
// On Windows+AMD, drivers before version 0x800106 (2.0.262) would
|
||||
// implicitly enable VK_EXT_full_screen_exclusive and start returning
|
||||
// extension-specific error codes in swapchain functions. Since the
|
||||
// extension was not enabled by ANGLE, it was impossible to handle these
|
||||
// error codes correctly. On these earlier drivers, we want to explicitly
|
||||
// enable the extension and opt out of it to avoid seeing those error codes
|
||||
// entirely.
|
||||
ANGLE_FEATURE_CONDITION(&mFeatures, forceDisableFullScreenExclusive,
|
||||
isAMD && mPhysicalDeviceProperties.driverVersion < 0x800106);
|
||||
#endif
|
||||
|
||||
ANGLE_FEATURE_CONDITION(
|
||||
&mFeatures, supportsExternalMemoryFuchsia,
|
||||
ExtensionFound(VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME, deviceExtensionNames));
|
||||
|
||||
@@ -1546,6 +1546,26 @@ angle::Result WindowSurfaceVk::createSwapChain(vk::Context *context,
|
||||
swapchainInfo.clipped = VK_TRUE;
|
||||
swapchainInfo.oldSwapchain = lastSwapchain;
|
||||
|
||||
#if defined(ANGLE_PLATFORM_WINDOWS)
|
||||
// On some AMD drivers we need to explicitly enable the extension and set
|
||||
// it to "disallowed" mode in order to avoid seeing impossible-to-handle
|
||||
// extension-specific error codes from swapchain functions.
|
||||
VkSurfaceFullScreenExclusiveInfoEXT fullscreen = {};
|
||||
fullscreen.sType = VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT;
|
||||
fullscreen.fullScreenExclusive = VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT;
|
||||
|
||||
VkSurfaceFullScreenExclusiveWin32InfoEXT fullscreenWin32 = {};
|
||||
fullscreenWin32.sType = VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT;
|
||||
fullscreenWin32.hmonitor = MonitorFromWindow((HWND)mNativeWindowType, MONITOR_DEFAULTTONEAREST);
|
||||
|
||||
if (renderer->getFeatures().supportsFullScreenExclusive.enabled &&
|
||||
renderer->getFeatures().forceDisableFullScreenExclusive.enabled)
|
||||
{
|
||||
vk::AddToPNextChain(&swapchainInfo, &fullscreen);
|
||||
vk::AddToPNextChain(&swapchainInfo, &fullscreenWin32);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (context->getFeatures().supportsSwapchainMaintenance1.enabled)
|
||||
{
|
||||
swapchainInfo.flags |= VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT;
|
||||
|
||||
@@ -148,6 +148,7 @@ constexpr PackedEnumMap<Feature, const char *> kFeatureNames = {{
|
||||
{Feature::ForceD16TexFilter, "forceD16TexFilter"},
|
||||
{Feature::ForceD24S8AsUnsupported, "forceD24S8AsUnsupported"},
|
||||
{Feature::ForceDepthAttachmentInitOnClear, "forceDepthAttachmentInitOnClear"},
|
||||
{Feature::ForceDisableFullScreenExclusive, "forceDisableFullScreenExclusive"},
|
||||
{Feature::ForceFallbackFormat, "forceFallbackFormat"},
|
||||
{Feature::ForceFragmentShaderPrecisionHighpToMediump, "forceFragmentShaderPrecisionHighpToMediump"},
|
||||
{Feature::ForceGlErrorChecking, "forceGlErrorChecking"},
|
||||
@@ -273,6 +274,7 @@ constexpr PackedEnumMap<Feature, const char *> kFeatureNames = {{
|
||||
{Feature::SupportsFragmentShaderOrderingINTEL, "supportsFragmentShaderOrderingINTEL"},
|
||||
{Feature::SupportsFragmentShaderPixelInterlock, "supportsFragmentShaderPixelInterlock"},
|
||||
{Feature::SupportsFragmentShadingRate, "supportsFragmentShadingRate"},
|
||||
{Feature::SupportsFullScreenExclusive, "supportsFullScreenExclusive"},
|
||||
{Feature::SupportsGeometryStreamsCapability, "supportsGeometryStreamsCapability"},
|
||||
{Feature::SupportsGetMemoryRequirements2, "supportsGetMemoryRequirements2"},
|
||||
{Feature::SupportsGGPFrameToken, "supportsGGPFrameToken"},
|
||||
|
||||
@@ -148,6 +148,7 @@ enum class Feature
|
||||
ForceD16TexFilter,
|
||||
ForceD24S8AsUnsupported,
|
||||
ForceDepthAttachmentInitOnClear,
|
||||
ForceDisableFullScreenExclusive,
|
||||
ForceFallbackFormat,
|
||||
ForceFragmentShaderPrecisionHighpToMediump,
|
||||
ForceGlErrorChecking,
|
||||
@@ -273,6 +274,7 @@ enum class Feature
|
||||
SupportsFragmentShaderOrderingINTEL,
|
||||
SupportsFragmentShaderPixelInterlock,
|
||||
SupportsFragmentShadingRate,
|
||||
SupportsFullScreenExclusive,
|
||||
SupportsGeometryStreamsCapability,
|
||||
SupportsGetMemoryRequirements2,
|
||||
SupportsGGPFrameToken,
|
||||
|
||||
Reference in New Issue
Block a user