1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-15 07:29:17 +01:00

[dxbc] Implement ld for images with sparse feedback

This commit is contained in:
Philip Rebohle 2022-08-22 04:29:56 +02:00
parent db3b2e23fb
commit e58f9a5e99

View File

@ -3310,6 +3310,9 @@ namespace dxvk {
const auto& texture = m_textures.at(ins.src[1].idx[0].offset); const auto& texture = m_textures.at(ins.src[1].idx[0].offset);
const uint32_t imageLayerDim = getTexLayerDim(texture.imageInfo); const uint32_t imageLayerDim = getTexLayerDim(texture.imageInfo);
bool isMultisampled = ins.op == DxbcOpcode::LdMs
|| ins.op == DxbcOpcode::LdMsS;
// Load the texture coordinates. The last component // Load the texture coordinates. The last component
// contains the LOD if the resource is an image. // contains the LOD if the resource is an image.
const DxbcRegisterValue address = emitRegisterLoad( const DxbcRegisterValue address = emitRegisterLoad(
@ -3318,6 +3321,7 @@ namespace dxvk {
// Additional image operands. This will store // Additional image operands. This will store
// the LOD and the address offset if present. // the LOD and the address offset if present.
SpirvImageOperands imageOperands; SpirvImageOperands imageOperands;
imageOperands.sparse = ins.dstCount == 2;
if (ins.sampleControls.u != 0 || ins.sampleControls.v != 0 || ins.sampleControls.w != 0) { if (ins.sampleControls.u != 0 || ins.sampleControls.v != 0 || ins.sampleControls.w != 0) {
const std::array<uint32_t, 3> offsetIds = { const std::array<uint32_t, 3> offsetIds = {
@ -3337,7 +3341,7 @@ namespace dxvk {
if (texture.imageInfo.dim != spv::DimBuffer && texture.imageInfo.ms == 0) { if (texture.imageInfo.dim != spv::DimBuffer && texture.imageInfo.ms == 0) {
DxbcRegisterValue imageLod; DxbcRegisterValue imageLod;
if (ins.op != DxbcOpcode::LdMs) { if (!isMultisampled) {
imageLod = emitRegisterExtract( imageLod = emitRegisterExtract(
address, DxbcRegMask(false, false, false, true)); address, DxbcRegMask(false, false, false, true));
} else { } else {
@ -3350,9 +3354,9 @@ namespace dxvk {
imageOperands.sLod = imageLod.id; imageOperands.sLod = imageLod.id;
} }
// The ld2ms instruction has a sample index, but we // The ld2dms instruction has a sample index, but we
// are only allowed to set it for multisample views // are only allowed to set it for multisample views
if (ins.op == DxbcOpcode::LdMs && texture.imageInfo.ms == 1) { if (isMultisampled && texture.imageInfo.ms == 1) {
DxbcRegisterValue sampleId = emitRegisterLoad( DxbcRegisterValue sampleId = emitRegisterLoad(
ins.src[2], DxbcRegMask(true, false, false, false)); ins.src[2], DxbcRegMask(true, false, false, false));
@ -3367,12 +3371,25 @@ namespace dxvk {
// always returns a four-component vector. // always returns a four-component vector.
const uint32_t imageId = m_module.opLoad(texture.imageTypeId, texture.varId); const uint32_t imageId = m_module.opLoad(texture.imageTypeId, texture.varId);
DxbcVectorType texelType;
texelType.ctype = texture.sampledType;
texelType.ccount = 4;
uint32_t texelTypeId = getVectorTypeId(texelType);
uint32_t resultTypeId = texelTypeId;
uint32_t resultId = 0;
if (imageOperands.sparse)
resultTypeId = getSparseResultTypeId(texelTypeId);
resultId = m_module.opImageFetch(resultTypeId,
imageId, coord.id, imageOperands);
DxbcRegisterValue result; DxbcRegisterValue result;
result.type.ctype = texture.sampledType; result.type = texelType;
result.type.ccount = 4; result.id = imageOperands.sparse
result.id = m_module.opImageFetch( ? emitExtractSparseTexel(texelTypeId, resultId)
getVectorTypeId(result.type), imageId, : resultId;
coord.id, imageOperands);
// 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
@ -3380,6 +3397,9 @@ namespace dxvk {
ins.src[1].swizzle, ins.dst[0].mask); ins.src[1].swizzle, ins.dst[0].mask);
emitRegisterStore(ins.dst[0], result); emitRegisterStore(ins.dst[0], result);
if (imageOperands.sparse)
emitStoreSparseFeedback(ins.dst[1], resultId);
} }