Implement Framebuffer Cache

Implements a cache for storing `VkFramebuffer` objects with a special path on devices with `VK_KHR_imageless_framebuffer` to allow for more cache hits due to an abstract image rather than a specific one. 

Caching framebuffers is a fairly crucial optimization due to the cost of creating framebuffers on TBDRs since it involves calculating tiling memory allocations and in the case of Adreno's proprietary driver involves several kernel calls for mapping and allocating the corresponding framebuffer memory.
This commit is contained in:
PixelyIon
2022-05-01 18:06:55 +05:30
parent af7f0c301e
commit 42573170c6
15 changed files with 336 additions and 73 deletions

View File

@ -277,13 +277,15 @@ namespace skyline::gpu {
texture->CopyToGuest(stagingBuffer ? stagingBuffer->data() : std::get<memory::Image>(texture->backing).data());
}
Texture::Texture(GPU &gpu, BackingType &&backing, texture::Dimensions dimensions, texture::Format format, vk::ImageLayout layout, vk::ImageTiling tiling, u32 mipLevels, u32 layerCount, vk::SampleCountFlagBits sampleCount)
Texture::Texture(GPU &gpu, BackingType &&backing, texture::Dimensions dimensions, texture::Format format, vk::ImageLayout layout, vk::ImageTiling tiling, vk::ImageCreateFlags flags, vk::ImageUsageFlags usage, u32 mipLevels, u32 layerCount, vk::SampleCountFlagBits sampleCount)
: gpu(gpu),
backing(std::move(backing)),
dimensions(dimensions),
format(format),
layout(layout),
tiling(tiling),
flags(flags),
usage(usage),
mipLevels(mipLevels),
layerCount(layerCount),
sampleCount(sampleCount) {}
@ -297,8 +299,9 @@ namespace skyline::gpu {
tiling(vk::ImageTiling::eOptimal), // Force Optimal due to not adhering to host subresource layout during Linear synchronization
mipLevels(1),
layerCount(guest->layerCount),
sampleCount(vk::SampleCountFlagBits::e1) {
vk::ImageUsageFlags usage{vk::ImageUsageFlagBits::eTransferSrc | vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled};
sampleCount(vk::SampleCountFlagBits::e1),
flags(gpu.traits.quirks.vkImageMutableFormatCostly ? vk::ImageCreateFlags{} : vk::ImageCreateFlagBits::eMutableFormat),
usage(vk::ImageUsageFlagBits::eTransferSrc | vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled) {
if ((format->vkAspect & vk::ImageAspectFlagBits::eColor) && !format->IsCompressed())
usage |= vk::ImageUsageFlagBits::eColorAttachment;
if (format->vkAspect & (vk::ImageAspectFlagBits::eDepth | vk::ImageAspectFlagBits::eStencil))
@ -319,14 +322,11 @@ namespace skyline::gpu {
}
}
vk::ImageCreateFlags flags{gpu.traits.quirks.vkImageMutableFormatCostly ? vk::ImageCreateFlags{} : vk::ImageCreateFlagBits::eMutableFormat};
if (imageType == vk::ImageType::e2D && dimensions.width == dimensions.height && layerCount >= 6)
flags |= vk::ImageCreateFlagBits::eCubeCompatible;
else if (imageType == vk::ImageType::e3D)
flags |= vk::ImageCreateFlagBits::e2DArrayCompatible;
vk::ImageCreateInfo imageCreateInfo{
.flags = flags,
.imageType = imageType,