Dynamic State Fixes (#57)
- Forcefully disabled dynamic state extensions if Vulkan reports that the device doesn't support it (need to update UI for this) - Adds some more supported state 3 extensions - Adds back stencil reinterpretation - default to 0 on Android and 1 on desktop Signed-off-by: swurl <swurl@swurl.xyz> Reviewed-on: #57 Co-authored-by: swurl <swurl@swurl.xyz> Co-committed-by: swurl <swurl@swurl.xyz>
This commit is contained in:
parent
47efb1873b
commit
808276b48a
8 changed files with 45 additions and 21 deletions
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash -ex
|
||||
#!/bin/bash -e
|
||||
|
||||
export NDK_CCACHE=$(which ccache)
|
||||
|
||||
|
|
|
@ -293,7 +293,7 @@
|
|||
<string name="nvdec_emulation_description">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.</string>
|
||||
<string name="shader_backend">Shader Backend</string>
|
||||
<string name="dyna_state">Extended Dynamic State</string>
|
||||
<string name="dyna_state_description">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</string>
|
||||
<string name="dyna_state_description">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.</string>
|
||||
|
||||
<!-- Debug settings strings -->
|
||||
<string name="cpu">CPU</string>
|
||||
|
|
|
@ -446,7 +446,7 @@ struct Values {
|
|||
Category::RendererAdvanced};
|
||||
|
||||
SwitchableSetting<u8, true> dyna_state{linkage,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
3,
|
||||
"dyna_state",
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <span>
|
||||
|
||||
#include <boost/container/small_vector.hpp>
|
||||
|
@ -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<VkDynamicState, 28> dynamic_states{
|
||||
static_vector<VkDynamicState, 38> 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,
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>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.</string>
|
||||
<string>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.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue