From 33c72ef7e1dad4b1a05eb576f113cc410961cc8f Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Sun, 23 Nov 2025 03:52:21 -0400 Subject: [PATCH] [vk] Updated maintenance features --- .../vulkan_common/vulkan_device.cpp | 83 ++++++++++++++++++- src/video_core/vulkan_common/vulkan_device.h | 60 +++++++++++++- 2 files changed, 139 insertions(+), 4 deletions(-) diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 6708874061..ad4cd48a5e 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -427,7 +427,6 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR const bool is_mvk = driver_id == VK_DRIVER_ID_MOLTENVK; const bool is_qualcomm = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY; const bool is_turnip = driver_id == VK_DRIVER_ID_MESA_TURNIP; - const bool is_s8gen2 = device_id == 0x43050a01; const bool is_arm = driver_id == VK_DRIVER_ID_ARM_PROPRIETARY; if ((is_mvk || is_qualcomm || is_turnip || is_arm) && !is_suitable) { @@ -593,9 +592,40 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR has_broken_compute = CheckBrokenCompute(properties.driver.driverID, properties.properties.driverVersion) && !Settings::values.enable_compute_pipelines.GetValue(); - if (is_intel_anv || (is_qualcomm && !is_s8gen2)) { - LOG_WARNING(Render_Vulkan, "Driver does not support native BGR format"); + must_emulate_bgr565 = false; // Default: assume emulation isn't required + + if (is_intel_anv) { + LOG_WARNING(Render_Vulkan, "Intel ANV driver does not support native BGR format"); must_emulate_bgr565 = true; + } else if (is_qualcomm) { + // Qualcomm driver version where VK_KHR_maintenance5 and A1B5G5R5 become reliable + constexpr uint32_t QUALCOMM_FIXED_DRIVER_VERSION = VK_MAKE_VERSION(512, 800, 1); + // Check if VK_KHR_maintenance5 is supported + if (extensions.maintenance5 && properties.properties.driverVersion >= QUALCOMM_FIXED_DRIVER_VERSION) { + LOG_INFO(Render_Vulkan, "Qualcomm driver supports VK_KHR_maintenance5, disabling BGR emulation"); + must_emulate_bgr565 = false; + } else { + LOG_WARNING(Render_Vulkan, "Qualcomm driver doesn't support native BGR, emulating formats"); + must_emulate_bgr565 = true; + } + } else if (is_turnip) { + // Mesa Turnip added support for maintenance5 in Mesa 25.0 + if (extensions.maintenance5) { + LOG_INFO(Render_Vulkan, "Turnip driver supports VK_KHR_maintenance5, disabling BGR emulation"); + must_emulate_bgr565 = false; + } else { + LOG_WARNING(Render_Vulkan, "Turnip driver doesn't support native BGR, emulating formats"); + must_emulate_bgr565 = true; + } + } else if (is_arm) { + // ARM Mali: stop emulating BGR5 formats when VK_KHR_maintenance5 is available + if (extensions.maintenance5) { + LOG_INFO(Render_Vulkan, "ARM driver supports VK_KHR_maintenance5, disabling BGR emulation"); + must_emulate_bgr565 = false; + } else { + LOG_WARNING(Render_Vulkan, "ARM driver doesn't support native BGR, emulating formats"); + must_emulate_bgr565 = true; + } } if (is_mvk) { @@ -1285,6 +1315,53 @@ void Device::RemoveUnsuitableExtensions() { RemoveExtensionFeatureIfUnsuitable(extensions.workgroup_memory_explicit_layout, features.workgroup_memory_explicit_layout, VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME); + + // VK_EXT_swapchain_maintenance1 (extension only, has features) + extensions.swapchain_maintenance1 = features.swapchain_maintenance1.swapchainMaintenance1; + RemoveExtensionFeatureIfUnsuitable(extensions.swapchain_maintenance1, features.swapchain_maintenance1, + VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME); + + // VK_KHR_maintenance1 (core in Vulkan 1.1, no features) + extensions.maintenance1 = loaded_extensions.contains(VK_KHR_MAINTENANCE_1_EXTENSION_NAME); + RemoveExtensionIfUnsuitable(extensions.maintenance1, VK_KHR_MAINTENANCE_1_EXTENSION_NAME); + + // VK_KHR_maintenance2 (core in Vulkan 1.1, no features) + extensions.maintenance2 = loaded_extensions.contains(VK_KHR_MAINTENANCE_2_EXTENSION_NAME); + RemoveExtensionIfUnsuitable(extensions.maintenance2, VK_KHR_MAINTENANCE_2_EXTENSION_NAME); + + // VK_KHR_maintenance3 (core in Vulkan 1.1, no features) + extensions.maintenance3 = loaded_extensions.contains(VK_KHR_MAINTENANCE_3_EXTENSION_NAME); + RemoveExtensionIfUnsuitable(extensions.maintenance3, VK_KHR_MAINTENANCE_3_EXTENSION_NAME); + + // VK_KHR_maintenance4 + extensions.maintenance4 = features.maintenance4.maintenance4; + RemoveExtensionFeatureIfUnsuitable(extensions.maintenance4, features.maintenance4, + VK_KHR_MAINTENANCE_4_EXTENSION_NAME); + + // VK_KHR_maintenance5 + extensions.maintenance5 = features.maintenance5.maintenance5; + RemoveExtensionFeatureIfUnsuitable(extensions.maintenance5, features.maintenance5, + VK_KHR_MAINTENANCE_5_EXTENSION_NAME); + + // VK_KHR_maintenance6 + extensions.maintenance6 = features.maintenance6.maintenance6; + RemoveExtensionFeatureIfUnsuitable(extensions.maintenance6, features.maintenance6, + VK_KHR_MAINTENANCE_6_EXTENSION_NAME); + + // VK_KHR_maintenance7 + extensions.maintenance7 = features.maintenance7.maintenance7; + RemoveExtensionFeatureIfUnsuitable(extensions.maintenance7, features.maintenance7, + VK_KHR_MAINTENANCE_7_EXTENSION_NAME); + + // VK_KHR_maintenance8 + extensions.maintenance8 = features.maintenance8.maintenance8; + RemoveExtensionFeatureIfUnsuitable(extensions.maintenance8, features.maintenance8, + VK_KHR_MAINTENANCE_8_EXTENSION_NAME); + + // VK_KHR_maintenance9 + extensions.maintenance9 = features.maintenance9.maintenance9; + RemoveExtensionFeatureIfUnsuitable(extensions.maintenance9, features.maintenance9, + VK_KHR_MAINTENANCE_9_EXTENSION_NAME); } void Device::SetupFamilies(VkSurfaceKHR surface) { diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index cb13f28523..13e8777a62 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -39,7 +39,8 @@ VK_DEFINE_HANDLE(VmaAllocator) #define FOR_EACH_VK_FEATURE_1_3(FEATURE) \ FEATURE(EXT, ShaderDemoteToHelperInvocation, SHADER_DEMOTE_TO_HELPER_INVOCATION, \ shader_demote_to_helper_invocation) \ - FEATURE(EXT, SubgroupSizeControl, SUBGROUP_SIZE_CONTROL, subgroup_size_control) + FEATURE(EXT, SubgroupSizeControl, SUBGROUP_SIZE_CONTROL, subgroup_size_control) \ + FEATURE(KHR, Maintenance4, MAINTENANCE_4, maintenance4) // Define all features which may be used by the implementation and require an extension here. #define FOR_EACH_VK_FEATURE_EXT(FEATURE) \ @@ -58,6 +59,12 @@ VK_DEFINE_HANDLE(VmaAllocator) FEATURE(EXT, Robustness2, ROBUSTNESS_2, robustness2) \ FEATURE(EXT, TransformFeedback, TRANSFORM_FEEDBACK, transform_feedback) \ FEATURE(EXT, VertexInputDynamicState, VERTEX_INPUT_DYNAMIC_STATE, vertex_input_dynamic_state) \ + FEATURE(EXT, SwapchainMaintenance1, SWAPCHAIN_MAINTENANCE_1, swapchain_maintenance1) \ + FEATURE(KHR, Maintenance5, MAINTENANCE_5, maintenance5) \ + FEATURE(KHR, Maintenance6, MAINTENANCE_6, maintenance6) \ + FEATURE(KHR, Maintenance7, MAINTENANCE_7, maintenance7) \ + FEATURE(KHR, Maintenance8, MAINTENANCE_8, maintenance8) \ + FEATURE(KHR, Maintenance9, MAINTENANCE_9, maintenance9) \ FEATURE(KHR, PipelineExecutableProperties, PIPELINE_EXECUTABLE_PROPERTIES, \ pipeline_executable_properties) \ FEATURE(KHR, WorkgroupMemoryExplicitLayout, WORKGROUP_MEMORY_EXPLICIT_LAYOUT, \ @@ -83,6 +90,7 @@ VK_DEFINE_HANDLE(VmaAllocator) EXTENSION(KHR, SPIRV_1_4, spirv_1_4) \ EXTENSION(KHR, SWAPCHAIN, swapchain) \ EXTENSION(KHR, SWAPCHAIN_MUTABLE_FORMAT, swapchain_mutable_format) \ + EXTENSION(EXT, SWAPCHAIN_MAINTENANCE_1, swapchain_maintenance1) \ EXTENSION(KHR, IMAGE_FORMAT_LIST, image_format_list) \ EXTENSION(NV, DEVICE_DIAGNOSTICS_CONFIG, device_diagnostics_config) \ EXTENSION(NV, GEOMETRY_SHADER_PASSTHROUGH, geometry_shader_passthrough) \ @@ -440,6 +448,11 @@ public: return extensions.swapchain_mutable_format; } + /// Returns true if VK_EXT_swapchain_maintenance1 is enabled. + bool IsExtSwapchainMaintenance1Enabled() const { + return extensions.swapchain_maintenance1; + } + /// Returns true if VK_KHR_shader_float_controls is enabled. bool IsKhrShaderFloatControlsSupported() const { return extensions.shader_float_controls; @@ -703,6 +716,51 @@ public: return features2.features.multiViewport; } + /// Returns true if the device supports VK_KHR_maintenance1. + bool IsKhrMaintenance1Supported() const { + return extensions.maintenance1; + } + + /// Returns true if the device supports VK_KHR_maintenance2. + bool IsKhrMaintenance2Supported() const { + return extensions.maintenance2; + } + + /// Returns true if the device supports VK_KHR_maintenance3. + bool IsKhrMaintenance3Supported() const { + return extensions.maintenance3; + } + + /// Returns true if the device supports VK_KHR_maintenance4. + bool IsKhrMaintenance4Supported() const { + return extensions.maintenance4; + } + + /// Returns true if the device supports VK_KHR_maintenance5. + bool IsKhrMaintenance5Supported() const { + return extensions.maintenance5; + } + + /// Returns true if the device supports VK_KHR_maintenance6. + bool IsKhrMaintenance6Supported() const { + return extensions.maintenance6; + } + + /// Returns true if the device supports VK_KHR_maintenance7. + bool IsKhrMaintenance7Supported() const { + return extensions.maintenance7; + } + + /// Returns true if the device supports VK_KHR_maintenance8. + bool IsKhrMaintenance8Supported() const { + return extensions.maintenance8; + } + + /// Returns true if the device supports VK_KHR_maintenance9. + bool IsKhrMaintenance9Supported() const { + return extensions.maintenance9; + } + [[nodiscard]] static constexpr bool CheckBrokenCompute(VkDriverId driver_id, u32 driver_version) { if (driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) {