Add quirk to avoid VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT on Adreno GPUs

Adreno GPUs have significant performance penalties from usage of `VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT` which require disabling UBWC and on Turnip, forces linear tiling. As a result, it's been made an optional quirk which doesn't supply the flag in `VkImageCreateInfo` and logs a warning if a view with a different Vulkan format from the original image is created.
This commit is contained in:
PixelyIon 2022-03-12 20:01:52 +05:30
parent 731d06010d
commit 24d7066d8b
3 changed files with 13 additions and 3 deletions

View File

@ -307,7 +307,7 @@ namespace skyline::gpu {
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment; usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
vk::ImageCreateInfo imageCreateInfo{ vk::ImageCreateInfo imageCreateInfo{
.flags = vk::ImageCreateFlagBits::eMutableFormat, .flags = gpu.traits.quirks.vkImageMutableFormatCostly ? vk::ImageCreateFlags{} : vk::ImageCreateFlagBits::eMutableFormat,
.imageType = guest->dimensions.GetType(), .imageType = guest->dimensions.GetType(),
.format = *guest->format, .format = *guest->format,
.extent = guest->dimensions, .extent = guest->dimensions,
@ -528,6 +528,9 @@ namespace skyline::gpu {
++viewIt; ++viewIt;
} }
if (gpu.traits.quirks.vkImageMutableFormatCostly && pFormat->vkFormat != format->vkFormat)
Logger::Warn("Creating a view of a texture with a different format without mutable format");
auto view{std::make_shared<TextureView>(shared_from_this(), type, range, pFormat, mapping)}; auto view{std::make_shared<TextureView>(shared_from_this(), type, range, pFormat, mapping)};
views.push_back(view); views.push_back(view);
return view; return view;

View File

@ -131,6 +131,12 @@ namespace skyline::gpu {
switch (driverProperties.driverID) { switch (driverProperties.driverID) {
case vk::DriverId::eQualcommProprietary: { case vk::DriverId::eQualcommProprietary: {
needsIndividualTextureBindingWrites = true; needsIndividualTextureBindingWrites = true;
vkImageMutableFormatCostly = true; // Disables UBWC
break;
}
case vk::DriverId::eMesaTurnip: {
vkImageMutableFormatCostly = true; // Disables UBWC and forces linear tiling
break; break;
} }
@ -141,8 +147,8 @@ namespace skyline::gpu {
std::string TraitManager::QuirkManager::Summary() { std::string TraitManager::QuirkManager::Summary() {
return fmt::format( return fmt::format(
"\n* Needs Individual Texture Binding Writes: {}", "\n* Needs Individual Texture Binding Writes: {}\n* VkImage Mutable Format is costly: {}",
needsIndividualTextureBindingWrites needsIndividualTextureBindingWrites, vkImageMutableFormatCostly
); );
} }

View File

@ -40,6 +40,7 @@ namespace skyline::gpu {
*/ */
struct QuirkManager { struct QuirkManager {
bool needsIndividualTextureBindingWrites{}; //!< [Adreno Proprietary] A bug that requires descriptor set writes for VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER to be done individually with descriptorCount = 1 rather than batched bool needsIndividualTextureBindingWrites{}; //!< [Adreno Proprietary] A bug that requires descriptor set writes for VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER to be done individually with descriptorCount = 1 rather than batched
bool vkImageMutableFormatCostly{}; //!< [Adreno Proprietary/Freedreno] An indication that VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT is costly and should not be enabled unless absolutely necessary (Disables UBWC on Adreno GPUs)
QuirkManager() = default; QuirkManager() = default;