mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-29 17:52:18 +01:00
[dxbc] Implemented SinCos, Min and Max instructions
This commit is contained in:
parent
464a3e7d4e
commit
a4eb807215
@ -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) {
|
||||
|
@ -280,6 +280,9 @@ namespace dxvk {
|
||||
DxbcError handleVectorDot(
|
||||
const DxbcInst& ins);
|
||||
|
||||
DxbcError handleVectorSinCos(
|
||||
const DxbcInst& ins);
|
||||
|
||||
///////////////////////
|
||||
// Declaration methods
|
||||
DxbcError declareGlobalFlags(
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user