From 61212c934125c613828ca8dc95fc55e26fa88100 Mon Sep 17 00:00:00 2001 From: wheremyfoodat Date: Sat, 24 Sep 2022 03:11:36 +0300 Subject: [PATCH] [PICA] Implement mul --- include/PICA/shader.hpp | 2 ++ src/core/PICA/shader_interpreter.cpp | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/include/PICA/shader.hpp b/include/PICA/shader.hpp index 2978192e..e4101141 100644 --- a/include/PICA/shader.hpp +++ b/include/PICA/shader.hpp @@ -14,6 +14,7 @@ namespace ShaderOpcodes { enum : u32 { ADD = 0x00, DP4 = 0x02, + MUL = 0x08, MOV = 0x13, END = 0x22 }; @@ -41,6 +42,7 @@ class PICAShader { void add(u32 instruction); void dp4(u32 instruction); void mov(u32 instruction); + void mul(u32 instruction); // src1, src2 and src3 have different negation & component swizzle bits in the operand descriptor // https://problemkaputt.github.io/gbatek.htm#3dsgpushaderinstructionsetopcodesummary in the diff --git a/src/core/PICA/shader_interpreter.cpp b/src/core/PICA/shader_interpreter.cpp index 0aae6da6..c55cd6a1 100644 --- a/src/core/PICA/shader_interpreter.cpp +++ b/src/core/PICA/shader_interpreter.cpp @@ -12,6 +12,7 @@ void PICAShader::run() { case ShaderOpcodes::DP4: dp4(instruction); break; case ShaderOpcodes::END: return; // Stop running shader case ShaderOpcodes::MOV: mov(instruction); break; + case ShaderOpcodes::MUL: mul(instruction); break; default:Helpers::panic("Unimplemented PICA instruction %08X (Opcode = %02X)", instruction, opcode); } } @@ -58,6 +59,27 @@ void PICAShader::add(u32 instruction) { } } +void PICAShader::mul(u32 instruction) { + const u32 operandDescriptor = operandDescriptors[instruction & 0x7f]; + const 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; + + if (idx) Helpers::panic("[PICA] MUL: idx != 0"); + vec4f srcVec1 = getSourceSwizzled<1>(src1, operandDescriptor); + vec4f srcVec2 = getSourceSwizzled<2>(src2, operandDescriptor); + + vec4f& 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 - 1]; + } + } +} + void PICAShader::mov(u32 instruction) { const u32 operandDescriptor = operandDescriptors[instruction & 0x7f]; const u32 src = (instruction >> 12) & 0x7f;