mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 10:54:16 +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) {
|
void DxbcCompiler::emitSample(const DxbcShaderInstruction& ins) {
|
||||||
// TODO support address offset
|
|
||||||
// TODO support more sample ops
|
// TODO support more sample ops
|
||||||
|
|
||||||
// All sample instructions have at least these operands:
|
// All sample instructions have at least these operands:
|
||||||
@ -1240,6 +1239,11 @@ namespace dxvk {
|
|||||||
m_samplers.at(samplerId).typeId,
|
m_samplers.at(samplerId).typeId,
|
||||||
m_samplers.at(samplerId).varId));
|
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
|
// Sampling an image always returns a four-component
|
||||||
// vector, whereas depth-compare ops return a scalar.
|
// vector, whereas depth-compare ops return a scalar.
|
||||||
DxbcRegisterValue result;
|
DxbcRegisterValue result;
|
||||||
@ -1247,25 +1251,29 @@ namespace dxvk {
|
|||||||
result.type.ccount = isDepthCompare ? 1 : 4;
|
result.type.ccount = isDepthCompare ? 1 : 4;
|
||||||
|
|
||||||
switch (ins.op) {
|
switch (ins.op) {
|
||||||
|
// Simple image sample operation
|
||||||
case DxbcOpcode::Sample: {
|
case DxbcOpcode::Sample: {
|
||||||
result.id = m_module.opImageSampleImplicitLod(
|
result.id = m_module.opImageSampleImplicitLod(
|
||||||
getVectorTypeId(result.type),
|
getVectorTypeId(result.type),
|
||||||
sampledImageId, coord.id);
|
sampledImageId, coord.id,
|
||||||
|
imageOperands);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
// Depth-compare operation
|
||||||
case DxbcOpcode::SampleC: {
|
case DxbcOpcode::SampleC: {
|
||||||
result.id = m_module.opImageSampleDrefImplicitLod(
|
result.id = m_module.opImageSampleDrefImplicitLod(
|
||||||
getVectorTypeId(result.type),
|
getVectorTypeId(result.type), sampledImageId, coord.id,
|
||||||
sampledImageId, coord.id,
|
referenceValue.id, imageOperands);
|
||||||
referenceValue.id);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
// Depth-compare operation on mip level zero
|
||||||
case DxbcOpcode::SampleClz: {
|
case DxbcOpcode::SampleClz: {
|
||||||
|
imageOperands.flags |= spv::ImageOperandsLodMask;
|
||||||
|
imageOperands.sLod = m_module.constf32(0.0f);
|
||||||
|
|
||||||
result.id = m_module.opImageSampleDrefExplicitLod(
|
result.id = m_module.opImageSampleDrefExplicitLod(
|
||||||
getVectorTypeId(result.type),
|
getVectorTypeId(result.type), sampledImageId, coord.id,
|
||||||
sampledImageId, coord.id,
|
referenceValue.id, imageOperands);
|
||||||
referenceValue.id,
|
|
||||||
m_module.constf32(0.0f));
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -472,7 +472,8 @@ namespace dxvk {
|
|||||||
typeSampledTex,
|
typeSampledTex,
|
||||||
module.opLoad(typeTexture, rcTexture),
|
module.opLoad(typeTexture, rcTexture),
|
||||||
module.opLoad(typeSampler, rcSampler)),
|
module.opLoad(typeSampler, rcSampler)),
|
||||||
module.opLoad(typeVec2, inTexCoord)));
|
module.opLoad(typeVec2, inTexCoord),
|
||||||
|
SpirvImageOperands()));
|
||||||
|
|
||||||
module.opReturn();
|
module.opReturn();
|
||||||
module.functionEnd();
|
module.functionEnd();
|
||||||
|
@ -1521,14 +1521,18 @@ namespace dxvk {
|
|||||||
uint32_t SpirvModule::opImageSampleImplicitLod(
|
uint32_t SpirvModule::opImageSampleImplicitLod(
|
||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t sampledImage,
|
uint32_t sampledImage,
|
||||||
uint32_t coordinates) {
|
uint32_t coordinates,
|
||||||
|
const SpirvImageOperands& operands) {
|
||||||
uint32_t resultId = this->allocateId();
|
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(resultType);
|
||||||
m_code.putWord(resultId);
|
m_code.putWord(resultId);
|
||||||
m_code.putWord(sampledImage);
|
m_code.putWord(sampledImage);
|
||||||
m_code.putWord(coordinates);
|
m_code.putWord(coordinates);
|
||||||
|
|
||||||
|
putImageOperands(operands);
|
||||||
return resultId;
|
return resultId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1537,16 +1541,18 @@ namespace dxvk {
|
|||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t sampledImage,
|
uint32_t sampledImage,
|
||||||
uint32_t coordinates,
|
uint32_t coordinates,
|
||||||
uint32_t lod) {
|
const SpirvImageOperands& operands) {
|
||||||
uint32_t resultId = this->allocateId();
|
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(resultType);
|
||||||
m_code.putWord(resultId);
|
m_code.putWord(resultId);
|
||||||
m_code.putWord(sampledImage);
|
m_code.putWord(sampledImage);
|
||||||
m_code.putWord(coordinates);
|
m_code.putWord(coordinates);
|
||||||
m_code.putWord(spv::ImageOperandsLodMask);
|
m_code.putWord(spv::ImageOperandsLodMask);
|
||||||
m_code.putWord(lod);
|
|
||||||
|
putImageOperands(operands);
|
||||||
return resultId;
|
return resultId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1555,15 +1561,19 @@ namespace dxvk {
|
|||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t sampledImage,
|
uint32_t sampledImage,
|
||||||
uint32_t coordinates,
|
uint32_t coordinates,
|
||||||
uint32_t reference) {
|
uint32_t reference,
|
||||||
|
const SpirvImageOperands& operands) {
|
||||||
uint32_t resultId = this->allocateId();
|
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(resultType);
|
||||||
m_code.putWord(resultId);
|
m_code.putWord(resultId);
|
||||||
m_code.putWord(sampledImage);
|
m_code.putWord(sampledImage);
|
||||||
m_code.putWord(coordinates);
|
m_code.putWord(coordinates);
|
||||||
m_code.putWord(reference);
|
m_code.putWord(reference);
|
||||||
|
|
||||||
|
putImageOperands(operands);
|
||||||
return resultId;
|
return resultId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1573,17 +1583,18 @@ namespace dxvk {
|
|||||||
uint32_t sampledImage,
|
uint32_t sampledImage,
|
||||||
uint32_t coordinates,
|
uint32_t coordinates,
|
||||||
uint32_t reference,
|
uint32_t reference,
|
||||||
uint32_t lod) {
|
const SpirvImageOperands& operands) {
|
||||||
uint32_t resultId = this->allocateId();
|
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(resultType);
|
||||||
m_code.putWord(resultId);
|
m_code.putWord(resultId);
|
||||||
m_code.putWord(sampledImage);
|
m_code.putWord(sampledImage);
|
||||||
m_code.putWord(coordinates);
|
m_code.putWord(coordinates);
|
||||||
m_code.putWord(reference);
|
m_code.putWord(reference);
|
||||||
m_code.putWord(spv::ImageOperandsLodMask);
|
|
||||||
m_code.putWord(lod);
|
putImageOperands(operands);
|
||||||
return resultId;
|
return resultId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1683,4 +1694,54 @@ namespace dxvk {
|
|||||||
m_instExt.putStr (name);
|
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 {
|
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
|
* \brief SPIR-V module
|
||||||
*
|
*
|
||||||
@ -518,26 +531,28 @@ namespace dxvk {
|
|||||||
uint32_t opImageSampleImplicitLod(
|
uint32_t opImageSampleImplicitLod(
|
||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t sampledImage,
|
uint32_t sampledImage,
|
||||||
uint32_t coordinates);
|
uint32_t coordinates,
|
||||||
|
const SpirvImageOperands& operands);
|
||||||
|
|
||||||
uint32_t opImageSampleExplicitLod(
|
uint32_t opImageSampleExplicitLod(
|
||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t sampledImage,
|
uint32_t sampledImage,
|
||||||
uint32_t coordinates,
|
uint32_t coordinates,
|
||||||
uint32_t lod);
|
const SpirvImageOperands& operands);
|
||||||
|
|
||||||
uint32_t opImageSampleDrefImplicitLod(
|
uint32_t opImageSampleDrefImplicitLod(
|
||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t sampledImage,
|
uint32_t sampledImage,
|
||||||
uint32_t coordinates,
|
uint32_t coordinates,
|
||||||
uint32_t reference);
|
uint32_t reference,
|
||||||
|
const SpirvImageOperands& operands);
|
||||||
|
|
||||||
uint32_t opImageSampleDrefExplicitLod(
|
uint32_t opImageSampleDrefExplicitLod(
|
||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
uint32_t sampledImage,
|
uint32_t sampledImage,
|
||||||
uint32_t coordinates,
|
uint32_t coordinates,
|
||||||
uint32_t reference,
|
uint32_t reference,
|
||||||
uint32_t lod);
|
const SpirvImageOperands& operands);
|
||||||
|
|
||||||
void opLoopMerge(
|
void opLoopMerge(
|
||||||
uint32_t mergeBlock,
|
uint32_t mergeBlock,
|
||||||
@ -587,6 +602,12 @@ namespace dxvk {
|
|||||||
|
|
||||||
void instImportGlsl450();
|
void instImportGlsl450();
|
||||||
|
|
||||||
|
uint32_t getImageOperandWordCount(
|
||||||
|
const SpirvImageOperands& op) const;
|
||||||
|
|
||||||
|
void putImageOperands(
|
||||||
|
const SpirvImageOperands& op);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user