add guards per subgroups support and remove forced turnip enabled on GS

This commit is contained in:
CamilleLaVey
2026-09-01 13:34:45 -04:00
parent b846577037
commit b7427684c0
4 changed files with 28 additions and 11 deletions
@@ -36,15 +36,14 @@ void RewriteAtomic(IR::Block& block, IR::Inst& inst) {
const IR::U32 amount{inst.Arg(2)}; const IR::U32 amount{inst.Arg(2)};
const IR::U32 primitive_id{ir.GetAttributeU32(IR::Attribute::PrimitiveId)}; const IR::U32 primitive_id{ir.GetAttributeU32(IR::Attribute::PrimitiveId)};
const IR::U32 new_index{ir.IMul(primitive_id, amount)}; const IR::U1 reserves_slot{ir.INotEqual(amount, ir.Imm32(0u))};
const IR::U32 new_atomic_value{ir.IAdd(new_index, amount)}; const IR::U32 slot_end{ir.IAdd(primitive_id, ir.Imm32(1u))};
const IR::U32 high_water{IR::U32{ir.Select(reserves_slot, slot_end, ir.Imm32(0u))}};
const IR::Value umax_result{&*block.PrependNewInst( block.PrependNewInst(insert_point, IR::Opcode::StorageAtomicUMax32,
insert_point, IR::Opcode::StorageAtomicUMax32, {inst.Arg(0), inst.Arg(1), high_water});
{inst.Arg(0), inst.Arg(1), new_atomic_value})};
static_cast<void>(umax_result);
inst.ReplaceUsesWith(new_index); inst.ReplaceUsesWith(primitive_id);
} }
} // Anonymous namespace } // Anonymous namespace
@@ -58,6 +57,9 @@ void CompactionFallbackPass(IR::Program& program, const HostTranslateInfo& host_
if (inst.GetOpcode() != IR::Opcode::StorageAtomicIAdd32) { if (inst.GetOpcode() != IR::Opcode::StorageAtomicIAdd32) {
continue; continue;
} }
if (!inst.HasUses()) {
continue;
}
if (!DependsOnSubgroupBallot(inst.Arg(2), 0)) { if (!DependsOnSubgroupBallot(inst.Arg(2), 0)) {
continue; continue;
} }
+3
View File
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -360,19 +360,26 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
const VkDriverId driver_id{device.GetDriverID()}; const VkDriverId driver_id{device.GetDriverID()};
const VkShaderStageFlags subgroup_stages{device.GetSubgroupSupportedStages()}; const VkShaderStageFlags subgroup_stages{device.GetSubgroupSupportedStages()};
const auto subgroup_stage_bit{[subgroup_stages](VkShaderStageFlags flag, Shader::Stage stage) { const auto subgroup_stage_bit{[subgroup_stages](VkShaderStageFlags flag, Shader::Stage stage) {
return (subgroup_stages & flag) != 0 ? (1u << static_cast<u32>(stage)) : 0u; if ((subgroup_stages & flag) == 0) {
return 0u;
}
return 1u << static_cast<u32>(stage);
}}; }};
const u32 supported_subgroup_stages{ u32 supported_subgroup_stages{
subgroup_stage_bit(VK_SHADER_STAGE_VERTEX_BIT, Shader::Stage::VertexA) | subgroup_stage_bit(VK_SHADER_STAGE_VERTEX_BIT, Shader::Stage::VertexA) |
subgroup_stage_bit(VK_SHADER_STAGE_VERTEX_BIT, Shader::Stage::VertexB) | subgroup_stage_bit(VK_SHADER_STAGE_VERTEX_BIT, Shader::Stage::VertexB) |
subgroup_stage_bit(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, subgroup_stage_bit(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
Shader::Stage::TessellationControl) | Shader::Stage::TessellationControl) |
subgroup_stage_bit(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, subgroup_stage_bit(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
Shader::Stage::TessellationEval) | Shader::Stage::TessellationEval) |
subgroup_stage_bit(driver_id == VK_DRIVER_ID_MESA_TURNIP ? 0 : VK_SHADER_STAGE_GEOMETRY_BIT, subgroup_stage_bit(VK_SHADER_STAGE_GEOMETRY_BIT, Shader::Stage::Geometry) |
Shader::Stage::Geometry) |
subgroup_stage_bit(VK_SHADER_STAGE_FRAGMENT_BIT, Shader::Stage::Fragment) | subgroup_stage_bit(VK_SHADER_STAGE_FRAGMENT_BIT, Shader::Stage::Fragment) |
subgroup_stage_bit(VK_SHADER_STAGE_COMPUTE_BIT, Shader::Stage::Compute)}; subgroup_stage_bit(VK_SHADER_STAGE_COMPUTE_BIT, Shader::Stage::Compute)};
if (!device.AreSubgroupFeaturesSupported(VK_SUBGROUP_FEATURE_VOTE_BIT |
VK_SUBGROUP_FEATURE_BALLOT_BIT |
VK_SUBGROUP_FEATURE_SHUFFLE_BIT)) {
supported_subgroup_stages = 0u;
}
profile = Shader::Profile{ profile = Shader::Profile{
.supported_spirv = device.SupportedSpirvVersion(), .supported_spirv = device.SupportedSpirvVersion(),
.unified_descriptor_binding = true, .unified_descriptor_binding = true,
@@ -479,6 +479,11 @@ FN_MAX_LIMIT_LIST
return properties.subgroup_properties.supportedStages; return properties.subgroup_properties.supportedStages;
} }
/// Returns true if every requested subgroup operation is supported by the device.
bool AreSubgroupFeaturesSupported(VkSubgroupFeatureFlags features) const {
return (properties.subgroup_properties.supportedOperations & features) == features;
}
/// Returns the maximum number of push descriptors. /// Returns the maximum number of push descriptors.
u32 MaxPushDescriptors() const { u32 MaxPushDescriptors() const {
return properties.push_descriptor.maxPushDescriptors; return properties.push_descriptor.maxPushDescriptors;