[dxbc] Implement EvalAttribute* instructions

This commit is contained in:
Philip Rebohle 2018-02-26 16:46:34 +01:00
parent e4292adf29
commit ec59389527
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
6 changed files with 135 additions and 5 deletions

View File

@ -85,6 +85,9 @@ namespace dxvk {
case DxbcInstClass::GeometryEmit:
return this->emitGeometryEmit(ins);
case DxbcInstClass::Interpolate:
return this->emitInterpolate(ins);
case DxbcInstClass::TextureQuery:
return this->emitTextureQuery(ins);
@ -2253,6 +2256,55 @@ namespace dxvk {
}
void DxbcCompiler::emitInterpolate(const DxbcShaderInstruction& ins) {
// The SPIR-V instructions operate on input variable pointers,
// which are all declared as four-component float vectors.
const uint32_t registerId = ins.src[0].idx[0].offset;
DxbcRegisterValue result;
result.type.ctype = DxbcScalarType::Float32;
result.type.ccount = 4;
switch (ins.op) {
case DxbcOpcode::EvalCentroid: {
result.id = m_module.opInterpolateAtCentroid(
getVectorTypeId(result.type),
m_vRegs.at(registerId));
} break;
case DxbcOpcode::EvalSampleIndex: {
const DxbcRegisterValue sampleIndex = emitRegisterLoad(
ins.src[1], DxbcRegMask(true, false, false, false));
result.id = m_module.opInterpolateAtSample(
getVectorTypeId(result.type),
m_vRegs.at(registerId),
sampleIndex.id);
} break;
case DxbcOpcode::EvalSnapped: {
const DxbcRegisterValue offset = emitRegisterLoad(
ins.src[1], DxbcRegMask(true, true, false, false));
result.id = m_module.opInterpolateAtOffset(
getVectorTypeId(result.type),
m_vRegs.at(registerId),
offset.id);
} break;
default:
Logger::warn(str::format(
"DxbcCompiler: Unhandled instruction: ",
ins.op));
return;
}
result = emitRegisterSwizzle(result,
ins.src[0].swizzle, ins.dst[0].mask);
emitRegisterStore(ins.dst[0], result);
}
void DxbcCompiler::emitTextureQuery(const DxbcShaderInstruction& ins) {
// resinfo has three operands:
// (dst0) The destination register
@ -4813,8 +4865,8 @@ namespace dxvk {
void DxbcCompiler::emitPsInit() {
m_module.enableCapability(
spv::CapabilityDerivativeControl);
m_module.enableCapability(spv::CapabilityDerivativeControl);
m_module.enableCapability(spv::CapabilityInterpolationFunction);
m_module.setExecutionMode(m_entryPointId,
spv::ExecutionModeOriginUpperLeft);

View File

@ -527,6 +527,9 @@ namespace dxvk {
void emitConvertFloat16(
const DxbcShaderInstruction& ins);
void emitInterpolate(
const DxbcShaderInstruction& ins);
void emitTextureQuery(
const DxbcShaderInstruction& ins);

View File

@ -972,11 +972,22 @@ namespace dxvk {
/* FtoD */
{ },
/* EvalSnapped */
{ },
{ 3, DxbcInstClass::Interpolate, {
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
} },
/* EvalSampleIndex */
{ },
{ 3, DxbcInstClass::Interpolate, {
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Sint32 },
} },
/* EvalCentroid */
{ },
{ 2, DxbcInstClass::Interpolate, {
{ DxbcOperandKind::DstReg, DxbcScalarType::Float32 },
{ DxbcOperandKind::SrcReg, DxbcScalarType::Float32 },
} },
/* DclGsInstanceCount */
{ },
}};

View File

@ -41,6 +41,7 @@ namespace dxvk {
BufferLoad, ///< Structured or raw buffer load
BufferStore, ///< Structured or raw buffer store
ConvertFloat16, ///< 16-bit float packing/unpacking
Interpolate, ///< Input attribute interpolation
TextureQuery, ///< Texture query instruction
TextureQueryLod, ///< Texture LOD query instruction
TextureQueryMs, ///< Multisample texture query

View File

@ -2306,6 +2306,55 @@ namespace dxvk {
}
uint32_t SpirvModule::opInterpolateAtCentroid(
uint32_t resultType,
uint32_t interpolant) {
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::GLSLstd450InterpolateAtCentroid);
m_code.putWord(interpolant);
return resultId;
}
uint32_t SpirvModule::opInterpolateAtSample(
uint32_t resultType,
uint32_t interpolant,
uint32_t sample) {
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::GLSLstd450InterpolateAtSample);
m_code.putWord(interpolant);
m_code.putWord(sample);
return resultId;
}
uint32_t SpirvModule::opInterpolateAtOffset(
uint32_t resultType,
uint32_t interpolant,
uint32_t offset) {
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::GLSLstd450InterpolateAtOffset);
m_code.putWord(interpolant);
m_code.putWord(offset);
return resultId;
}
uint32_t SpirvModule::opImageRead(
uint32_t resultType,
uint32_t image,

View File

@ -808,6 +808,20 @@ namespace dxvk {
uint32_t pointerId,
uint32_t valueId);
uint32_t opInterpolateAtCentroid(
uint32_t resultType,
uint32_t interpolant);
uint32_t opInterpolateAtSample(
uint32_t resultType,
uint32_t interpolant,
uint32_t sample);
uint32_t opInterpolateAtOffset(
uint32_t resultType,
uint32_t interpolant,
uint32_t offset);
uint32_t opImageRead(
uint32_t resultType,
uint32_t image,