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:
swurl 2025-04-27 20:48:26 +00:00
parent 47efb1873b
commit 808276b48a
8 changed files with 45 additions and 21 deletions

View file

@ -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,

View file

@ -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() {

View file

@ -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;