diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 3f595461..87a5343c 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -41,6 +41,9 @@ namespace dxvk { case DxbcOpcode::Add: return this->opAdd(ins); + case DxbcOpcode::Mul: + return this->opMul(ins); + case DxbcOpcode::Mov: return this->opMov(ins); @@ -164,6 +167,20 @@ namespace dxvk { } + void DxbcCompiler::opMul(const DxbcInstruction& ins) { + auto dstOp = ins.operand(0); + auto srcOp1 = ins.operand(dstOp.length()); + auto srcOp2 = ins.operand(dstOp.length() + srcOp1.length()); + DxbcComponentMask mask = this->getDstOperandMask(dstOp); + + DxbcValue src1 = this->loadOperand(srcOp1, mask, DxbcScalarType::Float32); + DxbcValue src2 = this->loadOperand(srcOp2, mask, DxbcScalarType::Float32); + DxbcValue val = m_gen->opMul(src1, src2); + val = this->applyResultModifiers(val, ins.token().control()); + this->storeOperand(dstOp, val, mask); + } + + void DxbcCompiler::opDpx(const DxbcInstruction& ins, uint32_t n) { 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 adf6630f..c9b75f7f 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -44,6 +44,9 @@ namespace dxvk { void opAdd( const DxbcInstruction& ins); + void opMul( + const DxbcInstruction& ins); + void opDpx( const DxbcInstruction& ins, uint32_t n); diff --git a/src/dxbc/gen/dxbc_gen_common.cpp b/src/dxbc/gen/dxbc_gen_common.cpp index c5d5e65b..0530b5a3 100644 --- a/src/dxbc/gen/dxbc_gen_common.cpp +++ b/src/dxbc/gen/dxbc_gen_common.cpp @@ -183,6 +183,32 @@ namespace dxvk { } + DxbcValue DxbcCodeGen::opMul(const DxbcValue& a, const DxbcValue& b) { + DxbcValue result; + result.type = a.type; + + switch (result.type.componentType) { + case DxbcScalarType::Sint32: + case DxbcScalarType::Sint64: + case DxbcScalarType::Uint32: + case DxbcScalarType::Uint64: + result.valueId = m_module.opIMul( + this->defValueType(result.type), + a.valueId, b.valueId); + break; + + case DxbcScalarType::Float32: + case DxbcScalarType::Float64: + result.valueId = m_module.opFMul( + this->defValueType(result.type), + a.valueId, b.valueId); + break; + } + + return result; + } + + DxbcValue DxbcCodeGen::opDot(const DxbcValue& a, const DxbcValue& b) { DxbcValue result; result.type = DxbcValueType(a.type.componentType, 1); diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index 6e67674b..49638813 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -722,6 +722,21 @@ namespace dxvk { } + uint32_t SpirvModule::opIMul( + uint32_t resultType, + uint32_t a, + uint32_t b) { + uint32_t resultId = this->allocateId(); + + m_code.putIns (spv::OpIMul, 5); + m_code.putWord(resultType); + m_code.putWord(resultId); + m_code.putWord(a); + m_code.putWord(b); + return resultId; + } + + uint32_t SpirvModule::opFMul( uint32_t resultType, uint32_t a, diff --git a/src/spirv/spirv_module.h b/src/spirv/spirv_module.h index 34b412c0..14eebaad 100644 --- a/src/spirv/spirv_module.h +++ b/src/spirv/spirv_module.h @@ -260,6 +260,11 @@ namespace dxvk { uint32_t a, uint32_t b); + uint32_t opIMul( + uint32_t resultType, + uint32_t a, + uint32_t b); + uint32_t opFMul( uint32_t resultType, uint32_t a,