1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-11-29 19: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:
Philip Rebohle 2017-12-29 19:26:59 +01:00
parent 2e215e24e5
commit 298eeedcc4
5 changed files with 174 additions and 19 deletions

View File

@ -963,6 +963,11 @@ namespace dxvk {
typeId, src.at(0).id); typeId, src.at(0).id);
break; break;
case DxbcOpcode::Frc:
dst.id = m_module.opFract(
typeId, src.at(0).id);
break;
case DxbcOpcode::Log: case DxbcOpcode::Log:
dst.id = m_module.opLog2( dst.id = m_module.opLog2(
typeId, src.at(0).id); typeId, src.at(0).id);
@ -974,12 +979,12 @@ namespace dxvk {
break; break;
case DxbcOpcode::Max: case DxbcOpcode::Max:
dst.id = m_module.opFMax(typeId, dst.id = m_module.opNMax(typeId,
src.at(0).id, src.at(1).id); src.at(0).id, src.at(1).id);
break; break;
case DxbcOpcode::Min: case DxbcOpcode::Min:
dst.id = m_module.opFMin(typeId, dst.id = m_module.opNMin(typeId,
src.at(0).id, src.at(1).id); src.at(0).id, src.at(1).id);
break; break;
@ -988,8 +993,23 @@ namespace dxvk {
src.at(0).id, src.at(1).id); src.at(0).id, src.at(1).id);
break; break;
case DxbcOpcode::Sqrt: case DxbcOpcode::RoundNe:
dst.id = m_module.opSqrt( 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); typeId, src.at(0).id);
break; break;
@ -998,6 +1018,11 @@ namespace dxvk {
typeId, src.at(0).id); typeId, src.at(0).id);
break; break;
case DxbcOpcode::Sqrt:
dst.id = m_module.opSqrt(
typeId, src.at(0).id);
break;
///////////////////////////////////// /////////////////////////////////////
// ALU operations on signed integers // ALU operations on signed integers
case DxbcOpcode::IAdd: case DxbcOpcode::IAdd:
@ -2419,7 +2444,7 @@ namespace dxvk {
if (value.type.ctype == DxbcScalarType::Float32) { if (value.type.ctype == DxbcScalarType::Float32) {
// Saturating only makes sense on floats // Saturating only makes sense on floats
if (modifiers.saturate) { if (modifiers.saturate) {
value.id = m_module.opFClamp( value.id = m_module.opNClamp(
typeId, value.id, typeId, value.id,
m_module.constf32(0.0f), m_module.constf32(0.0f),
m_module.constf32(1.0f)); m_module.constf32(1.0f));

View File

@ -103,7 +103,10 @@ namespace dxvk {
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
} }, } },
/* Frc */ /* Frc */
{ }, { 2, DxbcInstClass::VectorAlu, {
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
} },
/* FtoI */ /* FtoI */
{ 2, DxbcInstClass::VectorAlu, { { 2, DxbcInstClass::VectorAlu, {
{ DxbcOperandKind::DstReg, DxbcScalarType::Sint32 }, { DxbcOperandKind::DstReg, DxbcScalarType::Sint32 },
@ -296,13 +299,25 @@ namespace dxvk {
{ DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 }, { DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 },
} }, } },
/* RoundNe */ /* RoundNe */
{ }, { 2, DxbcInstClass::VectorAlu, {
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
} },
/* RoundNi */ /* RoundNi */
{ }, { 2, DxbcInstClass::VectorAlu, {
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
} },
/* RoundPi */ /* RoundPi */
{ }, { 2, DxbcInstClass::VectorAlu, {
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
} },
/* RoundZ */ /* RoundZ */
{ }, { 2, DxbcInstClass::VectorAlu, {
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
} },
/* Rsq */ /* Rsq */
{ 2, DxbcInstClass::VectorAlu, { { 2, DxbcInstClass::VectorAlu, {
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, { DxbcOperandKind::DstReg, DxbcScalarType::Float32 },

View File

@ -66,6 +66,7 @@ namespace dxvk {
TRACE(this); TRACE(this);
// We do not release the SDL window handle here since // We do not release the SDL window handle here since
// that would destroy the underlying window as well. // that would destroy the underlying window as well.
SDL_DestroyWindow(m_window);
} }

View File

@ -1151,7 +1151,7 @@ namespace dxvk {
} }
uint32_t SpirvModule::opFMax( uint32_t SpirvModule::opNMax(
uint32_t resultType, uint32_t resultType,
uint32_t a, uint32_t a,
uint32_t b) { uint32_t b) {
@ -1161,14 +1161,14 @@ namespace dxvk {
m_code.putWord(resultType); m_code.putWord(resultType);
m_code.putWord(resultId); m_code.putWord(resultId);
m_code.putWord(m_instExtGlsl450); m_code.putWord(m_instExtGlsl450);
m_code.putWord(spv::GLSLstd450FMax); m_code.putWord(spv::GLSLstd450NMax);
m_code.putWord(a); m_code.putWord(a);
m_code.putWord(b); m_code.putWord(b);
return resultId; return resultId;
} }
uint32_t SpirvModule::opFMin( uint32_t SpirvModule::opNMin(
uint32_t resultType, uint32_t resultType,
uint32_t a, uint32_t a,
uint32_t b) { uint32_t b) {
@ -1178,7 +1178,7 @@ namespace dxvk {
m_code.putWord(resultType); m_code.putWord(resultType);
m_code.putWord(resultId); m_code.putWord(resultId);
m_code.putWord(m_instExtGlsl450); m_code.putWord(m_instExtGlsl450);
m_code.putWord(spv::GLSLstd450FMin); m_code.putWord(spv::GLSLstd450NMin);
m_code.putWord(a); m_code.putWord(a);
m_code.putWord(b); m_code.putWord(b);
return resultId; return resultId;
@ -1253,7 +1253,7 @@ namespace dxvk {
} }
uint32_t SpirvModule::opFClamp( uint32_t SpirvModule::opNClamp(
uint32_t resultType, uint32_t resultType,
uint32_t x, uint32_t x,
uint32_t minVal, uint32_t minVal,
@ -1264,7 +1264,7 @@ namespace dxvk {
m_code.putWord(resultType); m_code.putWord(resultType);
m_code.putWord(resultId); m_code.putWord(resultId);
m_code.putWord(m_instExtGlsl450); m_code.putWord(m_instExtGlsl450);
m_code.putWord(spv::GLSLstd450FClamp); m_code.putWord(spv::GLSLstd450NClamp);
m_code.putWord(x); m_code.putWord(x);
m_code.putWord(minVal); m_code.putWord(minVal);
m_code.putWord(maxVal); 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 SpirvModule::opSelect(
uint32_t resultType, uint32_t resultType,
uint32_t condition, uint32_t condition,

View File

@ -413,12 +413,12 @@ namespace dxvk {
uint32_t b, uint32_t b,
uint32_t c); uint32_t c);
uint32_t opFMax( uint32_t opNMax(
uint32_t resultType, uint32_t resultType,
uint32_t a, uint32_t a,
uint32_t b); uint32_t b);
uint32_t opFMin( uint32_t opNMin(
uint32_t resultType, uint32_t resultType,
uint32_t a, uint32_t a,
uint32_t b); uint32_t b);
@ -443,7 +443,7 @@ namespace dxvk {
uint32_t a, uint32_t a,
uint32_t b); uint32_t b);
uint32_t opFClamp( uint32_t opNClamp(
uint32_t resultType, uint32_t resultType,
uint32_t x, uint32_t x,
uint32_t minVal, uint32_t minVal,
@ -558,6 +558,30 @@ namespace dxvk {
uint32_t resultType, uint32_t resultType,
uint32_t operand); 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 opSelect(
uint32_t resultType, uint32_t resultType,
uint32_t condition, uint32_t condition,