Browse Source

[Refactor, vk] DynamicState, ExtendedDynamicState and VertexInputDynamicState

pull/3115/head
CamilleLaVey 1 month ago
parent
commit
8be61d5067
  1. 4
      src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
  2. 5
      src/video_core/renderer_vulkan/fixed_pipeline_state.h
  3. 30
      src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
  4. 39
      src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
  5. 89
      src/video_core/vulkan_common/vulkan_device.cpp

4
src/video_core/renderer_vulkan/fixed_pipeline_state.cpp

@ -60,7 +60,7 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
raw1 = 0; raw1 = 0;
extended_dynamic_state.Assign(features.has_extended_dynamic_state ? 1 : 0); extended_dynamic_state.Assign(features.has_extended_dynamic_state ? 1 : 0);
extended_dynamic_state_2.Assign(features.has_extended_dynamic_state_2 ? 1 : 0); extended_dynamic_state_2.Assign(features.has_extended_dynamic_state_2 ? 1 : 0);
extended_dynamic_state_2_extra.Assign(features.has_extended_dynamic_state_2_extra ? 1 : 0);
extended_dynamic_state_2_logic_op.Assign(features.has_extended_dynamic_state_2_logic_op ? 1 : 0);
extended_dynamic_state_3_blend.Assign(features.has_extended_dynamic_state_3_blend ? 1 : 0); extended_dynamic_state_3_blend.Assign(features.has_extended_dynamic_state_3_blend ? 1 : 0);
extended_dynamic_state_3_enables.Assign(features.has_extended_dynamic_state_3_enables ? 1 : 0); extended_dynamic_state_3_enables.Assign(features.has_extended_dynamic_state_3_enables ? 1 : 0);
dynamic_vertex_input.Assign(features.has_dynamic_vertex_input ? 1 : 0); dynamic_vertex_input.Assign(features.has_dynamic_vertex_input ? 1 : 0);
@ -158,7 +158,7 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
return static_cast<u16>(array.stride.Value()); return static_cast<u16>(array.stride.Value());
}); });
} }
if (!extended_dynamic_state_2_extra) {
if (!extended_dynamic_state_2_logic_op) {
dynamic_state.Refresh2(regs, topology_, extended_dynamic_state_2); dynamic_state.Refresh2(regs, topology_, extended_dynamic_state_2);
} }
if (!extended_dynamic_state_3_blend) { if (!extended_dynamic_state_3_blend) {

5
src/video_core/renderer_vulkan/fixed_pipeline_state.h

@ -20,7 +20,8 @@ using Maxwell = Tegra::Engines::Maxwell3D::Regs;
struct DynamicFeatures { struct DynamicFeatures {
bool has_extended_dynamic_state; bool has_extended_dynamic_state;
bool has_extended_dynamic_state_2; bool has_extended_dynamic_state_2;
bool has_extended_dynamic_state_2_extra;
bool has_extended_dynamic_state_2_logic_op;
bool has_extended_dynamic_state_2_patch_control_points;
bool has_extended_dynamic_state_3_blend; bool has_extended_dynamic_state_3_blend;
bool has_extended_dynamic_state_3_enables; bool has_extended_dynamic_state_3_enables;
bool has_dynamic_vertex_input; bool has_dynamic_vertex_input;
@ -186,7 +187,7 @@ struct FixedPipelineState {
u32 raw1; u32 raw1;
BitField<0, 1, u32> extended_dynamic_state; BitField<0, 1, u32> extended_dynamic_state;
BitField<1, 1, u32> extended_dynamic_state_2; BitField<1, 1, u32> extended_dynamic_state_2;
BitField<2, 1, u32> extended_dynamic_state_2_extra;
BitField<2, 1, u32> extended_dynamic_state_2_logic_op;
BitField<3, 1, u32> extended_dynamic_state_3_blend; BitField<3, 1, u32> extended_dynamic_state_3_blend;
BitField<4, 1, u32> extended_dynamic_state_3_enables; BitField<4, 1, u32> extended_dynamic_state_3_enables;
BitField<5, 1, u32> dynamic_vertex_input; BitField<5, 1, u32> dynamic_vertex_input;

30
src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp

@ -845,7 +845,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
VK_DYNAMIC_STATE_LINE_WIDTH, VK_DYNAMIC_STATE_LINE_WIDTH,
}; };
if (key.state.extended_dynamic_state) { if (key.state.extended_dynamic_state) {
std::vector<VkDynamicState> extended{
static constexpr std::array extended{
VK_DYNAMIC_STATE_CULL_MODE_EXT, VK_DYNAMIC_STATE_CULL_MODE_EXT,
VK_DYNAMIC_STATE_FRONT_FACE_EXT, VK_DYNAMIC_STATE_FRONT_FACE_EXT,
VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT, VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT,
@ -855,13 +855,20 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT, VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT,
VK_DYNAMIC_STATE_STENCIL_OP_EXT, VK_DYNAMIC_STATE_STENCIL_OP_EXT,
}; };
if (!device.IsExtVertexInputDynamicStateSupported()) {
extended.push_back(VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT);
dynamic_states.insert(dynamic_states.end(), extended.begin(), extended.end());
// VERTEX_INPUT_BINDING_STRIDE is part of EDS1, not VIDS
if (!key.state.dynamic_vertex_input) {
dynamic_states.push_back(VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT);
}
} }
// Vertex Input Dynamic State (replaces VERTEX_INPUT_BINDING_STRIDE)
if (key.state.dynamic_vertex_input) { if (key.state.dynamic_vertex_input) {
dynamic_states.push_back(VK_DYNAMIC_STATE_VERTEX_INPUT_EXT); dynamic_states.push_back(VK_DYNAMIC_STATE_VERTEX_INPUT_EXT);
} }
dynamic_states.insert(dynamic_states.end(), extended.begin(), extended.end());
// EDS2 - Core (3 states)
if (key.state.extended_dynamic_state_2) { if (key.state.extended_dynamic_state_2) {
static constexpr std::array extended2{ static constexpr std::array extended2{
VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT, VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT,
@ -870,29 +877,29 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
}; };
dynamic_states.insert(dynamic_states.end(), extended2.begin(), extended2.end()); dynamic_states.insert(dynamic_states.end(), extended2.begin(), extended2.end());
} }
if (key.state.extended_dynamic_state_2_extra) {
// EDS2 - LogicOp (granular)
if (key.state.extended_dynamic_state_2_logic_op) {
dynamic_states.push_back(VK_DYNAMIC_STATE_LOGIC_OP_EXT); dynamic_states.push_back(VK_DYNAMIC_STATE_LOGIC_OP_EXT);
} }
// EDS3 - Blending (composite: 3 states)
if (key.state.extended_dynamic_state_3_blend) { if (key.state.extended_dynamic_state_3_blend) {
static constexpr std::array extended3{ static constexpr std::array extended3{
VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT, VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT,
VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT, VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT,
VK_DYNAMIC_STATE_COLOR_WRITE_MASK_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()); dynamic_states.insert(dynamic_states.end(), extended3.begin(), extended3.end());
} }
// EDS3 - Enables (composite: 9 states)
if (key.state.extended_dynamic_state_3_enables) { if (key.state.extended_dynamic_state_3_enables) {
static constexpr std::array extended3{ static constexpr std::array extended3{
VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT, VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT,
VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT, VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT,
// additional state3 extensions
VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT, VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT,
VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT, VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT,
VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT, VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT,
VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT, VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT,
VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT, VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT,
@ -901,7 +908,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
}; };
dynamic_states.insert(dynamic_states.end(), extended3.begin(), extended3.end()); dynamic_states.insert(dynamic_states.end(), extended3.begin(), extended3.end());
} }
}
const VkPipelineDynamicStateCreateInfo dynamic_state_ci{ const VkPipelineDynamicStateCreateInfo dynamic_state_ci{
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,

39
src/video_core/renderer_vulkan/vk_pipeline_cache.cpp

@ -404,14 +404,33 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
device.GetMaxVertexInputBindings(), Maxwell::NumVertexArrays); device.GetMaxVertexInputBindings(), Maxwell::NumVertexArrays);
} }
dynamic_features = DynamicFeatures{
.has_extended_dynamic_state = device.IsExtExtendedDynamicStateSupported(),
.has_extended_dynamic_state_2 = device.IsExtExtendedDynamicState2Supported(),
.has_extended_dynamic_state_2_extra = device.IsExtExtendedDynamicState2ExtrasSupported(),
.has_extended_dynamic_state_3_blend = device.IsExtExtendedDynamicState3BlendingSupported(),
.has_extended_dynamic_state_3_enables = device.IsExtExtendedDynamicState3EnablesSupported(),
.has_dynamic_vertex_input = device.IsExtVertexInputDynamicStateSupported(),
};
const u8 dynamic_state = Settings::values.dyna_state.GetValue();
LOG_INFO(Render_Vulkan, "DynamicState value is set to {}", static_cast<u32>(dynamic_state));
dynamic_features = {};
// EDS1 - Level 1 (all-or-nothing, enabled if driver supports AND setting > 0)
dynamic_features.has_extended_dynamic_state =
device.IsExtExtendedDynamicStateSupported() && dynamic_state > 0;
// EDS2 - Level 2 (core + granular features, enabled if driver supports AND setting > 1)
dynamic_features.has_extended_dynamic_state_2 =
device.IsExtExtendedDynamicState2Supported() && dynamic_state > 1;
dynamic_features.has_extended_dynamic_state_2_logic_op =
device.IsExtExtendedDynamicState2ExtrasSupported() && dynamic_state > 1;
dynamic_features.has_extended_dynamic_state_2_patch_control_points = false;
// EDS3 - Level 3 (granular features, enabled if driver supports AND setting > 2)
dynamic_features.has_extended_dynamic_state_3_blend =
device.IsExtExtendedDynamicState3BlendingSupported() && dynamic_state > 2;
dynamic_features.has_extended_dynamic_state_3_enables =
device.IsExtExtendedDynamicState3EnablesSupported() && dynamic_state > 2;
// VIDS - Independent toggle (not affected by dyna_state levels)
dynamic_features.has_dynamic_vertex_input =
device.IsExtVertexInputDynamicStateSupported() &&
Settings::values.vertex_input_dynamic_state.GetValue();
} }
PipelineCache::~PipelineCache() { PipelineCache::~PipelineCache() {
@ -516,8 +535,8 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
dynamic_features.has_extended_dynamic_state || dynamic_features.has_extended_dynamic_state ||
(key.state.extended_dynamic_state_2 != 0) != (key.state.extended_dynamic_state_2 != 0) !=
dynamic_features.has_extended_dynamic_state_2 || dynamic_features.has_extended_dynamic_state_2 ||
(key.state.extended_dynamic_state_2_extra != 0) !=
dynamic_features.has_extended_dynamic_state_2_extra ||
(key.state.extended_dynamic_state_2_logic_op != 0) !=
dynamic_features.has_extended_dynamic_state_2_logic_op ||
(key.state.extended_dynamic_state_3_blend != 0) != (key.state.extended_dynamic_state_3_blend != 0) !=
dynamic_features.has_extended_dynamic_state_3_blend || dynamic_features.has_extended_dynamic_state_3_blend ||
(key.state.extended_dynamic_state_3_enables != 0) != (key.state.extended_dynamic_state_3_enables != 0) !=

89
src/video_core/vulkan_common/vulkan_device.cpp

@ -1115,6 +1115,95 @@ bool Device::GetSuitability(bool requires_swapchain) {
} }
} }
// VK_DYNAMIC_STATE
// VK_EXT_extended_dynamic_state
// RADV < 21.2.0: Broken ExtendedDynamicState implementation
// Disable entire extension on old drivers
if (extensions.extended_dynamic_state && is_radv) {
const u32 version = (properties.properties.driverVersion << 3) >> 3;
if (version < VK_MAKE_API_VERSION(0, 21, 2, 0)) {
LOG_WARNING(Render_Vulkan,
"RADV < 21.2.0: Disabling broken VK_EXT_extended_dynamic_state");
features.extended_dynamic_state.extendedDynamicState = false;
}
}
// VK_EXT_extended_dynamic_state2
// RADV < 22.3.1: Broken ExtendedDynamicState2 implementation
// Disable entire extension on old drivers
if (extensions.extended_dynamic_state2 && is_radv) {
const u32 version = (properties.properties.driverVersion << 3) >> 3;
if (version < VK_MAKE_API_VERSION(0, 22, 3, 1)) {
LOG_WARNING(Render_Vulkan,
"RADV < 22.3.1: Disabling broken VK_EXT_extended_dynamic_state2");
features.extended_dynamic_state2.extendedDynamicState2 = false;
}
}
// Qualcomm Adreno 7xx (drivers 676.0 - 679.x): Broken ExtendedDynamicState2
// Disable ExtendedDynamicState2 on affected driver versions
if (extensions.extended_dynamic_state2 && is_qualcomm) {
const u32 version = (properties.properties.driverVersion << 3) >> 3;
if (version >= VK_MAKE_API_VERSION(0, 0, 676, 0) &&
version < VK_MAKE_API_VERSION(0, 0, 680, 0)) {
LOG_WARNING(Render_Vulkan,
"Qualcomm Adreno 7xx (676-679): Disabling broken VK_EXT_extended_dynamic_state2");
features.extended_dynamic_state2.extendedDynamicState2 = false;
}
}
// VK_EXT_extended_dynamic_state3
// AMD/Samsung/RADV: Broken extendedDynamicState3ColorBlendEquation
// Disable blend equation dynamic state, force static pipeline state
if (extensions.extended_dynamic_state3 &&
(is_amd_driver || is_radv || driver_id == VK_DRIVER_ID_SAMSUNG_PROPRIETARY)) {
LOG_WARNING(Render_Vulkan,
"AMD/Samsung/RADV: Disabling broken extendedDynamicState3ColorBlendEquation");
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false;
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false;
}
// VK_EXT_vertex_input_dynamic_state
// No RADV workarounds - assume modern drivers
// Qualcomm: Broken VertexInputDynamicState implementation
// Disable VertexInputDynamicState on all Qualcomm drivers
if (extensions.vertex_input_dynamic_state && is_qualcomm) {
LOG_WARNING(Render_Vulkan,
"Qualcomm: Disabling broken VK_EXT_vertex_input_dynamic_state");
features.vertex_input_dynamic_state.vertexInputDynamicState = false;
}
// Intel Windows < 27.20.100.0: Broken VertexInputDynamicState
// Disable VertexInputDynamicState on old Intel Windows drivers
if (extensions.vertex_input_dynamic_state && is_intel_windows) {
const u32 version = (properties.properties.driverVersion << 3) >> 3;
if (version < VK_MAKE_API_VERSION(27, 20, 100, 0)) {
LOG_WARNING(Render_Vulkan,
"Intel Windows < 27.20.100.0: Disabling broken VK_EXT_vertex_input_dynamic_state");
features.vertex_input_dynamic_state.vertexInputDynamicState = false;
}
}
// If user setting is dyna_state=0, disable all dynamic state features
if (Settings::values.dyna_state.GetValue() == 0) {
LOG_INFO(Render_Vulkan, "Dynamic state disabled by user setting, clearing all EDS features");
features.custom_border_color.customBorderColors = false;
features.custom_border_color.customBorderColorWithoutFormat = false;
features.extended_dynamic_state.extendedDynamicState = false;
features.extended_dynamic_state2.extendedDynamicState2 = false;
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false;
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false;
features.extended_dynamic_state3.extendedDynamicState3ColorWriteMask = false;
features.extended_dynamic_state3.extendedDynamicState3DepthClampEnable = false;
features.extended_dynamic_state3.extendedDynamicState3LogicOpEnable = false;
// Note: vertex_input_dynamic_state has independent toggle, NOT affected by dyna_state=0
}
// Return whether we were suitable. // Return whether we were suitable.
return suitable; return suitable;
} }

Loading…
Cancel
Save