Compare commits
6 Commits
stuffmadef
...
refactored
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4cfe0b44e | ||
|
|
f3a50cfcf7 | ||
|
|
6cfdecbc7b | ||
|
|
d06ef6b83b | ||
|
|
963365716e | ||
|
|
587c601dfe |
@@ -59,39 +59,40 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
|
||||
|
||||
raw1 = 0;
|
||||
raw1_eds3_extended = 0;
|
||||
pad_align_u64 = 0;
|
||||
|
||||
// EDS1
|
||||
extended_dynamic_state.Assign(features.has_extended_dynamic_state ? 1 : 0);
|
||||
extended_dynamic_state.Assign(features.has_extended_dynamic_state);
|
||||
|
||||
// EDS2
|
||||
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);
|
||||
extended_dynamic_state_2_patch_control_points.Assign(features.has_extended_dynamic_state_2_patch_control_points ? 1 : 0);
|
||||
extended_dynamic_state_2.Assign(features.has_extended_dynamic_state_2);
|
||||
extended_dynamic_state_2_logic_op.Assign(features.has_extended_dynamic_state_2_logic_op);
|
||||
extended_dynamic_state_2_patch_control_points.Assign(features.has_extended_dynamic_state_2_patch_control_points);
|
||||
|
||||
// EDS3 - Blending/Enables
|
||||
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_blend.Assign(features.has_extended_dynamic_state_3_blend);
|
||||
extended_dynamic_state_3_enables.Assign(features.has_extended_dynamic_state_3_enables);
|
||||
|
||||
// EDS3 - Granular features
|
||||
extended_dynamic_state_3_depth_clamp.Assign(features.has_extended_dynamic_state_3_depth_clamp ? 1 : 0);
|
||||
extended_dynamic_state_3_logic_op_enable.Assign(features.has_extended_dynamic_state_3_logic_op_enable ? 1 : 0);
|
||||
extended_dynamic_state_3_tessellation_domain_origin.Assign(features.has_extended_dynamic_state_3_tessellation_domain_origin ? 1 : 0);
|
||||
extended_dynamic_state_3_polygon_mode.Assign(features.has_extended_dynamic_state_3_polygon_mode ? 1 : 0);
|
||||
extended_dynamic_state_3_rasterization_samples.Assign(features.has_extended_dynamic_state_3_rasterization_samples ? 1 : 0);
|
||||
extended_dynamic_state_3_sample_mask.Assign(features.has_extended_dynamic_state_3_sample_mask ? 1 : 0);
|
||||
extended_dynamic_state_3_alpha_to_coverage_enable.Assign(features.has_extended_dynamic_state_3_alpha_to_coverage_enable ? 1 : 0);
|
||||
extended_dynamic_state_3_alpha_to_one_enable.Assign(features.has_extended_dynamic_state_3_alpha_to_one_enable ? 1 : 0);
|
||||
extended_dynamic_state_3_depth_clip_enable.Assign(features.has_extended_dynamic_state_3_depth_clip_enable ? 1 : 0);
|
||||
extended_dynamic_state_3_depth_clip_negative_one_to_one.Assign(features.has_extended_dynamic_state_3_depth_clip_negative_one_to_one ? 1 : 0);
|
||||
extended_dynamic_state_3_line_rasterization_mode.Assign(features.has_extended_dynamic_state_3_line_rasterization_mode ? 1 : 0);
|
||||
extended_dynamic_state_3_line_stipple_enable.Assign(features.has_extended_dynamic_state_3_line_stipple_enable ? 1 : 0);
|
||||
extended_dynamic_state_3_provoking_vertex_mode.Assign(features.has_extended_dynamic_state_3_provoking_vertex_mode ? 1 : 0);
|
||||
extended_dynamic_state_3_conservative_rasterization_mode.Assign(features.has_extended_dynamic_state_3_conservative_rasterization_mode ? 1 : 0);
|
||||
extended_dynamic_state_3_sample_locations_enable.Assign(features.has_extended_dynamic_state_3_sample_locations_enable ? 1 : 0);
|
||||
extended_dynamic_state_3_rasterization_stream.Assign(features.has_extended_dynamic_state_3_rasterization_stream ? 1 : 0);
|
||||
extended_dynamic_state_3_depth_clamp.Assign(features.has_extended_dynamic_state_3_depth_clamp);
|
||||
extended_dynamic_state_3_logic_op_enable.Assign(features.has_extended_dynamic_state_3_logic_op_enable);
|
||||
extended_dynamic_state_3_tessellation_domain_origin.Assign(features.has_extended_dynamic_state_3_tessellation_domain_origin);
|
||||
extended_dynamic_state_3_polygon_mode.Assign(features.has_extended_dynamic_state_3_polygon_mode);
|
||||
extended_dynamic_state_3_rasterization_samples.Assign(features.has_extended_dynamic_state_3_rasterization_samples);
|
||||
extended_dynamic_state_3_sample_mask.Assign(features.has_extended_dynamic_state_3_sample_mask);
|
||||
extended_dynamic_state_3_alpha_to_coverage_enable.Assign(features.has_extended_dynamic_state_3_alpha_to_coverage_enable);
|
||||
extended_dynamic_state_3_alpha_to_one_enable.Assign(features.has_extended_dynamic_state_3_alpha_to_one_enable);
|
||||
extended_dynamic_state_3_depth_clip_enable.Assign(features.has_extended_dynamic_state_3_depth_clip_enable);
|
||||
extended_dynamic_state_3_depth_clip_negative_one_to_one.Assign(features.has_extended_dynamic_state_3_depth_clip_negative_one_to_one);
|
||||
extended_dynamic_state_3_line_rasterization_mode.Assign(features.has_extended_dynamic_state_3_line_rasterization_mode);
|
||||
extended_dynamic_state_3_line_stipple_enable.Assign(features.has_extended_dynamic_state_3_line_stipple_enable);
|
||||
extended_dynamic_state_3_provoking_vertex_mode.Assign(features.has_extended_dynamic_state_3_provoking_vertex_mode);
|
||||
extended_dynamic_state_3_conservative_rasterization_mode.Assign(features.has_extended_dynamic_state_3_conservative_rasterization_mode);
|
||||
extended_dynamic_state_3_sample_locations_enable.Assign(features.has_extended_dynamic_state_3_sample_locations_enable);
|
||||
extended_dynamic_state_3_rasterization_stream.Assign(features.has_extended_dynamic_state_3_rasterization_stream);
|
||||
|
||||
// Vertex Input
|
||||
dynamic_vertex_input.Assign(features.has_dynamic_vertex_input ? 1 : 0);
|
||||
dynamic_vertex_input.Assign(features.has_dynamic_vertex_input);
|
||||
|
||||
xfb_enabled.Assign(regs.transform_feedback_enabled != 0);
|
||||
ndc_minus_one_to_one.Assign(regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1 : 0);
|
||||
@@ -187,7 +188,7 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
|
||||
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);
|
||||
}
|
||||
if (!extended_dynamic_state_3_blend) {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -18,37 +21,45 @@ namespace Vulkan {
|
||||
using Maxwell = Tegra::Engines::Maxwell3D::Regs;
|
||||
|
||||
struct DynamicFeatures {
|
||||
// VK_EXT_extended_dynamic_state (EDS1) - All-or-nothing
|
||||
bool has_extended_dynamic_state;
|
||||
|
||||
// VK_EXT_extended_dynamic_state2 (EDS2) - Granular features
|
||||
bool has_extended_dynamic_state_2; // Core EDS2 (RasterizerDiscard, DepthBias, PrimitiveRestart)
|
||||
bool has_extended_dynamic_state_2_logic_op; // LogicOp support
|
||||
bool has_extended_dynamic_state_2_patch_control_points; // TessellationPatchControlPoints
|
||||
|
||||
// VK_EXT_extended_dynamic_state3 (EDS3) - Highly granular features
|
||||
bool has_extended_dynamic_state_3_blend; // ColorBlendEnable + ColorBlendEquation + ColorWriteMask
|
||||
bool has_extended_dynamic_state_3_enables; // DepthClampEnable + LogicOpEnable
|
||||
bool has_extended_dynamic_state_3_depth_clamp; // DepthClampEnable only
|
||||
bool has_extended_dynamic_state_3_logic_op_enable; // LogicOpEnable only
|
||||
bool has_extended_dynamic_state_3_tessellation_domain_origin; // TessellationDomainOrigin
|
||||
bool has_extended_dynamic_state_3_polygon_mode; // PolygonMode
|
||||
bool has_extended_dynamic_state_3_rasterization_samples; // RasterizationSamples
|
||||
bool has_extended_dynamic_state_3_sample_mask; // SampleMask
|
||||
bool has_extended_dynamic_state_3_alpha_to_coverage_enable; // AlphaToCoverageEnable
|
||||
bool has_extended_dynamic_state_3_alpha_to_one_enable; // AlphaToOneEnable
|
||||
bool has_extended_dynamic_state_3_depth_clip_enable; // DepthClipEnable
|
||||
bool has_extended_dynamic_state_3_depth_clip_negative_one_to_one; // DepthClipNegativeOneToOne
|
||||
bool has_extended_dynamic_state_3_line_rasterization_mode; // LineRasterizationMode
|
||||
bool has_extended_dynamic_state_3_line_stipple_enable; // LineStippleEnable
|
||||
bool has_extended_dynamic_state_3_provoking_vertex_mode; // ProvokingVertexMode
|
||||
bool has_extended_dynamic_state_3_conservative_rasterization_mode; // ConservativeRasterizationMode
|
||||
bool has_extended_dynamic_state_3_sample_locations_enable; // SampleLocationsEnable
|
||||
bool has_extended_dynamic_state_3_rasterization_stream; // RasterizationStream
|
||||
|
||||
// VK_EXT_vertex_input_dynamic_state
|
||||
bool has_dynamic_vertex_input;
|
||||
union {
|
||||
u32 raw0;
|
||||
// VK_EXT_extended_dynamic_state (EDS1) - Bit 0
|
||||
BitField<0, 1, u32> has_extended_dynamic_state;
|
||||
|
||||
// VK_EXT_extended_dynamic_state2 (EDS2) - Bits 1-3
|
||||
BitField<1, 1, u32> has_extended_dynamic_state_2; // Core EDS2
|
||||
BitField<2, 1, u32> has_extended_dynamic_state_2_logic_op; // LogicOp
|
||||
BitField<3, 1, u32> has_extended_dynamic_state_2_patch_control_points; // Tessellation
|
||||
|
||||
// VK_EXT_extended_dynamic_state3 (EDS3) - Bits 4-5
|
||||
BitField<4, 1, u32> has_extended_dynamic_state_3_blend; // Blending composite
|
||||
BitField<5, 1, u32> has_extended_dynamic_state_3_enables; // Enables composite
|
||||
|
||||
// VK_EXT_vertex_input_dynamic_state - Bit 6
|
||||
BitField<6, 1, u32> has_dynamic_vertex_input;
|
||||
|
||||
// EDS3 Granular Features - Bits 7-15
|
||||
BitField<7, 1, u32> has_extended_dynamic_state_3_depth_clamp;
|
||||
BitField<8, 1, u32> has_extended_dynamic_state_3_logic_op_enable;
|
||||
BitField<9, 1, u32> has_extended_dynamic_state_3_tessellation_domain_origin;
|
||||
BitField<10, 1, u32> has_extended_dynamic_state_3_polygon_mode;
|
||||
BitField<11, 1, u32> has_extended_dynamic_state_3_rasterization_samples;
|
||||
BitField<12, 1, u32> has_extended_dynamic_state_3_sample_mask;
|
||||
BitField<13, 1, u32> has_extended_dynamic_state_3_alpha_to_coverage_enable;
|
||||
BitField<14, 1, u32> has_extended_dynamic_state_3_alpha_to_one_enable;
|
||||
BitField<15, 1, u32> has_extended_dynamic_state_3_depth_clip_enable;
|
||||
|
||||
// EDS3 Additional Features - Bits 16-22
|
||||
BitField<16, 1, u32> has_extended_dynamic_state_3_depth_clip_negative_one_to_one;
|
||||
BitField<17, 1, u32> has_extended_dynamic_state_3_line_rasterization_mode;
|
||||
BitField<18, 1, u32> has_extended_dynamic_state_3_line_stipple_enable;
|
||||
BitField<19, 1, u32> has_extended_dynamic_state_3_provoking_vertex_mode;
|
||||
BitField<20, 1, u32> has_extended_dynamic_state_3_conservative_rasterization_mode;
|
||||
BitField<21, 1, u32> has_extended_dynamic_state_3_sample_locations_enable;
|
||||
BitField<22, 1, u32> has_extended_dynamic_state_3_rasterization_stream;
|
||||
};
|
||||
};
|
||||
static_assert(std::has_unique_object_representations_v<DynamicFeatures>);
|
||||
|
||||
struct FixedPipelineState {
|
||||
static u32 PackComparisonOp(Maxwell::ComparisonOp op) noexcept;
|
||||
@@ -272,12 +283,15 @@ struct FixedPipelineState {
|
||||
BitField<16, 1, u32> alpha_to_one_enabled;
|
||||
BitField<17, 3, Tegra::Engines::Maxwell3D::EngineHint> app_stage;
|
||||
};
|
||||
std::array<u8, Maxwell::NumRenderTargets> color_formats;
|
||||
|
||||
|
||||
u32 alpha_test_ref;
|
||||
u32 point_size;
|
||||
|
||||
|
||||
std::array<u8, Maxwell::NumRenderTargets> color_formats;
|
||||
std::array<u16, Maxwell::NumViewports> viewport_swizzles;
|
||||
|
||||
u32 pad_align_u64;
|
||||
|
||||
union {
|
||||
u64 attribute_types; // Used with VK_EXT_vertex_input_dynamic_state
|
||||
u64 enabled_divisors;
|
||||
|
||||
@@ -900,7 +900,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
|
||||
}
|
||||
|
||||
// EDS2 - Logic Op (granular feature)
|
||||
if (key.state.extended_dynamic_state_2_extra) {
|
||||
if (key.state.extended_dynamic_state_2_logic_op) {
|
||||
dynamic_states.push_back(VK_DYNAMIC_STATE_LOGIC_OP_EXT);
|
||||
}
|
||||
|
||||
|
||||
@@ -342,14 +342,15 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
|
||||
.support_fp64_signed_zero_nan_preserve =
|
||||
float_control.shaderSignedZeroInfNanPreserveFloat64 != VK_FALSE,
|
||||
|
||||
// Switch/Maxwell native float behavior (auto-configured on Qualcomm)
|
||||
// Switch/Maxwell native float behavior - ONLY for Turnip Mesa (Stock Qualcomm broken)
|
||||
// Stock Adreno drivers have broken float controls disabled in vulkan_device.cpp
|
||||
.force_fp32_denorm_flush = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY &&
|
||||
device.IsKhrShaderFloatControlsSupported(),
|
||||
device.IsKhrShaderFloatControlsSupported(), // false on Stock, true on Turnip
|
||||
.force_fp32_denorm_preserve = false, // FTZ dominates
|
||||
.force_fp32_rte_rounding = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY &&
|
||||
device.IsKhrShaderFloatControlsSupported(),
|
||||
device.IsKhrShaderFloatControlsSupported(), // false on Stock, true on Turnip
|
||||
.force_fp32_signed_zero_inf_nan = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY &&
|
||||
device.IsKhrShaderFloatControlsSupported(),
|
||||
device.IsKhrShaderFloatControlsSupported(), // false on Stock, true on Turnip
|
||||
|
||||
.support_explicit_workgroup_layout = device.IsKhrWorkgroupMemoryExplicitLayoutSupported(),
|
||||
.support_vote = device.IsSubgroupFeatureSupported(VK_SUBGROUP_FEATURE_VOTE_BIT),
|
||||
@@ -381,7 +382,8 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
|
||||
.has_broken_spirv_position_input = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY,
|
||||
.has_broken_unsigned_image_offsets = false,
|
||||
.has_broken_signed_operations = false,
|
||||
.has_broken_fp16_float_controls = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY,
|
||||
.has_broken_fp16_float_controls = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY ||
|
||||
driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY,
|
||||
.ignore_nan_fp_comparisons = false,
|
||||
.has_broken_spirv_subgroup_mask_vector_extract_dynamic =
|
||||
driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY,
|
||||
@@ -424,39 +426,39 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
|
||||
|
||||
LOG_INFO(Render_Vulkan, "DynamicState value is set to {}", (u32) dynamic_state);
|
||||
|
||||
dynamic_features = DynamicFeatures{
|
||||
// EDS1 - All-or-nothing (enabled if driver supports AND setting > 0)
|
||||
.has_extended_dynamic_state = device.IsExtExtendedDynamicStateSupported() && dynamic_state > 0,
|
||||
|
||||
// EDS2 - Core features (enabled if driver supports AND setting > 1)
|
||||
.has_extended_dynamic_state_2 = device.IsExtExtendedDynamicState2Supported() && dynamic_state > 1,
|
||||
.has_extended_dynamic_state_2_logic_op = device.IsExtExtendedDynamicState2LogicOpSupported() && dynamic_state > 1,
|
||||
.has_extended_dynamic_state_2_patch_control_points = device.IsExtExtendedDynamicState2PatchControlPointsSupported() && dynamic_state > 1,
|
||||
|
||||
// EDS3 - Granular features (enabled if driver supports AND setting > 2)
|
||||
.has_extended_dynamic_state_3_blend = device.IsExtExtendedDynamicState3BlendingSupported() && dynamic_state > 2,
|
||||
.has_extended_dynamic_state_3_enables = device.IsExtExtendedDynamicState3EnablesSupported() && dynamic_state > 2,
|
||||
.has_extended_dynamic_state_3_depth_clamp = device.IsExtExtendedDynamicState3DepthClampEnableSupported() && dynamic_state > 2,
|
||||
.has_extended_dynamic_state_3_logic_op_enable = device.IsExtExtendedDynamicState3LogicOpEnableSupported() && dynamic_state > 2,
|
||||
.has_extended_dynamic_state_3_tessellation_domain_origin = device.IsExtExtendedDynamicState3TessellationDomainOriginSupported() && dynamic_state > 2,
|
||||
.has_extended_dynamic_state_3_polygon_mode = device.IsExtExtendedDynamicState3PolygonModeSupported() && dynamic_state > 2,
|
||||
.has_extended_dynamic_state_3_rasterization_samples = device.IsExtExtendedDynamicState3RasterizationSamplesSupported() && dynamic_state > 2,
|
||||
.has_extended_dynamic_state_3_sample_mask = device.IsExtExtendedDynamicState3SampleMaskSupported() && dynamic_state > 2,
|
||||
.has_extended_dynamic_state_3_alpha_to_coverage_enable = device.IsExtExtendedDynamicState3AlphaToCoverageEnableSupported() && dynamic_state > 2,
|
||||
.has_extended_dynamic_state_3_alpha_to_one_enable = device.IsExtExtendedDynamicState3AlphaToOneEnableSupported() && dynamic_state > 2,
|
||||
.has_extended_dynamic_state_3_depth_clip_enable = device.IsExtExtendedDynamicState3DepthClipEnableSupported() && dynamic_state > 2,
|
||||
.has_extended_dynamic_state_3_depth_clip_negative_one_to_one = device.IsExtExtendedDynamicState3DepthClipNegativeOneToOneSupported() && dynamic_state > 2,
|
||||
.has_extended_dynamic_state_3_line_rasterization_mode = device.IsExtExtendedDynamicState3LineRasterizationModeSupported() && dynamic_state > 2,
|
||||
.has_extended_dynamic_state_3_line_stipple_enable = device.IsExtExtendedDynamicState3LineStippleEnableSupported() && dynamic_state > 2,
|
||||
.has_extended_dynamic_state_3_provoking_vertex_mode = device.IsExtExtendedDynamicState3ProvokingVertexModeSupported() && dynamic_state > 2,
|
||||
.has_extended_dynamic_state_3_conservative_rasterization_mode = device.IsExtExtendedDynamicState3ConservativeRasterizationModeSupported() && dynamic_state > 2,
|
||||
.has_extended_dynamic_state_3_sample_locations_enable = device.IsExtExtendedDynamicState3SampleLocationsEnableSupported() && dynamic_state > 2,
|
||||
.has_extended_dynamic_state_3_rasterization_stream = device.IsExtExtendedDynamicState3RasterizationStreamSupported() && dynamic_state > 2,
|
||||
|
||||
// Vertex input dynamic state
|
||||
.has_dynamic_vertex_input = device.IsExtVertexInputDynamicStateSupported() &&
|
||||
Settings::values.vertex_input_dynamic_state.GetValue(),
|
||||
};
|
||||
dynamic_features.raw0 = 0;
|
||||
|
||||
// EDS1 - All-or-nothing (enabled if driver supports AND setting > 0)
|
||||
dynamic_features.has_extended_dynamic_state.Assign(device.IsExtExtendedDynamicStateSupported() && dynamic_state > 0);
|
||||
|
||||
// EDS2 - Core features (enabled if driver supports AND setting > 1)
|
||||
dynamic_features.has_extended_dynamic_state_2.Assign(device.IsExtExtendedDynamicState2Supported() && dynamic_state > 1);
|
||||
dynamic_features.has_extended_dynamic_state_2_logic_op.Assign(device.IsExtExtendedDynamicState2LogicOpSupported() && dynamic_state > 1);
|
||||
dynamic_features.has_extended_dynamic_state_2_patch_control_points.Assign(device.IsExtExtendedDynamicState2PatchControlPointsSupported() && dynamic_state > 1);
|
||||
|
||||
// EDS3 - Granular features (enabled if driver supports AND setting > 2)
|
||||
dynamic_features.has_extended_dynamic_state_3_blend.Assign(device.IsExtExtendedDynamicState3BlendingSupported() && dynamic_state > 2);
|
||||
dynamic_features.has_extended_dynamic_state_3_enables.Assign(device.IsExtExtendedDynamicState3EnablesSupported() && dynamic_state > 2);
|
||||
dynamic_features.has_extended_dynamic_state_3_depth_clamp.Assign(device.IsExtExtendedDynamicState3DepthClampEnableSupported() && dynamic_state > 2);
|
||||
dynamic_features.has_extended_dynamic_state_3_logic_op_enable.Assign(device.IsExtExtendedDynamicState3LogicOpEnableSupported() && dynamic_state > 2);
|
||||
dynamic_features.has_extended_dynamic_state_3_tessellation_domain_origin.Assign(device.IsExtExtendedDynamicState3TessellationDomainOriginSupported() && dynamic_state > 2);
|
||||
dynamic_features.has_extended_dynamic_state_3_polygon_mode.Assign(device.IsExtExtendedDynamicState3PolygonModeSupported() && dynamic_state > 2);
|
||||
dynamic_features.has_extended_dynamic_state_3_rasterization_samples.Assign(device.IsExtExtendedDynamicState3RasterizationSamplesSupported() && dynamic_state > 2);
|
||||
dynamic_features.has_extended_dynamic_state_3_sample_mask.Assign(device.IsExtExtendedDynamicState3SampleMaskSupported() && dynamic_state > 2);
|
||||
dynamic_features.has_extended_dynamic_state_3_alpha_to_coverage_enable.Assign(device.IsExtExtendedDynamicState3AlphaToCoverageEnableSupported() && dynamic_state > 2);
|
||||
dynamic_features.has_extended_dynamic_state_3_alpha_to_one_enable.Assign(device.IsExtExtendedDynamicState3AlphaToOneEnableSupported() && dynamic_state > 2);
|
||||
dynamic_features.has_extended_dynamic_state_3_depth_clip_enable.Assign(device.IsExtExtendedDynamicState3DepthClipEnableSupported() && dynamic_state > 2);
|
||||
dynamic_features.has_extended_dynamic_state_3_depth_clip_negative_one_to_one.Assign(device.IsExtExtendedDynamicState3DepthClipNegativeOneToOneSupported() && dynamic_state > 2);
|
||||
dynamic_features.has_extended_dynamic_state_3_line_rasterization_mode.Assign(device.IsExtExtendedDynamicState3LineRasterizationModeSupported() && dynamic_state > 2);
|
||||
dynamic_features.has_extended_dynamic_state_3_line_stipple_enable.Assign(device.IsExtExtendedDynamicState3LineStippleEnableSupported() && dynamic_state > 2);
|
||||
dynamic_features.has_extended_dynamic_state_3_provoking_vertex_mode.Assign(device.IsExtExtendedDynamicState3ProvokingVertexModeSupported() && dynamic_state > 2);
|
||||
dynamic_features.has_extended_dynamic_state_3_conservative_rasterization_mode.Assign(device.IsExtExtendedDynamicState3ConservativeRasterizationModeSupported() && dynamic_state > 2);
|
||||
dynamic_features.has_extended_dynamic_state_3_sample_locations_enable.Assign(device.IsExtExtendedDynamicState3SampleLocationsEnableSupported() && dynamic_state > 2);
|
||||
dynamic_features.has_extended_dynamic_state_3_rasterization_stream.Assign(device.IsExtExtendedDynamicState3RasterizationStreamSupported() && dynamic_state > 2);
|
||||
|
||||
// Vertex input dynamic state (independent toggle)
|
||||
dynamic_features.has_dynamic_vertex_input.Assign(device.IsExtVertexInputDynamicStateSupported() &&
|
||||
Settings::values.vertex_input_dynamic_state.GetValue());
|
||||
}
|
||||
|
||||
PipelineCache::~PipelineCache() {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
||||
@@ -518,19 +518,20 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
||||
|
||||
// Driver-specific handling for VK_EXT_custom_border_color
|
||||
// On some Qualcomm/Turnip/ARM drivers the extension may be partially implemented.
|
||||
// Enable it if ANY useful feature bit is reported; otherwise, let the removal pass drop it.
|
||||
// Disable completely if no feature bits are reported to avoid crashes/undefined behavior.
|
||||
if (is_qualcomm || is_turnip || is_arm) {
|
||||
const bool has_any_custom_border_color =
|
||||
features.custom_border_color.customBorderColors ||
|
||||
features.custom_border_color.customBorderColorWithoutFormat;
|
||||
if (!has_any_custom_border_color) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"Disabling VK_EXT_custom_border_color on '{}' — no usable custom border color features reported",
|
||||
"Disabling VK_EXT_custom_border_color on '{}' — no usable features reported",
|
||||
properties.driver.driverName);
|
||||
// Do not clear here; final removal happens in RemoveUnsuitableExtensions based on bits.
|
||||
RemoveExtensionFeature(extensions.custom_border_color, features.custom_border_color,
|
||||
VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME);
|
||||
} else {
|
||||
LOG_INFO(Render_Vulkan,
|
||||
"Partial VK_EXT_custom_border_color support detected on '{}' — enabling available features",
|
||||
"VK_EXT_custom_border_color enabled on '{}' (partial support detected)",
|
||||
properties.driver.driverName);
|
||||
}
|
||||
}
|
||||
@@ -542,32 +543,32 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
||||
|
||||
// Log Qualcomm-specific optimizations
|
||||
if (extensions.render_pass_store_ops) {
|
||||
LOG_INFO(Render_Vulkan, "VK_QCOM_render_pass_store_ops: ENABLED");
|
||||
LOG_INFO(Render_Vulkan, "VK_QCOM_render_pass_store_ops: Enabled");
|
||||
}
|
||||
if (extensions.tile_properties) {
|
||||
LOG_INFO(Render_Vulkan, "VK_QCOM_tile_properties: ENABLED (tile size queries available)");
|
||||
LOG_INFO(Render_Vulkan, "VK_QCOM_tile_properties: Enabled");
|
||||
}
|
||||
if (extensions.render_pass_shader_resolve) {
|
||||
LOG_INFO(Render_Vulkan, "VK_QCOM_render_pass_shader_resolve: ENABLED");
|
||||
LOG_INFO(Render_Vulkan, "VK_QCOM_render_pass_shader_resolve: Enabled");
|
||||
}
|
||||
if (extensions.render_pass_transform) {
|
||||
LOG_INFO(Render_Vulkan, "VK_QCOM_render_pass_transform: Enabled");
|
||||
}
|
||||
if (extensions.rotated_copy_commands) {
|
||||
LOG_INFO(Render_Vulkan, "VK_QCOM_rotated_copy_commands: Enabled");
|
||||
}
|
||||
if (extensions.image_processing) {
|
||||
LOG_INFO(Render_Vulkan, "VK_QCOM_image_processing: Enabled");
|
||||
}
|
||||
|
||||
// Shader Float Controls for Qualcomm Adreno
|
||||
LOG_INFO(Render_Vulkan, "Enabling Shader Float Controls with Switch/Maxwell native configuration");
|
||||
|
||||
// Log driver capabilities
|
||||
const auto& fc = properties.float_controls;
|
||||
LOG_INFO(Render_Vulkan, "Driver Capabilities:");
|
||||
LOG_INFO(Render_Vulkan, " - Denorm Flush FP32: {}", fc.shaderDenormFlushToZeroFloat32 ? "YES" : "NO");
|
||||
LOG_INFO(Render_Vulkan, " - RTE Rounding FP32: {}", fc.shaderRoundingModeRTEFloat32 ? "YES" : "NO");
|
||||
LOG_INFO(Render_Vulkan, " - Signed Zero/Inf/Nan FP32: {}", fc.shaderSignedZeroInfNanPreserveFloat32 ? "YES" : "NO");
|
||||
|
||||
// Apply Switch/Maxwell native float behavior
|
||||
LOG_INFO(Render_Vulkan, "Applying Switch/Maxwell native float behavior:");
|
||||
LOG_INFO(Render_Vulkan, " - FTZ (Flush-To-Zero): ON - Matches Switch hardware behavior");
|
||||
LOG_INFO(Render_Vulkan, " - RTE (Round-To-Even): ON - IEEE 754 standard precision");
|
||||
LOG_INFO(Render_Vulkan, " - SignedZero/Inf/NaN: ON - Mathematical correctness");
|
||||
|
||||
LOG_INFO(Render_Vulkan, "VK_KHR_shader_float_controls: ENABLED (auto-configured)");
|
||||
// Shader Float Controls: Completely broken on Stock Qualcomm
|
||||
// The extension causes rendering issues regardless of FP16/FP32 mode
|
||||
// Turnip Mesa: Works correctly, keep enabled
|
||||
if (!is_turnip) {
|
||||
LOG_WARNING(Render_Vulkan, "Disabling Shader Float Controls for Stock Qualcomm (broken implementation)");
|
||||
RemoveExtensionFeature(extensions.shader_float_controls, features.shader_float_controls,
|
||||
VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
// Int64 atomics - genuinely broken, always disable
|
||||
RemoveExtensionFeature(extensions.shader_atomic_int64, features.shader_atomic_int64,
|
||||
@@ -616,83 +617,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
||||
cant_blit_msaa = true;
|
||||
}
|
||||
}
|
||||
if (extensions.extended_dynamic_state && is_radv) {
|
||||
// Mask driver version variant
|
||||
const u32 version = (properties.properties.driverVersion << 3) >> 3;
|
||||
if (version < VK_MAKE_API_VERSION(0, 21, 2, 0)) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"RADV versions older than 21.2 have broken VK_EXT_extended_dynamic_state");
|
||||
//RemoveExtensionFeature(extensions.extended_dynamic_state,
|
||||
//features.extended_dynamic_state,
|
||||
//VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
|
||||
}
|
||||
}
|
||||
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 versions older than 22.3.1 have broken VK_EXT_extended_dynamic_state2");
|
||||
// RemoveExtensionFeature(extensions.extended_dynamic_state2,
|
||||
// features.extended_dynamic_state2,
|
||||
// VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
|
||||
}
|
||||
}
|
||||
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)) {
|
||||
// Qualcomm Adreno 7xx drivers do not properly support extended_dynamic_state2.
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"Qualcomm Adreno 7xx drivers have broken VK_EXT_extended_dynamic_state2");
|
||||
//RemoveExtensionFeature(extensions.extended_dynamic_state2,
|
||||
//features.extended_dynamic_state2,
|
||||
//VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
|
||||
}
|
||||
}
|
||||
if (extensions.extended_dynamic_state3 && is_radv) {
|
||||
LOG_WARNING(Render_Vulkan, "RADV has broken extendedDynamicState3ColorBlendEquation");
|
||||
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = true;
|
||||
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = true;
|
||||
dynamic_state3_blending = true;
|
||||
|
||||
const u32 version = (properties.properties.driverVersion << 3) >> 3;
|
||||
if (version < VK_MAKE_API_VERSION(0, 23, 1, 0)) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"RADV versions older than 23.1.0 have broken depth clamp dynamic state");
|
||||
features.extended_dynamic_state3.extendedDynamicState3DepthClampEnable = true;
|
||||
dynamic_state3_enables = true;
|
||||
}
|
||||
}
|
||||
if (extensions.extended_dynamic_state3 && (is_amd_driver || driver_id == VK_DRIVER_ID_SAMSUNG_PROPRIETARY)) {
|
||||
// AMD and Samsung drivers have broken extendedDynamicState3ColorBlendEquation
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"AMD and Samsung drivers have broken extendedDynamicState3ColorBlendEquation");
|
||||
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = true;
|
||||
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = true;
|
||||
dynamic_state3_blending = true;
|
||||
}
|
||||
if (extensions.vertex_input_dynamic_state && is_radv) {
|
||||
// TODO(ameerj): Blacklist only offending driver versions
|
||||
// TODO(ameerj): Confirm if RDNA1 is affected
|
||||
const bool is_rdna2 =
|
||||
supported_extensions.contains(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME);
|
||||
if (is_rdna2) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"RADV has broken VK_EXT_vertex_input_dynamic_state on RDNA2 hardware");
|
||||
// RemoveExtensionFeature(extensions.vertex_input_dynamic_state,
|
||||
// features.vertex_input_dynamic_state,
|
||||
// VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
|
||||
}
|
||||
}
|
||||
if (extensions.vertex_input_dynamic_state && is_qualcomm) {
|
||||
// Qualcomm drivers do not properly support vertex_input_dynamic_state.
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"Qualcomm drivers have broken VK_EXT_vertex_input_dynamic_state");
|
||||
//RemoveExtensionFeature(extensions.vertex_input_dynamic_state,
|
||||
// features.vertex_input_dynamic_state,
|
||||
// VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
|
||||
}
|
||||
// Dynamic state blacklists moved to GetSuitability() for proper ordering
|
||||
|
||||
sets_per_pool = 64;
|
||||
if (is_amd_driver) {
|
||||
@@ -721,15 +646,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
||||
}
|
||||
}
|
||||
|
||||
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 has broken VK_EXT_vertex_input_dynamic_state");
|
||||
//RemoveExtensionFeature(extensions.vertex_input_dynamic_state,
|
||||
//features.vertex_input_dynamic_state,
|
||||
//VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
|
||||
}
|
||||
}
|
||||
// VertexInputDynamicState blacklist moved to GetSuitability() for proper ordering
|
||||
if (features.shader_float16_int8.shaderFloat16 && is_intel_windows) {
|
||||
// Intel's compiler crashes when using fp16 on Astral Chain, disable it for the time being.
|
||||
LOG_WARNING(Render_Vulkan, "Intel has broken float16 math");
|
||||
@@ -820,35 +737,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
||||
VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
if (!extensions.extended_dynamic_state2 && extensions.extended_dynamic_state3) {
|
||||
LOG_INFO(Render_Vulkan,
|
||||
"Removing extendedDynamicState3 due to missing extendedDynamicState2");
|
||||
RemoveExtensionFeature(extensions.extended_dynamic_state3, features.extended_dynamic_state3,
|
||||
VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME);
|
||||
dynamic_state3_blending = true;
|
||||
dynamic_state3_enables = true;
|
||||
}
|
||||
|
||||
// Mesa Intel drivers on UHD 620 have broken EDS causing extreme flickering - unknown if it affects other iGPUs
|
||||
// ALSO affects ALL versions of UHD drivers on Windows 10+, seems to cause even worse issues like straight up crashing
|
||||
// So... Yeah, UHD drivers fucking suck -- maybe one day we can work past this, maybe; some driver hacking?
|
||||
// And then we can rest in peace by doing `< VK_MAKE_API_VERSION(26, 0, 0)` for our beloved mesa drivers... one day
|
||||
if ((is_mvk || (is_integrated && is_intel_anv) || (is_integrated && is_intel_windows)) && Settings::values.dyna_state.GetValue() != 0) {
|
||||
LOG_WARNING(Render_Vulkan, "Driver has broken dynamic state, forcing to 0 to prevent graphical issues");
|
||||
Settings::values.dyna_state.SetValue(0);
|
||||
}
|
||||
|
||||
if (Settings::values.dyna_state.GetValue() == 0) {
|
||||
RemoveExtensionFeature(extensions.custom_border_color, features.custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME);
|
||||
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;
|
||||
|
||||
LOG_INFO(Render_Vulkan, "Extended dynamic state is fully disabled");
|
||||
// Note: vertex_input_dynamic_state has its own independent toggle and is NOT affected by dyna_state = 0
|
||||
}
|
||||
// Intel iGPU/MoltenVK blacklist moved to GetSuitability() for proper ordering
|
||||
|
||||
#ifdef ANDROID
|
||||
// Stock Qualcomm and ARM Mali drivers don't report VK_FORMAT_*_SSCALED/USCALED formats
|
||||
@@ -903,7 +792,7 @@ Device::~Device() {
|
||||
VkFormat Device::GetSupportedFormat(VkFormat wanted_format, VkFormatFeatureFlags wanted_usage,
|
||||
FormatType format_type) const {
|
||||
if (IsFormatSupported(wanted_format, wanted_usage, format_type)) {
|
||||
// CRITICAL FIX: Even if format is "supported", check for STORAGE + HDR + no MSAA support
|
||||
// Critical: Even if format is "supported", check for STORAGE + HDR + no MSAA support
|
||||
// Driver may report STORAGE_IMAGE_BIT but shaderStorageImageMultisample=false means
|
||||
// it will fail at runtime when used with MSAA (CopyImageMSAA silently fails)
|
||||
const bool requests_storage = (wanted_usage & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0;
|
||||
@@ -1330,6 +1219,148 @@ bool Device::GetSuitability(bool requires_swapchain) {
|
||||
}
|
||||
}
|
||||
|
||||
// CRITICAL: Apply driver-specific feature workarounds BEFORE validation
|
||||
// These blacklists disable broken features on specific drivers to prevent
|
||||
// rendering issues and crashes.
|
||||
// MUST execute before RemoveUnsuitableExtensions() calculates feature flags.
|
||||
|
||||
const VkDriverId driver_id = properties.driver.driverID;
|
||||
const bool is_radv = driver_id == VK_DRIVER_ID_MESA_RADV;
|
||||
const bool is_amd_driver =
|
||||
driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE;
|
||||
const bool is_intel_windows = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS;
|
||||
const bool is_intel_anv = driver_id == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA;
|
||||
const bool is_qualcomm = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY;
|
||||
const bool is_mvk = driver_id == VK_DRIVER_ID_MOLTENVK;
|
||||
const bool is_integrated = properties.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
|
||||
|
||||
// VK_DYNAMIC_STATE
|
||||
|
||||
// Mesa Intel drivers on UHD 620 have broken EDS causing extreme flickering - unknown if it affects other iGPUs
|
||||
// ALSO affects ALL versions of UHD drivers on Windows 10+, seems to cause even worse issues like straight up crashing
|
||||
// So... Yeah, UHD drivers fucking suck -- maybe one day we can work past this, maybe; some driver hacking?
|
||||
// And then we can rest in peace by doing `< VK_MAKE_API_VERSION(26, 0, 0)` for our beloved mesa drivers... one day
|
||||
// Disable dynamic state on affected drivers
|
||||
if ((is_mvk || (is_integrated && is_intel_anv) || (is_integrated && is_intel_windows)) &&
|
||||
Settings::values.dyna_state.GetValue() != 0) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"Intel iGPU/MoltenVK: Forcing dyna_state=0 due to broken dynamic state implementation");
|
||||
Settings::values.dyna_state.SetValue(0);
|
||||
}
|
||||
|
||||
// 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: Broken extendedDynamicState3ColorBlendEquation
|
||||
// Disable blend equation dynamic state, force static pipeline state
|
||||
if (extensions.extended_dynamic_state3 &&
|
||||
(is_amd_driver || driver_id == VK_DRIVER_ID_SAMSUNG_PROPRIETARY)) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"AMD/Samsung: Disabling broken extendedDynamicState3ColorBlendEquation");
|
||||
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false;
|
||||
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false;
|
||||
}
|
||||
|
||||
// RADV: Broken extendedDynamicState3ColorBlendEquation
|
||||
// Disable problematic features based on driver version < 23.1.0
|
||||
if (extensions.extended_dynamic_state3 && is_radv) {
|
||||
LOG_WARNING(Render_Vulkan, "RADV: Disabling broken extendedDynamicState3ColorBlendEquation");
|
||||
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false;
|
||||
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false;
|
||||
|
||||
const u32 version = (properties.properties.driverVersion << 3) >> 3;
|
||||
if (version < VK_MAKE_API_VERSION(0, 23, 1, 0)) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"RADV < 23.1.0: Disabling broken depth clamp dynamic state");
|
||||
features.extended_dynamic_state3.extendedDynamicState3DepthClampEnable = false;
|
||||
}
|
||||
}
|
||||
|
||||
// VK_EXT_vertex_input_dynamic_state
|
||||
|
||||
// RADV + RDNA2: Broken VertexInputDynamicState on RDNA2 hardware
|
||||
// Disable VertexInputDynamicState on RDNA2
|
||||
if (extensions.vertex_input_dynamic_state && is_radv) {
|
||||
const bool is_rdna2 =
|
||||
supported_extensions.contains(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME);
|
||||
if (is_rdna2) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"RADV + RDNA2: Disabling broken VK_EXT_vertex_input_dynamic_state");
|
||||
features.vertex_input_dynamic_state.vertexInputDynamicState = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 suitable;
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ VK_DEFINE_HANDLE(VmaAllocator)
|
||||
pipeline_executable_properties) \
|
||||
FEATURE(KHR, WorkgroupMemoryExplicitLayout, WORKGROUP_MEMORY_EXPLICIT_LAYOUT, \
|
||||
workgroup_memory_explicit_layout) \
|
||||
FEATURE(QCOM, ImageProcessing, IMAGE_PROCESSING, image_processing_qcom) \
|
||||
FEATURE(QCOM, TileProperties, TILE_PROPERTIES, tile_properties_qcom)
|
||||
|
||||
// Define miscellaneous extensions which may be used by the implementation here.
|
||||
@@ -98,6 +99,9 @@ VK_DEFINE_HANDLE(VmaAllocator)
|
||||
EXTENSION(QCOM, FILTER_CUBIC_WEIGHTS, filter_cubic_weights) \
|
||||
EXTENSION(QCOM, RENDER_PASS_SHADER_RESOLVE, render_pass_shader_resolve) \
|
||||
EXTENSION(QCOM, RENDER_PASS_STORE_OPS, render_pass_store_ops) \
|
||||
EXTENSION(QCOM, RENDER_PASS_TRANSFORM, render_pass_transform) \
|
||||
EXTENSION(QCOM, ROTATED_COPY_COMMANDS, rotated_copy_commands) \
|
||||
EXTENSION(QCOM, IMAGE_PROCESSING, image_processing) \
|
||||
EXTENSION(QCOM, TILE_PROPERTIES, tile_properties) \
|
||||
EXTENSION(KHR, MAINTENANCE_1, maintenance1) \
|
||||
EXTENSION(KHR, MAINTENANCE_2, maintenance2) \
|
||||
@@ -714,6 +718,21 @@ public:
|
||||
return extensions.tile_properties;
|
||||
}
|
||||
|
||||
/// Returns true if the device supports VK_QCOM_render_pass_transform
|
||||
bool IsQcomRenderPassTransformSupported() const {
|
||||
return extensions.render_pass_transform;
|
||||
}
|
||||
|
||||
/// Returns true if the device supports VK_QCOM_rotated_copy_commands
|
||||
bool IsQcomRotatedCopyCommandsSupported() const {
|
||||
return extensions.rotated_copy_commands;
|
||||
}
|
||||
|
||||
/// Returns true if the device supports VK_QCOM_image_processing
|
||||
bool IsQcomImageProcessingSupported() const {
|
||||
return extensions.image_processing;
|
||||
}
|
||||
|
||||
/// Returns Qualcomm tile size (width, height, depth). Returns {0,0,0} if not queried or unsupported
|
||||
VkExtent3D GetQcomTileSize() const {
|
||||
return properties.qcom_tile_size;
|
||||
|
||||
Reference in New Issue
Block a user