From a18ae0f6ac313a35945ccf4d9e7d1d1089af40d2 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Wed, 29 Nov 2017 19:09:59 +0300 Subject: [PATCH] rsx/fp: Reimplement PK(X) and UP(X) opcodes. The read back values are obviously in normalized range - Confirmed with a GOW shader which writes result of UP8 to BGRA8 output --- .../Emu/RSX/Common/FragmentProgramDecompiler.cpp | 16 ++++++++-------- .../RSX/D3D12/D3D12FragmentProgramDecompiler.cpp | 3 +++ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp index 79dcea7482..c00146f815 100644 --- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp @@ -494,10 +494,10 @@ bool FragmentProgramDecompiler::handle_scb(u32 opcode) case RSX_FP_OPCODE_MIN: SetDst("min($0, $1)"); return true; case RSX_FP_OPCODE_MOV: SetDst("$0"); return true; case RSX_FP_OPCODE_MUL: SetDst("($0 * $1)"); return true; - case RSX_FP_OPCODE_PK2: SetDst(getFloatTypeName(4) + "(packSnorm2x16($0.xy))"); return true; - case RSX_FP_OPCODE_PK4: SetDst(getFloatTypeName(4) + "(packSnorm4x8($0))"); return true; - case RSX_FP_OPCODE_PK16: SetDst(getFloatTypeName(4) + "(packHalf2x16($0.xy))"); return true; - case RSX_FP_OPCODE_PKB: SetDst(getFloatTypeName(4) + "(packUnorm4x8($0 / 255.))"); return true; + case RSX_FP_OPCODE_PK2: SetDst(getFloatTypeName(4) + "(uintBitsToFloat(packSnorm2x16($0.xy)))"); return true; + case RSX_FP_OPCODE_PK4: SetDst(getFloatTypeName(4) + "(uintBitsToFloat(packSnorm4x8($0)))"); return true; + case RSX_FP_OPCODE_PK16: SetDst(getFloatTypeName(4) + "(uintBitsToFloat(packHalf2x16($0.xy)))"); return true; + case RSX_FP_OPCODE_PKB: SetDst(getFloatTypeName(4) + "(uintBitsToFloat(packUnorm4x8($0)))"); return true; case RSX_FP_OPCODE_PKG: LOG_ERROR(RSX, "Unimplemented SCB instruction: PKG"); return true; case RSX_FP_OPCODE_SEQ: SetDst(getFloatTypeName(4) + "(" + compareFunction(COMPARE::FUNCTION_SEQ, "$0", "$1") + ")"); return true; case RSX_FP_OPCODE_SFL: SetDst(getFunction(FUNCTION::FUNCTION_SFL)); return true; @@ -614,10 +614,10 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode) return true; } return false; - case RSX_FP_OPCODE_UP2: SetDst("unpackSnorm2x16(uint($0.x)).xyxy"); return true; // TODO: More testing (Sonic The Hedgehog (NPUB-30442/NPEB-00478)) - case RSX_FP_OPCODE_UP4: SetDst("unpackSnorm4x8(uint($0.x))"); return true; // TODO: More testing (Sonic The Hedgehog (NPUB-30442/NPEB-00478)) - case RSX_FP_OPCODE_UP16: SetDst("unpackHalf2x16(uint($0.x)).xyxy"); return true; - case RSX_FP_OPCODE_UPB: SetDst("(unpackUnorm4x8(uint($0.x)) * 255.)"); return true; + case RSX_FP_OPCODE_UP2: SetDst("unpackSnorm2x16(floatBitsToUint($0.x)).xyxy"); return true; // TODO: More testing (Sonic The Hedgehog (NPUB-30442/NPEB-00478)) + case RSX_FP_OPCODE_UP4: SetDst("unpackSnorm4x8(floatBitsToUint($0.x))"); return true; // TODO: More testing (Sonic The Hedgehog (NPUB-30442/NPEB-00478)) + case RSX_FP_OPCODE_UP16: SetDst("unpackHalf2x16(floatBitsToUint($0.x)).xyxy"); return true; + case RSX_FP_OPCODE_UPB: SetDst("(unpackUnorm4x8(floatBitsToUint($0.x)))"); return true; case RSX_FP_OPCODE_UPG: LOG_ERROR(RSX, "Unimplemented TEX_SRB instruction: UPG"); return true; } return false; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp index c3b738949d..44187e83e1 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp @@ -35,6 +35,9 @@ std::string D3D12FragmentDecompiler::compareFunction(COMPARE f, const std::strin void D3D12FragmentDecompiler::insertHeader(std::stringstream & OS) { + OS << "#define floatBitsToUint as_uint\n"; + OS << "#define uintBitsToFloat as_float\n\n"; + OS << "cbuffer SCALE_OFFSET : register(b0)\n"; OS << "{\n"; OS << " float4x4 scaleOffsetMat;\n";