mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-02-04 02:51:18 +01:00
[vulkan] Adjusting DynamicState functionality + including Static Pipelines Mode
This commit is contained in:
@@ -611,7 +611,8 @@
|
||||
</integer-array>
|
||||
|
||||
<string-array name="dynaStateEntries">
|
||||
<item>@string/disabled</item>
|
||||
<item>Static</item>
|
||||
<item>Core</item>
|
||||
<item>ExtendedDynamicState 1</item>
|
||||
<item>ExtendedDynamicState 2</item>
|
||||
<item>ExtendedDynamicState 3</item>
|
||||
@@ -622,6 +623,7 @@
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
<item>4</item>
|
||||
</integer-array>
|
||||
|
||||
<string-array name="installKeysResults">
|
||||
|
||||
@@ -535,9 +535,9 @@ struct Values {
|
||||
#elif defined (__FreeBSD__)
|
||||
ExtendedDynamicState::EDS3,
|
||||
#elif defined (ANDROID)
|
||||
ExtendedDynamicState::Disabled,
|
||||
ExtendedDynamicState::Static,
|
||||
#elif defined (__APPLE__)
|
||||
ExtendedDynamicState::Disabled,
|
||||
ExtendedDynamicState::Static,
|
||||
#else
|
||||
ExtendedDynamicState::EDS2,
|
||||
#endif
|
||||
|
||||
@@ -153,7 +153,7 @@ ENUM(GpuUnswizzleSize, VerySmall, Small, Normal, Large, VeryLarge)
|
||||
ENUM(GpuUnswizzle, VeryLow, Low, Normal, Medium, High)
|
||||
ENUM(GpuUnswizzleChunk, VeryLow, Low, Normal, Medium, High)
|
||||
ENUM(TemperatureUnits, Celsius, Fahrenheit)
|
||||
ENUM(ExtendedDynamicState, Disabled, EDS1, EDS2, EDS3);
|
||||
ENUM(ExtendedDynamicState, Static, Core, EDS1, EDS2, EDS3);
|
||||
ENUM(GpuLogLevel, Off, Errors, Standard, Verbose, All)
|
||||
|
||||
template <typename Type>
|
||||
|
||||
@@ -57,6 +57,7 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
|
||||
const auto topology_ = maxwell3d.draw_manager->GetDrawState().topology;
|
||||
|
||||
raw1 = 0;
|
||||
dynamic_state_enabled.Assign(features.has_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_logic_op.Assign(features.has_extended_dynamic_state_2_logic_op ? 1 : 0);
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace Vulkan {
|
||||
using Maxwell = Tegra::Engines::Maxwell3D::Regs;
|
||||
|
||||
struct DynamicFeatures {
|
||||
bool has_dynamic_state;
|
||||
bool has_extended_dynamic_state;
|
||||
bool has_extended_dynamic_state_2;
|
||||
bool has_extended_dynamic_state_2_logic_op;
|
||||
@@ -188,19 +189,20 @@ struct FixedPipelineState {
|
||||
|
||||
union {
|
||||
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<0, 1, u32> dynamic_state_enabled;
|
||||
BitField<1, 1, u32> extended_dynamic_state;
|
||||
BitField<2, 1, u32> extended_dynamic_state_2;
|
||||
BitField<3, 1, u32> extended_dynamic_state_2_logic_op;
|
||||
BitField<4, 1, u32> extended_dynamic_state_3_blend;
|
||||
BitField<5, 1, u32> extended_dynamic_state_3_enables;
|
||||
BitField<6, 1, u32> dynamic_vertex_input;
|
||||
BitField<7, 1, u32> xfb_enabled;
|
||||
BitField<8, 1, u32> ndc_minus_one_to_one;
|
||||
BitField<9, 2, u32> polygon_mode;
|
||||
BitField<11, 2, u32> tessellation_primitive;
|
||||
BitField<13, 2, u32> tessellation_spacing;
|
||||
BitField<15, 1, u32> tessellation_clockwise;
|
||||
BitField<16, 5, u32> patch_control_points_minus_one;
|
||||
|
||||
BitField<24, 4, Maxwell::PrimitiveTopology> topology;
|
||||
BitField<28, 4, Tegra::Texture::MsaaMode> msaa_mode;
|
||||
|
||||
@@ -826,13 +826,22 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
|
||||
.pAttachments = cb_attachments.data(),
|
||||
.blendConstants = {}
|
||||
};
|
||||
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,
|
||||
};
|
||||
|
||||
// Dynamic states configuration based on feature support
|
||||
static_vector<VkDynamicState, 34> dynamic_states;
|
||||
|
||||
// Core dynamic states (Vulkan 1.0) - Only if not in Static mode
|
||||
if (key.state.dynamic_state_enabled) {
|
||||
static constexpr std::array core_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,
|
||||
};
|
||||
dynamic_states.insert(dynamic_states.end(), core_states.begin(), core_states.end());
|
||||
}
|
||||
|
||||
if (key.state.extended_dynamic_state) {
|
||||
static constexpr std::array extended{
|
||||
VK_DYNAMIC_STATE_CULL_MODE_EXT,
|
||||
|
||||
@@ -437,13 +437,7 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
|
||||
|
||||
dynamic_features = {};
|
||||
|
||||
// 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_dynamic_state = device.IsCoreDynamicStateSupported();
|
||||
dynamic_features.has_extended_dynamic_state =
|
||||
device.IsExtExtendedDynamicStateSupported();
|
||||
|
||||
|
||||
@@ -1009,16 +1009,16 @@ bool AccelerateDMA::BufferToImage(const Tegra::DMA::ImageCopy& copy_info,
|
||||
void RasterizerVulkan::UpdateDynamicStates() {
|
||||
auto& regs = maxwell3d->regs;
|
||||
|
||||
// Core Dynamic States (Vulkan 1.0) - Always active regardless of dyna_state setting
|
||||
UpdateViewportsState(regs);
|
||||
UpdateScissorsState(regs);
|
||||
UpdateDepthBias(regs);
|
||||
UpdateBlendConstants(regs);
|
||||
UpdateDepthBounds(regs);
|
||||
UpdateStencilFaces(regs);
|
||||
UpdateLineWidth(regs);
|
||||
if (device.IsCoreDynamicStateSupported()) {
|
||||
UpdateViewportsState(regs);
|
||||
UpdateScissorsState(regs);
|
||||
UpdateDepthBias(regs);
|
||||
UpdateBlendConstants(regs);
|
||||
UpdateDepthBounds(regs);
|
||||
UpdateStencilFaces(regs);
|
||||
UpdateLineWidth(regs);
|
||||
}
|
||||
|
||||
// EDS1: CullMode, DepthCompare, FrontFace, StencilOp, DepthBoundsTest, DepthTest, DepthWrite, StencilTest
|
||||
if (device.IsExtExtendedDynamicStateSupported()) {
|
||||
UpdateCullMode(regs);
|
||||
UpdateDepthCompareOp(regs);
|
||||
@@ -1032,22 +1032,18 @@ void RasterizerVulkan::UpdateDynamicStates() {
|
||||
}
|
||||
}
|
||||
|
||||
// EDS2: PrimitiveRestart, RasterizerDiscard, DepthBias enable/disable
|
||||
if (device.IsExtExtendedDynamicState2Supported()) {
|
||||
UpdatePrimitiveRestartEnable(regs);
|
||||
UpdateRasterizerDiscardEnable(regs);
|
||||
UpdateDepthBiasEnable(regs);
|
||||
}
|
||||
|
||||
// EDS2 Extras: LogicOp operation selection
|
||||
if (device.IsExtExtendedDynamicState2ExtrasSupported()) {
|
||||
UpdateLogicOp(regs);
|
||||
}
|
||||
|
||||
// EDS3 Enables: LogicOpEnable, DepthClamp, LineStipple, ConservativeRaster
|
||||
if (device.IsExtExtendedDynamicState3EnablesSupported()) {
|
||||
using namespace Tegra::Engines;
|
||||
// AMD Workaround: LogicOp incompatible with float render targets
|
||||
if (device.GetDriverID() == VkDriverIdKHR::VK_DRIVER_ID_AMD_OPEN_SOURCE ||
|
||||
device.GetDriverID() == VkDriverIdKHR::VK_DRIVER_ID_AMD_PROPRIETARY) {
|
||||
const auto has_float = std::any_of(
|
||||
@@ -1069,13 +1065,10 @@ void RasterizerVulkan::UpdateDynamicStates() {
|
||||
UpdateAlphaToOneEnable(regs);
|
||||
}
|
||||
|
||||
// EDS3 Blending: ColorBlendEnable, ColorBlendEquation, ColorWriteMask
|
||||
// or VK_EXT_color_write_enable if EDS3 is not available
|
||||
if (device.IsExtExtendedDynamicState3BlendingSupported()) {
|
||||
UpdateBlending(regs);
|
||||
}
|
||||
|
||||
// Vertex Input Dynamic State: Independent from EDS levels
|
||||
if (device.IsExtVertexInputDynamicStateSupported()) {
|
||||
if (auto* gp = pipeline_cache.CurrentGraphicsPipeline(); gp && gp->HasDynamicVertexInput()) {
|
||||
UpdateVertexInput(regs);
|
||||
|
||||
@@ -650,16 +650,21 @@ 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: Disable all extended dynamic state extensions
|
||||
case Settings::ExtendedDynamicState::Static:
|
||||
LOG_INFO(Render_Vulkan, "STATIC Mode (fully static pipelines)");
|
||||
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,
|
||||
VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
|
||||
RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3,
|
||||
VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME);
|
||||
dynamic_state3_blending = false;
|
||||
dynamic_state3_enables = false;
|
||||
supports_dynamic_state = false;
|
||||
break;
|
||||
case Settings::ExtendedDynamicState::Core:
|
||||
LOG_INFO(Render_Vulkan, "DynamicState - Enabled");
|
||||
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,
|
||||
@@ -670,7 +675,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
||||
dynamic_state3_enables = false;
|
||||
break;
|
||||
case Settings::ExtendedDynamicState::EDS1:
|
||||
// Level 1: Enable EDS1, disable EDS2 and EDS3
|
||||
LOG_INFO(Render_Vulkan, "ExtededDynamicState1 - Enabled");
|
||||
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,
|
||||
@@ -679,7 +684,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
||||
dynamic_state3_enables = false;
|
||||
break;
|
||||
case Settings::ExtendedDynamicState::EDS2:
|
||||
// Level 2: Enable EDS1 + EDS2, disable EDS3
|
||||
LOG_INFO(Render_Vulkan, "ExtededDynamicState2 - Enabled");
|
||||
RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3,
|
||||
VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME);
|
||||
dynamic_state3_blending = false;
|
||||
@@ -687,12 +692,10 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
||||
break;
|
||||
case Settings::ExtendedDynamicState::EDS3:
|
||||
default:
|
||||
// Level 3: Enable all (EDS1 + EDS2 + EDS3)
|
||||
LOG_INFO(Render_Vulkan, "ExtededDynamicState3 - Enabled");
|
||||
break;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
@@ -1206,8 +1209,10 @@ bool Device::GetSuitability(bool requires_swapchain) {
|
||||
}
|
||||
}
|
||||
|
||||
if (u32(Settings::values.dyna_state.GetValue()) == 0) {
|
||||
LOG_INFO(Render_Vulkan, "Extended Dynamic State disabled by user setting, clearing all EDS features");
|
||||
const auto dyna_state_setting = Settings::values.dyna_state.GetValue();
|
||||
if (dyna_state_setting == Settings::ExtendedDynamicState::Static) {
|
||||
LOG_INFO(Render_Vulkan, "Static pipeline mode: All dynamic states disabled");
|
||||
supports_dynamic_state = false;
|
||||
features.custom_border_color.customBorderColors = false;
|
||||
features.custom_border_color.customBorderColorWithoutFormat = false;
|
||||
features.extended_dynamic_state.extendedDynamicState = false;
|
||||
@@ -1219,7 +1224,7 @@ bool Device::GetSuitability(bool requires_swapchain) {
|
||||
features.extended_dynamic_state3.extendedDynamicState3LogicOpEnable = false;
|
||||
}
|
||||
|
||||
// Return whether we were suitable.
|
||||
return suitable;
|
||||
return suitable;
|
||||
}
|
||||
|
||||
|
||||
@@ -609,6 +609,11 @@ public:
|
||||
return features.custom_border_color.customBorderColorWithoutFormat;
|
||||
}
|
||||
|
||||
/// Returns true if the device supports core Vulkan 1.0 dynamic states.
|
||||
bool IsCoreDynamicStateSupported() const {
|
||||
return supports_dynamic_state;
|
||||
}
|
||||
|
||||
/// Returns true if the device supports VK_EXT_extended_dynamic_state.
|
||||
bool IsExtExtendedDynamicStateSupported() const {
|
||||
return extensions.extended_dynamic_state;
|
||||
@@ -1067,6 +1072,7 @@ private:
|
||||
bool dynamic_state3_alpha_to_coverage{};
|
||||
bool dynamic_state3_alpha_to_one{};
|
||||
bool supports_conditional_barriers{}; ///< Allows barriers in conditional control flow.
|
||||
bool supports_dynamic_state{true}; ///< Core Vulkan 1.0 dynamic states
|
||||
size_t sampler_heap_budget{}; ///< Sampler budget for buggy drivers (0 = unlimited).
|
||||
u64 device_access_memory{}; ///< Total size of device local memory in bytes.
|
||||
u32 sets_per_pool{}; ///< Sets per Description Pool
|
||||
|
||||
Reference in New Issue
Block a user