From 85c586b3d052092ef245d25c11b7a42dc3f55323 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Sat, 12 Aug 2023 23:36:56 +0300 Subject: [PATCH 1/2] [Shader JIT] Add DPHI --- src/core/PICA/dynapica/shader_rec_emitter_x64.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/core/PICA/dynapica/shader_rec_emitter_x64.cpp b/src/core/PICA/dynapica/shader_rec_emitter_x64.cpp index 7bcf4b46..d95f7bf5 100644 --- a/src/core/PICA/dynapica/shader_rec_emitter_x64.cpp +++ b/src/core/PICA/dynapica/shader_rec_emitter_x64.cpp @@ -143,7 +143,9 @@ void ShaderEmitter::compileInstruction(const PICAShader& shaderUnit) { break; case ShaderOpcodes::DP3: recDP3(shaderUnit, instruction); break; case ShaderOpcodes::DP4: recDP4(shaderUnit, instruction); break; - case ShaderOpcodes::DPH: recDPH(shaderUnit, instruction); break; + case ShaderOpcodes::DPH: + case ShaderOpcodes::DPHI: + recDPH(shaderUnit, instruction); break; case ShaderOpcodes::END: recEND(shaderUnit, instruction); break; case ShaderOpcodes::EX2: recEX2(shaderUnit, instruction); break; case ShaderOpcodes::FLR: recFLR(shaderUnit, instruction); break; @@ -531,15 +533,17 @@ void ShaderEmitter::recDP4(const PICAShader& shader, u32 instruction) { } void ShaderEmitter::recDPH(const PICAShader& shader, u32 instruction) { + const bool isDPHI = (instruction >> 26) == ShaderOpcodes::DPHI; + const u32 operandDescriptor = shader.operandDescriptors[instruction & 0x7f]; - const u32 src1 = getBits<12, 7>(instruction); - const u32 src2 = getBits<7, 5>(instruction); // src2 coming first because PICA moment + const u32 src1 = isDPHI ? getBits<14, 5>(instruction) : getBits<12, 7>(instruction); + const u32 src2 = isDPHI ? getBits<7, 7>(instruction) : getBits<7, 5>(instruction); const u32 idx = getBits<19, 2>(instruction); const u32 dest = getBits<21, 5>(instruction); // TODO: Safe multiplication equivalent (Multiplication is not IEEE compliant on the PICA) - loadRegister<1>(src1_xmm, shader, src1, idx, operandDescriptor); - loadRegister<2>(src2_xmm, shader, src2, 0, operandDescriptor); + loadRegister<1>(src1_xmm, shader, src1, isDPHI ? 0 : idx, operandDescriptor); + loadRegister<2>(src2_xmm, shader, src2, isDPHI ? idx : 0, operandDescriptor); // Attach 1.0 to the w component of src1 if (haveSSE4_1) { From ccdf8f7722ede5a17f12099c7a324b7f058560e2 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Sat, 12 Aug 2023 23:46:42 +0300 Subject: [PATCH 2/2] Shader Interpreter: implement SGE --- include/PICA/shader.hpp | 1 + src/core/PICA/shader_interpreter.cpp | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/include/PICA/shader.hpp b/include/PICA/shader.hpp index 48db777d..63b59914 100644 --- a/include/PICA/shader.hpp +++ b/include/PICA/shader.hpp @@ -159,6 +159,7 @@ class PICAShader { void mul(u32 instruction); void rcp(u32 instruction); void rsq(u32 instruction); + void sge(u32 instruction); void sgei(u32 instruction); void slt(u32 instruction); void slti(u32 instruction); diff --git a/src/core/PICA/shader_interpreter.cpp b/src/core/PICA/shader_interpreter.cpp index 9fed6bba..85ca3c6e 100644 --- a/src/core/PICA/shader_interpreter.cpp +++ b/src/core/PICA/shader_interpreter.cpp @@ -45,6 +45,7 @@ void PICAShader::run() { case ShaderOpcodes::NOP: break; // Do nothing case ShaderOpcodes::RCP: rcp(instruction); break; case ShaderOpcodes::RSQ: rsq(instruction); break; + case ShaderOpcodes::SGE: sge(instruction); break; case ShaderOpcodes::SGEI: sgei(instruction); break; case ShaderOpcodes::SLT: slt(instruction); break; case ShaderOpcodes::SLTI: slti(instruction); break; @@ -517,6 +518,26 @@ void PICAShader::slt(u32 instruction) { } } +void PICAShader::sge(u32 instruction) { + const u32 operandDescriptor = operandDescriptors[instruction & 0x7f]; + u32 src1 = getBits<12, 7>(instruction); + const u32 src2 = getBits<7, 5>(instruction); // src2 coming first because PICA moment + const u32 idx = getBits<19, 2>(instruction); + const u32 dest = getBits<21, 5>(instruction); + + src1 = getIndexedSource(src1, idx); + vec4f srcVec1 = getSourceSwizzled<1>(src1, operandDescriptor); + vec4f srcVec2 = getSourceSwizzled<2>(src2, operandDescriptor); + auto& destVector = getDest(dest); + + u32 componentMask = operandDescriptor & 0xf; + for (int i = 0; i < 4; i++) { + if (componentMask & (1 << i)) { + destVector[3 - i] = srcVec1[3 - i] >= srcVec2[3 - i] ? f24::fromFloat32(1.0) : f24::zero(); + } + } +} + void PICAShader::sgei(u32 instruction) { const u32 operandDescriptor = operandDescriptors[instruction & 0x7f]; const u32 src1 = getBits<14, 5>(instruction);