mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-11 10:24:10 +01:00
[dxbc] Fix up incorrect infinity returned by f32tof16
Completely insane fix for #1826.
This commit is contained in:
parent
d0cdd79dd2
commit
61a07fc9b9
@ -2925,15 +2925,36 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store result in the destination register
|
|
||||||
DxbcRegisterValue result;
|
DxbcRegisterValue result;
|
||||||
result.type.ctype = ins.dst[0].dataType;
|
result.type.ctype = ins.dst[0].dataType;
|
||||||
result.type.ccount = componentCount;
|
result.type.ccount = componentCount;
|
||||||
|
|
||||||
|
uint32_t typeId = getVectorTypeId(result.type);
|
||||||
result.id = componentCount > 1
|
result.id = componentCount > 1
|
||||||
? m_module.opCompositeConstruct(
|
? m_module.opCompositeConstruct(typeId,
|
||||||
getVectorTypeId(result.type),
|
|
||||||
componentCount, scalarIds.data())
|
componentCount, scalarIds.data())
|
||||||
: scalarIds[0];
|
: scalarIds[0];
|
||||||
|
|
||||||
|
if (isPack) {
|
||||||
|
// Some drivers return infinity if the input value is above a certain
|
||||||
|
// threshold, but D3D wants us to return infinity only if the input is
|
||||||
|
// actually infinite. Fix this up to return the maximum representable
|
||||||
|
// 16-bit floating point number instead, but preserve input infinity.
|
||||||
|
uint32_t t_bvec = getVectorTypeId({ DxbcScalarType::Bool, componentCount });
|
||||||
|
uint32_t f16Infinity = m_module.constuReplicant(0x7C00, componentCount);
|
||||||
|
uint32_t f16Unsigned = m_module.constuReplicant(0x7FFF, componentCount);
|
||||||
|
|
||||||
|
uint32_t isInputInf = m_module.opIsInf(t_bvec, src.id);
|
||||||
|
uint32_t isValueInf = m_module.opIEqual(t_bvec, f16Infinity,
|
||||||
|
m_module.opBitwiseAnd(typeId, result.id, f16Unsigned));
|
||||||
|
|
||||||
|
result.id = m_module.opSelect(getVectorTypeId(result.type),
|
||||||
|
m_module.opLogicalAnd(t_bvec, isValueInf, m_module.opLogicalNot(t_bvec, isInputInf)),
|
||||||
|
m_module.opISub(typeId, result.id, m_module.constuReplicant(1, componentCount)),
|
||||||
|
result.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store result in the destination register
|
||||||
emitRegisterStore(ins.dst[0], result);
|
emitRegisterStore(ins.dst[0], result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2912,6 +2912,19 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t SpirvModule::opIsInf(
|
||||||
|
uint32_t resultType,
|
||||||
|
uint32_t operand) {
|
||||||
|
uint32_t resultId = this->allocateId();
|
||||||
|
|
||||||
|
m_code.putIns (spv::OpIsInf, 4);
|
||||||
|
m_code.putWord(resultType);
|
||||||
|
m_code.putWord(resultId);
|
||||||
|
m_code.putWord(operand);
|
||||||
|
return resultId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t SpirvModule::opFunctionCall(
|
uint32_t SpirvModule::opFunctionCall(
|
||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t functionId,
|
uint32_t functionId,
|
||||||
|
@ -998,6 +998,10 @@ namespace dxvk {
|
|||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t operand);
|
uint32_t operand);
|
||||||
|
|
||||||
|
uint32_t opIsInf(
|
||||||
|
uint32_t resultType,
|
||||||
|
uint32_t operand);
|
||||||
|
|
||||||
uint32_t opFunctionCall(
|
uint32_t opFunctionCall(
|
||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t functionId,
|
uint32_t functionId,
|
||||||
|
Loading…
Reference in New Issue
Block a user