mirror of
https://github.com/izzy2lost/PSX2.git
synced 2026-07-05 15:18:36 -07:00
mali love incoming. start with detecting mali devices set default settings
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
// SPDX-FileCopyrightText: 2025 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#ifdef __ANDROID__
|
||||
|
||||
#include "AndroidDeviceDetection.h"
|
||||
#include "common/Console.h"
|
||||
#include <sys/system_properties.h>
|
||||
#include <cstring>
|
||||
|
||||
namespace AndroidDeviceDetection
|
||||
{
|
||||
static std::string GetSystemProperty(const char* key)
|
||||
{
|
||||
char value[PROP_VALUE_MAX] = {};
|
||||
if (__system_property_get(key, value) > 0)
|
||||
return std::string(value);
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string GetManufacturer()
|
||||
{
|
||||
return GetSystemProperty("ro.product.manufacturer");
|
||||
}
|
||||
|
||||
std::string GetModel()
|
||||
{
|
||||
return GetSystemProperty("ro.product.model");
|
||||
}
|
||||
|
||||
std::string GetGPURenderer()
|
||||
{
|
||||
// This would need to be called from GL/Vulkan context
|
||||
// For now, we rely on hardware detection
|
||||
return GetSystemProperty("ro.hardware");
|
||||
}
|
||||
|
||||
bool IsMediatek()
|
||||
{
|
||||
std::string hardware = GetSystemProperty("ro.hardware");
|
||||
std::string board = GetSystemProperty("ro.product.board");
|
||||
std::string platform = GetSystemProperty("ro.board.platform");
|
||||
|
||||
// Convert to lowercase for comparison
|
||||
auto toLower = [](std::string str) {
|
||||
for (char& c : str) c = std::tolower(c);
|
||||
return str;
|
||||
};
|
||||
|
||||
hardware = toLower(hardware);
|
||||
board = toLower(board);
|
||||
platform = toLower(platform);
|
||||
|
||||
// Check for Mediatek identifiers
|
||||
return (hardware.find("mt") == 0 ||
|
||||
hardware.find("mediatek") != std::string::npos ||
|
||||
board.find("mt") == 0 ||
|
||||
platform.find("mt") == 0 ||
|
||||
platform.find("mediatek") != std::string::npos);
|
||||
}
|
||||
|
||||
bool IsSnapdragon()
|
||||
{
|
||||
std::string hardware = GetSystemProperty("ro.hardware");
|
||||
std::string board = GetSystemProperty("ro.product.board");
|
||||
std::string platform = GetSystemProperty("ro.board.platform");
|
||||
|
||||
auto toLower = [](std::string str) {
|
||||
for (char& c : str) c = std::tolower(c);
|
||||
return str;
|
||||
};
|
||||
|
||||
hardware = toLower(hardware);
|
||||
board = toLower(board);
|
||||
platform = toLower(platform);
|
||||
|
||||
// Check for Qualcomm/Snapdragon identifiers
|
||||
return (hardware.find("qcom") != std::string::npos ||
|
||||
hardware.find("qualcomm") != std::string::npos ||
|
||||
platform.find("msm") == 0 ||
|
||||
platform.find("sdm") == 0 ||
|
||||
platform.find("sm") == 0 ||
|
||||
platform.find("qcom") != std::string::npos);
|
||||
}
|
||||
|
||||
GPUVendor DetectGPUVendor()
|
||||
{
|
||||
if (IsSnapdragon())
|
||||
{
|
||||
Console.WriteLn("Detected Qualcomm Snapdragon (Adreno GPU)");
|
||||
return GPUVendor::Qualcomm;
|
||||
}
|
||||
|
||||
if (IsMediatek())
|
||||
{
|
||||
Console.WriteLn("Detected Mediatek (Mali GPU)");
|
||||
return GPUVendor::ARM;
|
||||
}
|
||||
|
||||
// Check for other vendors via hardware string
|
||||
std::string hardware = GetSystemProperty("ro.hardware");
|
||||
if (hardware.find("exynos") != std::string::npos)
|
||||
{
|
||||
Console.WriteLn("Detected Samsung Exynos (Mali GPU)");
|
||||
return GPUVendor::ARM;
|
||||
}
|
||||
|
||||
Console.WriteLn("Unknown GPU vendor, hardware: %s", hardware.c_str());
|
||||
return GPUVendor::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // __ANDROID__
|
||||
@@ -0,0 +1,40 @@
|
||||
// SPDX-FileCopyrightText: 2025 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __ANDROID__
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace AndroidDeviceDetection
|
||||
{
|
||||
enum class GPUVendor
|
||||
{
|
||||
Unknown,
|
||||
Qualcomm, // Adreno (Snapdragon)
|
||||
ARM, // Mali (Mediatek, Exynos, etc.)
|
||||
Imagination, // PowerVR
|
||||
Other
|
||||
};
|
||||
|
||||
// Detect GPU vendor from system properties and GL/Vulkan strings
|
||||
GPUVendor DetectGPUVendor();
|
||||
|
||||
// Check if device is Mediatek (Mali GPU)
|
||||
bool IsMediatek();
|
||||
|
||||
// Check if device is Snapdragon (Adreno GPU)
|
||||
bool IsSnapdragon();
|
||||
|
||||
// Get device manufacturer
|
||||
std::string GetManufacturer();
|
||||
|
||||
// Get device model
|
||||
std::string GetModel();
|
||||
|
||||
// Get GPU renderer string (requires GL context or Vulkan device)
|
||||
std::string GetGPURenderer();
|
||||
}
|
||||
|
||||
#endif // __ANDROID__
|
||||
@@ -1127,6 +1127,7 @@ if(ANDROID)
|
||||
../AchievementsJNI.cpp
|
||||
../AchievementsAndroid.cpp
|
||||
../AchievementsNativeMethods.cpp
|
||||
../AndroidDeviceDetection.cpp
|
||||
)
|
||||
elseif(LINUX)
|
||||
target_sources(PCSX2 PRIVATE
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "GS/GSUtil.h"
|
||||
#include "MultiISA.h"
|
||||
#include "common/StringUtil.h"
|
||||
#include "common/Console.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
@@ -22,6 +23,10 @@
|
||||
#include <wil/com.h>
|
||||
#endif
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include "AndroidDeviceDetection.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
struct GSUtilMaps
|
||||
{
|
||||
@@ -213,6 +218,58 @@ GSRendererType GSUtil::GetPreferredRenderer()
|
||||
#elif defined(_WIN32)
|
||||
// Use D3D device info to select renderer.
|
||||
preferred_renderer = D3D::GetPreferredRenderer();
|
||||
#elif defined(__ANDROID__)
|
||||
// Android: Detect GPU vendor and choose appropriate renderer
|
||||
using namespace AndroidDeviceDetection;
|
||||
GPUVendor vendor = DetectGPUVendor();
|
||||
|
||||
if (vendor == GPUVendor::ARM)
|
||||
{
|
||||
// Mediatek/Mali GPUs: Prefer OpenGL over Vulkan
|
||||
// Vulkan drivers on Mali are often buggy, especially on Mediatek
|
||||
// OpenGL works but may have 2D graphics issues that need workarounds
|
||||
Console.Warning("Mediatek/Mali GPU detected: Using OpenGL renderer (Vulkan has known issues)");
|
||||
#if defined(ENABLE_OPENGL)
|
||||
preferred_renderer = GSRendererType::OGL;
|
||||
#elif defined(ENABLE_VULKAN)
|
||||
// Fallback to Vulkan if OpenGL not available (but warn user)
|
||||
Console.Error("OpenGL not available, falling back to Vulkan (may have issues on Mali)");
|
||||
preferred_renderer = GSRendererType::VK;
|
||||
#else
|
||||
preferred_renderer = GSRendererType::SW;
|
||||
#endif
|
||||
}
|
||||
else if (vendor == GPUVendor::Qualcomm)
|
||||
{
|
||||
// Snapdragon/Adreno GPUs: Prefer Vulkan (good driver support)
|
||||
Console.WriteLn("Qualcomm/Adreno GPU detected: Using Vulkan renderer");
|
||||
#if defined(ENABLE_VULKAN)
|
||||
preferred_renderer = GSRendererType::VK;
|
||||
#elif defined(ENABLE_OPENGL)
|
||||
preferred_renderer = GSRendererType::OGL;
|
||||
#else
|
||||
preferred_renderer = GSRendererType::SW;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown vendor: Try Vulkan first, then OpenGL
|
||||
Console.WriteLn("Unknown GPU vendor: Trying Vulkan renderer");
|
||||
#if defined(ENABLE_VULKAN)
|
||||
if (GSDeviceVK::IsSuitableDefaultRenderer())
|
||||
preferred_renderer = GSRendererType::VK;
|
||||
#endif
|
||||
if (preferred_renderer == GSRendererType::Auto)
|
||||
{
|
||||
#if defined(ENABLE_OPENGL)
|
||||
preferred_renderer = GSRendererType::OGL;
|
||||
#elif defined(ENABLE_VULKAN)
|
||||
preferred_renderer = GSRendererType::VK;
|
||||
#else
|
||||
preferred_renderer = GSRendererType::SW;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
// Linux: Prefer Vulkan if the driver isn't buggy.
|
||||
#if defined(ENABLE_VULKAN)
|
||||
|
||||
@@ -18,9 +18,18 @@
|
||||
#include "IconsFontAwesome5.h"
|
||||
|
||||
#include <cinttypes>
|
||||
#include <cctype>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
// Some texture barrier extension macros may not be generated by GLAD for GLES builds.
|
||||
#ifndef GLAD_GL_EXT_texture_barrier
|
||||
#define GLAD_GL_EXT_texture_barrier 0
|
||||
#endif
|
||||
#ifndef GLAD_GL_OES_texture_barrier
|
||||
#define GLAD_GL_OES_texture_barrier 0
|
||||
#endif
|
||||
|
||||
static constexpr u32 g_vs_cb_index = 1;
|
||||
static constexpr u32 g_ps_cb_index = 0;
|
||||
|
||||
@@ -626,24 +635,42 @@ bool GSDeviceOGL::CheckFeatures(bool& buggy_pbo)
|
||||
//bool vendor_id_amd = false;
|
||||
bool vendor_id_nvidia = false;
|
||||
//bool vendor_id_intel = false;
|
||||
bool vendor_id_arm_mali = false;
|
||||
|
||||
const char* vendor = (const char*)glGetString(GL_VENDOR);
|
||||
if (std::strstr(vendor, "Advanced Micro Devices") || std::strstr(vendor, "ATI Technologies Inc.") ||
|
||||
std::strstr(vendor, "ATI"))
|
||||
const char* renderer = (const char*)glGetString(GL_RENDERER);
|
||||
const std::string vendor_str = vendor ? vendor : "";
|
||||
const std::string renderer_str = renderer ? renderer : "";
|
||||
const auto to_lower = [](std::string s) {
|
||||
for (char& c : s)
|
||||
c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
|
||||
return s;
|
||||
};
|
||||
const std::string vendor_lower = to_lower(vendor_str);
|
||||
const std::string renderer_lower = to_lower(renderer_str);
|
||||
|
||||
if (vendor_lower.find("advanced micro devices") != std::string::npos ||
|
||||
vendor_lower.find("ati technologies inc.") != std::string::npos ||
|
||||
vendor_lower.find("ati") != std::string::npos)
|
||||
{
|
||||
Console.WriteLn(Color_StrongRed, "GL: AMD GPU detected.");
|
||||
//vendor_id_amd = true;
|
||||
}
|
||||
else if (std::strstr(vendor, "NVIDIA Corporation"))
|
||||
else if (vendor_lower.find("nvidia corporation") != std::string::npos || vendor_lower.find("nvidia") != std::string::npos)
|
||||
{
|
||||
Console.WriteLn(Color_StrongGreen, "GL: NVIDIA GPU detected.");
|
||||
vendor_id_nvidia = true;
|
||||
}
|
||||
else if (std::strstr(vendor, "Intel"))
|
||||
else if (vendor_lower.find("intel") != std::string::npos)
|
||||
{
|
||||
Console.WriteLn(Color_StrongBlue, "GL: Intel GPU detected.");
|
||||
//vendor_id_intel = true;
|
||||
}
|
||||
else if (vendor_lower.find("arm") != std::string::npos || renderer_lower.find("mali") != std::string::npos)
|
||||
{
|
||||
Console.Warning("GL: ARM Mali GPU detected - applying workarounds for 2D graphics issues.");
|
||||
vendor_id_arm_mali = true;
|
||||
}
|
||||
|
||||
GLint major_gl = 0;
|
||||
GLint minor_gl = 0;
|
||||
@@ -724,7 +751,7 @@ bool GSDeviceOGL::CheckFeatures(bool& buggy_pbo)
|
||||
if (!m_is_gles) {
|
||||
buggy_pbo = !GLAD_GL_VERSION_4_4 && !GLAD_GL_ARB_buffer_storage && !GLAD_GL_EXT_buffer_storage;
|
||||
} else {
|
||||
buggy_pbo = GLAD_GL_EXT_buffer_storage;
|
||||
buggy_pbo = !GLAD_GL_EXT_buffer_storage;
|
||||
}
|
||||
if (buggy_pbo)
|
||||
Console.Warning("GL: Not using PBOs for texture uploads because buffer_storage is unavailable.");
|
||||
@@ -747,12 +774,14 @@ bool GSDeviceOGL::CheckFeatures(bool& buggy_pbo)
|
||||
m_features.framebuffer_fetch = false;
|
||||
}
|
||||
|
||||
const bool has_texture_barrier =
|
||||
GLAD_GL_ARB_texture_barrier || GLAD_GL_EXT_texture_barrier || GLAD_GL_OES_texture_barrier;
|
||||
if (GSConfig.OverrideTextureBarriers == 0)
|
||||
m_features.texture_barrier = m_features.framebuffer_fetch; // Force Disabled
|
||||
else if (GSConfig.OverrideTextureBarriers == 1)
|
||||
m_features.texture_barrier = true; // Force Enabled
|
||||
else
|
||||
m_features.texture_barrier = m_features.framebuffer_fetch || GLAD_GL_ARB_texture_barrier;
|
||||
m_features.texture_barrier = m_features.framebuffer_fetch || has_texture_barrier;
|
||||
if (!m_features.texture_barrier)
|
||||
{
|
||||
// OSD message disabled: GL_ARB_texture_barrier warning
|
||||
@@ -801,6 +830,54 @@ bool GSDeviceOGL::CheckFeatures(bool& buggy_pbo)
|
||||
m_features.line_expand ? "hardware" : (m_features.vs_expand ? "vertex expanding" : "UNSUPPORTED"),
|
||||
m_features.vs_expand ? "vertex expanding" : "CPU");
|
||||
|
||||
// Mali GPU workarounds for missing 2D graphics
|
||||
if (vendor_id_arm_mali)
|
||||
{
|
||||
Console.Warning("GL: Applying Mali GPU workarounds:");
|
||||
|
||||
// Mali has issues with framebuffer fetch - disable it
|
||||
if (m_features.framebuffer_fetch)
|
||||
{
|
||||
Console.Warning(" - Disabling framebuffer fetch (causes 2D graphics issues on Mali)");
|
||||
m_features.framebuffer_fetch = false;
|
||||
}
|
||||
|
||||
// Force texture barriers on Mali
|
||||
if (!m_features.texture_barrier && has_texture_barrier)
|
||||
{
|
||||
Console.Warning(" - Enabling texture barriers (required for proper blending on Mali)");
|
||||
m_features.texture_barrier = true;
|
||||
}
|
||||
else if (!has_texture_barrier)
|
||||
{
|
||||
// Keep barriers disabled so we fall back to safe RT copies instead of no-op barriers.
|
||||
m_features.texture_barrier = false;
|
||||
}
|
||||
|
||||
// Disable vertex shader expansion on Mali (can cause rendering issues)
|
||||
if (m_features.vs_expand)
|
||||
{
|
||||
Console.Warning(" - Disabling vertex shader expansion (unstable on Mali)");
|
||||
m_features.vs_expand = false;
|
||||
}
|
||||
|
||||
// Force PBO usage off on Mali (can cause texture corruption)
|
||||
if (!buggy_pbo)
|
||||
{
|
||||
Console.Warning(" - Disabling PBO for texture uploads (causes corruption on Mali)");
|
||||
buggy_pbo = true;
|
||||
}
|
||||
|
||||
// Disable download PBO as well
|
||||
if (!m_disable_download_pbo)
|
||||
{
|
||||
Console.Warning(" - Disabling PBO for texture downloads (causes corruption on Mali)");
|
||||
m_disable_download_pbo = true;
|
||||
}
|
||||
|
||||
Console.Warning("GL: Mali workarounds applied. If 2D graphics still missing, try Software renderer.");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1368,10 +1445,14 @@ std::string GSDeviceOGL::GenGlslHeader(const std::string_view entry, GLenum type
|
||||
else
|
||||
header += "#define HAS_FRAMEBUFFER_FETCH 0\n";
|
||||
|
||||
if (GLAD_GL_ARB_clip_control)
|
||||
header += "#define HAS_CLIP_CONTROL 1\n";
|
||||
else
|
||||
header += "#define HAS_CLIP_CONTROL 0\n";
|
||||
if (GLAD_GL_ARB_clip_control)
|
||||
{
|
||||
header += "#define HAS_CLIP_CONTROL 1\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
header += "#define HAS_CLIP_CONTROL 0\n";
|
||||
}
|
||||
|
||||
// Allow to puts several shader in 1 files
|
||||
switch (type)
|
||||
|
||||
Reference in New Issue
Block a user