diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt index 0a6930bc3e..251e765842 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt @@ -29,7 +29,6 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting { BUFFER_REORDER_DISABLE("disable_buffer_reorder"), RENDERER_DEBUG("debug"), RENDERER_PATCH_OLD_QCOM_DRIVERS("patch_old_qcom_drivers"), - RENDERER_PROVOKING_VERTEX("provoking_vertex"), RENDERER_DESCRIPTOR_INDEXING("descriptor_indexing"), RENDERER_SAMPLE_SHADING("sample_shading"), GPU_UNSWIZZLE_ENABLED("gpu_unswizzle_enabled"), diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt index b047c7c09e..0dd94a01c4 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt @@ -141,13 +141,6 @@ abstract class SettingsItem( valuesId = R.array.dynaStateValues ) ) - put( - SwitchSetting( - BooleanSetting.RENDERER_PROVOKING_VERTEX, - titleId = R.string.provoking_vertex, - descriptionId = R.string.provoking_vertex_description - ) - ) put( SwitchSetting( BooleanSetting.RENDERER_DESCRIPTOR_INDEXING, diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt index 682d854ce2..657ef52793 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt @@ -290,7 +290,6 @@ class SettingsFragmentPresenter( add(HeaderSetting(R.string.extensions)) add(IntSetting.RENDERER_DYNA_STATE.key) - add(BooleanSetting.RENDERER_PROVOKING_VERTEX.key) add(BooleanSetting.RENDERER_DESCRIPTOR_INDEXING.key) add(IntSetting.RENDERER_SAMPLE_SHADING.key) diff --git a/src/common/settings.h b/src/common/settings.h index 7f54872434..ed00ab002e 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -572,7 +572,7 @@ struct Values { SwitchableSetting dyna_state{linkage, #if defined (ANDROID) || defined (__APPLE__) - ExtendedDynamicState::Disabled, + ExtendedDynamicState::EDS1, #else ExtendedDynamicState::EDS2, #endif @@ -587,7 +587,6 @@ struct Values { Category::RendererExtensions, Specialization::Scalar}; - SwitchableSetting provoking_vertex{linkage, false, "provoking_vertex", Category::RendererExtensions}; SwitchableSetting descriptor_indexing{linkage, false, "descriptor_indexing", Category::RendererExtensions}; Setting renderer_debug{linkage, false, "debug", Category::RendererDebug}; diff --git a/src/qt_common/config/shared_translation.cpp b/src/qt_common/config/shared_translation.cpp index 3fa49f45c2..dc9a08b009 100644 --- a/src/qt_common/config/shared_translation.cpp +++ b/src/qt_common/config/shared_translation.cpp @@ -359,12 +359,6 @@ std::unique_ptr InitializeTranslations(QObject* parent) "Higher states allow for more features and can increase performance, but may cause " "additional graphical issues.")); - INSERT(Settings, - provoking_vertex, - tr("Provoking Vertex"), - tr("Improves lighting and vertex handling in some games.\n" - "Only Vulkan 1.0+ devices support this extension.")); - INSERT(Settings, descriptor_indexing, tr("Descriptor Indexing"), diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index ea7cde0365..02fc9170b4 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -736,10 +736,15 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { : VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT, .extraPrimitiveOverestimationSize = 0.0f, }; + const bool preserve_provoking_vertex_for_xfb = + !key.state.xfb_enabled || device.IsTransformFeedbackProvokingVertexPreserved(); + const bool use_last_provoking_vertex = + key.state.provoking_vertex_last != 0 && preserve_provoking_vertex_for_xfb; + VkPipelineRasterizationProvokingVertexStateCreateInfoEXT provoking_vertex{ .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT, .pNext = nullptr, - .provokingVertexMode = key.state.provoking_vertex_last != 0 + .provokingVertexMode = use_last_provoking_vertex ? VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT : VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT, }; @@ -750,7 +755,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { if (device.IsExtConservativeRasterizationSupported()) { conservative_raster.pNext = std::exchange(rasterization_ci.pNext, &conservative_raster); } - if (device.IsExtProvokingVertexSupported() && Settings::values.provoking_vertex.GetValue()) { + if (device.IsExtProvokingVertexSupported()) { provoking_vertex.pNext = std::exchange(rasterization_ci.pNext, &provoking_vertex); } diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 9ba4f62136..e0e567ab29 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -660,12 +660,6 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR const auto dyna_state = Settings::values.dyna_state.GetValue(); - // Base dynamic states (VIEWPORT, SCISSOR, DEPTH_BIAS, etc.) are ALWAYS active in vk_graphics_pipeline.cpp - // This slider controls EXTENDED dynamic states with accumulative levels per Vulkan specs: - // Level 0 = Core Dynamic States only (Vulkan 1.0) - // Level 1 = Core + VK_EXT_extended_dynamic_state - // Level 2 = Core + VK_EXT_extended_dynamic_state + VK_EXT_extended_dynamic_state2 - switch (dyna_state) { case Settings::ExtendedDynamicState::Disabled: // Level 0: Disable all configured extended dynamic state extensions @@ -1147,6 +1141,8 @@ bool Device::GetSuitability(bool requires_swapchain) { // Driver detection variables for workarounds in GetSuitability const VkDriverId driver_id = properties.driver.driverID; + // VK_EXT_extended_dynamic_state below this will appear drivers that need workarounds. + // VK_EXT_extended_dynamic_state2 below this will appear drivers that need workarounds. if (u32(Settings::values.dyna_state.GetValue()) == 0) { @@ -1163,15 +1159,9 @@ bool Device::GetSuitability(bool requires_swapchain) { void Device::RemoveUnsuitableExtensions() { // VK_EXT_custom_border_color - // Enable extension if driver supports it, then check individual features - // - customBorderColors: Required to use VK_BORDER_COLOR_FLOAT_CUSTOM_EXT - // - customBorderColorWithoutFormat: Optional, allows VK_FORMAT_UNDEFINED - // If only customBorderColors is available, we must provide a specific format if (extensions.custom_border_color) { // Verify that at least customBorderColors is available if (!features.custom_border_color.customBorderColors) { - LOG_WARNING(Render_Vulkan, - "VK_EXT_custom_border_color reported but customBorderColors feature not available, disabling"); extensions.custom_border_color = false; } } @@ -1221,20 +1211,6 @@ void Device::RemoveUnsuitableExtensions() { 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 - && features.provoking_vertex - .transformFeedbackPreservesProvokingVertex; - RemoveExtensionFeatureIfUnsuitable(extensions.provoking_vertex, - features.provoking_vertex, - VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME); - } else { - RemoveExtensionFeature(extensions.provoking_vertex, - features.provoking_vertex, - VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME); - } - // VK_KHR_shader_atomic_int64 extensions.shader_atomic_int64 = features.shader_atomic_int64.shaderBufferInt64Atomics && features.shader_atomic_int64.shaderSharedInt64Atomics; @@ -1258,21 +1234,18 @@ void Device::RemoveUnsuitableExtensions() { VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME); // VK_EXT_transform_feedback - // We only require the basic transformFeedback feature and at least - // one transform feedback buffer. We keep transformFeedbackQueries as it's used by - // the streaming byte count implementation. GeometryStreams and multiple streams - // are not strictly required since we currently support only stream 0. extensions.transform_feedback = features.transform_feedback.transformFeedback && properties.transform_feedback.maxTransformFeedbackBuffers > 0 && properties.transform_feedback.transformFeedbackQueries; RemoveExtensionFeatureIfUnsuitable(extensions.transform_feedback, features.transform_feedback, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME); - if (extensions.transform_feedback) { - LOG_INFO(Render_Vulkan, "VK_EXT_transform_feedback enabled (buffers={}, queries={})", - properties.transform_feedback.maxTransformFeedbackBuffers, - properties.transform_feedback.transformFeedbackQueries); - } + + // VK_EXT_provoking_vertex + extensions.provoking_vertex = features.provoking_vertex.provokingVertexLast; + RemoveExtensionFeatureIfUnsuitable(extensions.provoking_vertex, + features.provoking_vertex, + VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME); // VK_EXT_multi_draw extensions.multi_draw = features.multi_draw.multiDraw; diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index b7cb64fc7c..dc76d56675 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -508,13 +508,11 @@ public: } /// Returns true if the device supports VK_EXT_shader_stencil_export. - /// Note: Most Mali/NVIDIA drivers don't support this. Use hardware blits as fallback. bool IsExtShaderStencilExportSupported() const { return extensions.shader_stencil_export; } - /// Returns true if depth/stencil operations can be performed efficiently. - /// Either through shader export or hardware blits. + /// Returns true if depth/stencil operations through shader export or hardware blits. bool CanPerformDepthStencilOperations() const { return extensions.shader_stencil_export || is_blit_depth24_stencil8_supported || is_blit_depth32_stencil8_supported; @@ -550,11 +548,16 @@ public: return extensions.transform_feedback; } - /// Returns true if the device supports VK_EXT_transform_feedback properly. + /// Returns true if the device supports VK_EXT_transform_feedback. bool AreTransformFeedbackGeometryStreamsSupported() const { return features.transform_feedback.geometryStreams; } + /// Returns true if transform feedback preserves provoking vertex. + bool IsTransformFeedbackProvokingVertexPreserved() const { + return features.provoking_vertex.transformFeedbackPreservesProvokingVertex; + } + /// Returns true if the device supports VK_EXT_custom_border_color. bool IsExtCustomBorderColorSupported() const { return extensions.custom_border_color;