Revert "[vulkan] Rework DynamicState - ExtendedDynamicState"

This commit is contained in:
CamilleLaVey 2026-04-15 18:54:10 -04:00
parent c926b558da
commit 7c04884d54
6 changed files with 92 additions and 486 deletions

View file

@ -57,11 +57,6 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
const auto topology_ = maxwell3d.draw_manager->GetDrawState().topology;
raw1 = 0;
core_dynamic_viewport_scissor.Assign(features.has_core_dynamic_viewport_scissor ? 1 : 0);
core_dynamic_depth_bias.Assign(features.has_core_dynamic_depth_bias ? 1 : 0);
core_dynamic_depth_bounds.Assign(features.has_core_dynamic_depth_bounds ? 1 : 0);
core_dynamic_line_width.Assign(features.has_core_dynamic_line_width ? 1 : 0);
core_dynamic_stencil_masks.Assign(features.has_core_dynamic_stencil_masks ? 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_logic_op.Assign(features.has_extended_dynamic_state_2_logic_op ? 1 : 0);
@ -81,7 +76,6 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
raw2 = 0;
const auto test_func =
regs.alpha_test_enabled != 0 ? regs.alpha_test_func : Maxwell::ComparisonOp::Always_GL;
alpha_test_func.Assign(PackComparisonOp(test_func));
@ -112,18 +106,10 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
}
provoking_vertex_last.Assign(use_last_provoking_vertex ? 1 : 0);
if (!features.has_dynamic_state3_conservative_rasterization_mode) {
conservative_raster_enable.Assign(regs.conservative_raster_enable != 0 ? 1 : 0);
}
if (!features.has_dynamic_state3_line_rasterization_mode) {
smooth_lines.Assign(regs.line_anti_alias_enable != 0 ? 1 : 0);
}
if (!features.has_dynamic_state3_alpha_to_coverage_enable) {
alpha_to_coverage_enabled.Assign(regs.anti_alias_alpha_control.alpha_to_coverage != 0 ? 1 : 0);
}
if (!features.has_dynamic_state3_alpha_to_one_enable) {
alpha_to_one_enabled.Assign(regs.anti_alias_alpha_control.alpha_to_one != 0 ? 1 : 0);
}
conservative_raster_enable.Assign(regs.conservative_raster_enable != 0 ? 1 : 0);
smooth_lines.Assign(regs.line_anti_alias_enable != 0 ? 1 : 0);
alpha_to_coverage_enabled.Assign(regs.anti_alias_alpha_control.alpha_to_coverage != 0 ? 1 : 0);
alpha_to_one_enabled.Assign(regs.anti_alias_alpha_control.alpha_to_one != 0 ? 1 : 0);
app_stage.Assign(maxwell3d.engine_state);
depth_bounds_min = static_cast<u32>(regs.depth_bounds[0]);
@ -187,49 +173,24 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
}
dynamic_state.raw1 = 0;
dynamic_state.raw2 = 0;
const bool any_eds1_baked = !features.has_extended_dynamic_state ||
!features.has_eds1_cull_mode || !features.has_eds1_front_face ||
!features.has_eds1_depth_test_enable || !features.has_eds1_depth_write_enable ||
!features.has_eds1_depth_compare_op ||
!(features.has_eds1_depth_bounds_test_enable || features.has_core_dynamic_depth_bounds) ||
!features.has_eds1_stencil_test_enable || !features.has_eds1_stencil_op;
if (any_eds1_baked) {
if (!extended_dynamic_state) {
dynamic_state.Refresh(regs);
}
if (!features.has_extended_dynamic_state || !features.has_eds1_vertex_input_binding_stride) {
std::ranges::transform(regs.vertex_streams, vertex_strides.begin(), [](const auto& array) {
return static_cast<u16>(array.stride.Value());
});
}
const bool any_eds2_baked = !features.has_extended_dynamic_state_2 ||
!(features.has_eds2_depth_bias_enable || features.has_core_dynamic_depth_bias) ||
!features.has_eds2_primitive_restart_enable ||
!features.has_eds2_rasterizer_discard_enable || !features.has_extended_dynamic_state_2_logic_op;
if (any_eds2_baked) {
if (!extended_dynamic_state_2_logic_op) {
dynamic_state.Refresh2(regs, topology_, extended_dynamic_state_2);
}
const bool any_eds3_baked = !features.has_extended_dynamic_state_3_blend ||
!features.has_dynamic_state3_depth_clamp_enable || !features.has_dynamic_state3_logic_op_enable ||
!features.has_dynamic_state3_line_stipple_enable || !features.has_dynamic_state3_alpha_to_coverage_enable ||
!features.has_dynamic_state3_alpha_to_one_enable || !features.has_dynamic_state3_line_rasterization_mode ||
!features.has_dynamic_state3_conservative_rasterization_mode;
if (any_eds3_baked) {
if (!extended_dynamic_state_3_blend) {
if (maxwell3d.dirty.flags[Dirty::Blending]) {
maxwell3d.dirty.flags[Dirty::Blending] = false;
for (size_t index = 0; index < attachments.size(); ++index) {
attachments[index].Refresh(regs, index);
}
}
dynamic_state.Refresh3(regs, features);
}
dynamic_state.Refresh3(regs, features);
if (xfb_enabled) {
RefreshXfbState(xfb_state, regs);
}

View file

@ -21,25 +21,8 @@ namespace Vulkan {
using Maxwell = Tegra::Engines::Maxwell3D::Regs;
struct DynamicFeatures {
bool has_core_dynamic_viewport_scissor;
bool has_core_dynamic_depth_bias;
bool has_core_dynamic_depth_bounds;
bool has_core_dynamic_line_width;
bool has_core_dynamic_stencil_masks;
bool has_extended_dynamic_state;
bool has_eds1_cull_mode;
bool has_eds1_front_face;
bool has_eds1_depth_test_enable;
bool has_eds1_depth_write_enable;
bool has_eds1_depth_compare_op;
bool has_eds1_depth_bounds_test_enable;
bool has_eds1_stencil_test_enable;
bool has_eds1_stencil_op;
bool has_eds1_vertex_input_binding_stride;
bool has_extended_dynamic_state_2;
bool has_eds2_depth_bias_enable;
bool has_eds2_primitive_restart_enable;
bool has_eds2_rasterizer_discard_enable;
bool has_extended_dynamic_state_2_logic_op;
bool has_extended_dynamic_state_2_patch_control_points;
bool has_extended_dynamic_state_3_blend;
@ -47,10 +30,6 @@ struct DynamicFeatures {
bool has_dynamic_state3_depth_clamp_enable;
bool has_dynamic_state3_logic_op_enable;
bool has_dynamic_state3_line_stipple_enable;
bool has_dynamic_state3_alpha_to_coverage_enable;
bool has_dynamic_state3_alpha_to_one_enable;
bool has_dynamic_state3_line_rasterization_mode;
bool has_dynamic_state3_conservative_rasterization_mode;
bool has_dynamic_vertex_input;
bool has_provoking_vertex;
bool has_provoking_vertex_first_mode;
@ -215,27 +194,23 @@ struct FixedPipelineState {
};
union {
u64 raw1;
BitField<0, 1, u64> core_dynamic_viewport_scissor;
BitField<1, 1, u64> core_dynamic_depth_bias;
BitField<2, 1, u64> core_dynamic_depth_bounds;
BitField<3, 1, u64> core_dynamic_line_width;
BitField<4, 1, u64> core_dynamic_stencil_masks;
BitField<5, 1, u64> extended_dynamic_state;
BitField<6, 1, u64> extended_dynamic_state_2;
BitField<7, 1, u64> extended_dynamic_state_2_logic_op;
BitField<8, 1, u64> extended_dynamic_state_3_blend;
BitField<9, 1, u64> extended_dynamic_state_3_enables;
BitField<10, 1, u64> dynamic_vertex_input;
BitField<11, 1, u64> xfb_enabled;
BitField<12, 1, u64> ndc_minus_one_to_one;
BitField<13, 2, u64> polygon_mode;
BitField<15, 2, u64> tessellation_primitive;
BitField<17, 2, u64> tessellation_spacing;
BitField<19, 1, u64> tessellation_clockwise;
BitField<20, 5, u64> patch_control_points_minus_one;
BitField<25, 4, Maxwell::PrimitiveTopology> topology;
BitField<29, 4, Tegra::Texture::MsaaMode> msaa_mode;
u32 raw1;
BitField<0, 1, u32> extended_dynamic_state;
BitField<1, 1, u32> extended_dynamic_state_2;
BitField<2, 1, u32> extended_dynamic_state_2_logic_op;
BitField<3, 1, u32> extended_dynamic_state_3_blend;
BitField<4, 1, u32> extended_dynamic_state_3_enables;
BitField<5, 1, u32> dynamic_vertex_input;
BitField<6, 1, u32> xfb_enabled;
BitField<7, 1, u32> ndc_minus_one_to_one;
BitField<8, 2, u32> polygon_mode;
BitField<10, 2, u32> tessellation_primitive;
BitField<12, 2, u32> tessellation_spacing;
BitField<14, 1, u32> tessellation_clockwise;
BitField<15, 5, u32> patch_control_points_minus_one;
BitField<24, 4, Maxwell::PrimitiveTopology> topology;
BitField<28, 4, Tegra::Texture::MsaaMode> msaa_mode;
};
union {
u32 raw2;

View file

@ -848,94 +848,62 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
.pAttachments = cb_attachments.data(),
.blendConstants = {}
};
static_vector<VkDynamicState, 34> dynamic_states{};
// Core dynamic states (Vulkan 1.0)
if (device.SupportsCoreDynamicViewportScissor()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_VIEWPORT);
dynamic_states.push_back(VK_DYNAMIC_STATE_SCISSOR);
}
if (device.SupportsCoreDynamicDepthBias()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_DEPTH_BIAS);
}
// Blend constants are commonly available; keep as default dynamic state.
dynamic_states.push_back(VK_DYNAMIC_STATE_BLEND_CONSTANTS);
if (device.SupportsCoreDynamicDepthBounds()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_DEPTH_BOUNDS);
}
if (device.SupportsCoreDynamicStencilMasks()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK);
dynamic_states.push_back(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK);
dynamic_states.push_back(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
}
if (device.SupportsCoreDynamicLineWidth()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_LINE_WIDTH);
}
static_vector<VkDynamicState, 34> 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,
};
if (key.state.extended_dynamic_state) {
if (device.SupportsEds1CullMode()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_CULL_MODE_EXT);
}
if (device.SupportsEds1FrontFace()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_FRONT_FACE_EXT);
}
if (device.SupportsEds1DepthTestEnable()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT);
}
if (device.SupportsEds1DepthWriteEnable()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT);
}
if (device.SupportsEds1DepthCompareOp()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT);
}
if (device.SupportsEds1DepthBoundsTestEnable()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT);
}
if (device.SupportsEds1StencilTestEnable()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT);
}
if (device.SupportsEds1StencilOp()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_STENCIL_OP_EXT);
}
static constexpr std::array extended{
VK_DYNAMIC_STATE_CULL_MODE_EXT,
VK_DYNAMIC_STATE_FRONT_FACE_EXT,
VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT,
VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT,
VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT,
VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT,
VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT,
VK_DYNAMIC_STATE_STENCIL_OP_EXT,
};
dynamic_states.insert(dynamic_states.end(), extended.begin(), extended.end());
// VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT
if (!key.state.dynamic_vertex_input && device.SupportsEds1VertexInputBindingStride()) {
// VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT is part of EDS1
// Only use it if VIDS is not active (VIDS replaces it with full vertex input control)
if (!key.state.dynamic_vertex_input) {
dynamic_states.push_back(VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT);
}
}
// VK_DYNAMIC_STATE_VERTEX_INPUT_EXT (VIDS) replaces VERTEX_INPUT_BINDING_STRIDE
// VK_DYNAMIC_STATE_VERTEX_INPUT_EXT (VIDS) - Independent from EDS
// Provides full dynamic vertex input control, replaces VERTEX_INPUT_BINDING_STRIDE
if (key.state.dynamic_vertex_input) {
dynamic_states.push_back(VK_DYNAMIC_STATE_VERTEX_INPUT_EXT);
}
// EDS2 - Core (3 states) — include only supported subfeatures
// EDS2 - Core (3 states)
if (key.state.extended_dynamic_state_2) {
if (device.SupportsEds2DepthBiasEnable()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT);
}
if (device.SupportsEds2PrimitiveRestartEnable()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT);
}
if (device.SupportsEds2RasterizerDiscardEnable()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT);
}
static constexpr std::array extended2{
VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT,
VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT,
VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT,
};
dynamic_states.insert(dynamic_states.end(), extended2.begin(), extended2.end());
}
// EDS2 - LogicOp (granular)
if (key.state.extended_dynamic_state_2_logic_op && device.SupportsDynamicState2LogicOp()) {
if (key.state.extended_dynamic_state_2_logic_op) {
dynamic_states.push_back(VK_DYNAMIC_STATE_LOGIC_OP_EXT);
}
// EDS3 - Blending (composite: 3 states)
if (key.state.extended_dynamic_state_3_blend) {
if (device.SupportsDynamicState3ColorBlendEnable()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT);
}
if (device.SupportsDynamicState3ColorBlendEquation()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT);
}
if (device.SupportsDynamicState3ColorWriteMask()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT);
}
static constexpr std::array extended3{
VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT,
VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT,
VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT,
};
dynamic_states.insert(dynamic_states.end(), extended3.begin(), extended3.end());
}
// EDS3 - Enables (composite: per-feature)

View file

@ -58,7 +58,7 @@ using VideoCommon::FileEnvironment;
using VideoCommon::GenericEnvironment;
using VideoCommon::GraphicsEnvironment;
constexpr u32 CACHE_VERSION = 17;
constexpr u32 CACHE_VERSION = 16;
constexpr std::array<char, 8> VULKAN_CACHE_MAGIC_NUMBER{'y', 'u', 'z', 'u', 'v', 'k', 'c', 'h'};
template <typename Container>
@ -465,46 +465,18 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
dynamic_features = {};
dynamic_features.has_core_dynamic_viewport_scissor =
device.SupportsCoreDynamicViewportScissor();
dynamic_features.has_core_dynamic_depth_bias =
device.SupportsCoreDynamicDepthBias();
dynamic_features.has_core_dynamic_depth_bounds =
device.SupportsCoreDynamicDepthBounds();
dynamic_features.has_core_dynamic_line_width =
device.SupportsCoreDynamicLineWidth();
dynamic_features.has_core_dynamic_stencil_masks =
device.SupportsCoreDynamicStencilMasks();
// User granularity enforced in vulkan_device.cpp switch statement:
// Level 0: Core Dynamic States only
// Level 1: Core + EDS1
// Level 2: Core + EDS1 + EDS2 (accumulative)
// Level 3: Core + EDS1 + EDS2 + EDS3 (accumulative)
// Here we only verify if extensions were successfully loaded by the device
dynamic_features.has_extended_dynamic_state =
device.IsExtExtendedDynamicStateSupported();
dynamic_features.has_eds1_cull_mode =
device.SupportsEds1CullMode();
dynamic_features.has_eds1_front_face =
device.SupportsEds1FrontFace();
dynamic_features.has_eds1_depth_test_enable =
device.SupportsEds1DepthTestEnable();
dynamic_features.has_eds1_depth_write_enable =
device.SupportsEds1DepthWriteEnable();
dynamic_features.has_eds1_depth_compare_op =
device.SupportsEds1DepthCompareOp();
dynamic_features.has_eds1_depth_bounds_test_enable =
device.SupportsEds1DepthBoundsTestEnable();
dynamic_features.has_eds1_stencil_test_enable =
device.SupportsEds1StencilTestEnable();
dynamic_features.has_eds1_stencil_op =
device.SupportsEds1StencilOp();
dynamic_features.has_eds1_vertex_input_binding_stride =
device.SupportsEds1VertexInputBindingStride();
dynamic_features.has_extended_dynamic_state_2 =
device.IsExtExtendedDynamicState2Supported();
dynamic_features.has_eds2_depth_bias_enable =
device.SupportsEds2DepthBiasEnable();
dynamic_features.has_eds2_primitive_restart_enable =
device.SupportsEds2PrimitiveRestartEnable();
dynamic_features.has_eds2_rasterizer_discard_enable =
device.SupportsEds2RasterizerDiscardEnable();
dynamic_features.has_extended_dynamic_state_2_logic_op =
device.IsExtExtendedDynamicState2ExtrasSupported();
dynamic_features.has_extended_dynamic_state_2_patch_control_points = false;
@ -519,21 +491,13 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
device.SupportsDynamicState3LogicOpEnable();
dynamic_features.has_dynamic_state3_line_stipple_enable =
device.SupportsDynamicState3LineStippleEnable();
dynamic_features.has_dynamic_state3_alpha_to_coverage_enable =
device.SupportsDynamicState3AlphaToCoverageEnable();
dynamic_features.has_dynamic_state3_alpha_to_one_enable =
device.SupportsDynamicState3AlphaToOneEnable();
dynamic_features.has_dynamic_state3_line_rasterization_mode =
device.SupportsDynamicState3LineRasterizationMode();
dynamic_features.has_dynamic_state3_conservative_rasterization_mode =
device.SupportsDynamicState3ConservativeRasterizationMode();
// VIDS: Independent toggle (not affected by dyna_state levels)
dynamic_features.has_dynamic_vertex_input =
device.IsExtVertexInputDynamicStateSupported() &&
Settings::values.vertex_input_dynamic_state.GetValue();
dynamic_features.has_provoking_vertex =
device.IsExtProvokingVertexSupported();
dynamic_features.has_provoking_vertex = device.IsExtProvokingVertexSupported();
dynamic_features.has_provoking_vertex_first_mode =
device.SupportsProvokingVertexFirstMode();
dynamic_features.has_provoking_vertex_last_mode =
@ -640,20 +604,8 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
GraphicsPipelineCacheKey key;
file.read(reinterpret_cast<char*>(&key), sizeof(key));
if ((key.state.core_dynamic_viewport_scissor != 0) !=
dynamic_features.has_core_dynamic_viewport_scissor ||
(key.state.core_dynamic_depth_bias != 0) !=
dynamic_features.has_core_dynamic_depth_bias ||
(key.state.core_dynamic_depth_bounds != 0) !=
dynamic_features.has_core_dynamic_depth_bounds ||
(key.state.core_dynamic_line_width != 0) !=
dynamic_features.has_core_dynamic_line_width ||
(key.state.core_dynamic_stencil_masks != 0) !=
dynamic_features.has_core_dynamic_stencil_masks ||
(key.state.extended_dynamic_state != 0) !=
if ((key.state.extended_dynamic_state != 0) !=
dynamic_features.has_extended_dynamic_state ||
(key.state.dynamic_vertex_input != 0) !=
dynamic_features.has_dynamic_vertex_input ||
(key.state.extended_dynamic_state_2 != 0) !=
dynamic_features.has_extended_dynamic_state_2 ||
(key.state.extended_dynamic_state_2_logic_op != 0) !=
@ -661,7 +613,8 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
(key.state.extended_dynamic_state_3_blend != 0) !=
dynamic_features.has_extended_dynamic_state_3_blend ||
(key.state.extended_dynamic_state_3_enables != 0) !=
dynamic_features.has_extended_dynamic_state_3_enables) {
dynamic_features.has_extended_dynamic_state_3_enables ||
(key.state.dynamic_vertex_input != 0) != dynamic_features.has_dynamic_vertex_input) {
return;
}

View file

@ -648,9 +648,16 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
const auto dyna_state = Settings::values.dyna_state.GetValue();
// Base dynamic states (VIEWPORT, SCISSOR, DEPTH_BIAS, etc.) are ALWAYS active in vk_graphics_pipeline.cpp
// This slider controls EXTENDED dynamic states with accumulative levels per Vulkan specs:
// Level 0 = Core Dynamic States only (Vulkan 1.0)
// Level 1 = Core + VK_EXT_extended_dynamic_state
// Level 2 = Core + VK_EXT_extended_dynamic_state + VK_EXT_extended_dynamic_state2
// Level 3 = Core + VK_EXT_extended_dynamic_state + VK_EXT_extended_dynamic_state2 + VK_EXT_extended_dynamic_state3
switch (dyna_state) {
case Settings::ExtendedDynamicState::Disabled:
// Level 0: Enable DynamicState (Static) + Disable all extended dynamic state extensions
// Level 0: Disable all extended dynamic state extensions
RemoveExtensionFeature(extensions.extended_dynamic_state, features.extended_dynamic_state,
VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
RemoveExtensionFeature(extensions.extended_dynamic_state2, features.extended_dynamic_state2,
@ -659,60 +666,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME);
dynamic_state3_blending = false;
dynamic_state3_enables = false;
core_dynamic_viewport_scissor = (dld.vkCmdSetViewport != nullptr) && (dld.vkCmdSetScissor != nullptr);
core_dynamic_depth_bias = (dld.vkCmdSetDepthBias != nullptr) || (dld.vkCmdSetDepthBias2EXT != nullptr) ||
(features.depth_bias_control.depthBiasControl != VK_FALSE);
if (features.core.features.depthBounds && dld.vkCmdSetDepthBounds == nullptr) {
features.core.features.depthBounds = VK_FALSE;
core_dynamic_depth_bounds = false;
} else {
core_dynamic_depth_bounds = (dld.vkCmdSetDepthBounds != nullptr) && features.core.features.depthBounds;
}
if (features.core.features.wideLines && dld.vkCmdSetLineWidth == nullptr) {
features.core.features.wideLines = VK_FALSE;
core_dynamic_line_width = false;
} else {
core_dynamic_line_width = (dld.vkCmdSetLineWidth != nullptr) && features.core.features.wideLines;
}
core_dynamic_stencil_masks = (dld.vkCmdSetStencilCompareMask != nullptr) &&
(dld.vkCmdSetStencilWriteMask != nullptr) &&
(dld.vkCmdSetStencilReference != nullptr);
break;
case Settings::ExtendedDynamicState::EDS1:
// Level 1: Enable EDS1, disable EDS2 and EDS3
if (dyna_state_enabled && extensions.extended_dynamic_state) {
eds1_cull_mode = features.extended_dynamic_state.extendedDynamicState && (dld.vkCmdSetCullModeEXT != nullptr);
eds1_front_face = features.extended_dynamic_state.extendedDynamicState && (dld.vkCmdSetFrontFaceEXT != nullptr);
eds1_depth_test_enable = features.extended_dynamic_state.extendedDynamicState && (dld.vkCmdSetDepthTestEnableEXT != nullptr);
eds1_depth_write_enable = features.extended_dynamic_state.extendedDynamicState && (dld.vkCmdSetDepthWriteEnableEXT != nullptr);
eds1_depth_compare_op = features.extended_dynamic_state.extendedDynamicState && (dld.vkCmdSetDepthCompareOpEXT != nullptr);
eds1_depth_bounds_test_enable = features.extended_dynamic_state.extendedDynamicState && (dld.vkCmdSetDepthBoundsTestEnableEXT != nullptr);
eds1_stencil_test_enable = features.extended_dynamic_state.extendedDynamicState && (dld.vkCmdSetStencilTestEnableEXT != nullptr);
eds1_stencil_op = features.extended_dynamic_state.extendedDynamicState && (dld.vkCmdSetStencilOpEXT != nullptr);
vertex_input_binding_stride = features.extended_dynamic_state.extendedDynamicState && (dld.vkCmdBindVertexBuffers2EXT != nullptr);
const bool eds1_any = eds1_cull_mode || eds1_front_face || eds1_depth_test_enable ||
eds1_depth_write_enable || eds1_depth_compare_op || eds1_depth_bounds_test_enable ||
eds1_stencil_test_enable || eds1_stencil_op || vertex_input_binding_stride;
if (!eds1_any) {
extensions.extended_dynamic_state = false;
RemoveExtensionFeature(extensions.extended_dynamic_state, features.extended_dynamic_state, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
// Clear flags
eds1_cull_mode = eds1_front_face = eds1_depth_test_enable = eds1_depth_write_enable = false;
eds1_depth_compare_op = eds1_depth_bounds_test_enable = eds1_stencil_test_enable = eds1_stencil_op = false;
vertex_input_binding_stride = false;
}
} else {
extensions.extended_dynamic_state = false;
eds1_cull_mode = eds1_front_face = eds1_depth_test_enable = eds1_depth_write_enable = false;
eds1_depth_compare_op = eds1_depth_bounds_test_enable = eds1_stencil_test_enable = eds1_stencil_op = false;
vertex_input_binding_stride = false;
}
RemoveExtensionFeature(extensions.extended_dynamic_state2, features.extended_dynamic_state2,
VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3,
@ -722,32 +678,6 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
break;
case Settings::ExtendedDynamicState::EDS2:
// Level 2: Enable EDS1 + EDS2, disable EDS3
{
bool eds1_any = (features.extended_dynamic_state.extendedDynamicState &&
((dld.vkCmdBindVertexBuffers2EXT != nullptr) || (dld.vkCmdSetCullModeEXT != nullptr)));
if (!eds1_any) {
extensions.extended_dynamic_state2 = false;
}
}
if (dyna_state_enabled && extensions.extended_dynamic_state2) {
eds2_depth_bias_enable = features.extended_dynamic_state2.extendedDynamicState2 && (dld.vkCmdSetDepthBiasEnableEXT != nullptr);
eds2_primitive_restart_enable = features.extended_dynamic_state2.extendedDynamicState2 && (dld.vkCmdSetPrimitiveRestartEnableEXT != nullptr);
eds2_rasterizer_discard_enable = features.extended_dynamic_state2.extendedDynamicState2 && (dld.vkCmdSetRasterizerDiscardEnableEXT != nullptr);
if (features.extended_dynamic_state2.extendedDynamicState2LogicOp && (dld.vkCmdSetLogicOpEXT == nullptr)) {
features.extended_dynamic_state2.extendedDynamicState2LogicOp = VK_FALSE;
}
const bool eds2_any = eds2_depth_bias_enable || eds2_primitive_restart_enable || eds2_rasterizer_discard_enable ||
(features.extended_dynamic_state2.extendedDynamicState2LogicOp && (dld.vkCmdSetLogicOpEXT != nullptr));
if (!eds2_any) {
extensions.extended_dynamic_state2 = false;
RemoveExtensionFeature(extensions.extended_dynamic_state2, features.extended_dynamic_state2, VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
eds2_depth_bias_enable = eds2_primitive_restart_enable = eds2_rasterizer_discard_enable = false;
}
} else {
extensions.extended_dynamic_state2 = false;
}
RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3,
VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME);
dynamic_state3_blending = false;
@ -756,96 +686,13 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
case Settings::ExtendedDynamicState::EDS3:
default:
// Level 3: Enable all (EDS1 + EDS2 + EDS3)
{
bool eds1_any = (features.extended_dynamic_state.extendedDynamicState &&
((dld.vkCmdBindVertexBuffers2EXT != nullptr) || (dld.vkCmdSetCullModeEXT != nullptr)));
bool eds2_any = ((features.extended_dynamic_state2.extendedDynamicState2 &&
((dld.vkCmdSetDepthBiasEnableEXT != nullptr) || (dld.vkCmdSetPrimitiveRestartEnableEXT != nullptr))) ||
(features.extended_dynamic_state2.extendedDynamicState2LogicOp && (dld.vkCmdSetLogicOpEXT != nullptr)));
if (!(eds1_any || eds2_any)) {
extensions.extended_dynamic_state3 = false;
}
}
if (dyna_state_enabled && extensions.extended_dynamic_state3) {
if (!(features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable && (dld.vkCmdSetColorBlendEnableEXT != nullptr))) {
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = VK_FALSE;
}
if (!(features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation && (dld.vkCmdSetColorBlendEquationEXT != nullptr))) {
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = VK_FALSE;
}
if (!(features.extended_dynamic_state3.extendedDynamicState3ColorWriteMask && (dld.vkCmdSetColorWriteMaskEXT != nullptr))) {
features.extended_dynamic_state3.extendedDynamicState3ColorWriteMask = VK_FALSE;
}
if (!(features.extended_dynamic_state3.extendedDynamicState3DepthClampEnable && (dld.vkCmdSetDepthClampEnableEXT != nullptr))) {
features.extended_dynamic_state3.extendedDynamicState3DepthClampEnable = VK_FALSE;
}
if (!(features.extended_dynamic_state3.extendedDynamicState3LogicOpEnable && (dld.vkCmdSetLogicOpEnableEXT != nullptr))) {
features.extended_dynamic_state3.extendedDynamicState3LogicOpEnable = VK_FALSE;
}
if (!(features.extended_dynamic_state3.extendedDynamicState3AlphaToCoverageEnable && (dld.vkCmdSetAlphaToCoverageEnableEXT != nullptr))) {
features.extended_dynamic_state3.extendedDynamicState3AlphaToCoverageEnable = VK_FALSE;
}
if (!(features.extended_dynamic_state3.extendedDynamicState3AlphaToOneEnable && (dld.vkCmdSetAlphaToOneEnableEXT != nullptr))) {
features.extended_dynamic_state3.extendedDynamicState3AlphaToOneEnable = VK_FALSE;
}
if (!(features.extended_dynamic_state3.extendedDynamicState3LineRasterizationMode && (dld.vkCmdSetLineRasterizationModeEXT != nullptr))) {
features.extended_dynamic_state3.extendedDynamicState3LineRasterizationMode = VK_FALSE;
}
if (!(features.extended_dynamic_state3.extendedDynamicState3ConservativeRasterizationMode && (dld.vkCmdSetConservativeRasterizationModeEXT != nullptr))) {
features.extended_dynamic_state3.extendedDynamicState3ConservativeRasterizationMode = VK_FALSE;
}
if (!(features.extended_dynamic_state3.extendedDynamicState3LineStippleEnable && (dld.vkCmdSetLineStippleEnableEXT != nullptr))) {
features.extended_dynamic_state3.extendedDynamicState3LineStippleEnable = VK_FALSE;
}
bool blending = features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable ||
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation ||
features.extended_dynamic_state3.extendedDynamicState3ColorWriteMask;
bool enables = features.extended_dynamic_state3.extendedDynamicState3DepthClampEnable ||
features.extended_dynamic_state3.extendedDynamicState3LogicOpEnable ||
features.extended_dynamic_state3.extendedDynamicState3LineStippleEnable ||
features.extended_dynamic_state3.extendedDynamicState3AlphaToCoverageEnable ||
features.extended_dynamic_state3.extendedDynamicState3AlphaToOneEnable ||
features.extended_dynamic_state3.extendedDynamicState3LineRasterizationMode ||
features.extended_dynamic_state3.extendedDynamicState3ConservativeRasterizationMode;
if (!blending && !enables) {
extensions.extended_dynamic_state3 = false;
RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3, VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME);
} else {
dynamic_state3_blending = blending;
dynamic_state3_enables = enables;
}
} else {
extensions.extended_dynamic_state3 = false;
}
break;
}
// VK_EXT_vertex_input_dynamic_state and features.vertex_input_binding_stride
// VK_EXT_vertex_input_dynamic_state is independent from EDS
// It can be enabled even without extended_dynamic_state
if (!Settings::values.vertex_input_dynamic_state.GetValue()) {
RemoveExtensionFeature(extensions.vertex_input_dynamic_state, features.vertex_input_dynamic_state, VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
} else {
bool vids_entrypoint = dld.vkCmdSetVertexInputEXT != nullptr;
bool vb2_entrypoint = dld.vkCmdBindVertexBuffers2EXT != nullptr;
if (!vids_entrypoint) {
features.vertex_input_dynamic_state.vertexInputDynamicState = VK_FALSE;
}
if (vids_entrypoint && features.vertex_input_dynamic_state.vertexInputDynamicState) {
vertex_input_binding_stride = false;
} else {
// Only enable binding stride if EDS1 and the VB2 entrypoint are available.
vertex_input_binding_stride = features.extended_dynamic_state.extendedDynamicState && vb2_entrypoint;
}
if (!features.vertex_input_dynamic_state.vertexInputDynamicState) {
extensions.vertex_input_dynamic_state = false;
}
}
if (!features.extended_dynamic_state.extendedDynamicState) {
extensions.extended_dynamic_state = false;
}
logical = vk::Device::Create(physical, queue_cis, ExtensionListForVulkan(loaded_extensions), first_next, dld);

View file

@ -569,112 +569,31 @@ public:
return features.custom_border_color.customBorderColorWithoutFormat;
}
/// Core dynamic states availability (Vulkan 1.0)
bool SupportsCoreDynamicViewportScissor() const {
return core_dynamic_viewport_scissor;
}
bool SupportsCoreDynamicDepthBias() const {
return core_dynamic_depth_bias;
}
bool SupportsCoreDynamicDepthBounds() const {
return core_dynamic_depth_bounds;
}
bool SupportsCoreDynamicLineWidth() const {
return core_dynamic_line_width;
}
bool SupportsCoreDynamicStencilMasks() const {
return core_dynamic_stencil_masks;
}
/// Returns true if the device supports VK_EXT_extended_dynamic_state.
bool IsExtExtendedDynamicStateSupported() const {
return extensions.extended_dynamic_state;
}
/// VK_EXT_extended_dynamic_state core dynamic states availability
bool SupportsEds1CullMode() const {
return eds1_cull_mode;
}
bool SupportsEds1FrontFace() const {
return eds1_front_face;
}
bool SupportsEds1DepthTestEnable() const {
return eds1_depth_test_enable;
}
bool SupportsEds1DepthWriteEnable() const {
return eds1_depth_write_enable;
}
bool SupportsEds1DepthCompareOp() const {
return eds1_depth_compare_op;
}
bool SupportsEds1DepthBoundsTestEnable() const {
return eds1_depth_bounds_test_enable;
}
bool SupportsEds1StencilTestEnable() const {
return eds1_stencil_test_enable;
}
bool SupportsEds1StencilOp() const {
return eds1_stencil_op;
}
bool SupportsEds1VertexInputBindingStride() const {
return eds1_vertex_input_binding_stride;
}
/// Returns true if the device supports VK_EXT_extended_dynamic_state2.
bool IsExtExtendedDynamicState2Supported() const {
return extensions.extended_dynamic_state2;
}
/// VK_EXT_extended_dynamic_state2 core dynamic states availability
bool SupportsEds2DepthBiasEnable() const {
return eds2_depth_bias_enable;
}
bool SupportsEds2PrimitiveRestartEnable() const {
return eds2_primitive_restart_enable;
}
bool SupportsEds2RasterizerDiscardEnable() const {
return eds2_rasterizer_discard_enable;
}
bool IsExtExtendedDynamicState2ExtrasSupported() const {
return features.extended_dynamic_state2.extendedDynamicState2LogicOp;
}
bool SupportsDynamicState2LogicOp() const {
return extensions.extended_dynamic_state2 &&
features.extended_dynamic_state2.extendedDynamicState2LogicOp;
}
/// Returns true if the device supports VK_EXT_extended_dynamic_state3.
bool IsExtExtendedDynamicState3Supported() const {
return extensions.extended_dynamic_state3;
}
/// Returns true if the device supports VK_EXT_extended_dynamic_state3 color blend enable.
bool SupportsDynamicState3ColorBlendEnable() const {
return extensions.extended_dynamic_state3 &&
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable;
}
/// Returns true if the device supports VK_EXT_extended_dynamic_state3 color blend equation.
bool SupportsDynamicState3ColorBlendEquation() const {
return extensions.extended_dynamic_state3 &&
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation;
}
/// Returns true if the device supports VK_EXT_extended_dynamic_state3 color write mask.
bool SupportsDynamicState3ColorWriteMask() const {
return extensions.extended_dynamic_state3 &&
features.extended_dynamic_state3.extendedDynamicState3ColorWriteMask;
}
/// Returns true if the device supports VK_EXT_4444_formats.
bool IsExt4444FormatsSupported() const {
return features.format_a4b4g4r4.formatA4B4G4R4;
}
/// Returns true if the device supports VK_EXT_extended_dynamic_state3 blending.
/// Returns true if the device supports VK_EXT_extended_dynamic_state3.
bool IsExtExtendedDynamicState3BlendingSupported() const {
return dynamic_state3_blending;
}
@ -1103,32 +1022,15 @@ private:
bool supports_d24_depth{}; ///< Supports D24 depth buffers.
bool cant_blit_msaa{}; ///< Does not support MSAA<->MSAA blitting.
bool must_emulate_scaled_formats{}; ///< Requires scaled vertex format emulation
bool core_dynamic_viewport_scissor{}; ///< vkCmdSetViewport && vkCmdSetScissor
bool core_dynamic_depth_bias{}; ///< vkCmdSetDepthBias (or alternative)
bool core_dynamic_depth_bounds{}; ///< vkCmdSetDepthBounds
bool core_dynamic_line_width{}; ///< vkCmdSetLineWidth
bool core_dynamic_stencil_masks{}; ///< vkCmdSetStencilCompareMask/WriteMask/Reference
bool eds1_cull_mode{}; ///< Has EDS1 support for dynamic cull mode state.
bool eds1_front_face{}; ///< Has EDS1 support for dynamic front face state.
bool eds1_depth_test_enable{}; ///< Has EDS1 support for dynamic depth test enable state.
bool eds1_depth_write_enable{}; ///< Has EDS1 support for dynamic depth write enable state.
bool eds1_depth_compare_op{}; ///< Has EDS1 support for dynamic depth compare op state.
bool eds1_depth_bounds_test_enable{}; ///< Has EDS1 support for dynamic depth bounds test enable state.
bool eds1_stencil_test_enable{}; ///< Has EDS1 support for dynamic stencil test enable state.
bool eds1_stencil_op{}; ///< Has EDS1 support for dynamic stencil op state.
bool eds1_vertex_input_binding_stride{}; ///< Has EDS1 support for dynamic vertex input binding stride state.
bool eds2_depth_bias_enable{}; ///< Has EDS2 support for depth bias enable state.
bool eds2_primitive_restart_enable{}; ///< Has EDS2 support for primitive restart enable state.
bool eds2_rasterizer_discard_enable{}; ///< Has EDS2 support for rasterizer discard enable state.
bool dynamic_state3_blending{}; ///< Has blending features of dynamic_state3.
bool dynamic_state3_enables{}; ///< Has at least one enable feature of dynamic_state3.
bool dynamic_state3_depth_clamp_enable{}; ///< Has dynamic_state3 support for depth clamp enable state.
bool dynamic_state3_logic_op_enable{}; ///< Has dynamic_state3 support for logic op enable state.
bool dynamic_state3_line_raster_mode{}; ///< Has dynamic_state3 support for line raster mode state.
bool dynamic_state3_conservative_raster_mode{}; ///< Has dynamic_state3 support for conservative raster mode state.
bool dynamic_state3_line_stipple_enable{}; ///< Has dynamic_state3 support for line stipple enable state.
bool dynamic_state3_alpha_to_coverage{}; ///< Has dynamic_state3 support for alpha to coverage state.
bool dynamic_state3_alpha_to_one{}; ///< Has dynamic_state3 support for alpha to one state.
bool dynamic_state3_depth_clamp_enable{};
bool dynamic_state3_logic_op_enable{};
bool dynamic_state3_line_raster_mode{};
bool dynamic_state3_conservative_raster_mode{};
bool dynamic_state3_line_stipple_enable{};
bool dynamic_state3_alpha_to_coverage{};
bool dynamic_state3_alpha_to_one{};
bool supports_conditional_barriers{}; ///< Allows barriers in conditional control flow.
size_t sampler_heap_budget{}; ///< Sampler budget for buggy drivers (0 = unlimited).
u64 device_access_memory{}; ///< Total size of device local memory in bytes.