mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 19:07:01 +02:00
graphics: accept phi-mediated SRT cycles
This commit is contained in:
@@ -308,8 +308,17 @@ private:
|
|||||||
if (inst == nullptr) {
|
if (inst == nullptr) {
|
||||||
return Fail(use_pc, error, "invalid typed planning value");
|
return Fail(use_pc, error, "invalid typed planning value");
|
||||||
}
|
}
|
||||||
if (std::ranges::find(m_visiting, inst) != m_visiting.end()) {
|
const auto cycle = std::ranges::find(m_visiting, inst);
|
||||||
return inst->GetOpcode() == ValueOpcode::Phi;
|
if (cycle != m_visiting.end()) {
|
||||||
|
const auto contains_phi = std::any_of(cycle, m_visiting.end(), [](const Inst* value) {
|
||||||
|
return value->GetOpcode() == ValueOpcode::Phi;
|
||||||
|
});
|
||||||
|
if (contains_phi) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return Fail(use_pc, error,
|
||||||
|
fmt::format("cyclic typed planning value {} without a phi",
|
||||||
|
ValueOpcodeName(inst->GetOpcode())));
|
||||||
}
|
}
|
||||||
if (std::ranges::find(m_visited, inst) != m_visited.end()) {
|
if (std::ranges::find(m_visited, inst) != m_visited.end()) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -447,6 +447,28 @@ void TestPhiValidation() {
|
|||||||
"control-dependent descriptor phi was not rejected transactionally");
|
"control-dependent descriptor phi was not rejected transactionally");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestLoopCycleEnteredThroughRuntimeValue() {
|
||||||
|
Fixture fixture;
|
||||||
|
auto *entry = fixture.block;
|
||||||
|
auto *loop = fixture.AddBlock();
|
||||||
|
const auto initial = fixture.UserData(0);
|
||||||
|
entry->AddBranch(loop);
|
||||||
|
loop->AddBranch(loop);
|
||||||
|
auto &phi = loop->AppendNewInst(ValueOpcode::Phi, {},
|
||||||
|
static_cast<uint64_t>(Type::U32));
|
||||||
|
const auto carried = fixture.Emit(
|
||||||
|
ValueOpcode::BitwiseAnd32, {Value(&phi), Value(0xffffffffu)}, 0, loop);
|
||||||
|
phi.AddPhiOperand(entry, initial);
|
||||||
|
phi.AddPhiOperand(loop, carried);
|
||||||
|
fixture.Emit(ValueOpcode::GetBufferResource,
|
||||||
|
{carried, Value(0u), Value(0u), Value(0u)},
|
||||||
|
MemoryFlags{0, 12}, loop);
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
Check(BuildSrtPlan(fixture.program, &error),
|
||||||
|
"SRT planning rejected a valid loop entered through a runtime value");
|
||||||
|
}
|
||||||
|
|
||||||
void TestInvariantLoopPhi() {
|
void TestInvariantLoopPhi() {
|
||||||
Fixture fixture;
|
Fixture fixture;
|
||||||
auto *entry = fixture.block;
|
auto *entry = fixture.block;
|
||||||
@@ -610,6 +632,7 @@ int main() {
|
|||||||
Run("SRT runtime", TestSrtFlatteningAndRuntimeMemoization);
|
Run("SRT runtime", TestSrtFlatteningAndRuntimeMemoization);
|
||||||
Run("dynamic SRT", TestDynamicSrtReadRemainsExplicit);
|
Run("dynamic SRT", TestDynamicSrtReadRemainsExplicit);
|
||||||
Run("phi validation", TestPhiValidation);
|
Run("phi validation", TestPhiValidation);
|
||||||
|
Run("runtime-rooted loop", TestLoopCycleEnteredThroughRuntimeValue);
|
||||||
Run("invariant loop phi", TestInvariantLoopPhi);
|
Run("invariant loop phi", TestInvariantLoopPhi);
|
||||||
Run("address materialization", TestAddressMaterializationAndSpecialization);
|
Run("address materialization", TestAddressMaterializationAndSpecialization);
|
||||||
Run("shader info and bindings", TestShaderInfoAndBindingLayout);
|
Run("shader info and bindings", TestShaderInfoAndBindingLayout);
|
||||||
|
|||||||
Reference in New Issue
Block a user