mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-18 04:54:15 +01:00
[spirv] Added image operand structure for more flexible sample ops
This commit is contained in:
parent
84190369ab
commit
41d660f220
@ -1193,7 +1193,6 @@ namespace dxvk {
|
||||
|
||||
|
||||
void DxbcCompiler::emitSample(const DxbcShaderInstruction& ins) {
|
||||
// TODO support address offset
|
||||
// TODO support more sample ops
|
||||
|
||||
// All sample instructions have at least these operands:
|
||||
@ -1240,6 +1239,11 @@ namespace dxvk {
|
||||
m_samplers.at(samplerId).typeId,
|
||||
m_samplers.at(samplerId).varId));
|
||||
|
||||
// Accumulate additional image operands. These are
|
||||
// not part of the actual operand token in SPIR-V.
|
||||
SpirvImageOperands imageOperands;
|
||||
// TODO implement sample controls
|
||||
|
||||
// Sampling an image always returns a four-component
|
||||
// vector, whereas depth-compare ops return a scalar.
|
||||
DxbcRegisterValue result;
|
||||
@ -1247,25 +1251,29 @@ namespace dxvk {
|
||||
result.type.ccount = isDepthCompare ? 1 : 4;
|
||||
|
||||
switch (ins.op) {
|
||||
// Simple image sample operation
|
||||
case DxbcOpcode::Sample: {
|
||||
result.id = m_module.opImageSampleImplicitLod(
|
||||
getVectorTypeId(result.type),
|
||||
sampledImageId, coord.id);
|
||||
sampledImageId, coord.id,
|
||||
imageOperands);
|
||||
} break;
|
||||
|
||||
// Depth-compare operation
|
||||
case DxbcOpcode::SampleC: {
|
||||
result.id = m_module.opImageSampleDrefImplicitLod(
|
||||
getVectorTypeId(result.type),
|
||||
sampledImageId, coord.id,
|
||||
referenceValue.id);
|
||||
getVectorTypeId(result.type), sampledImageId, coord.id,
|
||||
referenceValue.id, imageOperands);
|
||||
} break;
|
||||
|
||||
// Depth-compare operation on mip level zero
|
||||
case DxbcOpcode::SampleClz: {
|
||||
imageOperands.flags |= spv::ImageOperandsLodMask;
|
||||
imageOperands.sLod = m_module.constf32(0.0f);
|
||||
|
||||
result.id = m_module.opImageSampleDrefExplicitLod(
|
||||
getVectorTypeId(result.type),
|
||||
sampledImageId, coord.id,
|
||||
referenceValue.id,
|
||||
m_module.constf32(0.0f));
|
||||
getVectorTypeId(result.type), sampledImageId, coord.id,
|
||||
referenceValue.id, imageOperands);
|
||||
} break;
|
||||
|
||||
default:
|
||||
|
@ -472,7 +472,8 @@ namespace dxvk {
|
||||
typeSampledTex,
|
||||
module.opLoad(typeTexture, rcTexture),
|
||||
module.opLoad(typeSampler, rcSampler)),
|
||||
module.opLoad(typeVec2, inTexCoord)));
|
||||
module.opLoad(typeVec2, inTexCoord),
|
||||
SpirvImageOperands()));
|
||||
|
||||
module.opReturn();
|
||||
module.functionEnd();
|
||||
|
@ -1521,14 +1521,18 @@ namespace dxvk {
|
||||
uint32_t SpirvModule::opImageSampleImplicitLod(
|
||||
uint32_t resultType,
|
||||
uint32_t sampledImage,
|
||||
uint32_t coordinates) {
|
||||
uint32_t coordinates,
|
||||
const SpirvImageOperands& operands) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpImageSampleImplicitLod, 5);
|
||||
m_code.putIns(spv::OpImageSampleImplicitLod,
|
||||
5 + getImageOperandWordCount(operands));
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(sampledImage);
|
||||
m_code.putWord(coordinates);
|
||||
|
||||
putImageOperands(operands);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
@ -1537,16 +1541,18 @@ namespace dxvk {
|
||||
uint32_t resultType,
|
||||
uint32_t sampledImage,
|
||||
uint32_t coordinates,
|
||||
uint32_t lod) {
|
||||
const SpirvImageOperands& operands) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpImageSampleExplicitLod, 7);
|
||||
m_code.putIns(spv::OpImageSampleExplicitLod,
|
||||
5 + getImageOperandWordCount(operands));
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(sampledImage);
|
||||
m_code.putWord(coordinates);
|
||||
m_code.putWord(spv::ImageOperandsLodMask);
|
||||
m_code.putWord(lod);
|
||||
|
||||
putImageOperands(operands);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
@ -1555,15 +1561,19 @@ namespace dxvk {
|
||||
uint32_t resultType,
|
||||
uint32_t sampledImage,
|
||||
uint32_t coordinates,
|
||||
uint32_t reference) {
|
||||
uint32_t reference,
|
||||
const SpirvImageOperands& operands) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpImageSampleDrefImplicitLod, 6);
|
||||
m_code.putIns(spv::OpImageSampleDrefImplicitLod,
|
||||
6 + getImageOperandWordCount(operands));
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(sampledImage);
|
||||
m_code.putWord(coordinates);
|
||||
m_code.putWord(reference);
|
||||
|
||||
putImageOperands(operands);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
@ -1573,17 +1583,18 @@ namespace dxvk {
|
||||
uint32_t sampledImage,
|
||||
uint32_t coordinates,
|
||||
uint32_t reference,
|
||||
uint32_t lod) {
|
||||
const SpirvImageOperands& operands) {
|
||||
uint32_t resultId = this->allocateId();
|
||||
|
||||
m_code.putIns (spv::OpImageSampleDrefExplicitLod, 8);
|
||||
m_code.putIns(spv::OpImageSampleDrefExplicitLod,
|
||||
6 + getImageOperandWordCount(operands));
|
||||
m_code.putWord(resultType);
|
||||
m_code.putWord(resultId);
|
||||
m_code.putWord(sampledImage);
|
||||
m_code.putWord(coordinates);
|
||||
m_code.putWord(reference);
|
||||
m_code.putWord(spv::ImageOperandsLodMask);
|
||||
m_code.putWord(lod);
|
||||
|
||||
putImageOperands(operands);
|
||||
return resultId;
|
||||
}
|
||||
|
||||
@ -1683,4 +1694,54 @@ namespace dxvk {
|
||||
m_instExt.putStr (name);
|
||||
}
|
||||
|
||||
|
||||
uint32_t SpirvModule::getImageOperandWordCount(const SpirvImageOperands& op) const {
|
||||
// Each flag may add one or more operands
|
||||
const uint32_t result
|
||||
= ((op.flags & spv::ImageOperandsBiasMask) ? 1 : 0)
|
||||
+ ((op.flags & spv::ImageOperandsLodMask) ? 1 : 0)
|
||||
+ ((op.flags & spv::ImageOperandsConstOffsetMask) ? 1 : 0)
|
||||
+ ((op.flags & spv::ImageOperandsGradMask) ? 2 : 0)
|
||||
+ ((op.flags & spv::ImageOperandsOffsetMask) ? 1 : 0)
|
||||
+ ((op.flags & spv::ImageOperandsConstOffsetsMask)? 1 : 0)
|
||||
+ ((op.flags & spv::ImageOperandsSampleMask) ? 1 : 0)
|
||||
+ ((op.flags & spv::ImageOperandsMinLodMask) ? 1 : 0);
|
||||
|
||||
// Add a DWORD for the operand mask if it is non-zero
|
||||
return result != 0 ? result + 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
void SpirvModule::putImageOperands(const SpirvImageOperands& op) {
|
||||
if (op.flags != 0) {
|
||||
m_code.putWord(op.flags);
|
||||
|
||||
if (op.flags & spv::ImageOperandsBiasMask)
|
||||
m_code.putWord(op.sLodBias);
|
||||
|
||||
if (op.flags & spv::ImageOperandsLodMask)
|
||||
m_code.putWord(op.sLod);
|
||||
|
||||
if (op.flags & spv::ImageOperandsConstOffsetMask)
|
||||
m_code.putWord(op.sConstOffset);
|
||||
|
||||
if (op.flags & spv::ImageOperandsGradMask) {
|
||||
m_code.putWord(op.sGradX);
|
||||
m_code.putWord(op.sGradY);
|
||||
}
|
||||
|
||||
if (op.flags & spv::ImageOperandsOffsetMask)
|
||||
m_code.putWord(op.gOffset);
|
||||
|
||||
if (op.flags & spv::ImageOperandsConstOffsetsMask)
|
||||
m_code.putWord(op.gConstOffsets);
|
||||
|
||||
if (op.flags & spv::ImageOperandsSampleMask)
|
||||
m_code.putWord(op.sSampleId);
|
||||
|
||||
if (op.flags & spv::ImageOperandsMinLodMask)
|
||||
m_code.putWord(op.sMinLod);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -4,6 +4,19 @@
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
struct SpirvImageOperands {
|
||||
uint32_t flags = 0;
|
||||
uint32_t sLodBias = 0;
|
||||
uint32_t sLod = 0;
|
||||
uint32_t sConstOffset = 0;
|
||||
uint32_t sGradX = 0;
|
||||
uint32_t sGradY = 0;
|
||||
uint32_t gOffset = 0;
|
||||
uint32_t gConstOffsets = 0;
|
||||
uint32_t sSampleId = 0;
|
||||
uint32_t sMinLod = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief SPIR-V module
|
||||
*
|
||||
@ -518,26 +531,28 @@ namespace dxvk {
|
||||
uint32_t opImageSampleImplicitLod(
|
||||
uint32_t resultType,
|
||||
uint32_t sampledImage,
|
||||
uint32_t coordinates);
|
||||
uint32_t coordinates,
|
||||
const SpirvImageOperands& operands);
|
||||
|
||||
uint32_t opImageSampleExplicitLod(
|
||||
uint32_t resultType,
|
||||
uint32_t sampledImage,
|
||||
uint32_t coordinates,
|
||||
uint32_t lod);
|
||||
const SpirvImageOperands& operands);
|
||||
|
||||
uint32_t opImageSampleDrefImplicitLod(
|
||||
uint32_t resultType,
|
||||
uint32_t sampledImage,
|
||||
uint32_t coordinates,
|
||||
uint32_t reference);
|
||||
uint32_t reference,
|
||||
const SpirvImageOperands& operands);
|
||||
|
||||
uint32_t opImageSampleDrefExplicitLod(
|
||||
uint32_t resultType,
|
||||
uint32_t sampledImage,
|
||||
uint32_t coordinates,
|
||||
uint32_t reference,
|
||||
uint32_t lod);
|
||||
const SpirvImageOperands& operands);
|
||||
|
||||
void opLoopMerge(
|
||||
uint32_t mergeBlock,
|
||||
@ -587,6 +602,12 @@ namespace dxvk {
|
||||
|
||||
void instImportGlsl450();
|
||||
|
||||
uint32_t getImageOperandWordCount(
|
||||
const SpirvImageOperands& op) const;
|
||||
|
||||
void putImageOperands(
|
||||
const SpirvImageOperands& op);
|
||||
|
||||
};
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user