diff --git a/src/common/settings.h b/src/common/settings.h index 2e16e4bc59..9018cc140b 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -546,6 +546,7 @@ struct Values { Category::RendererExtensions, Specialization::Scalar}; + SwitchableSetting enable_vertex_input_dynamic_state{linkage, false, "enable_vertex_input_dynamic_state", Category::RendererExtensions}; SwitchableSetting provoking_vertex{linkage, false, "provoking_vertex", Category::RendererExtensions}; SwitchableSetting descriptor_indexing{linkage, false, "descriptor_indexing", Category::RendererExtensions}; SwitchableSetting sample_shading{linkage, false, "sample_shading", Category::RendererExtensions, Specialization::Paired}; diff --git a/src/qt_common/config/shared_translation.cpp b/src/qt_common/config/shared_translation.cpp index b54211142c..e8bdc43a48 100644 --- a/src/qt_common/config/shared_translation.cpp +++ b/src/qt_common/config/shared_translation.cpp @@ -329,6 +329,11 @@ std::unique_ptr InitializeTranslations(QObject* parent) tr("Extended Dynamic State"), tr("Controls the number of features that can be used in Extended Dynamic State.\nHigher numbers allow for more features and can increase performance, but may cause issues.\nThe default value is per-system.")); + INSERT(Settings, + enable_vertex_input_dynamic_state, + tr("Enable Vertex Input Dynamic State"), + tr("Enables vertex input dynamic state feature for better quality and performance.")); + INSERT(Settings, provoking_vertex, tr("Provoking Vertex"), diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 6f25267a8f..d5ad363a5b 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1196,17 +1196,15 @@ void RasterizerOpenGL::SyncLogicOpState() { if (device.IsAmd()) { using namespace Tegra::Engines; - struct In { - const Maxwell3D::Regs::VertexAttribute::Type d; - In(Maxwell3D::Regs::VertexAttribute::Type n) : d(n) {} - bool operator()(Maxwell3D::Regs::VertexAttribute n) const { - return n.type == d; + + bool has_float = std::any_of( + regs.vertex_attrib_format.begin(), + regs.vertex_attrib_format.end(), + [](const auto& n) { + return n.type == Maxwell3D::Regs::VertexAttribute::Type::Float; } - }; + ); - bool has_float = - std::any_of(regs.vertex_attrib_format.begin(), regs.vertex_attrib_format.end(), - In(Maxwell3D::Regs::VertexAttribute::Type::Float)); regs.logic_op.enable = static_cast(!has_float); } diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index 00f2decba4..daadd958a1 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp @@ -579,12 +579,11 @@ void BufferCacheRuntime::BindQuadIndexBuffer(PrimitiveTopology topology, u32 fir } } -void BufferCacheRuntime::BindVertexBuffer(u32 index, VkBuffer buffer, u32 offset, u32 size, - u32 stride) { +void BufferCacheRuntime::BindVertexBuffer(u32 index, VkBuffer buffer, u32 offset, u32 size, u32 stride) { if (index >= device.GetMaxVertexInputBindings()) { return; } - if (device.IsExtExtendedDynamicStateSupported()) { + if (device.IsExtExtendedDynamicStateSupported() && Settings::values.dyna_state.GetValue() > 0) { scheduler.Record([index, buffer, offset, size, stride](vk::CommandBuffer cmdbuf) { const VkDeviceSize vk_offset = buffer != VK_NULL_HANDLE ? offset : 0; const VkDeviceSize vk_size = buffer != VK_NULL_HANDLE ? size : VK_WHOLE_SIZE; @@ -624,7 +623,7 @@ void BufferCacheRuntime::BindVertexBuffers(VideoCommon::HostBindings& bi if (binding_count == 0) { return; } - if (device.IsExtExtendedDynamicStateSupported()) { + if (device.IsExtExtendedDynamicStateSupported() && Settings::values.dyna_state.GetValue() > 0) { scheduler.Record([bindings_ = std::move(bindings), buffer_handles_ = std::move(buffer_handles), binding_count](vk::CommandBuffer cmdbuf) { diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 14a4fee69b..821b01bd5c 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -405,8 +405,7 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, } const u8 dynamic_state = Settings::values.dyna_state.GetValue(); - - LOG_INFO(Render_Vulkan, "DynamicState value is set to {}", (u32) dynamic_state); + const bool enable_vertex_input_dynamic_state = Settings::values.enable_vertex_input_dynamic_state.GetValue(); dynamic_features = DynamicFeatures{ .has_extended_dynamic_state = device.IsExtExtendedDynamicStateSupported() && dynamic_state > 0, @@ -414,7 +413,7 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, .has_extended_dynamic_state_2_extra = device.IsExtExtendedDynamicState2ExtrasSupported() && dynamic_state > 1, .has_extended_dynamic_state_3_blend = device.IsExtExtendedDynamicState3BlendingSupported() && dynamic_state > 2, .has_extended_dynamic_state_3_enables = device.IsExtExtendedDynamicState3EnablesSupported() && dynamic_state > 2, - .has_dynamic_vertex_input = device.IsExtVertexInputDynamicStateSupported() && dynamic_state > 0, + .has_dynamic_vertex_input = device.IsExtVertexInputDynamicStateSupported() && enable_vertex_input_dynamic_state, }; } diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 59af3f33b6..bc4af0f1f5 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -955,6 +955,7 @@ void RasterizerVulkan::UpdateDynamicStates() { UpdateLineWidth(regs); const u8 dynamic_state = Settings::values.dyna_state.GetValue(); + const bool enable_vertex_input_dynamic_state = Settings::values.enable_vertex_input_dynamic_state.GetValue(); if (device.IsExtExtendedDynamicStateSupported() && dynamic_state > 0) { UpdateCullMode(regs); @@ -974,14 +975,13 @@ void RasterizerVulkan::UpdateDynamicStates() { if (device.IsExtExtendedDynamicState3EnablesSupported() && dynamic_state > 2) { using namespace Tegra::Engines; if (device.GetDriverID() == VkDriverIdKHR::VK_DRIVER_ID_AMD_OPEN_SOURCE || device.GetDriverID() == VkDriverIdKHR::VK_DRIVER_ID_AMD_PROPRIETARY) { - struct In { - const Maxwell3D::Regs::VertexAttribute::Type d; - In(Maxwell3D::Regs::VertexAttribute::Type n) : d(n) {} - bool operator()(Maxwell3D::Regs::VertexAttribute n) const { - return n.type == d; + const auto has_float = std::any_of( + regs.vertex_attrib_format.begin(), + regs.vertex_attrib_format.end(), + [](const auto& attrib) { + return attrib.type == Maxwell3D::Regs::VertexAttribute::Type::Float; } - }; - auto has_float = std::any_of(regs.vertex_attrib_format.begin(), regs.vertex_attrib_format.end(), In(Maxwell3D::Regs::VertexAttribute::Type::Float)); + ); if (regs.logic_op.enable) { regs.logic_op.enable = static_cast(!has_float); } @@ -999,9 +999,11 @@ void RasterizerVulkan::UpdateDynamicStates() { UpdateBlending(regs); } } - if (device.IsExtVertexInputDynamicStateSupported() && dynamic_state > 0) - if (auto* gp = pipeline_cache.CurrentGraphicsPipeline(); gp && gp->HasDynamicVertexInput()) + if (device.IsExtVertexInputDynamicStateSupported() && enable_vertex_input_dynamic_state) { + if (auto* gp = pipeline_cache.CurrentGraphicsPipeline(); gp && gp->HasDynamicVertexInput()) { UpdateVertexInput(regs); + } + } } void RasterizerVulkan::HandleTransformFeedback() { diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 81e60f1c6a..cce84d0d26 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -743,22 +743,22 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR Settings::values.dyna_state.SetValue(0); } - if (Settings::values.dyna_state.GetValue() == 0) { - must_emulate_scaled_formats = true; - LOG_INFO(Render_Vulkan, "Extended dynamic state is fully disabled, scaled format emulation is ON"); - - RemoveExtensionFeature(extensions.custom_border_color, features.custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); + switch (Settings::values.dyna_state.GetValue()) { + case 0: RemoveExtensionFeature(extensions.extended_dynamic_state, features.extended_dynamic_state, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); + [[fallthrough]]; + case 1: RemoveExtensionFeature(extensions.extended_dynamic_state2, features.extended_dynamic_state2, VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); + [[fallthrough]]; + case 2: RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3, VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); - RemoveExtensionFeature(extensions.vertex_input_dynamic_state, features.vertex_input_dynamic_state, VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); dynamic_state3_blending = false; dynamic_state3_enables = false; + break; + } - LOG_INFO(Render_Vulkan, "All dynamic state extensions and features have been disabled"); - } else { - must_emulate_scaled_formats = false; - LOG_INFO(Render_Vulkan, "Extended dynamic state is enabled, scaled format emulation is OFF"); + if (!Settings::values.enable_vertex_input_dynamic_state.GetValue()) { + RemoveExtensionFeature(extensions.vertex_input_dynamic_state, features.vertex_input_dynamic_state, VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); } logical = vk::Device::Create(physical, queue_cis, ExtensionListForVulkan(loaded_extensions), first_next, dld);