Match mip layers and array layers in texture manager

This commit is contained in:
Billy Laws 2022-11-03 22:36:03 +00:00
parent d502adb309
commit 3ae1e78544

View File

@ -25,7 +25,19 @@ namespace skyline::gpu {
std::shared_ptr<Texture> match{}; std::shared_ptr<Texture> match{};
boost::container::small_vector<std::shared_ptr<Texture>, 4> matches{}; boost::container::small_vector<std::shared_ptr<Texture>, 4> matches{};
auto mappingEnd{std::upper_bound(textures.begin(), textures.end(), guestMapping)}, hostMapping{mappingEnd}; auto mappingEnd{std::upper_bound(textures.begin(), textures.end(), guestMapping, [](const auto &value, const auto &element) {
return value.end() < element.end();
})}, hostMapping{mappingEnd};
while (hostMapping != textures.end() && guestMapping.begin() < hostMapping->end())
hostMapping++;
std::shared_ptr<Texture> fullMatch{};
std::shared_ptr<Texture> layerMipMatch{};
u32 matchLevel{};
u32 matchLayer{};
while (hostMapping != textures.begin() && (--hostMapping)->end() > guestMapping.begin()) { while (hostMapping != textures.begin() && (--hostMapping)->end() > guestMapping.begin()) {
auto &hostMappings{hostMapping->texture->guest->mappings}; auto &hostMappings{hostMapping->texture->guest->mappings};
if (!hostMapping->contains(guestMapping)) if (!hostMapping->contains(guestMapping))
@ -51,30 +63,63 @@ namespace skyline::gpu {
matchGuestTexture.GetViewDepth() <= guestTexture.GetViewDepth()) matchGuestTexture.GetViewDepth() <= guestTexture.GetViewDepth())
|| matchGuestTexture.viewMipBase > 0) || matchGuestTexture.viewMipBase > 0)
&& matchGuestTexture.tileConfig == guestTexture.tileConfig) { && matchGuestTexture.tileConfig == guestTexture.tileConfig) {
auto &texture{hostMapping->texture}; fullMatch = hostMapping->texture;
ContextLock textureLock{tag, *texture}; } else {
return texture->GetView(guestTexture.viewType, vk::ImageSubresourceRange{ matches.push_back(hostMapping->texture);
}
} else {
auto &matchGuestTexture{*hostMapping->texture->guest};
if (matchGuestTexture.format->IsCompatible(*guestTexture.format) && matchGuestTexture.tileConfig == guestTexture.tileConfig &&
(!layerMipMatch || (matchGuestTexture.GetViewLayerCount() >= layerMipMatch->guest->GetViewLayerCount() && matchGuestTexture.mipLevelCount >= layerMipMatch->guest->mipLevelCount))) {
size_t memOffset{static_cast<size_t>(guestMapping.data() - hostMapping->texture->guest->mappings.front().data())};
size_t layerMemOffset{};
bool matched{};
for (u32 layer{}; layer < hostMapping->texture->layerCount; layer++) {
u32 level{};
size_t levelMemOffset{};
for (auto &mipLevel : hostMapping->texture->mipLayouts) {
if (layerMemOffset + levelMemOffset == memOffset) {
if (mipLevel.blockLinearSize == guestTexture.CalculateLayerSize()) {
matched = true;
matchLayer = layer;
matchLevel = level;
break;
}
level++;
levelMemOffset += mipLevel.blockLinearSize;
}
}
if (matched)
break;
layerMemOffset += matchGuestTexture.GetLayerStride();
}
if (matched)
layerMipMatch = hostMapping->texture;
}
}
}
if (layerMipMatch) {
ContextLock textureLock{tag, *layerMipMatch};
return layerMipMatch->GetView(guestTexture.viewType, vk::ImageSubresourceRange{
.aspectMask = guestTexture.aspect,
.baseMipLevel = guestTexture.viewMipBase + matchLevel,
.levelCount = guestTexture.viewMipCount,
.baseArrayLayer = guestTexture.baseArrayLayer + matchLayer,
.layerCount = guestTexture.GetViewLayerCount(),
}, guestTexture.format, guestTexture.swizzle);
} else if (fullMatch) {
ContextLock textureLock{tag, *fullMatch};
return fullMatch->GetView(guestTexture.viewType, vk::ImageSubresourceRange{
.aspectMask = guestTexture.aspect, .aspectMask = guestTexture.aspect,
.baseMipLevel = guestTexture.viewMipBase, .baseMipLevel = guestTexture.viewMipBase,
.levelCount = guestTexture.viewMipCount, .levelCount = guestTexture.viewMipCount,
.baseArrayLayer = guestTexture.baseArrayLayer, .baseArrayLayer = guestTexture.baseArrayLayer,
.layerCount = guestTexture.GetViewLayerCount(), .layerCount = guestTexture.GetViewLayerCount(),
}, guestTexture.format, guestTexture.swizzle); }, guestTexture.format, guestTexture.swizzle);
} else {
matches.push_back(hostMapping->texture);
}
} /* else if (mappingMatch) {
// We've gotten a partial match with a certain subset of contiguous mappings matching, we need to check if this is a meaningful overlap
if (MeaningfulOverlap) {
// TODO: Layout Checks + Check match against Base Layer in TIC
auto &texture{hostMapping->texture};
return TextureView(texture, static_cast<vk::ImageViewType>(guestTexture.type), vk::ImageSubresourceRange{
.aspectMask = guestTexture.format->vkAspect,
.levelCount = texture->mipLevels,
.layerCount = texture->layerCount,
}, guestTexture.format);
}
} */
} }
for (auto &texture : matches) for (auto &texture : matches)