From 1373ee90b0fdd1a192e34d4b2ed6e71f370d7988 Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Mon, 24 Nov 2025 00:31:10 -0400 Subject: [PATCH] [vk] Robustness2 and Image Robustness --- .../vulkan_common/vulkan_device.cpp | 27 +++++++++++++ src/video_core/vulkan_common/vulkan_device.h | 38 ++++++++++++++++++- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index de4254cdad..50cd4cc191 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -1266,6 +1266,33 @@ void Device::RemoveUnsuitableExtensions() { features.extended_dynamic_state3, VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); + // VK_EXT_robustness2 + // Enable if at least one robustness2 feature is available + extensions.robustness_2 = features.robustness2.robustBufferAccess2 || + features.robustness2.robustImageAccess2 || + features.robustness2.nullDescriptor; + + // Log which features are available + if (extensions.robustness_2) { + LOG_INFO(Render_Vulkan, "VK_EXT_robustness2 features: robustBufferAccess2={} " + "robustImageAccess2={} nullDescriptor={}", + features.robustness2.robustBufferAccess2, + features.robustness2.robustImageAccess2, + features.robustness2.nullDescriptor); + } + RemoveExtensionFeatureIfUnsuitable(extensions.robustness_2, features.robustness2, + VK_EXT_ROBUSTNESS_2_EXTENSION_NAME); + + // VK_EXT_image_robustness + // Enable if robustImageAccess is available + extensions.image_robustness = features.image_robustness.robustImageAccess; + + if (extensions.image_robustness) { + LOG_INFO(Render_Vulkan, "VK_EXT_image_robustness feature: robustImageAccess=true"); + } + RemoveExtensionFeatureIfUnsuitable(extensions.image_robustness, features.image_robustness, + VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME); + // VK_EXT_provoking_vertex if (Settings::values.provoking_vertex.GetValue()) { extensions.provoking_vertex = features.provoking_vertex.provokingVertexLast diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index c891d29180..3b93f00f91 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -37,6 +37,7 @@ VK_DEFINE_HANDLE(VmaAllocator) FEATURE(KHR, TimelineSemaphore, TIMELINE_SEMAPHORE, timeline_semaphore) #define FOR_EACH_VK_FEATURE_1_3(FEATURE) \ + FEATURE(EXT, ImageRobustness, IMAGE_ROBUSTNESS, image_robustness) \ FEATURE(EXT, ShaderDemoteToHelperInvocation, SHADER_DEMOTE_TO_HELPER_INVOCATION, \ shader_demote_to_helper_invocation) \ FEATURE(EXT, SubgroupSizeControl, SUBGROUP_SIZE_CONTROL, subgroup_size_control) \ @@ -74,6 +75,7 @@ VK_DEFINE_HANDLE(VmaAllocator) EXTENSION(EXT, CONDITIONAL_RENDERING, conditional_rendering) \ EXTENSION(EXT, CONSERVATIVE_RASTERIZATION, conservative_rasterization) \ EXTENSION(EXT, DEPTH_RANGE_UNRESTRICTED, depth_range_unrestricted) \ + EXTENSION(EXT, IMAGE_ROBUSTNESS, image_robustness) \ EXTENSION(EXT, MEMORY_BUDGET, memory_budget) \ EXTENSION(EXT, ROBUSTNESS_2, robustness_2) \ EXTENSION(EXT, SAMPLER_FILTER_MINMAX, sampler_filter_minmax) \ @@ -122,6 +124,7 @@ VK_DEFINE_HANDLE(VmaAllocator) EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME) \ EXTENSION_NAME(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME) \ EXTENSION_NAME(VK_EXT_4444_FORMATS_EXTENSION_NAME) \ + EXTENSION_NAME(VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME) \ EXTENSION_NAME(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME) \ EXTENSION_NAME(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME) \ EXTENSION_NAME(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME) \ @@ -173,6 +176,7 @@ VK_DEFINE_HANDLE(VmaAllocator) FEATURE_NAME(depth_bias_control, depthBiasExact) \ FEATURE_NAME(extended_dynamic_state, extendedDynamicState) \ FEATURE_NAME(format_a4b4g4r4, formatA4B4G4R4) \ + FEATURE_NAME(image_robustness, robustImageAccess) \ FEATURE_NAME(index_type_uint8, indexTypeUint8) \ FEATURE_NAME(primitive_topology_list_restart, primitiveTopologyListRestart) \ FEATURE_NAME(provoking_vertex, provokingVertexLast) \ @@ -545,12 +549,42 @@ public: return extensions.custom_border_color; } - /// Returns true if customBorderColors feature is available (required for custom colors). + /// Returns true if the device supports VK_EXT_image_robustness. + bool IsExtImageRobustnessSupported() const { + return extensions.image_robustness; + } + + /// Returns true if robustImageAccess is supported. + bool IsRobustImageAccessSupported() const { + return features.image_robustness.robustImageAccess; + } + + /// Returns true if the device supports VK_EXT_robustness2. + bool IsExtRobustness2Supported() const { + return extensions.robustness_2; + } + + /// Returns true if robustBufferAccess2 is supported. + bool IsRobustBufferAccess2Supported() const { + return features.robustness2.robustBufferAccess2; + } + + /// Returns true if robustImageAccess2 is supported. + bool IsRobustImageAccess2Supported() const { + return features.robustness2.robustImageAccess2; + } + + /// Returns true if nullDescriptor is supported. + bool IsNullDescriptorSupported() const { + return features.robustness2.nullDescriptor; + } + + /// Returns true if customBorderColors feature is available. bool IsCustomBorderColorsSupported() const { return features.custom_border_color.customBorderColors; } - /// Returns true if customBorderColorWithoutFormat feature is available (allows VK_FORMAT_UNDEFINED). + /// Returns true if customBorderColorWithoutFormat feature is available. bool IsCustomBorderColorWithoutFormatSupported() const { return features.custom_border_color.customBorderColorWithoutFormat; }