mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-13 16:08:50 +01:00
[dxso] Correctly handle multiplication by zero
This commit is contained in:
parent
804eca9cad
commit
ebc5326ed5
@ -1436,15 +1436,61 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
DxsoRegisterValue DxsoCompiler::emitMulOperand(
|
||||
DxsoRegisterValue operand,
|
||||
DxsoRegisterValue other) {
|
||||
if (!m_moduleInfo.options.d3d9FloatEmulation)
|
||||
return operand;
|
||||
|
||||
uint32_t boolId = getVectorTypeId({ DxsoScalarType::Bool, other.type.ccount });
|
||||
uint32_t zeroId = m_module.constfReplicant(0.0f, other.type.ccount);
|
||||
|
||||
DxsoRegisterValue result;
|
||||
result.type = operand.type;
|
||||
result.id = m_module.opSelect(getVectorTypeId(result.type),
|
||||
m_module.opFOrdEqual(boolId, other.id, zeroId), zeroId, operand.id);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
DxsoRegisterValue DxsoCompiler::emitMul(
|
||||
DxsoRegisterValue a,
|
||||
DxsoRegisterValue b) {
|
||||
auto az = emitMulOperand(a, b);
|
||||
auto bz = emitMulOperand(b, a);
|
||||
|
||||
DxsoRegisterValue result;
|
||||
result.type = a.type;
|
||||
result.id = m_module.opFMul(getVectorTypeId(result.type), az.id, bz.id);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
DxsoRegisterValue DxsoCompiler::emitFma(
|
||||
DxsoRegisterValue a,
|
||||
DxsoRegisterValue b,
|
||||
DxsoRegisterValue c) {
|
||||
auto az = emitMulOperand(a, b);
|
||||
auto bz = emitMulOperand(b, a);
|
||||
|
||||
DxsoRegisterValue result;
|
||||
result.type = a.type;
|
||||
result.id = m_module.opFFma(getVectorTypeId(result.type), az.id, bz.id, c.id);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
DxsoRegisterValue DxsoCompiler::emitDot(
|
||||
DxsoRegisterValue a,
|
||||
DxsoRegisterValue b) {
|
||||
auto az = emitMulOperand(a, b);
|
||||
auto bz = emitMulOperand(b, a);
|
||||
|
||||
DxsoRegisterValue dot;
|
||||
dot.type = a.type;
|
||||
dot.type.ccount = 1;
|
||||
|
||||
dot.id = m_module.opDot(getVectorTypeId(dot.type), a.id, b.id);
|
||||
|
||||
dot.id = m_module.opDot(getVectorTypeId(dot.type), az.id, bz.id);
|
||||
return dot;
|
||||
}
|
||||
|
||||
@ -1865,15 +1911,15 @@ namespace dxvk {
|
||||
break;
|
||||
case DxsoOpcode::Mad:
|
||||
if (!m_moduleInfo.options.longMad) {
|
||||
result.id = m_module.opFFma(typeId,
|
||||
emitRegisterLoad(src[0], mask).id,
|
||||
emitRegisterLoad(src[1], mask).id,
|
||||
emitRegisterLoad(src[2], mask).id);
|
||||
result.id = emitFma(
|
||||
emitRegisterLoad(src[0], mask),
|
||||
emitRegisterLoad(src[1], mask),
|
||||
emitRegisterLoad(src[2], mask)).id;
|
||||
}
|
||||
else {
|
||||
result.id = m_module.opFMul(typeId,
|
||||
emitRegisterLoad(src[0], mask).id,
|
||||
emitRegisterLoad(src[1], mask).id);
|
||||
result.id = emitMul(
|
||||
emitRegisterLoad(src[0], mask),
|
||||
emitRegisterLoad(src[1], mask)).id;
|
||||
|
||||
result.id = m_module.opFAdd(typeId,
|
||||
result.id,
|
||||
@ -1881,9 +1927,9 @@ namespace dxvk {
|
||||
}
|
||||
break;
|
||||
case DxsoOpcode::Mul:
|
||||
result.id = m_module.opFMul(typeId,
|
||||
emitRegisterLoad(src[0], mask).id,
|
||||
emitRegisterLoad(src[1], mask).id);
|
||||
result.id = emitMul(
|
||||
emitRegisterLoad(src[0], mask),
|
||||
emitRegisterLoad(src[1], mask)).id;
|
||||
break;
|
||||
case DxsoOpcode::Rcp:
|
||||
result.id = m_module.opFDiv(typeId,
|
||||
|
@ -545,6 +545,19 @@ namespace dxvk {
|
||||
DxsoRegisterValue emitSaturate(
|
||||
DxsoRegisterValue srcValue);
|
||||
|
||||
DxsoRegisterValue emitMulOperand(
|
||||
DxsoRegisterValue operand,
|
||||
DxsoRegisterValue other);
|
||||
|
||||
DxsoRegisterValue emitMul(
|
||||
DxsoRegisterValue a,
|
||||
DxsoRegisterValue b);
|
||||
|
||||
DxsoRegisterValue emitFma(
|
||||
DxsoRegisterValue a,
|
||||
DxsoRegisterValue b,
|
||||
DxsoRegisterValue c);
|
||||
|
||||
DxsoRegisterValue emitDot(
|
||||
DxsoRegisterValue a,
|
||||
DxsoRegisterValue b);
|
||||
|
Loading…
Reference in New Issue
Block a user