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.
This commit is contained in:
Henrik Rydgård 2023-02-27 23:59:57 +01:00
parent ca8af6f4c7
commit 970f7993df
7 changed files with 21 additions and 5 deletions

View File

@ -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 = {};

View File

@ -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);

View File

@ -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;
}

View File

@ -598,6 +598,11 @@ struct DeviceCaps {
// Important: only write to the provided pointer, don't read from it.
typedef std::function<bool(uint8_t *data, const uint8_t *initData, uint32_t w, uint32_t h, uint32_t d, uint32_t byteStride, uint32_t sliceByteStride)> 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.

View File

@ -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<TextStringEntry>(entry);

View File

@ -40,6 +40,7 @@ private:
jmethodID method_renderText;
uint32_t fontHash_;
bool use4444Format_ = false;
std::map<uint32_t, AndroidFontEntry> fontMap_;

View File

@ -1384,6 +1384,7 @@ Draw::Texture *FramebufferManagerCommon::MakePixelTexture(const u8 *srcPixels, G
1,
1,
false,
Draw::TextureSwizzle::DEFAULT,
"DrawPixels",
{ (uint8_t *)srcPixels },
generateTexture,