From 970f7993df79518c4ca5c7f3dd20212720dc3c09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 27 Feb 2023 23:59:57 +0100 Subject: [PATCH] Android: Make font rendering work even absent support for R4G4B4A4 textures. This shouldn't normally happen as conforming drivers are required to support that texture format, but the software driver that we accidentally choose on Poco C40 (see issue #16391) doesn't. That we choose that driver will be fixed separately. This fix on its own at least lets the user comfortably navigate to settings and switch to OpenGL. --- Common/GPU/Vulkan/VulkanContext.cpp | 4 ++-- Common/GPU/Vulkan/VulkanLoader.cpp | 1 + Common/GPU/Vulkan/thin3d_vulkan.cpp | 4 +++- Common/GPU/thin3d.h | 6 ++++++ Common/Render/Text/draw_text_android.cpp | 9 +++++++-- Common/Render/Text/draw_text_android.h | 1 + GPU/Common/FramebufferManagerCommon.cpp | 1 + 7 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Common/GPU/Vulkan/VulkanContext.cpp b/Common/GPU/Vulkan/VulkanContext.cpp index fe15710d7040..a8e2a1846c53 100644 --- a/Common/GPU/Vulkan/VulkanContext.cpp +++ b/Common/GPU/Vulkan/VulkanContext.cpp @@ -535,7 +535,7 @@ int VulkanContext::GetBestPhysicalDevice() { void VulkanContext::ChooseDevice(int physical_device) { physical_device_ = physical_device; - INFO_LOG(G3D, "Chose physical device %d: %p", physical_device, physical_devices_[physical_device]); + INFO_LOG(G3D, "Chose physical device %d: %s", physical_device, physicalDeviceProperties_[physical_device].properties.deviceName); GetDeviceLayerProperties(); if (!CheckLayers(device_layer_properties_, device_layer_names_)) { @@ -711,7 +711,7 @@ VkResult VulkanContext::CreateDevice() { } else { VulkanLoadDeviceFunctions(device_, extensionsLookup_); } - INFO_LOG(G3D, "Vulkan Device created"); + INFO_LOG(G3D, "Vulkan Device created: %s", physicalDeviceProperties_[physical_device_].properties.deviceName); VulkanSetAvailable(true); VmaAllocatorCreateInfo allocatorInfo = {}; diff --git a/Common/GPU/Vulkan/VulkanLoader.cpp b/Common/GPU/Vulkan/VulkanLoader.cpp index 2a00ed962229..2a3778554465 100644 --- a/Common/GPU/Vulkan/VulkanLoader.cpp +++ b/Common/GPU/Vulkan/VulkanLoader.cpp @@ -470,6 +470,7 @@ bool VulkanMayBeAvailable() { case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: anyGood = true; + INFO_LOG(G3D, "VulkanMayBeAvailable: Eligible device found: '%s'", props.deviceName); break; default: INFO_LOG(G3D, "VulkanMayBeAvailable: Ineligible device found and ignored: '%s'", props.deviceName); diff --git a/Common/GPU/Vulkan/thin3d_vulkan.cpp b/Common/GPU/Vulkan/thin3d_vulkan.cpp index b0c74c5c761e..2d58bebdc839 100644 --- a/Common/GPU/Vulkan/thin3d_vulkan.cpp +++ b/Common/GPU/Vulkan/thin3d_vulkan.cpp @@ -742,7 +742,9 @@ bool VKTexture::Create(VkCommandBuffer cmd, VulkanPushBuffer *push, const Textur usageBits |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; } - if (!vkTex_->CreateDirect(cmd, width_, height_, 1, mipLevels_, vulkanFormat, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, usageBits)) { + VkComponentMapping r8AsAlpha[4] = { VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_R }; + + if (!vkTex_->CreateDirect(cmd, width_, height_, 1, mipLevels_, vulkanFormat, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, usageBits, desc.swizzle == TextureSwizzle::R8_AS_ALPHA ? r8AsAlpha : nullptr)) { ERROR_LOG(G3D, "Failed to create VulkanTexture: %dx%dx%d fmt %d, %d levels", width_, height_, depth_, (int)vulkanFormat, mipLevels_); return false; } diff --git a/Common/GPU/thin3d.h b/Common/GPU/thin3d.h index 9a427027a986..3013470e95d8 100644 --- a/Common/GPU/thin3d.h +++ b/Common/GPU/thin3d.h @@ -598,6 +598,11 @@ struct DeviceCaps { // Important: only write to the provided pointer, don't read from it. typedef std::function TextureCallback; +enum class TextureSwizzle { + DEFAULT, + R8_AS_ALPHA, +}; + struct TextureDesc { TextureType type; DataFormat format; @@ -607,6 +612,7 @@ struct TextureDesc { int depth; int mipLevels; bool generateMips; + TextureSwizzle swizzle; // Optional, for tracking memory usage and graphcis debuggers. const char *tag; // Does not take ownership over pointed-to data. diff --git a/Common/Render/Text/draw_text_android.cpp b/Common/Render/Text/draw_text_android.cpp index b6ada98a94c5..1cc3dc9d1ed6 100644 --- a/Common/Render/Text/draw_text_android.cpp +++ b/Common/Render/Text/draw_text_android.cpp @@ -27,7 +27,10 @@ TextDrawerAndroid::TextDrawerAndroid(Draw::DrawContext *draw) : TextDrawer(draw) ERROR_LOG(G3D, "Failed to find class: '%s'", textRendererClassName); } dpiScale_ = CalculateDPIScale(); - INFO_LOG(G3D, "Initializing TextDrawerAndroid with DPI scale %f", dpiScale_); + + use4444Format_ = (draw->GetDataFormatSupport(Draw::DataFormat::R4G4B4A4_UNORM_PACK16) & Draw::FMT_TEXTURE) != 0; + + INFO_LOG(G3D, "Initializing TextDrawerAndroid with DPI scale %f, use4444=%d", dpiScale_, (int)use4444Format_); } TextDrawerAndroid::~TextDrawerAndroid() { @@ -244,7 +247,8 @@ void TextDrawerAndroid::DrawString(DrawBuffer &target, const char *str, float x, entry = iter->second.get(); entry->lastUsedFrame = frameCount_; } else { - DataFormat texFormat = Draw::DataFormat::R4G4B4A4_UNORM_PACK16; + // Actually, I don't know why we don't always use R8_UNORM.. + DataFormat texFormat = use4444Format_ ? Draw::DataFormat::R4G4B4A4_UNORM_PACK16 : Draw::DataFormat::R8_UNORM; entry = new TextStringEntry(); @@ -260,6 +264,7 @@ void TextDrawerAndroid::DrawString(DrawBuffer &target, const char *str, float x, desc.depth = 1; desc.mipLevels = 1; desc.generateMips = false; + desc.swizzle = use4444Format_ ? Draw::TextureSwizzle::DEFAULT : Draw::TextureSwizzle::R8_AS_ALPHA, desc.tag = "TextDrawer"; entry->texture = draw_->CreateTexture(desc); cache_[key] = std::unique_ptr(entry); diff --git a/Common/Render/Text/draw_text_android.h b/Common/Render/Text/draw_text_android.h index 4b95bdeb7576..f4b7e431e6ca 100644 --- a/Common/Render/Text/draw_text_android.h +++ b/Common/Render/Text/draw_text_android.h @@ -40,6 +40,7 @@ class TextDrawerAndroid : public TextDrawer { jmethodID method_renderText; uint32_t fontHash_; + bool use4444Format_ = false; std::map fontMap_; diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index deba2f8d39af..91005fd71ca7 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -1384,6 +1384,7 @@ Draw::Texture *FramebufferManagerCommon::MakePixelTexture(const u8 *srcPixels, G 1, 1, false, + Draw::TextureSwizzle::DEFAULT, "DrawPixels", { (uint8_t *)srcPixels }, generateTexture,