mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-25 12:26:51 +01:00
Recognize null-destination SWAPPC shader handoffs
Credits: BlackCAT (@psnwd): https://github.com/KytyPS5/KytyPS5/pull/613 YuhiAida (@YuhiAida): https://github.com/KytyPS5/KytyPS5/pull/655
This commit is contained in:
@@ -137,6 +137,10 @@ void DecodeSop1(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
|
|||||||
inst.family = Family::SOP1;
|
inst.family = Family::SOP1;
|
||||||
inst.opcode_id = opcode;
|
inst.opcode_id = opcode;
|
||||||
inst.opcode = Detail::LookupOpcode(SOP1_OPS, opcode);
|
inst.opcode = Detail::LookupOpcode(SOP1_OPS, opcode);
|
||||||
|
if (opcode == 0x21u && sdst == 125u) {
|
||||||
|
// S_SWAPPC_B64 with NULL discards the return PC, so it is a plain jump.
|
||||||
|
inst.opcode = Opcode::S_SETPC_B64;
|
||||||
|
}
|
||||||
SetRawWords(inst, code, word_index, 1);
|
SetRawWords(inst, code, word_index, 1);
|
||||||
|
|
||||||
if (inst.opcode == Opcode::UNSUPPORTED) {
|
if (inst.opcode == Opcode::UNSUPPORTED) {
|
||||||
|
|||||||
+15
-12
@@ -9435,7 +9435,7 @@ void TestNewShaderRecompilerSetpcBranch() {
|
|||||||
|
|
||||||
void TestFusedShaderHandoffPreservesRegisters() {
|
void TestFusedShaderHandoffPreservesRegisters() {
|
||||||
using namespace ShaderRecompiler;
|
using namespace ShaderRecompiler;
|
||||||
const uint32_t front[] = {
|
uint32_t front[] = {
|
||||||
EncodeSMovB32(12, 255), 0x1003u, // three vertices and one primitive
|
EncodeSMovB32(12, 255), 0x1003u, // three vertices and one primitive
|
||||||
EncodeSop1(0x20, 0, 6), // merged-stage handoff through s[6:7]
|
EncodeSop1(0x20, 0, 6), // merged-stage handoff through s[6:7]
|
||||||
0xffffffffu, // front shader metadata must not be decoded
|
0xffffffffu, // front shader metadata must not be decoded
|
||||||
@@ -9454,20 +9454,23 @@ void TestFusedShaderHandoffPreservesRegisters() {
|
|||||||
options.stage = ShaderType::Mesh;
|
options.stage = ShaderType::Mesh;
|
||||||
options.input_info.vertex = &input;
|
options.input_info.vertex = &input;
|
||||||
options.back_code = back;
|
options.back_code = back;
|
||||||
auto translated = TranslateProgram(front, options);
|
for (const auto handoff: {EncodeSop1(0x20, 0, 6), 0xbefd2106u}) {
|
||||||
uint32_t allocations = 0;
|
front[2] = handoff; // SETPC or captured SWAPPC with NULL destination
|
||||||
for (const auto* block: translated.program.blocks) {
|
auto translated = TranslateProgram(front, options);
|
||||||
for (const auto& inst: *block) {
|
uint32_t allocations = 0;
|
||||||
if (inst.GetOpcode() != IR::ValueOpcode::MeshAllocate) {
|
for (const auto* block: translated.program.blocks) {
|
||||||
continue;
|
for (const auto& inst: *block) {
|
||||||
|
if (inst.GetOpcode() != IR::ValueOpcode::MeshAllocate) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto value = inst.Arg(0).Resolve();
|
||||||
|
Check(value.IsImmediate() && value.U32() == 0x1003u,
|
||||||
|
"fused back shader lost the front shader's scalar register value");
|
||||||
|
allocations++;
|
||||||
}
|
}
|
||||||
const auto value = inst.Arg(0).Resolve();
|
|
||||||
Check(value.IsImmediate() && value.U32() == 0x1003u,
|
|
||||||
"fused back shader lost the front shader's scalar register value");
|
|
||||||
allocations++;
|
|
||||||
}
|
}
|
||||||
|
Check(allocations == 1u, "fused shader omitted the back shader allocation");
|
||||||
}
|
}
|
||||||
Check(allocations == 1u, "fused shader omitted the back shader allocation");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestMeshExportStorage() {
|
void TestMeshExportStorage() {
|
||||||
|
|||||||
Reference in New Issue
Block a user