mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
shader: share scalar condition results with direct subgroup votes
Co-authored-by: fxpw <fxpw@outlook.com>
This commit is contained in:
@@ -535,6 +535,7 @@ static vk::Device VulkanCreateDevice(GraphicContext& graphics,
|
||||
subgroup_size_control.pNext = &graphics.mesh_shader_properties;
|
||||
}
|
||||
physical_device.getProperties2(&properties2);
|
||||
EXIT_NOT_IMPLEMENTED(!(properties11.subgroupSupportedOperations & vk::SubgroupFeatureFlagBits::eVote));
|
||||
|
||||
graphics.subgroup_size = properties11.subgroupSize;
|
||||
graphics.min_subgroup_size = subgroup_size_control.minSubgroupSize;
|
||||
|
||||
@@ -721,17 +721,22 @@ uint32_t EmitDppUpdateU32(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
|
||||
uint32_t EmitConditionRef(ValueEmitContext& ctx, const IR::Inst& inst) {
|
||||
// Scalar branches include lanes disabled by EXEC, which the branch body may restore.
|
||||
if (ctx.other_half != nullptr && ctx.half != 0) return ctx.other_half->Def(IR::Value(&inst));
|
||||
if (ctx.other_half != nullptr && ctx.half != 0) return ctx.other_half->Result(inst);
|
||||
const auto kind = inst.Flags<CFG::BranchCondition>();
|
||||
if (kind == CFG::BranchCondition::ScalarInstruction) return ctx.Arg(inst, 0);
|
||||
const bool zero = kind == CFG::BranchCondition::ExecZero ||
|
||||
kind == CFG::BranchCondition::VccZero || kind == CFG::BranchCondition::SccZero;
|
||||
const auto ballot = ctx.Ballot(inst.Arg(0));
|
||||
const auto reference = zero ? ctx.Ballot(IR::Value(true))
|
||||
: ConstantU32CompositeZero(ctx.state, 4);
|
||||
const auto compare = Binary(ctx.state, zero ? spv::OpIEqual : spv::OpINotEqual,
|
||||
TypeBoolVector(ctx.state, 4), ballot, reference);
|
||||
return Unary(ctx.state, zero ? spv::OpAll : spv::OpAny, TypeBool(ctx.state), compare);
|
||||
// Zero-kind predicates are already inverted by translation.
|
||||
auto predicate = ctx.Arg(inst, 0);
|
||||
if (ctx.other_half != nullptr) {
|
||||
predicate = Binary(ctx.state, zero ? spv::OpLogicalAnd : spv::OpLogicalOr,
|
||||
TypeBool(ctx.state), predicate, ctx.HalfArg(inst, 0, 1));
|
||||
}
|
||||
const auto result = ctx.state.builder.AllocateId();
|
||||
ctx.state.builder.AddFunction(zero ? spv::OpGroupNonUniformAll : spv::OpGroupNonUniformAny,
|
||||
TypeBool(ctx.state), result,
|
||||
ConstantU32(ctx.state, spv::ScopeSubgroup), predicate);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t EmitBallot(ValueEmitContext& ctx, IR::Value predicate) {
|
||||
|
||||
@@ -764,13 +764,17 @@ void DefineModule(EmitterState& state) {
|
||||
state.builder.RequireCapability(spv::CapabilityImageGatherExtended);
|
||||
}
|
||||
if (state.lane_count == 2 || state.program.info.subgroup_barrier ||
|
||||
state.program.info.subgroup_ballot || state.program.info.subgroup_shuffle ||
|
||||
state.program.info.subgroup_ballot || state.program.info.subgroup_vote ||
|
||||
state.program.info.subgroup_shuffle ||
|
||||
state.program.info.subgroup_arithmetic || state.program.info.subgroup_local_invocation_id) {
|
||||
state.builder.RequireCapability(spv::CapabilityGroupNonUniform);
|
||||
}
|
||||
if (state.lane_count == 2 || state.program.info.subgroup_ballot) {
|
||||
state.builder.RequireCapability(spv::CapabilityGroupNonUniformBallot);
|
||||
}
|
||||
if (state.program.info.subgroup_vote) {
|
||||
state.builder.RequireCapability(spv::CapabilityGroupNonUniformVote);
|
||||
}
|
||||
if (state.program.info.subgroup_shuffle) {
|
||||
state.builder.RequireCapability(spv::CapabilityGroupNonUniformShuffle);
|
||||
}
|
||||
|
||||
@@ -506,6 +506,7 @@ struct ShaderInfo {
|
||||
bool uses_dispatch_threads = false;
|
||||
bool bvh = false;
|
||||
bool subgroup_ballot = false;
|
||||
bool subgroup_vote = false;
|
||||
bool subgroup_barrier = false;
|
||||
bool subgroup_shuffle = false;
|
||||
bool subgroup_arithmetic = false;
|
||||
|
||||
@@ -510,7 +510,7 @@ void Visit(Program& program, ShaderStageInputInfo input_info, InputUsage& inputs
|
||||
case ValueOpcode::StoreCompletion: info.subgroup_barrier = true; break;
|
||||
case ValueOpcode::BvhIntersect: info.bvh = true; break;
|
||||
case ValueOpcode::ConditionRef:
|
||||
info.subgroup_ballot |=
|
||||
info.subgroup_vote |=
|
||||
inst.Flags<CFG::BranchCondition>() != CFG::BranchCondition::ScalarInstruction;
|
||||
break;
|
||||
case ValueOpcode::Ballot: info.subgroup_ballot = true; break;
|
||||
@@ -572,7 +572,8 @@ void CollectShaderInfo(Program& program, ShaderStageInputInfo input_info) {
|
||||
for (auto& buffer: info.buffers) buffer.live = false;
|
||||
info.has_bitwise_xor = info.uses_lds = info.uses_gds = info.uses_flattened_srt =
|
||||
info.uses_dispatch_threads = info.uses_swizzle = false;
|
||||
info.bvh = info.subgroup_ballot = info.subgroup_barrier = info.subgroup_shuffle = info.subgroup_arithmetic =
|
||||
info.bvh = info.subgroup_ballot = info.subgroup_vote = info.subgroup_barrier =
|
||||
info.subgroup_shuffle = info.subgroup_arithmetic =
|
||||
info.subgroup_local_invocation_id = info.compute_derivatives = info.image_gather_extended =
|
||||
info.function_lds = info.function_scratch = info.pixel_valid_mask = info.buffer_int64_atomics =
|
||||
info.buffer_u8 = info.buffer_u16 = info.shared_int64_atomics = info.coherent_buffers = info.float64 = false;
|
||||
|
||||
Reference in New Issue
Block a user