[dxbc] Implemented GatherPo and GatherPoC instructions

This commit is contained in:
Philip Rebohle 2018-02-04 17:40:02 +01:00
parent 49f13cfdc4
commit d0201a1bab
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
4 changed files with 109 additions and 7 deletions

View File

@ -2436,11 +2436,16 @@ namespace dxvk {
// (src2) The sampler, with a component selector
// Gather4C takes the following additional operand:
// (src3) The depth reference value
// The Gather4Po variants take an additional operand
// which defines an extended constant offset.
// TODO reduce code duplication by moving some common code
// in both sample() and gather() into separate methods
const bool isExtendedGather = ins.op == DxbcOpcode::Gather4Po
|| ins.op == DxbcOpcode::Gather4PoC;
const DxbcRegister& texCoordReg = ins.src[0];
const DxbcRegister& textureReg = ins.src[1];
const DxbcRegister& samplerReg = ins.src[2];
const DxbcRegister& textureReg = ins.src[1 + isExtendedGather];
const DxbcRegister& samplerReg = ins.src[2 + isExtendedGather];
// Texture and sampler register IDs
const uint32_t textureId = textureReg.idx[0].offset;
@ -2459,10 +2464,12 @@ namespace dxvk {
DxbcRegisterValue coord = emitRegisterLoad(texCoordReg, coordArrayMask);
// Load reference value for depth-compare operations
const bool isDepthCompare = ins.op == DxbcOpcode::Gather4C;
const bool isDepthCompare = ins.op == DxbcOpcode::Gather4C
|| ins.op == DxbcOpcode::Gather4PoC;
const DxbcRegisterValue referenceValue = isDepthCompare
? emitRegisterLoad(ins.src[3], DxbcRegMask(true, false, false, false))
? emitRegisterLoad(ins.src[3 + isExtendedGather],
DxbcRegMask(true, false, false, false))
: DxbcRegisterValue();
if (isDepthCompare && m_options.packDrefValueIntoCoordinates) {
@ -2484,7 +2491,15 @@ namespace dxvk {
// Accumulate additional image operands.
SpirvImageOperands imageOperands;
if (ins.sampleControls.u != 0 || ins.sampleControls.v != 0 || ins.sampleControls.w != 0) {
if (isExtendedGather) {
m_module.enableCapability(spv::CapabilityImageGatherExtended);
DxbcRegisterValue gatherOffset = emitRegisterLoad(
ins.src[1], DxbcRegMask::firstN(imageLayerDim));
imageOperands.flags |= spv::ImageOperandsOffsetMask;
imageOperands.gOffset = gatherOffset.id;
} else if (ins.sampleControls.u != 0 || ins.sampleControls.v != 0 || ins.sampleControls.w != 0) {
const std::array<uint32_t, 3> offsetIds = {
imageLayerDim >= 1 ? m_module.consti32(ins.sampleControls.u) : 0,
imageLayerDim >= 2 ? m_module.consti32(ins.sampleControls.v) : 0,

View File

@ -600,9 +600,22 @@ namespace dxvk {
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
} },
/* Gather4Po */
{ },
{ 5, DxbcInstClass::TextureGather, {
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Sint32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
} },
/* Gather4PoC */
{ },
{ 6, DxbcInstClass::TextureGather, {
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Sint32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
} },
/* Rcp */
{ 2, DxbcInstClass::VectorAlu, {
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },

View File

@ -933,6 +933,64 @@ namespace dxvk {
}
uint32_t SpirvModule::opBitCount(
uint32_t resultType,
uint32_t operand) {
uint32_t resultId = this->allocateId();
m_code.putIns (spv::OpBitCount, 4);
m_code.putWord(resultType);
m_code.putWord(resultId);
m_code.putWord(operand);
return resultId;
}
uint32_t SpirvModule::opFindILsb(
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::GLSLstd450FindILsb);
m_code.putWord(operand);
return resultId;
}
uint32_t SpirvModule::opFindUMsb(
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::GLSLstd450FindUMsb);
m_code.putWord(operand);
return resultId;
}
uint32_t SpirvModule::opFindSMsb(
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::GLSLstd450FindSMsb);
m_code.putWord(operand);
return resultId;
}
uint32_t SpirvModule::opBitFieldInsert(
uint32_t resultType,
uint32_t base,

View File

@ -377,6 +377,22 @@ namespace dxvk {
uint32_t resultType,
uint32_t operand);
uint32_t opBitCount(
uint32_t resultType,
uint32_t operand);
uint32_t opFindILsb(
uint32_t resultType,
uint32_t operand);
uint32_t opFindUMsb(
uint32_t resultType,
uint32_t operand);
uint32_t opFindSMsb(
uint32_t resultType,
uint32_t operand);
uint32_t opBitFieldInsert(
uint32_t resultType,
uint32_t base,