mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-06 20:58:37 +01:00
[dxbc] Implement gather operations with sparse feedback
This commit is contained in:
parent
614024873d
commit
d5b68b3642
2 changed files with 94 additions and 18 deletions
src/dxbc
|
@ -3386,6 +3386,7 @@ namespace dxvk {
|
||||||
void DxbcCompiler::emitTextureGather(const DxbcShaderInstruction& ins) {
|
void DxbcCompiler::emitTextureGather(const DxbcShaderInstruction& ins) {
|
||||||
// Gather4 takes the following operands:
|
// Gather4 takes the following operands:
|
||||||
// (dst0) The destination register
|
// (dst0) The destination register
|
||||||
|
// (dst1) The residency code for sparse ops
|
||||||
// (src0) Texture coordinates
|
// (src0) Texture coordinates
|
||||||
// (src1) The texture itself
|
// (src1) The texture itself
|
||||||
// (src2) The sampler, with a component selector
|
// (src2) The sampler, with a component selector
|
||||||
|
@ -3396,7 +3397,9 @@ namespace dxvk {
|
||||||
// TODO reduce code duplication by moving some common code
|
// TODO reduce code duplication by moving some common code
|
||||||
// in both sample() and gather() into separate methods
|
// in both sample() and gather() into separate methods
|
||||||
const bool isExtendedGather = ins.op == DxbcOpcode::Gather4Po
|
const bool isExtendedGather = ins.op == DxbcOpcode::Gather4Po
|
||||||
|| ins.op == DxbcOpcode::Gather4PoC;
|
|| ins.op == DxbcOpcode::Gather4PoC
|
||||||
|
|| ins.op == DxbcOpcode::Gather4PoS
|
||||||
|
|| ins.op == DxbcOpcode::Gather4PoCS;
|
||||||
|
|
||||||
const DxbcRegister& texCoordReg = ins.src[0];
|
const DxbcRegister& texCoordReg = ins.src[0];
|
||||||
const DxbcRegister& textureReg = ins.src[1 + isExtendedGather];
|
const DxbcRegister& textureReg = ins.src[1 + isExtendedGather];
|
||||||
|
@ -3415,8 +3418,10 @@ namespace dxvk {
|
||||||
|
|
||||||
// Load reference value for depth-compare operations
|
// 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;
|
|| ins.op == DxbcOpcode::Gather4PoC
|
||||||
|
|| ins.op == DxbcOpcode::Gather4CS
|
||||||
|
|| ins.op == DxbcOpcode::Gather4PoCS;
|
||||||
|
|
||||||
const DxbcRegisterValue referenceValue = isDepthCompare
|
const DxbcRegisterValue referenceValue = isDepthCompare
|
||||||
? emitRegisterLoad(ins.src[3 + isExtendedGather],
|
? emitRegisterLoad(ins.src[3 + isExtendedGather],
|
||||||
DxbcRegMask(true, false, false, false))
|
DxbcRegMask(true, false, false, false))
|
||||||
|
@ -3424,7 +3429,8 @@ namespace dxvk {
|
||||||
|
|
||||||
// Accumulate additional image operands.
|
// Accumulate additional image operands.
|
||||||
SpirvImageOperands imageOperands;
|
SpirvImageOperands imageOperands;
|
||||||
|
imageOperands.sparse = ins.dstCount == 2;
|
||||||
|
|
||||||
if (isExtendedGather) {
|
if (isExtendedGather) {
|
||||||
m_module.enableCapability(spv::CapabilityImageGatherExtended);
|
m_module.enableCapability(spv::CapabilityImageGatherExtended);
|
||||||
|
|
||||||
|
@ -3445,30 +3451,41 @@ namespace dxvk {
|
||||||
getVectorTypeId({ DxbcScalarType::Sint32, imageLayerDim }),
|
getVectorTypeId({ DxbcScalarType::Sint32, imageLayerDim }),
|
||||||
imageLayerDim, offsetIds.data());
|
imageLayerDim, offsetIds.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gathering texels always returns a four-component
|
// Gathering texels always returns a four-component
|
||||||
// vector, even for the depth-compare variants.
|
// vector, even for the depth-compare variants.
|
||||||
uint32_t sampledImageId = emitLoadSampledImage(texture, sampler, isDepthCompare);
|
uint32_t sampledImageId = emitLoadSampledImage(texture, sampler, isDepthCompare);
|
||||||
|
|
||||||
DxbcRegisterValue result;
|
DxbcVectorType texelType;
|
||||||
result.type.ctype = texture.sampledType;
|
texelType.ctype = texture.sampledType;
|
||||||
result.type.ccount = 4;
|
texelType.ccount = 4;
|
||||||
|
|
||||||
|
uint32_t texelTypeId = getVectorTypeId(texelType);
|
||||||
|
uint32_t resultTypeId = texelTypeId;
|
||||||
|
uint32_t resultId = 0;
|
||||||
|
|
||||||
|
if (imageOperands.sparse)
|
||||||
|
resultTypeId = getSparseResultTypeId(texelTypeId);
|
||||||
|
|
||||||
switch (ins.op) {
|
switch (ins.op) {
|
||||||
// Simple image gather operation
|
// Simple image gather operation
|
||||||
case DxbcOpcode::Gather4:
|
case DxbcOpcode::Gather4:
|
||||||
case DxbcOpcode::Gather4Po: {
|
case DxbcOpcode::Gather4S:
|
||||||
result.id = m_module.opImageGather(
|
case DxbcOpcode::Gather4Po:
|
||||||
getVectorTypeId(result.type), sampledImageId, coord.id,
|
case DxbcOpcode::Gather4PoS: {
|
||||||
|
resultId = m_module.opImageGather(
|
||||||
|
resultTypeId, sampledImageId, coord.id,
|
||||||
m_module.consti32(samplerReg.swizzle[0]),
|
m_module.consti32(samplerReg.swizzle[0]),
|
||||||
imageOperands);
|
imageOperands);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
// Depth-compare operation
|
// Depth-compare operation
|
||||||
case DxbcOpcode::Gather4C:
|
case DxbcOpcode::Gather4C:
|
||||||
case DxbcOpcode::Gather4PoC: {
|
case DxbcOpcode::Gather4CS:
|
||||||
result.id = m_module.opImageDrefGather(
|
case DxbcOpcode::Gather4PoC:
|
||||||
getVectorTypeId(result.type), sampledImageId, coord.id,
|
case DxbcOpcode::Gather4PoCS: {
|
||||||
|
resultId = m_module.opImageDrefGather(
|
||||||
|
resultTypeId, sampledImageId, coord.id,
|
||||||
referenceValue.id, imageOperands);
|
referenceValue.id, imageOperands);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -3478,13 +3495,23 @@ namespace dxvk {
|
||||||
ins.op));
|
ins.op));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If necessary, deal with the sparse result
|
||||||
|
DxbcRegisterValue result;
|
||||||
|
result.type = texelType;
|
||||||
|
result.id = imageOperands.sparse
|
||||||
|
? emitExtractSparseTexel(texelTypeId, resultId)
|
||||||
|
: resultId;
|
||||||
|
|
||||||
// Swizzle components using the texture swizzle
|
// Swizzle components using the texture swizzle
|
||||||
// and the destination operand's write mask
|
// and the destination operand's write mask
|
||||||
result = emitRegisterSwizzle(result,
|
result = emitRegisterSwizzle(result,
|
||||||
textureReg.swizzle, ins.dst[0].mask);
|
textureReg.swizzle, ins.dst[0].mask);
|
||||||
|
|
||||||
emitRegisterStore(ins.dst[0], result);
|
emitRegisterStore(ins.dst[0], result);
|
||||||
|
|
||||||
|
if (imageOperands.sparse)
|
||||||
|
emitStoreSparseFeedback(ins.dst[1], resultId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4549,6 +4576,33 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t DxbcCompiler::emitExtractSparseTexel(
|
||||||
|
uint32_t texelTypeId,
|
||||||
|
uint32_t resultId) {
|
||||||
|
uint32_t index = 1;
|
||||||
|
|
||||||
|
return m_module.opCompositeExtract(
|
||||||
|
texelTypeId, resultId, 1, &index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxbcCompiler::emitStoreSparseFeedback(
|
||||||
|
const DxbcRegister& feedbackRegister,
|
||||||
|
uint32_t resultId) {
|
||||||
|
if (feedbackRegister.type != DxbcOperandType::Null) {
|
||||||
|
uint32_t index = 0;
|
||||||
|
|
||||||
|
DxbcRegisterValue result;
|
||||||
|
result.type = { DxbcScalarType::Uint32, 1 };
|
||||||
|
result.id = m_module.opCompositeExtract(
|
||||||
|
getScalarTypeId(DxbcScalarType::Uint32),
|
||||||
|
resultId, 1, &index);
|
||||||
|
|
||||||
|
emitRegisterStore(feedbackRegister, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DxbcRegisterValue DxbcCompiler::emitDstOperandModifiers(
|
DxbcRegisterValue DxbcCompiler::emitDstOperandModifiers(
|
||||||
DxbcRegisterValue value,
|
DxbcRegisterValue value,
|
||||||
DxbcOpModifiers modifiers) {
|
DxbcOpModifiers modifiers) {
|
||||||
|
@ -7592,6 +7646,15 @@ namespace dxvk {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t DxbcCompiler::getSparseResultTypeId(uint32_t baseType) {
|
||||||
|
m_module.enableCapability(spv::CapabilitySparseResidency);
|
||||||
|
|
||||||
|
uint32_t uintType = getScalarTypeId(DxbcScalarType::Uint32);
|
||||||
|
std::array<uint32_t, 2> typeIds = { uintType, baseType };
|
||||||
|
return m_module.defStructType(typeIds.size(), typeIds.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t DxbcCompiler::getPerVertexBlockId() {
|
uint32_t DxbcCompiler::getPerVertexBlockId() {
|
||||||
uint32_t t_f32 = m_module.defFloatType(32);
|
uint32_t t_f32 = m_module.defFloatType(32);
|
||||||
uint32_t t_f32_v4 = m_module.defVectorType(t_f32, 4);
|
uint32_t t_f32_v4 = m_module.defVectorType(t_f32, 4);
|
||||||
|
|
|
@ -882,6 +882,16 @@ namespace dxvk {
|
||||||
DxbcRegisterValue value,
|
DxbcRegisterValue value,
|
||||||
DxbcOpModifiers modifiers);
|
DxbcOpModifiers modifiers);
|
||||||
|
|
||||||
|
///////////////////////////
|
||||||
|
// Sparse feedback methods
|
||||||
|
uint32_t emitExtractSparseTexel(
|
||||||
|
uint32_t texelTypeId,
|
||||||
|
uint32_t resultId);
|
||||||
|
|
||||||
|
void emitStoreSparseFeedback(
|
||||||
|
const DxbcRegister& feedbackRegister,
|
||||||
|
uint32_t resultId);
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
// Pointer manipulation methods
|
// Pointer manipulation methods
|
||||||
DxbcRegisterPointer emitArrayAccess(
|
DxbcRegisterPointer emitArrayAccess(
|
||||||
|
@ -1149,7 +1159,7 @@ namespace dxvk {
|
||||||
uint32_t emitSamplePosArray();
|
uint32_t emitSamplePosArray();
|
||||||
|
|
||||||
void emitFloatControl();
|
void emitFloatControl();
|
||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
// Variable definition methods
|
// Variable definition methods
|
||||||
uint32_t emitNewVariable(
|
uint32_t emitNewVariable(
|
||||||
|
@ -1223,7 +1233,10 @@ namespace dxvk {
|
||||||
|
|
||||||
uint32_t getPointerTypeId(
|
uint32_t getPointerTypeId(
|
||||||
const DxbcRegisterInfo& type);
|
const DxbcRegisterInfo& type);
|
||||||
|
|
||||||
|
uint32_t getSparseResultTypeId(
|
||||||
|
uint32_t baseType);
|
||||||
|
|
||||||
uint32_t getPerVertexBlockId();
|
uint32_t getPerVertexBlockId();
|
||||||
|
|
||||||
uint32_t getFunctionId(
|
uint32_t getFunctionId(
|
||||||
|
|
Loading…
Add table
Reference in a new issue