mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-23 20:36:58 +02:00
recompiler: allow a shader to be refused instead of aborting
A shader the recompiler cannot translate is a gap in emulation, not a reason to take the process down: skipping the draw or dispatch that wanted it costs some rendering, while aborting costs the title. CompileOptions gains non_fatal and CompileResult gains unsupported. With non_fatal set, the three places the recompile path gives up - an opcode with no IR translation, a CFG that will not build, and resource tracking that cannot resolve a descriptor - record the failure and unwind rather than calling EXIT, and Recompile returns a result marked unsupported. The caller skips that draw or dispatch. Nothing changes when non_fatal is clear. Marvel's Spider-Man: Miles Morales meets an untranslatable compute shader on its third frame, so a strict build cannot pass the opening logo. Astro's Playroom is also stopped by a shader today and reaches a later, different failure with this in place.
This commit is contained in:
@@ -3,16 +3,23 @@
|
||||
|
||||
namespace Libs::Graphics::ShaderRecompiler::Frontend {
|
||||
|
||||
|
||||
void Translator::TranslateInstruction(const Decoder::Instruction& inst) {
|
||||
current_opcode = inst.opcode;
|
||||
current_pc = inst.pc;
|
||||
|
||||
if (TranslationUnsupportedFlag()) {
|
||||
return;
|
||||
}
|
||||
switch (inst.opcode) {
|
||||
case Decoder::Opcode::UNKNOWN:
|
||||
case Decoder::Opcode::COUNT:
|
||||
EXIT("decoded opcode has no IR translation at pc 0x%08x", inst.pc);
|
||||
case Decoder::Opcode::UNSUPPORTED:
|
||||
EXIT("unsupported decoded instruction: %s", Decoder::InstructionToString(inst).c_str());
|
||||
if (TranslationNonFatalFlag()) {
|
||||
TranslationUnsupportedFlag() = true;
|
||||
return;
|
||||
}
|
||||
EXIT("decoded opcode has no IR translation at pc 0x%08x", inst.pc);
|
||||
default: break;
|
||||
}
|
||||
|
||||
@@ -43,6 +50,10 @@ void Translator::TranslateInstruction(const Decoder::Instruction& inst) {
|
||||
}
|
||||
|
||||
if (!translated) {
|
||||
if (TranslationNonFatalFlag()) {
|
||||
TranslationUnsupportedFlag() = true;
|
||||
return;
|
||||
}
|
||||
EXIT("opcode %s at pc 0x%08x has no IR translation",
|
||||
Decoder::InstructionToString(inst).c_str(), inst.pc);
|
||||
}
|
||||
|
||||
@@ -231,6 +231,7 @@ private:
|
||||
bool V_CNDMASK_B32(const Decoder::Instruction& inst);
|
||||
bool PackB16(const Decoder::Instruction& inst, bool high0, bool high1);
|
||||
|
||||
bool S_CMP_MASK_ANY(const Decoder::Instruction& inst, bool not_equal);
|
||||
void S_SAVEEXEC(const Decoder::Instruction& inst, IR::ValueOpcode operation, bool negate_exec,
|
||||
bool negate_source, bool write_64);
|
||||
void ADD_U32(const Decoder::Instruction& inst, bool vector, bool use_carry_in);
|
||||
@@ -276,4 +277,27 @@ private:
|
||||
uint32_t current_wave_size = 64;
|
||||
};
|
||||
|
||||
inline bool& TranslationNonFatalFlag() {
|
||||
static thread_local bool value = false;
|
||||
return value;
|
||||
}
|
||||
|
||||
inline bool& TranslationUnsupportedFlag() {
|
||||
static thread_local bool value = false;
|
||||
return value;
|
||||
}
|
||||
|
||||
inline void SetTranslationNonFatal(bool enabled) {
|
||||
TranslationNonFatalFlag() = enabled;
|
||||
TranslationUnsupportedFlag() = false;
|
||||
}
|
||||
|
||||
inline bool TranslationUnsupported() {
|
||||
return TranslationUnsupportedFlag();
|
||||
}
|
||||
|
||||
inline bool TranslationNonFatal() {
|
||||
return TranslationNonFatalFlag();
|
||||
}
|
||||
|
||||
} // namespace Libs::Graphics::ShaderRecompiler::Frontend
|
||||
|
||||
Reference in New Issue
Block a user