diff --git a/.ci/android.sh b/.ci/android.sh index 79b1bc6732..a92e1a0ae8 100755 --- a/.ci/android.sh +++ b/.ci/android.sh @@ -1,4 +1,4 @@ -#!/bin/bash -ex +#!/bin/bash -e export NDK_CCACHE=$(which ccache) diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 293f4beea5..e47d1df498 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -293,7 +293,7 @@ Specifies how videos should be decoded. It can either use the CPU or the GPU for decoding, or perform no decoding at all (black screen on videos). In most cases, GPU decoding provides the best performance. Shader Backend Extended Dynamic State - Enables the VkExtendedDynamicState* extensions.\nHigher dynamic states will generally improve performance, but may cause issues on certain games or devices\nDefault value is 0 for Disabled, The third value might not work properly on some devices + Enables the VkExtendedDynamicState* extensions.\nHigher dynamic states will generally improve performance, but may cause issues on certain games or devices.\nSet to 0 to disable. CPU diff --git a/src/common/settings.h b/src/common/settings.h index 82900e163a..0ddc5f85f8 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -446,7 +446,7 @@ struct Values { Category::RendererAdvanced}; SwitchableSetting dyna_state{linkage, - 0, + 1, 0, 3, "dyna_state", diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 130dee3222..b73b7630f5 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -3,6 +3,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include +#include #include #include @@ -740,12 +741,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { ? VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT : VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT, }; - VkPipelineRasterizationDepthClipStateCreateInfoEXT depth_clip{ - .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT, - .pNext = nullptr, - .flags = 0, - .depthClipEnable = VK_TRUE, - }; if (IsLine(input_assembly_topology) && device.IsExtLineRasterizationSupported()) { line_state.pNext = std::exchange(rasterization_ci.pNext, &line_state); } @@ -755,9 +750,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { if (device.IsExtProvokingVertexSupported()) { provoking_vertex.pNext = std::exchange(rasterization_ci.pNext, &provoking_vertex); } - if (device.IsExtDepthClipControlSupported()) { - depth_clip.pNext = std::exchange(rasterization_ci.pNext, &depth_clip); - } const VkPipelineMultisampleStateCreateInfo multisample_ci{ .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, @@ -825,12 +817,12 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { .pAttachments = cb_attachments.data(), .blendConstants = {} }; - static_vector dynamic_states{ + static_vector dynamic_states{ VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_BLEND_CONSTANTS, VK_DYNAMIC_STATE_DEPTH_BOUNDS, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, VK_DYNAMIC_STATE_STENCIL_REFERENCE, - VK_DYNAMIC_STATE_LINE_WIDTH, + VK_DYNAMIC_STATE_LINE_WIDTH, VK_DYNAMIC_STATE_LINE_STIPPLE, }; if (key.state.extended_dynamic_state) { static constexpr std::array extended{ @@ -864,6 +856,8 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT, VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT, VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT, + + // VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT, }; dynamic_states.insert(dynamic_states.end(), extended3.begin(), extended3.end()); } @@ -871,10 +865,26 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) { static constexpr std::array extended3{ VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT, VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT, + + // additional state3 extensions + + // FIXME(crueter): conservative rasterization is totally broken + // VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT, + VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT, + + VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT, + + VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT, + VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT, + VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT, + VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT, + VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT, + VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT, }; dynamic_states.insert(dynamic_states.end(), extended3.begin(), extended3.end()); } } + const VkPipelineDynamicStateCreateInfo dynamic_state_ci{ .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, .pNext = nullptr, diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 3a27ed895b..104c1ed46a 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -428,14 +428,20 @@ 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); dynamic_features = DynamicFeatures{ - .has_extended_dynamic_state = dynamic_state > 0, - .has_extended_dynamic_state_2 = dynamic_state > 1, - .has_extended_dynamic_state_2_extra = dynamic_state > 1, - .has_extended_dynamic_state_3_blend = dynamic_state > 2, - .has_extended_dynamic_state_3_enables = dynamic_state > 2, + .has_extended_dynamic_state = device.IsExtExtendedDynamicStateSupported() && dynamic_state > 0, + .has_extended_dynamic_state_2 = device.IsExtExtendedDynamicState2Supported() && dynamic_state > 1, + .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(), }; + + LOG_INFO(Render_Vulkan, "DynamicState1: {}", dynamic_features.has_extended_dynamic_state); + LOG_INFO(Render_Vulkan, "DynamicState2: {}", dynamic_features.has_extended_dynamic_state_2); + LOG_INFO(Render_Vulkan, "DynamicState3: {}", dynamic_features.has_extended_dynamic_state_3_enables); } PipelineCache::~PipelineCache() { diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 98288d069d..18bee98e49 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -898,6 +898,13 @@ bool TextureCacheRuntime::ShouldReinterpret(Image& dst, Image& src) { !device.IsExtShaderStencilExportSupported()) { return true; } + + if (VideoCore::Surface::GetFormatType(src.info.format) == + VideoCore::Surface::SurfaceType::DepthStencil && + !device.IsExtShaderStencilExportSupported()) { + return true; + } + if (dst.info.format == PixelFormat::D32_FLOAT_S8_UINT || src.info.format == PixelFormat::D32_FLOAT_S8_UINT) { return true; diff --git a/src/yuzu/configuration/configure_graphics_extensions.ui b/src/yuzu/configuration/configure_graphics_extensions.ui index 3033bd090c..e9f5ace53e 100644 --- a/src/yuzu/configuration/configure_graphics_extensions.ui +++ b/src/yuzu/configuration/configure_graphics_extensions.ui @@ -28,7 +28,8 @@ - While it's recommended to use state 3, some games may perform better on lower states. Additionally, some older devices and drivers will not work properly with state 3. + While it's recommended to use state 3, some games may perform better on lower states. Setting to 0 (disabled) may also break games. +If your device doesn't support the selected state, the renderer will automatically disable the unsupported states. true diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 48fbfd6b8e..7f52b8fbc4 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -4710,7 +4710,7 @@ void GMainWindow::UpdateStatusBar() { } game_fps_label->setText( - tr("Game: %1 FPS").arg(std::round(results.average_game_fps), 0, 'f', 0) + tr(Settings::values.use_speed_limit ? " (Unlocked)" : "")); + tr("Game: %1 FPS").arg(std::round(results.average_game_fps), 0, 'f', 0) + tr(Settings::values.use_speed_limit ? "" : " (Unlocked)")); emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2));