mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-11-29 10:24:10 +01:00
[dxbc] Implemented round instructions
Also fixed potential numerical stability issues in with min/max instructions and saturation when an operand is NaN.
This commit is contained in:
parent
2e215e24e5
commit
298eeedcc4
@ -963,6 +963,11 @@ namespace dxvk {
|
||||
typeId, src.at(0).id);
|
||||
break;
|
||||
|
||||
case DxbcOpcode::Frc:
|
||||
dst.id = m_module.opFract(
|
||||
typeId, src.at(0).id);
|
||||
break;
|
||||
|
||||
case DxbcOpcode::Log:
|
||||
dst.id = m_module.opLog2(
|
||||
typeId, src.at(0).id);
|
||||
@ -974,12 +979,12 @@ namespace dxvk {
|
||||
break;
|
||||
|
||||
case DxbcOpcode::Max:
|
||||
dst.id = m_module.opFMax(typeId,
|
||||
dst.id = m_module.opNMax(typeId,
|
||||
src.at(0).id, src.at(1).id);
|
||||
break;
|
||||
|
||||
case DxbcOpcode::Min:
|
||||
dst.id = m_module.opFMin(typeId,
|
||||
dst.id = m_module.opNMin(typeId,
|
||||
src.at(0).id, src.at(1).id);
|
||||
break;
|
||||
|
||||
@ -988,8 +993,23 @@ namespace dxvk {
|
||||
src.at(0).id, src.at(1).id);
|
||||
break;
|
||||
|
||||
case DxbcOpcode::Sqrt:
|
||||
dst.id = m_module.opSqrt(
|
||||
case DxbcOpcode::RoundNe:
|
||||
dst.id = m_module.opRoundEven(
|
||||
typeId, src.at(0).id);
|
||||
break;
|
||||
|
||||
case DxbcOpcode::RoundNi:
|
||||
dst.id = m_module.opFloor(
|
||||
typeId, src.at(0).id);
|
||||
break;
|
||||
|
||||
case DxbcOpcode::RoundPi:
|
||||
dst.id = m_module.opCeil(
|
||||
typeId, src.at(0).id);
|
||||
break;
|
||||
|
||||
case DxbcOpcode::RoundZ:
|
||||
dst.id = m_module.opTrunc(
|
||||
typeId, src.at(0).id);
|
||||
break;
|
||||
|
||||
@ -998,6 +1018,11 @@ namespace dxvk {
|
||||
typeId, src.at(0).id);
|
||||
break;
|
||||
|
||||
case DxbcOpcode::Sqrt:
|
||||
dst.id = m_module.opSqrt(
|
||||
typeId, src.at(0).id);
|
||||
break;
|
||||
|
||||
/////////////////////////////////////
|
||||
// ALU operations on signed integers
|
||||
case DxbcOpcode::IAdd:
|
||||
@ -2419,7 +2444,7 @@ namespace dxvk {
|
||||
if (value.type.ctype == DxbcScalarType::Float32) {
|
||||
// Saturating only makes sense on floats
|
||||
if (modifiers.saturate) {
|
||||
value.id = m_module.opFClamp(
|
||||
value.id = m_module.opNClamp(
|
||||
typeId, value.id,
|
||||
m_module.constf32(0.0f),
|
||||
m_module.constf32(1.0f));
|
||||
|
@ -103,7 +103,10 @@ namespace dxvk {
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
|
||||
} },
|
||||
/* Frc */
|
||||
{ },
|
||||
{ 2, DxbcInstClass::VectorAlu, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
|
||||
} },
|
||||
/* FtoI */
|
||||
{ 2, DxbcInstClass::VectorAlu, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Sint32 },
|
||||
@ -296,13 +299,25 @@ namespace dxvk {
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
|
||||
} },
|
||||
/* RoundNe */
|
||||
{ },
|
||||
{ 2, DxbcInstClass::VectorAlu, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
|
||||
} },
|
||||
/* RoundNi */
|
||||
{ },
|
||||
{ 2, DxbcInstClass::VectorAlu, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
|
||||
} },
|
||||
/* RoundPi */
|
||||
{ },
|
||||
{ 2, DxbcInstClass::VectorAlu, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
|
||||
} },
|
||||
/* RoundZ */
|
||||
{ },
|
||||
{ 2, DxbcInstClass::VectorAlu, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
|
||||
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
|
||||
} },
|
||||
/* Rsq */
|
||||
{ 2, DxbcInstClass::VectorAlu, {
|
||||
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
|
||||
|
@ -66,6 +66,7 @@ namespace dxvk {
|
||||
TRACE(this);
|
||||
// We do not release the SDL window handle here since
|
||||
// that would destroy the underlying window as well.
|
||||
SDL_DestroyWindow(m_window);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1151,7 +1151,7 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opFMax(
|
||||
uint32_t SpirvModule::opNMax(
|
||||
uint32_t resultType,
|
||||
uint32_t a,
|
||||
uint32_t b) {
|
||||
@ -1161,14 +1161,14 @@ namespace dxvk {
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(m_instExtGlsl450);
|
||||
m_code.putWord(spv::GLSLstd450FMax);
|
||||
m_code.putWord(spv::GLSLstd450NMax);
|
||||
m_code.putWord(a);
|
||||
m_code.putWord(b);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opFMin(
|
||||
uint32_t SpirvModule::opNMin(
|
||||
uint32_t resultType,
|
||||
uint32_t a,
|
||||
uint32_t b) {
|
||||
@ -1178,7 +1178,7 @@ namespace dxvk {
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(m_instExtGlsl450);
|
||||
m_code.putWord(spv::GLSLstd450FMin);
|
||||
m_code.putWord(spv::GLSLstd450NMin);
|
||||
m_code.putWord(a);
|
||||
m_code.putWord(b);
|
||||
return resultId;
|
||||
@ -1253,7 +1253,7 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opFClamp(
|
||||
uint32_t SpirvModule::opNClamp(
|
||||
uint32_t resultType,
|
||||
uint32_t x,
|
||||
uint32_t minVal,
|
||||
@ -1264,7 +1264,7 @@ namespace dxvk {
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(m_instExtGlsl450);
|
||||
m_code.putWord(spv::GLSLstd450FClamp);
|
||||
m_code.putWord(spv::GLSLstd450NClamp);
|
||||
m_code.putWord(x);
|
||||
m_code.putWord(minVal);
|
||||
m_code.putWord(maxVal);
|
||||
@ -1617,6 +1617,96 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opFract(
|
||||
uint32_t resultType,
|
||||
uint32_t operand) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpExtInst, 6);
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(m_instExtGlsl450);
|
||||
m_code.putWord(spv::GLSLstd450Fract);
|
||||
m_code.putWord(operand);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opCeil(
|
||||
uint32_t resultType,
|
||||
uint32_t operand) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpExtInst, 6);
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(m_instExtGlsl450);
|
||||
m_code.putWord(spv::GLSLstd450Ceil);
|
||||
m_code.putWord(operand);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opFloor(
|
||||
uint32_t resultType,
|
||||
uint32_t operand) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpExtInst, 6);
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(m_instExtGlsl450);
|
||||
m_code.putWord(spv::GLSLstd450Floor);
|
||||
m_code.putWord(operand);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opRound(
|
||||
uint32_t resultType,
|
||||
uint32_t operand) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpExtInst, 6);
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(m_instExtGlsl450);
|
||||
m_code.putWord(spv::GLSLstd450Round);
|
||||
m_code.putWord(operand);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opRoundEven(
|
||||
uint32_t resultType,
|
||||
uint32_t operand) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpExtInst, 6);
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(m_instExtGlsl450);
|
||||
m_code.putWord(spv::GLSLstd450RoundEven);
|
||||
m_code.putWord(operand);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opTrunc(
|
||||
uint32_t resultType,
|
||||
uint32_t operand) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpExtInst, 6);
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(m_instExtGlsl450);
|
||||
m_code.putWord(spv::GLSLstd450Trunc);
|
||||
m_code.putWord(operand);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::opSelect(
|
||||
uint32_t resultType,
|
||||
uint32_t condition,
|
||||
|
@ -413,12 +413,12 @@ namespace dxvk {
|
||||
uint32_t b,
|
||||
uint32_t c);
|
||||
|
||||
uint32_t opFMax(
|
||||
uint32_t opNMax(
|
||||
uint32_t resultType,
|
||||
uint32_t a,
|
||||
uint32_t b);
|
||||
|
||||
uint32_t opFMin(
|
||||
uint32_t opNMin(
|
||||
uint32_t resultType,
|
||||
uint32_t a,
|
||||
uint32_t b);
|
||||
@ -443,7 +443,7 @@ namespace dxvk {
|
||||
uint32_t a,
|
||||
uint32_t b);
|
||||
|
||||
uint32_t opFClamp(
|
||||
uint32_t opNClamp(
|
||||
uint32_t resultType,
|
||||
uint32_t x,
|
||||
uint32_t minVal,
|
||||
@ -558,6 +558,30 @@ namespace dxvk {
|
||||
uint32_t resultType,
|
||||
uint32_t operand);
|
||||
|
||||
uint32_t opFract(
|
||||
uint32_t resultType,
|
||||
uint32_t operand);
|
||||
|
||||
uint32_t opCeil(
|
||||
uint32_t resultType,
|
||||
uint32_t operand);
|
||||
|
||||
uint32_t opFloor(
|
||||
uint32_t resultType,
|
||||
uint32_t operand);
|
||||
|
||||
uint32_t opRound(
|
||||
uint32_t resultType,
|
||||
uint32_t operand);
|
||||
|
||||
uint32_t opRoundEven(
|
||||
uint32_t resultType,
|
||||
uint32_t operand);
|
||||
|
||||
uint32_t opTrunc(
|
||||
uint32_t resultType,
|
||||
uint32_t operand);
|
||||
|
||||
uint32_t opSelect(
|
||||
uint32_t resultType,
|
||||
uint32_t condition,
|
||||
|
Loading…
Reference in New Issue
Block a user