mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 02:47:02 +02: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.opcode_id = 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);
|
||||
|
||||
if (inst.opcode == Opcode::UNSUPPORTED) {
|
||||
|
||||
+15
-12
@@ -9435,7 +9435,7 @@ void TestNewShaderRecompilerSetpcBranch() {
|
||||
|
||||
void TestFusedShaderHandoffPreservesRegisters() {
|
||||
using namespace ShaderRecompiler;
|
||||
const uint32_t front[] = {
|
||||
uint32_t front[] = {
|
||||
EncodeSMovB32(12, 255), 0x1003u, // three vertices and one primitive
|
||||
EncodeSop1(0x20, 0, 6), // merged-stage handoff through s[6:7]
|
||||
0xffffffffu, // front shader metadata must not be decoded
|
||||
@@ -9454,20 +9454,23 @@ void TestFusedShaderHandoffPreservesRegisters() {
|
||||
options.stage = ShaderType::Mesh;
|
||||
options.input_info.vertex = &input;
|
||||
options.back_code = back;
|
||||
auto translated = TranslateProgram(front, options);
|
||||
uint32_t allocations = 0;
|
||||
for (const auto* block: translated.program.blocks) {
|
||||
for (const auto& inst: *block) {
|
||||
if (inst.GetOpcode() != IR::ValueOpcode::MeshAllocate) {
|
||||
continue;
|
||||
for (const auto handoff: {EncodeSop1(0x20, 0, 6), 0xbefd2106u}) {
|
||||
front[2] = handoff; // SETPC or captured SWAPPC with NULL destination
|
||||
auto translated = TranslateProgram(front, options);
|
||||
uint32_t allocations = 0;
|
||||
for (const auto* block: translated.program.blocks) {
|
||||
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() {
|
||||
|
||||
Reference in New Issue
Block a user