diff --git a/core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp b/core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp index a3294a30fe1..fb14ab026e0 100644 --- a/core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp +++ b/core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp @@ -1941,6 +1941,20 @@ void verifyDescriptorPhis() { sequential.context.memory = sequentialMemory.Regions(); static_cast(Recompile(sequential, *sequentialCapture)); + const auto planRestoredSampler = [&](std::span code, const char* message) { + auto request = makeRequest(code); + const auto plan = GetResourcePlan(request); + require(plan->info.samplers.size() == 1u && plan->info.sampledPairs.size() == 1u, message); + AgcDriver::ShaderMemory memory({}); + const auto capture = memory.Capture(request); + request.context.memory = memory.Regions(); + static_cast(Recompile(request, *capture)); + }; + std::vector restoredSamplerCode{0xf40c0200u, 0xfa000000u, 0xf4080500u, 0xfa000020u, 0xf4080600u, 0xfa000040u, 0xbe930380u, 0xbf8cc07fu, 0xf09c0f08u, 0x00a20400u, 0xbe900380u, 0xbe910380u, 0xbe9c0414u, 0xbe9e0416u, 0xbf068011u, 0xbf850001u, 0x80128112u, 0xbe94041cu, 0xbe96041eu, 0x80118111u, 0xbf0a8211u, 0xbf85fff6u, 0xf09c0f08u, 0x00a20000u, 0x80108110u, 0xbf0a8210u, 0xbf85fff0u, 0x80138113u, 0xbf0a8213u, 0xbf85ffecu, 0xbf8c3f70u, 0xe0700000u, 0x80060000u, 0xe0700000u, 0x80060400u, 0x7d880090u, 0xbea23c6au, 0x4a020081u, 0xe0700000u, 0x80060100u, 0xbf810000u}; + planRestoredSampler(restoredSamplerCode, "descriptor Phi: an S# copied out and back in three nested loops was planned as more than one sampler"); + restoredSamplerCode.erase(restoredSamplerCode.end() - 6, restoredSamplerCode.end() - 1); + planRestoredSampler(restoredSamplerCode, "descriptor Phi: an S# copied out and back in three nested loops without a masked write was planned as more than one sampler"); + const auto entryWrites = [&](std::initializer_list words) { auto code = loopCode; code.insert(code.begin() + 8, words); diff --git a/core/shader/recompiler/Optimization/src/ConstantFolder.cpp b/core/shader/recompiler/Optimization/src/ConstantFolder.cpp index 3505f640f4d..0e00f936f1e 100644 --- a/core/shader/recompiler/Optimization/src/ConstantFolder.cpp +++ b/core/shader/recompiler/Optimization/src/ConstantFolder.cpp @@ -828,6 +828,23 @@ void ConstantFolder::Fold(IrProgram& program, std::span blocks) const auto success = tryFoldValue(program, *inst); } } + std::vector phis; + for (IrBlock* block : blocks) { + for (IrValue* inst : block->Instructions()) { + if (inst->Opcode() == IrOpcode::Phi) { + phis.push_back(inst); + } + } + } + bool folded = true; + while (folded) { + folded = false; + for (IrValue* phi : phis) { + if (phi->Opcode() == IrOpcode::Phi && foldPhi(*phi)) { + folded = true; + } + } + } std::vector words; for (IrBlock* block : blocks) { for (IrValue* inst : block->Instructions()) {