mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 19:21:55 +01:00
Match mip layers and array layers in texture manager
This commit is contained in:
parent
d502adb309
commit
3ae1e78544
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user