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 DxsoCompiler::emitDot(
|
||||||
DxsoRegisterValue a,
|
DxsoRegisterValue a,
|
||||||
DxsoRegisterValue b) {
|
DxsoRegisterValue b) {
|
||||||
|
auto az = emitMulOperand(a, b);
|
||||||
|
auto bz = emitMulOperand(b, a);
|
||||||
|
|
||||||
DxsoRegisterValue dot;
|
DxsoRegisterValue dot;
|
||||||
dot.type = a.type;
|
dot.type = a.type;
|
||||||
dot.type.ccount = 1;
|
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;
|
return dot;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1865,15 +1911,15 @@ namespace dxvk {
|
|||||||
break;
|
break;
|
||||||
case DxsoOpcode::Mad:
|
case DxsoOpcode::Mad:
|
||||||
if (!m_moduleInfo.options.longMad) {
|
if (!m_moduleInfo.options.longMad) {
|
||||||
result.id = m_module.opFFma(typeId,
|
result.id = emitFma(
|
||||||
emitRegisterLoad(src[0], mask).id,
|
emitRegisterLoad(src[0], mask),
|
||||||
emitRegisterLoad(src[1], mask).id,
|
emitRegisterLoad(src[1], mask),
|
||||||
emitRegisterLoad(src[2], mask).id);
|
emitRegisterLoad(src[2], mask)).id;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result.id = m_module.opFMul(typeId,
|
result.id = emitMul(
|
||||||
emitRegisterLoad(src[0], mask).id,
|
emitRegisterLoad(src[0], mask),
|
||||||
emitRegisterLoad(src[1], mask).id);
|
emitRegisterLoad(src[1], mask)).id;
|
||||||
|
|
||||||
result.id = m_module.opFAdd(typeId,
|
result.id = m_module.opFAdd(typeId,
|
||||||
result.id,
|
result.id,
|
||||||
@ -1881,9 +1927,9 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DxsoOpcode::Mul:
|
case DxsoOpcode::Mul:
|
||||||
result.id = m_module.opFMul(typeId,
|
result.id = emitMul(
|
||||||
emitRegisterLoad(src[0], mask).id,
|
emitRegisterLoad(src[0], mask),
|
||||||
emitRegisterLoad(src[1], mask).id);
|
emitRegisterLoad(src[1], mask)).id;
|
||||||
break;
|
break;
|
||||||
case DxsoOpcode::Rcp:
|
case DxsoOpcode::Rcp:
|
||||||
result.id = m_module.opFDiv(typeId,
|
result.id = m_module.opFDiv(typeId,
|
||||||
|
@ -545,6 +545,19 @@ namespace dxvk {
|
|||||||
DxsoRegisterValue emitSaturate(
|
DxsoRegisterValue emitSaturate(
|
||||||
DxsoRegisterValue srcValue);
|
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 emitDot(
|
||||||
DxsoRegisterValue a,
|
DxsoRegisterValue a,
|
||||||
DxsoRegisterValue b);
|
DxsoRegisterValue b);
|
||||||
|
Loading…
Reference in New Issue
Block a user