[dxbc] Implemented SinCos, Min and Max instructions

This commit is contained in:
Philip Rebohle 2017-12-13 16:35:01 +01:00
parent 464a3e7d4e
commit a4eb807215
6 changed files with 168 additions and 3 deletions

View File

@ -61,6 +61,7 @@ namespace dxvk {
case DxbcInstClass::TextureSample: return this->handleTextureSample(parsedInst);
case DxbcInstClass::VectorAlu: return this->handleVectorAlu (parsedInst);
case DxbcInstClass::VectorDot: return this->handleVectorDot (parsedInst);
case DxbcInstClass::VectorSinCos: return this->handleVectorSinCos (parsedInst);
default: return DxbcError::eUnhandledOpcode;
}
}
@ -676,6 +677,20 @@ namespace dxvk {
arguments[2].valueId);
break;
case DxbcOpcode::Max:
result.valueId = m_module.opFMax(
resultTypeId,
arguments[0].valueId,
arguments[1].valueId);
break;
case DxbcOpcode::Min:
result.valueId = m_module.opFMin(
resultTypeId,
arguments[0].valueId,
arguments[1].valueId);
break;
case DxbcOpcode::Mov:
result.valueId = arguments[0].valueId;
break;
@ -747,6 +762,58 @@ namespace dxvk {
}
DxbcError DxbcCompiler2::handleVectorSinCos(const DxbcInst& ins) {
// sincos has three operands:
// (1) Destination register for sin(x)
// (2) Destination register for cos(x)
// (3) Source operand x
const DxbcInstOp dstSinOp = ins.operands[0];
const DxbcInstOp dstCosOp = ins.operands[1];
const DxbcInstOp srcOp = ins.operands[2];
// Load source operand as 32-bit float vector
const DxbcValue2 srcValue = this->loadOp(srcOp,
DxbcRegMask(true, true, true, true),
DxbcScalarType::Float32);
// Either output may be DxbcOperandType::Null, in
// which case we don't have to generate any code
if (dstSinOp.type != DxbcOperandType::Null) {
const DxbcValue2 sinInput = this->extractReg(
srcValue, dstSinOp.mask);
DxbcValue2 sinValue;
sinValue.componentType = srcValue.componentType;
sinValue.componentCount = srcValue.componentCount;
sinValue.valueId = m_module.opSin(
this->defineVectorType(
sinInput.componentType,
sinInput.componentCount),
sinInput.valueId);
this->storeOp(dstSinOp, sinValue);
}
if (dstCosOp.type != DxbcOperandType::Null) {
const DxbcValue2 cosInput = this->extractReg(
srcValue, dstCosOp.mask);
DxbcValue2 cosValue;
cosValue.componentType = srcValue.componentType;
cosValue.componentCount = srcValue.componentCount;
cosValue.valueId = m_module.opCos(
this->defineVectorType(
cosInput.componentType,
cosInput.componentCount),
cosInput.valueId);
this->storeOp(dstCosOp, cosValue);
}
return DxbcError::sOk;
}
DxbcValue2 DxbcCompiler2::bitcastReg(
const DxbcValue2& src,
DxbcScalarType type) {

View File

@ -280,6 +280,9 @@ namespace dxvk {
DxbcError handleVectorDot(
const DxbcInst& ins);
DxbcError handleVectorSinCos(
const DxbcInst& ins);
///////////////////////
// Declaration methods
DxbcError declareGlobalFlags(

View File

@ -127,9 +127,17 @@ namespace dxvk {
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
} },
/* Min */
{ },
{ 3, DxbcInstClass::VectorAlu, {
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
} },
/* Max */
{ },
{ 3, DxbcInstClass::VectorAlu, {
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
} },
/* CustomData */
{ },
/* Mov */
@ -194,7 +202,11 @@ namespace dxvk {
/* Switch */
{ },
/* SinCos */
{ },
{ 3, DxbcInstClass::VectorSinCos, {
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
} },
/* UDiv */
{ },
/* ULt */

View File

@ -20,6 +20,7 @@ namespace dxvk {
VectorAlu, ///< Component-wise vector instructions
VectorCmp, ///< Component-wise vector comparison
VectorDot, ///< Dot product instruction
VectorSinCos, ///< Sine and Cosine instruction
ControlFlow, ///< Control flow instructions
Undefined, ///< Instruction code not defined
};

View File

@ -785,6 +785,40 @@ namespace dxvk {
m_code.putWord(c);
return resultId;
}
uint32_t SpirvModule::opFMax(
uint32_t resultType,
uint32_t a,
uint32_t b) {
uint32_t resultId = this->allocateId();
m_code.putIns (spv::OpExtInst, 7);
m_code.putWord(resultType);
m_code.putWord(resultId);
m_code.putWord(m_instExtGlsl450);
m_code.putWord(spv::GLSLstd450FMax);
m_code.putWord(a);
m_code.putWord(b);
return resultId;
}
uint32_t SpirvModule::opFMin(
uint32_t resultType,
uint32_t a,
uint32_t b) {
uint32_t resultId = this->allocateId();
m_code.putIns (spv::OpExtInst, 7);
m_code.putWord(resultType);
m_code.putWord(resultId);
m_code.putWord(m_instExtGlsl450);
m_code.putWord(spv::GLSLstd450FMin);
m_code.putWord(a);
m_code.putWord(b);
return resultId;
}
uint32_t SpirvModule::opFClamp(
@ -821,6 +855,36 @@ namespace dxvk {
}
uint32_t SpirvModule::opSin(
uint32_t resultType,
uint32_t vector) {
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::GLSLstd450Sin);
m_code.putWord(vector);
return resultId;
}
uint32_t SpirvModule::opCos(
uint32_t resultType,
uint32_t vector) {
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::GLSLstd450Cos);
m_code.putWord(vector);
return resultId;
}
uint32_t SpirvModule::opInverseSqrt(
uint32_t resultType,
uint32_t x) {

View File

@ -281,6 +281,16 @@ namespace dxvk {
uint32_t b,
uint32_t c);
uint32_t opFMax(
uint32_t resultType,
uint32_t a,
uint32_t b);
uint32_t opFMin(
uint32_t resultType,
uint32_t a,
uint32_t b);
uint32_t opFClamp(
uint32_t resultType,
uint32_t x,
@ -292,6 +302,14 @@ namespace dxvk {
uint32_t vector1,
uint32_t vector2);
uint32_t opSin(
uint32_t resultType,
uint32_t vector);
uint32_t opCos(
uint32_t resultType,
uint32_t vector);
uint32_t opInverseSqrt(
uint32_t resultType,
uint32_t x);