mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
shader: accept dword SETPC tables whose load reuses the selector
This commit is contained in:
@@ -470,8 +470,10 @@ bool ResolveSetpcDwordJumpTable(const Decoder::Program& program, uint32_t setpc_
|
||||
if (!ResolveJumpTableEntryCount(program, load_index, load.src1, 2u, &entry_count)) {
|
||||
return false;
|
||||
}
|
||||
// Code-table loads are not translated, so a selector that is also the load destination
|
||||
// keeps its scaled index at the branch.
|
||||
uint32_t selector_code = UINT32_MAX;
|
||||
if (!ScalarOperandCode(load.src1, selector_code) || selector_code == offset_code ||
|
||||
if (!ScalarOperandCode(load.src1, selector_code) ||
|
||||
ScalarCodeWrittenInRange(program, load_index + 1u, setpc_index, selector_code)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+15
-12
@@ -11740,7 +11740,7 @@ void TestNewShaderRecompilerSetpcJumpTable() {
|
||||
Check((*jump)->terminator.cases.size() == 2,
|
||||
"S_SETPC_B64 jump table did not retain selector mapping");
|
||||
Check(
|
||||
(result.ir_dump.find("SLoadDword") == std::string::npos),
|
||||
(result.ir_dump.find("LoadAddressU32") == std::string::npos),
|
||||
"S_SETPC_B64 jump table load was reflected as a raw scalar buffer load");
|
||||
Check(SpirvContainsOpcode(result.spirv, 251),
|
||||
"dispatcher SPIR-V lacks OpSwitch");
|
||||
@@ -11801,7 +11801,9 @@ void TestNewShaderRecompilerPrunesUnreachableSetpcMetadata() {
|
||||
"unreachable S_SETPC metadata suppressed a reachable scalar load component");
|
||||
}
|
||||
|
||||
void TestNewShaderRecompilerSetpcDwordJumpTable() {
|
||||
// offset_sgpr 106 aliases the vcc_lo selector, like PPSA34015's
|
||||
// s_load_dword s17, s[22:23], s17.
|
||||
void TestNewShaderRecompilerSetpcDwordJumpTable(uint32_t offset_sgpr) {
|
||||
const uint32_t shader[] = {
|
||||
EncodeSopp(0x02, 1), // skip one unreachable block
|
||||
EncodeSMovB32(100, 129), // unreachable
|
||||
@@ -11811,20 +11813,20 @@ void TestNewShaderRecompilerSetpcDwordJumpTable() {
|
||||
EncodeSop2(0x00, 4, 4, 255), // s_add_u32 s4, s4, literal
|
||||
0x00000034u,
|
||||
EncodeSop2(0x04, 5, 5, 128), // s_addc_u32 s5, s5, 0
|
||||
EncodeSmem0(0x00, 6, 2),
|
||||
(106u << 25u) | 4u, // s_load_dword s6, s[4:5], vcc_lo offset:4
|
||||
EncodeSopp(0x0c, 0), // s_waitcnt 0
|
||||
EncodeSop2(0x01, 4, 4, 6), // s_sub_u32 s4, s4, s6
|
||||
EncodeSop2(0x05, 5, 5, 128), // s_subb_u32 s5, s5, 0
|
||||
EncodeSop1(0x20, 0, 4), // s_setpc_b64 s[4:5]
|
||||
EncodeSMovB32(1, 129), // case 0
|
||||
EncodeSmem0(0x00, offset_sgpr, 2),
|
||||
(106u << 25u) | 4u, // s_load_dword offset, s[4:5], vcc_lo offset:4
|
||||
EncodeSopp(0x0c, 0), // s_waitcnt 0
|
||||
EncodeSop2(0x01, 4, 4, offset_sgpr), // s_sub_u32 s4, s4, offset
|
||||
EncodeSop2(0x05, 5, 5, 128), // s_subb_u32 s5, s5, 0
|
||||
EncodeSop1(0x20, 0, 4), // s_setpc_b64 s[4:5]
|
||||
EncodeSMovB32(1, 129), // case 0
|
||||
EncodeSopp(0x02, 1),
|
||||
EncodeSMovB32(2, 129), // case 1
|
||||
EncodeSopp(0x01, 0),
|
||||
0u,
|
||||
0x00000010u,
|
||||
0x00000008u,
|
||||
0x00000010u, // table at pc 0x44, targets relative backward from pc 0x40
|
||||
0x00000010u, // table at pc 0x4c, targets relative backward from pc 0x48
|
||||
};
|
||||
|
||||
auto options = MakeCompileOptions(ShaderType::Compute);
|
||||
@@ -11850,7 +11852,7 @@ void TestNewShaderRecompilerSetpcDwordJumpTable() {
|
||||
result.program.blocks,
|
||||
[](const auto *block) { return block->start_pc == 0x04u; }),
|
||||
"subtractive S_SETPC_B64 table targets or selector mapping changed");
|
||||
Check((result.ir_dump.find("SLoadDword") == std::string::npos),
|
||||
Check((result.ir_dump.find("LoadAddressU32") == std::string::npos),
|
||||
"subtractive S_SETPC_B64 table load reached normal IR");
|
||||
Check(SpirvContainsOpcode(result.spirv, 251),
|
||||
"subtractive S_SETPC_B64 dispatcher lacks OpSwitch");
|
||||
@@ -16764,7 +16766,8 @@ int main() {
|
||||
TestEmbeddedVertexFormatSwizzle();
|
||||
TestNewShaderRecompilerSetpcJumpTable();
|
||||
TestNewShaderRecompilerPrunesUnreachableSetpcMetadata();
|
||||
TestNewShaderRecompilerSetpcDwordJumpTable();
|
||||
TestNewShaderRecompilerSetpcDwordJumpTable(6);
|
||||
TestNewShaderRecompilerSetpcDwordJumpTable(106);
|
||||
TestTypedEntryStateIsMinimal();
|
||||
#if KYTY_PLATFORM != KYTY_PLATFORM_WINDOWS
|
||||
TestFinalSsaRejectsRegisterStatePseudos();
|
||||
|
||||
Reference in New Issue
Block a user