diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 330f139d..57d0f98d 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -47,6 +47,9 @@ namespace dxvk { case DxbcOpcode::Add: return this->opAdd(ins); + case DxbcOpcode::Mad: + return this->opMad(ins); + case DxbcOpcode::Mul: return this->opMul(ins); @@ -235,6 +238,24 @@ namespace dxvk { } + void DxbcCompiler::opMad(const DxbcInstruction& ins) { + auto dstOp = ins.operand(0); + auto srcOp1 = ins.operand(dstOp.length()); + auto srcOp2 = ins.operand(dstOp.length() + srcOp1.length()); + auto srcOp3 = ins.operand(dstOp.length() + srcOp1.length() + srcOp2.length()); + DxbcComponentMask mask = this->getDstOperandMask(dstOp); + + DxbcValue src1 = this->loadOperand(srcOp1, mask, DxbcScalarType::Float32); + DxbcValue src2 = this->loadOperand(srcOp2, mask, DxbcScalarType::Float32); + DxbcValue src3 = this->loadOperand(srcOp3, mask, DxbcScalarType::Float32); + // TODO implement with native FMA instruction + DxbcValue val = m_gen->opMul(src1, src2); + val = m_gen->opAdd(val, src3); + val = this->applyResultModifiers(val, ins.token().control()); + this->storeOperand(dstOp, val, mask); + } + + void DxbcCompiler::opMul(const DxbcInstruction& ins) { auto dstOp = ins.operand(0); auto srcOp1 = ins.operand(dstOp.length()); diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index fa6278a7..afce1f41 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -50,6 +50,9 @@ namespace dxvk { void opAdd( const DxbcInstruction& ins); + void opMad( + const DxbcInstruction& ins); + void opMul( const DxbcInstruction& ins);