mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-30 09:08:19 +00:00
shader: lower whole-wave OR scans to subgroup reductions
This commit is contained in:
1 parent
eb3cb47296
commit
0c2546e850
8 files changed
+80
-41
No files matched your search
@@ -695,7 +695,7 @@ void TestCompleteWaveReduction() {
|
||||
Shift, FetchInactive, BoundControl, Dpp8, MoveExec, UpdateExec,
|
||||
Previous, DppSource, CrossExec, CrossRow, CrossSelectorLow,
|
||||
CrossSelectorHigh, CrossFetch, CrossBound, CrossSource, FinalExec,
|
||||
Endpoint, EndpointSource, CrossBlock, WrongOperation
|
||||
Endpoint, EndpointSource, CrossBlock, WrongOperation, Or
|
||||
};
|
||||
for (const auto test : {Case::Masked, Case::ScalarExec, Case::Wave32,
|
||||
Case::Wave32Rows, Case::Wave32Maximum, Case::RowMask, Case::BankMask,
|
||||
@@ -704,7 +704,7 @@ void TestCompleteWaveReduction() {
|
||||
Case::CrossExec, Case::CrossRow, Case::CrossSelectorLow,
|
||||
Case::CrossSelectorHigh, Case::CrossFetch, Case::CrossBound,
|
||||
Case::CrossSource, Case::FinalExec, Case::Endpoint, Case::EndpointSource,
|
||||
Case::CrossBlock, Case::WrongOperation}) {
|
||||
Case::CrossBlock, Case::WrongOperation, Case::Or}) {
|
||||
Fixture fixture(test == Case::CrossBlock ? 2 : 1);
|
||||
const auto source = fixture.Emit(ValueOpcode::LaneId);
|
||||
const auto mask = fixture.Emit(ValueOpcode::ULessThan32, {source, Value(19u)});
|
||||
@@ -720,14 +720,20 @@ void TestCompleteWaveReduction() {
|
||||
enabled = fixture.Emit(ValueOpcode::INotEqual32,
|
||||
{fixture.Emit(ValueOpcode::BitwiseAnd32, {shifted, Value(1u)}), Value(0u)});
|
||||
}
|
||||
// A UMax scan seeds lanes outside EXEC with zero.
|
||||
// UMax and OR scans seed lanes outside EXEC with zero.
|
||||
const bool maximum = test == Case::Wave32Maximum;
|
||||
const uint32_t neutral = maximum ? 0u : UINT32_MAX;
|
||||
const bool bitwise_or = test == Case::Or;
|
||||
const uint32_t neutral = maximum || bitwise_or ? 0u : UINT32_MAX;
|
||||
const auto seed = fixture.Emit(ValueOpcode::SelectU32, {mask, source, Value(neutral)});
|
||||
auto prefix = fixture.Emit(ValueOpcode::SelectU32, {enabled, seed, source});
|
||||
Value preserved;
|
||||
auto operation = maximum ? ValueOpcode::UMax32 : ValueOpcode::UMin32;
|
||||
if (test == Case::WrongOperation) operation = ValueOpcode::BitwiseOr32;
|
||||
auto reduction_opcode = maximum ? ValueOpcode::SubgroupUMaxU32 : ValueOpcode::SubgroupUMinU32;
|
||||
if (bitwise_or) {
|
||||
operation = ValueOpcode::BitwiseOr32;
|
||||
reduction_opcode = ValueOpcode::SubgroupOrU32;
|
||||
}
|
||||
if (test == Case::WrongOperation) operation = ValueOpcode::IAdd32;
|
||||
for (const uint32_t shift : {1u, 2u, 4u, 8u}) {
|
||||
DppMoveFlags flags{.control = 0x110u + shift};
|
||||
if (shift == 2) {
|
||||
@@ -787,13 +793,12 @@ void TestCompleteWaveReduction() {
|
||||
const uint32_t wave_size = test == Case::Wave32 || rows ? 32u : 64u;
|
||||
ConstantPropagationPass(fixture.program.blocks, wave_size);
|
||||
const auto stats = EliminateReadLane(fixture.program, wave_size);
|
||||
const bool matches = test == Case::Masked || rows;
|
||||
const bool matches = test == Case::Masked || rows || bitwise_or;
|
||||
Check(stats.rewritten_reductions == (matches ? 1u : 0u) && stats.rewritten_reads == 0,
|
||||
("wave reduction proof failed case " + std::to_string(static_cast<unsigned>(test))).c_str());
|
||||
if (matches) {
|
||||
const auto *reduction = use.Instruction()->Arg(0).ResolveInstruction();
|
||||
Check(reduction->GetOpcode() ==
|
||||
(maximum ? ValueOpcode::SubgroupUMaxU32 : ValueOpcode::SubgroupUMinU32) &&
|
||||
Check(reduction->GetOpcode() == reduction_opcode &&
|
||||
reduction->Arg(0).Resolve() == seed.Resolve(),
|
||||
"wave reduction changed the neutral-masked input");
|
||||
RemoveIdentities(fixture.program);
|
||||
|
||||
Reference in new issue
Block a user