mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-02 01:24:11 +01:00
[dxbc] Fix up incorrect infinity returned by f32tof16
Completely insane fix for #1826.
This commit is contained in:
parent
d0cdd79dd2
commit
61a07fc9b9
@ -2924,16 +2924,37 @@ namespace dxvk {
|
||||
1, &zeroIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Store result in the destination register
|
||||
|
||||
DxbcRegisterValue result;
|
||||
result.type.ctype = ins.dst[0].dataType;
|
||||
result.type.ccount = componentCount;
|
||||
|
||||
uint32_t typeId = getVectorTypeId(result.type);
|
||||
result.id = componentCount > 1
|
||||
? m_module.opCompositeConstruct(
|
||||
getVectorTypeId(result.type),
|
||||
? m_module.opCompositeConstruct(typeId,
|
||||
componentCount, scalarIds.data())
|
||||
: 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);
|
||||
}
|
||||
|
||||
|
@ -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 resultType,
|
||||
uint32_t functionId,
|
||||
|
@ -998,6 +998,10 @@ namespace dxvk {
|
||||
uint32_t resultType,
|
||||
uint32_t operand);
|
||||
|
||||
uint32_t opIsInf(
|
||||
uint32_t resultType,
|
||||
uint32_t operand);
|
||||
|
||||
uint32_t opFunctionCall(
|
||||
uint32_t resultType,
|
||||
uint32_t functionId,
|
||||
|
Loading…
Reference in New Issue
Block a user