diff --git a/include/PICA/shader.hpp b/include/PICA/shader.hpp index b1833607..25574199 100644 --- a/include/PICA/shader.hpp +++ b/include/PICA/shader.hpp @@ -16,6 +16,7 @@ namespace ShaderOpcodes { DP3 = 0x01, DP4 = 0x02, MUL = 0x08, + SLT = 0x0A, FLR = 0x0B, MAX = 0x0C, MIN = 0x0D, @@ -23,6 +24,7 @@ namespace ShaderOpcodes { RSQ = 0x0F, MOVA = 0x12, MOV = 0x13, + SGEI = 0x1A, SLTI = 0x1B, NOP = 0x21, END = 0x22, @@ -112,6 +114,8 @@ class PICAShader { void mul(u32 instruction); void rcp(u32 instruction); void rsq(u32 instruction); + void sgei(u32 instruction); + void slt(u32 instruction); void slti(u32 instruction); // src1, src2 and src3 have different negation & component swizzle bits in the operand descriptor diff --git a/src/core/PICA/shader_interpreter.cpp b/src/core/PICA/shader_interpreter.cpp index 4a7e0e70..ec5a269d 100644 --- a/src/core/PICA/shader_interpreter.cpp +++ b/src/core/PICA/shader_interpreter.cpp @@ -36,6 +36,8 @@ void PICAShader::run() { case ShaderOpcodes::NOP: break; // Do nothing case ShaderOpcodes::RCP: rcp(instruction); break; case ShaderOpcodes::RSQ: rsq(instruction); break; + case ShaderOpcodes::SGEI: sgei(instruction); break; + case ShaderOpcodes::SLT: slt(instruction); break; case ShaderOpcodes::SLTI: slti(instruction); break; case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: @@ -407,6 +409,47 @@ void PICAShader::madi(u32 instruction) { } } +void PICAShader::slt(u32 instruction) { + const u32 operandDescriptor = operandDescriptors[instruction & 0x7f]; + u32 src1 = (instruction >> 12) & 0x7f; + const u32 src2 = (instruction >> 7) & 0x1f; // src2 coming first because PICA moment + const u32 idx = (instruction >> 19) & 3; + const u32 dest = (instruction >> 21) & 0x1f; + + 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 & 0x1f]; + const u32 src1 = (instruction >> 14) & 0x1f; + u32 src2 = (instruction >> 7) & 0x7f; + const u32 idx = (instruction >> 19) & 3; + const u32 dest = (instruction >> 21) & 0x1f; + + src2 = getIndexedSource(src2, idx); + + auto srcVec1 = getSourceSwizzled<1>(src1, operandDescriptor); + auto 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::slti(u32 instruction) { const u32 operandDescriptor = operandDescriptors[instruction & 0x1f]; const u32 src1 = (instruction >> 14) & 0x1f;