shader: decode the combined conditional-debug branch

Co-authored-by: Mac <me@itsmemac.com>
Co-authored-by: Senaxx <michelbeld@gmail.com>
Co-authored-by: BlackCAT <52720489+psnwd@users.noreply.github.com>
This commit is contained in:
nmzik
2026-10-01 07:06:51 +04:00
parent 0ecd32299c
commit 64dcbe0ea1
5 changed files with 42 additions and 33 deletions
@@ -108,6 +108,7 @@ constexpr OpcodeMap SOPP_OPCODE_LIST[] = {
{0x12u, Opcode::S_TRAP}, {0x12u, Opcode::S_TRAP},
{0x16u, Opcode::S_TTRACEDATA}, {0x16u, Opcode::S_TTRACEDATA},
{0x17u, Opcode::S_CBRANCH_CDBGSYS}, {0x17u, Opcode::S_CBRANCH_CDBGSYS},
{0x19u, Opcode::S_CBRANCH_CDBGSYS_OR_USER},
{0x20u, Opcode::S_INST_PREFETCH}, {0x20u, Opcode::S_INST_PREFETCH},
{0x23u, Opcode::S_WAITCNT_DEPCTR}, {0x23u, Opcode::S_WAITCNT_DEPCTR},
}; };
@@ -184,8 +184,9 @@ std::string FormatExp(const Instruction& inst) {
bool IsConditionalBranch(Opcode opcode) { bool IsConditionalBranch(Opcode opcode) {
switch (opcode) { switch (opcode) {
// DevKit NGG should be disabled. // Conditional shader debugging is disabled.
case Opcode::S_CBRANCH_CDBGSYS: return false; case Opcode::S_CBRANCH_CDBGSYS:
case Opcode::S_CBRANCH_CDBGSYS_OR_USER: return false;
case Opcode::S_CBRANCH_SCC0: case Opcode::S_CBRANCH_SCC0:
case Opcode::S_CBRANCH_SCC1: case Opcode::S_CBRANCH_SCC1:
case Opcode::S_CBRANCH_VCCZ: case Opcode::S_CBRANCH_VCCZ:
@@ -560,6 +561,7 @@ std::string InstructionToString(const Instruction& inst) {
case Opcode::S_CBRANCH_EXECZ: case Opcode::S_CBRANCH_EXECZ:
case Opcode::S_CBRANCH_EXECNZ: case Opcode::S_CBRANCH_EXECNZ:
case Opcode::S_CBRANCH_CDBGSYS: case Opcode::S_CBRANCH_CDBGSYS:
case Opcode::S_CBRANCH_CDBGSYS_OR_USER:
return WithUnsupportedReason(inst, fmt::format("0x{:08x}: {} 0x{:08x}", inst.pc, return WithUnsupportedReason(inst, fmt::format("0x{:08x}: {} 0x{:08x}", inst.pc,
magic_enum::enum_name(inst.opcode), magic_enum::enum_name(inst.opcode),
inst.branch_target)); inst.branch_target));
@@ -608,6 +608,7 @@ enum class Opcode {
S_CBRANCH_EXECZ, S_CBRANCH_EXECZ,
S_CBRANCH_EXECNZ, S_CBRANCH_EXECNZ,
S_CBRANCH_CDBGSYS, S_CBRANCH_CDBGSYS,
S_CBRANCH_CDBGSYS_OR_USER,
S_SENDMSG, S_SENDMSG,
S_SETREG_B32, S_SETREG_B32,
S_SLEEP, S_SLEEP,
@@ -231,6 +231,7 @@ void Translator::EmitScalar(const Decoder::Instruction& inst) {
case O::S_CBRANCH_EXECZ: case O::S_CBRANCH_EXECZ:
case O::S_CBRANCH_EXECNZ: case O::S_CBRANCH_EXECNZ:
case O::S_CBRANCH_CDBGSYS: case O::S_CBRANCH_CDBGSYS:
case O::S_CBRANCH_CDBGSYS_OR_USER:
case O::S_ENDPGM: return; case O::S_ENDPGM: return;
default: return FailMissingTranslation(inst); default: return FailMissingTranslation(inst);
} }
+35 -31
View File
@@ -1884,37 +1884,41 @@ void TestSopkCompareImmediateExtension() {
} }
} }
void TestDisabledSystemDebugBranch() { void TestDisabledDebugBranches() {
using namespace ShaderRecompiler; using namespace ShaderRecompiler;
// Relocate PPSA08709 MS pc 0x530 to zero, retaining its displacement to the // Both debug branches fall through when conditional shader debugging is disabled.
// system validation helper immediately after the main shader's S_ENDPGM. // Retain the post-ENDPGM helper displacement from PPSA08709 and exercise the
std::array<uint32_t, 274> shader; // OR_USER variant encountered in PPSA03671 with the same body.
shader.fill(EncodeSopp(0x00)); for (const auto opcode : {Decoder::Opcode::S_CBRANCH_CDBGSYS,
shader[0] = 0xbf97010fu; Decoder::Opcode::S_CBRANCH_CDBGSYS_OR_USER}) {
shader[1] = EncodeVop1(0x01, 1, 129); std::array<uint32_t, 274> shader;
shader[2] = EncodeMubuf0(0x1c, 0, false); shader.fill(EncodeSopp(0x00));
shader[3] = EncodeMubuf1(1, 0, 0); shader[0] = EncodeSopp(opcode == Decoder::Opcode::S_CBRANCH_CDBGSYS ? 0x17 : 0x19, 0x10f);
shader[271] = EncodeSopp(0x01); shader[1] = EncodeVop1(0x01, 1, 129);
shader[272] = 0xffffffffu; // System-only helper must not be decoded. shader[2] = EncodeMubuf0(0x1c, 0, false);
shader[273] = 0xffffffffu; shader[3] = EncodeMubuf1(1, 0, 0);
Decoder::Program decoded; shader[271] = EncodeSopp(0x01);
Decoder::DecodeProgram(shader, decoded); shader[272] = 0xffffffffu; // Debug-only helper must not be decoded.
Check(decoded.instructions.front().opcode == Decoder::Opcode::S_CBRANCH_CDBGSYS && shader[273] = 0xffffffffu;
decoded.instructions.front().branch_target == 0x440u && Decoder::Program decoded;
decoded.instructions.back().pc == 0x43cu && Decoder::DecodeProgram(shader, decoded);
decoded.instructions.back().opcode == Decoder::Opcode::S_ENDPGM, Check(decoded.instructions.front().opcode == opcode &&
"disabled system debug branch reached its post-ENDPGM validation helper"); decoded.instructions.front().branch_target == 0x440u &&
auto graph = CFG::BuildGraph(decoded); decoded.instructions.back().pc == 0x43cu &&
Check(graph.blocks.size() == 1u && graph.FindBlockByPc(0x440u) == nullptr && decoded.instructions.back().opcode == Decoder::Opcode::S_ENDPGM,
graph.blocks.front().terminator.kind == CFG::TerminatorKind::Return, "disabled debug branch reached its post-ENDPGM validation helper");
"disabled system debug branch changed normal shader control flow"); auto graph = CFG::BuildGraph(decoded);
auto options = MakeCompileOptions(ShaderType::Compute); Check(graph.blocks.size() == 1u && graph.FindBlockByPc(0x440u) == nullptr &&
options.dump_ir = true; graph.blocks.front().terminator.kind == CFG::TerminatorKind::Return,
auto result = RecompileForTest(shader, options); "disabled debug branch changed normal shader control flow");
Check((result.decoded_dump.find("S_CBRANCH_CDBGSYS 0x00000440") != std::string::npos) && auto options = MakeCompileOptions(ShaderType::Compute);
(result.ir_dump.find("StoreBufferU32") != std::string::npos), options.dump_ir = true;
"disabled system debug branch lost its identity or fallthrough write"); auto result = RecompileForTest(shader, options);
CheckSpirvBinaryValidates(result.spirv); Check((result.decoded_dump.find(" 0x00000440") != std::string::npos) &&
(result.ir_dump.find("StoreBufferU32") != std::string::npos),
"disabled debug branch lost its identity or fallthrough write");
CheckSpirvBinaryValidates(result.spirv);
}
} }
void TestNewShaderRecompilerRdna2ScalarOpcodes() { void TestNewShaderRecompilerRdna2ScalarOpcodes() {
@@ -14142,7 +14146,7 @@ int main() {
TestNewShaderRecompilerBufferLoadsGuardedByExec(); TestNewShaderRecompilerBufferLoadsGuardedByExec();
TestNewShaderRecompilerBufferAtomicsGuardedByBounds(); TestNewShaderRecompilerBufferAtomicsGuardedByBounds();
TestCapturedBufferAtomicsX2(); TestCapturedBufferAtomicsX2();
TestDisabledSystemDebugBranch(); TestDisabledDebugBranches();
TestNewShaderRecompilerPixelImageSampleLodSelection(); TestNewShaderRecompilerPixelImageSampleLodSelection();
TestNewShaderRecompilerBranchConditionForms(); TestNewShaderRecompilerBranchConditionForms();
TestNewShaderRecompilerSetpcBranch(); TestNewShaderRecompilerSetpcBranch();