Improve ARM64 CPU detection and Android device diagnostics

The fallback CPU table was missing cores found in recent handheld SoCs
(Cortex-A510, A715, X3, A520, A720, X4). Because get_cpu_name() bails out
when any detected MIDR is unknown, a single missing core sent the whole
lookup to the cortex-a78 fallback whenever LLVM host detection returned
"generic".

Display names were also reused as LLVM -mcpu values, which happens to work
for the Cortex names but not for Qualcomm Oryon: the display name lowercased
to "x-elite", which is not an LLVM processor, so the JIT silently lost
per-CPU scheduling. Entries now carry an explicit canonical LLVM name
alongside the human-readable one; get_cpu_brand() keeps using the latter.
The Qualcomm entry is named "Oryon" rather than "X-Elite" because MIDR
0x51/0x001 only identifies an Oryon core, not the SoC it sits in.

MIDRs cannot identify the SoC at all, which made bug reports ambiguous.
Android's own SOC_MANUFACTURER/SOC_MODEL are now passed to the core and
logged as a separate "SoC:" line, so SoC identity, core topology and the
resolved LLVM target are three distinct values. The LLVM target reported by
system info now comes from the same resolution path the JIT uses, rather
than from the fallback alone, so it no longer disagrees with the target
actually compiled for.

The Vulkan renderer logs one verdict for the adapter it selected, recording
whether BC1-BC3 support keeps DXT textures compressed or whether they are
decoded on the CPU. It sits in render_device::create rather than where the
flag is resolved, because physical_device::create runs for every GPU of
every instance, and not in TextureUtils, whose fallback branches run per
texture and per mip level.

SoC information travels through a new optional _rpcsx_setSocInfo export
instead of an added _rpcsx_initialize parameter. The core is dlopen()ed and
can be updated independently of the JNI glue, so changing an existing
export's signature would make older glue call it with a garbage argument.
Older glue simply never calls the setter, and newer glue null-checks the
symbol against older cores.

No JIT feature policy and no texture decoding behaviour changed.

Verified on an AYN Odin 3 (ayn CQ8725S, 8x Oryon, Adreno 830) running
Turnip 26.2.99: SoC line reads "ayn CQ8725S (Snapdragon 8 Elite-class)",
the brand line reports Oryon rather than X-Elite, the JIT resolves to
oryon-1, and a single BC verdict reports the GPU path. That BC result
applies to the Turnip driver tested; stock-driver behaviour is unmeasured.
This commit is contained in:
Zulux91
2026-08-10 01:43:45 -04:00
committed by jpolo1224
parent 76b556a492
commit 27465da4ce
10 changed files with 234 additions and 48 deletions
+1 -1
View File
@@ -1086,13 +1086,13 @@ const char * fallback_cpu_detection()
#ifdef ANDROID
static std::string s_result = []() -> std::string
{
// get_cpu_name() already returns a canonical LLVM processor name
std::string result = aarch64::get_cpu_name();
if (result.empty())
{
return "cortex-a78";
}
std::transform(result.begin(), result.end(), result.begin(), ::tolower);
return result;
}();
@@ -20,6 +20,7 @@ struct RPCSXApi {
bool (*overlayPadData)(int port, int digital1, int digital2, int leftStickX,
int leftStickY, int rightStickX, int rightStickY);
bool (*initialize)(std::string_view rootDir, std::string_view user);
void (*setSocInfo)(std::string_view socInfo);
bool (*processCompilationQueue)(JNIEnv *env);
bool (*startMainThreadProcessor)(JNIEnv *env);
bool (*collectGameInfo)(JNIEnv *env, std::string_view rootDir,
@@ -104,6 +105,7 @@ struct RPCSXLibrary : RPCSXApi {
// clang-format off
result.overlayPadData = reinterpret_cast<decltype(overlayPadData)>(dlsym(handle, "_rpcsx_overlayPadData"));
result.initialize = reinterpret_cast<decltype(initialize)>(dlsym(handle, "_rpcsx_initialize"));
result.setSocInfo = reinterpret_cast<decltype(setSocInfo)>(dlsym(handle, "_rpcsx_setSocInfo"));
result.processCompilationQueue = reinterpret_cast<decltype(processCompilationQueue)>(dlsym(handle, "_rpcsx_processCompilationQueue"));
result.startMainThreadProcessor = reinterpret_cast<decltype(startMainThreadProcessor)>(dlsym(handle, "_rpcsx_startMainThreadProcessor"));
result.collectGameInfo = reinterpret_cast<decltype(collectGameInfo)>(dlsym(handle, "_rpcsx_collectGameInfo"));
@@ -200,7 +202,7 @@ extern "C" JNIEXPORT jboolean JNICALL Java_net_rpcsx_RPCSX_overlayPadData(
}
extern "C" JNIEXPORT jboolean JNICALL Java_net_rpcsx_RPCSX_initialize(
JNIEnv *env, jobject, jstring rootDir, jstring user) {
JNIEnv *env, jobject, jstring rootDir, jstring user, jstring socInfo) {
// The core is dlopen()ed separately and may not be up yet -- during
// onboarding, or if it failed to load. Calling through a null pointer
// is an instant SIGSEGV, so fail the call instead.
@@ -208,6 +210,12 @@ extern "C" JNIEXPORT jboolean JNICALL Java_net_rpcsx_RPCSX_initialize(
return false;
}
// Before initialize(), which is where the core assembles its startup log.
// Null on cores older than this export; the SoC line then reads "unknown".
if (rpcsxLib.setSocInfo != nullptr) {
rpcsxLib.setSocInfo(unwrap(env, socInfo));
}
return rpcsxLib.initialize(unwrap(env, rootDir), unwrap(env, user));
}
@@ -83,4 +83,53 @@ object DeviceTier {
} catch (_: Throwable) {
"unknown"
}
/** Known annotations for exact SoC model strings. Exact matches only —
* equivalences are never guessed from CPU topology.
*
* CQ8725S is the Qualcomm Dragonwing Q8 part in the AYN Odin 3, confirmed
* from the device itself (ro.soc.model=CQ8725S, reporting 8 Oryon cores and
* an Adreno 830). "-class" is deliberate: it is 8 Elite-family silicon, not
* a claim that the part is identical to the phone SKU. */
private val socAnnotations = mapOf(
"QCS8550" to "Snapdragon 8 Gen 2-class",
"QCS9075" to "Snapdragon 8 Elite-class",
"CQ8725S" to "Snapdragon 8 Elite-class",
)
/** Android reports missing Build fields as the literal [Build.UNKNOWN]
* ("unknown") rather than null, so that value counts as "not reported" —
* otherwise diagnostics read "unknown unknown" instead of falling back to
* Build.HARDWARE. */
private fun String?.orNotReported(): String? =
this?.takeIf { it.isNotBlank() && !it.equals(Build.UNKNOWN, ignoreCase = true) }
/**
* Pure, JVM-testable formatter for the device's SoC identity, e.g.
* "Qualcomm QCS8550 (Snapdragon 8 Gen 2-class)".
*
* The model is what identifies the SoC, so a manufacturer on its own is not
* an identity: without a model this falls back to [hardware], the platform
* codename, which at least names the silicon. Model strings without a known
* annotation are preserved unchanged. Returns "" when nothing is reported.
*/
fun formatSocIdentity(manufacturer: String?, model: String?, hardware: String?): String {
val socModel = model.orNotReported()
?: return hardware.orNotReported() ?: ""
val base = listOfNotNull(manufacturer.orNotReported(), socModel).joinToString(" ")
val annotation = socAnnotations[socModel]
return if (annotation != null) "$base ($annotation)" else base
}
/** SoC identity from Android's public fields: Build.SOC_MANUFACTURER /
* Build.SOC_MODEL on API 31+, Build.HARDWARE before that. */
fun socIdentity(): String = try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
formatSocIdentity(Build.SOC_MANUFACTURER, Build.SOC_MODEL, Build.HARDWARE)
else
formatSocIdentity(null, null, Build.HARDWARE)
} catch (_: Throwable) {
""
}
}
@@ -67,13 +67,8 @@ class AboutViewModel(application: Application) : AndroidViewModel(application) {
val memoryInfo = ActivityManager.MemoryInfo().also(activityManager::getMemoryInfo)
val metrics = context.resources.displayMetrics
val pageBytes = runCatching { Os.sysconf(OsConstants._SC_PAGESIZE) }.getOrDefault(4096L)
val soc = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
listOf(Build.SOC_MANUFACTURER, Build.SOC_MODEL).filter(String::isNotBlank).joinToString(" ")
} else {
Build.HARDWARE
}
return DeviceDetails(
soc = soc.ifBlank { "" },
soc = com.armsx2.DeviceTier.socIdentity().ifBlank { "" },
gpu = queryGpuRenderer().ifBlank { "" },
cpu = Runtime.getRuntime().availableProcessors().toString(),
memory = String.format(Locale.US, "%.1f GB", memoryInfo.totalMem / 1_073_741_824.0),
@@ -123,7 +123,7 @@ object Rpcs3Bridge {
// Discard database configs split by an older build, so a setting later found to
// break a game is not left applying forever on machines that already downloaded.
runCatching { com.armsx2.config.ConfigDatabase.purgeIfStale() }
RPCSX.instance.initialize(RPCSX.rootDirectory, "00000001")
RPCSX.instance.initialize(RPCSX.rootDirectory, "00000001", com.armsx2.DeviceTier.socIdentity())
RPCSX.initialized = true
// Two blocking service loops the core needs someone to run for it.
@@ -72,7 +72,7 @@ enum class BootResult
class RPCSX {
external fun openLibrary(path: String): Boolean
external fun getLibraryVersion(path: String): String?
external fun initialize(rootDir: String, user: String): Boolean
external fun initialize(rootDir: String, user: String, socInfo: String): Boolean
external fun installFw(fd: Int, progressId: Long): Boolean
external fun install(fd: Int, progressId: Long): Boolean
/** Install several .pkg parts of one split package together, in order. */
@@ -0,0 +1,86 @@
package com.armsx2
import org.junit.Assert.assertEquals
import org.junit.Test
class DeviceTierTest {
@Test
fun qcs8550IsAnnotated() {
assertEquals(
"Qualcomm QCS8550 (Snapdragon 8 Gen 2-class)",
DeviceTier.formatSocIdentity("Qualcomm", "QCS8550", "kalama"),
)
}
@Test
fun qcs9075IsAnnotated() {
assertEquals(
"Qualcomm QCS9075 (Snapdragon 8 Elite-class)",
DeviceTier.formatSocIdentity("Qualcomm", "QCS9075", "sun"),
)
}
/** AYN Odin 3, as reported by the device: ro.soc.manufacturer=ayn,
* ro.soc.model=CQ8725S. */
@Test
fun cq8725sIsAnnotated() {
assertEquals(
"ayn CQ8725S (Snapdragon 8 Elite-class)",
DeviceTier.formatSocIdentity("ayn", "CQ8725S", "qcom"),
)
}
@Test
fun unknownModelPassesThroughUnchanged() {
assertEquals(
"Qualcomm SM8550",
DeviceTier.formatSocIdentity("Qualcomm", "SM8550", "kalama"),
)
}
@Test
fun blankManufacturerKeepsModel() {
assertEquals(
"QCS8550 (Snapdragon 8 Gen 2-class)",
DeviceTier.formatSocIdentity("", "QCS8550", "kalama"),
)
}
@Test
fun blankModelAndManufacturerFallBackToHardware() {
assertEquals("kalama", DeviceTier.formatSocIdentity("", "", "kalama"))
assertEquals("kalama", DeviceTier.formatSocIdentity(null, null, "kalama"))
}
/** A manufacturer with no model does not identify the SoC. */
@Test
fun manufacturerWithoutModelFallsBackToHardware() {
assertEquals("kalama", DeviceTier.formatSocIdentity("Qualcomm", "", "kalama"))
}
@Test
fun nothingKnownReturnsEmpty() {
assertEquals("", DeviceTier.formatSocIdentity("", "", ""))
assertEquals("", DeviceTier.formatSocIdentity(null, null, null))
}
/** Android fills unset Build fields with the literal "unknown". */
@Test
fun unknownSentinelFallsBackToHardware() {
assertEquals("kalama", DeviceTier.formatSocIdentity("unknown", "unknown", "kalama"))
assertEquals("kalama", DeviceTier.formatSocIdentity("Qualcomm", "unknown", "kalama"))
}
@Test
fun unknownSentinelWithNoHardwareReturnsEmpty() {
assertEquals("", DeviceTier.formatSocIdentity("unknown", "unknown", "unknown"))
}
@Test
fun unknownManufacturerStillKeepsRealModel() {
assertEquals(
"QCS8550 (Snapdragon 8 Gen 2-class)",
DeviceTier.formatSocIdentity("unknown", "QCS8550", "kalama"),
)
}
}
+29 -4
View File
@@ -113,6 +113,9 @@ static std::atomic<bool> g_paused_by_surface_loss;
extern std::string g_android_executable_dir;
extern std::string g_android_config_dir;
extern std::string g_android_cache_dir;
// Exact SoC identity as reported by Android (Build.SOC_MANUFACTURER/SOC_MODEL),
// handed in through _rpcsx_setSocInfo. MIDRs cannot identify the SoC.
static std::string g_android_soc_info;
static std::mutex g_virtual_pad_mutex;
// One per PS3 pad port. This was a single pad, which silently capped local
// co-op at one player: every port above the first registered a Pad the app
@@ -2112,6 +2115,19 @@ extern "C" bool _rpcsx_overlayPadData(int port, int digital1, int digital2,
return true;
}
// Hand the core Android's exact SoC identity. Deliberately a separate export
// rather than an extra _rpcsx_initialize parameter: the core is dlopen()ed and
// can be updated independently of the JNI glue that calls it, so changing an
// existing export's signature would make older glue call it with a garbage
// argument. Glue that predates this export simply never calls it, and glue that
// has it null-checks the symbol against older cores.
//
// Must be called before _rpcsx_initialize, which is where the startup messages
// are assembled.
extern "C" void _rpcsx_setSocInfo(std::string_view socInfo) {
g_android_soc_info = std::string(socInfo);
}
extern "C" bool _rpcsx_initialize(std::string_view rootDir,
std::string_view user) {
auto rootDirStr = fix_dir_path(std::string(rootDir));
@@ -2174,6 +2190,11 @@ extern "C" bool _rpcsx_initialize(std::string_view rootDir,
logs::stored_message ver{rpcsx_android.always()};
ver.text = fmt::format("RPCSX-ps3-android v%s", rpcs3::get_version().to_string());
// Write exact SoC identity (from Android, not inferred from MIDRs)
logs::stored_message soc{rpcsx_android.always()};
soc.text = fmt::format(
"SoC: %s", g_android_soc_info.empty() ? "unknown" : g_android_soc_info);
// Write System information
logs::stored_message sys{rpcsx_android.always()};
sys.text = utils::get_system_info();
@@ -2186,8 +2207,8 @@ extern "C" bool _rpcsx_initialize(std::string_view rootDir,
logs::stored_message time{rpcsx_android.always()};
time.text = fmt::format("Current Time: %s", std::chrono::system_clock::now());
logs::set_init(
{std::move(ver), std::move(sys), std::move(os), std::move(time)});
logs::set_init({std::move(ver), std::move(soc), std::move(sys), std::move(os),
std::move(time)});
auto set_rlim = [](int resource, std::uint64_t limit) {
rlimit64 rlim{};
@@ -3787,8 +3808,12 @@ extern "C" bool _rpcsx_installKey(JNIEnv *env, int fd, long progressId,
extern "C" std::string _rpcsx_systemInfo() {
std::string result;
fmt::append(result, "%s\n\nLLVM CPU: %s\n\n", utils::get_system_info(),
fallback_cpu_detection());
// LLVM CPU reports the same resolution path the JIT actually uses (configured
// CPU -> LLVM host detection -> project fallback), not just the fallback guess.
fmt::append(result, "SoC: %s\n\n%s\n\nLLVM CPU: %s\n\n",
g_android_soc_info.empty() ? "unknown" : g_android_soc_info,
utils::get_system_info(),
jit_compiler::cpu(g_cfg.core.llvm_cpu.to_string()));
{
vk::instance device_enum_context;
@@ -17,7 +17,8 @@ namespace aarch64
u32 part;
const char* arch;
const char* family;
const char* name;
const char* name; // Human-readable display name
const char* llvm_name; // Canonical LLVM processor name (valid -mcpu), see 3rdparty/llvm TargetParser/Host.cpp
};
struct cpu_vendor_t
@@ -50,42 +51,50 @@ namespace aarch64
static cpu_entry_t s_cpu_list[] =
{
// ARM
{ 0x41, 0xd01, "armv8-a+crc+simd", "", "Cortex-A32" },
{ 0x41, 0xd04, "armv8-a+crc+simd", "", "Cortex-A35" },
{ 0x41, 0xd03, "armv8-a+crc+simd", "", "Cortex-A53" },
{ 0x41, 0xd07, "armv8-a+crc+simd", "", "Cortex-A57" },
{ 0x41, 0xd08, "armv8-a+crc+simd", "", "Cortex-A72" },
{ 0x41, 0xd09, "armv8-a+crc+simd", "", "Cortex-A73" },
{ 0x41, 0xd05, "armv8.2-a+fp16+dotprod", "", "Cortex-A55" },
{ 0x41, 0xd0a, "armv8.2-a+fp16+dotprod", "", "Cortex-A75" },
{ 0x41, 0xd0b, "armv8.2-a+fp16+dotprod", "", "Cortex-A76" },
{ 0x41, 0xd0e, "armv8.2-a+fp16+dotprod", "", "Cortex-A76ae" },
{ 0x41, 0xd0d, "armv8.2-a+fp16+dotprod", "", "Cortex-A77" },
{ 0x41, 0xd41, "armv8.2-a+fp16+dotprod", "", "Cortex-A78" },
{ 0x41, 0xd42, "armv8.2-a+fp16+dotprod", "", "Cortex-A78ae" },
{ 0x41, 0xd4b, "armv8.2-a+fp16+dotprod", "", "Cortex-A78c" },
{ 0x41, 0xd47, "armv9-a+fp16+bf16+i8mm", "", "Cortex-A710" },
{ 0x41, 0xd44, "armv8.2-a+fp16+dotprod", "", "Cortex-X1" },
{ 0x41, 0xd4c, "armv8.2-a+fp16+dotprod", "", "Cortex-X1c" },
{ 0x41, 0xd0c, "armv8.2-a+fp16+dotprod", "", "Neoverse-N1" },
{ 0x41, 0xd40, "armv8.4-a+fp16+bf16+i8mm", "", "Neoverse-V1" },
{ 0x41, 0xd49, "armv8.5-a+fp16+bf16+i8mm", "", "Neoverse-N2" },
{ 0x41, 0xd23, "armv8.1-m.main+pacbti+mve.fp+fp.dp", "", "Cortex-M85" },
{ 0x41, 0xd13, "armv8-r+crc+simd", "", "Cortex-R52" },
{ 0x41, 0xd16, "armv8-r+crc+simd", "", "Cortex-R52+" },
{ 0x41, 0xd01, "armv8-a+crc+simd", "", "Cortex-A32", "cortex-a32" },
{ 0x41, 0xd04, "armv8-a+crc+simd", "", "Cortex-A35", "cortex-a35" },
{ 0x41, 0xd03, "armv8-a+crc+simd", "", "Cortex-A53", "cortex-a53" },
{ 0x41, 0xd07, "armv8-a+crc+simd", "", "Cortex-A57", "cortex-a57" },
{ 0x41, 0xd08, "armv8-a+crc+simd", "", "Cortex-A72", "cortex-a72" },
{ 0x41, 0xd09, "armv8-a+crc+simd", "", "Cortex-A73", "cortex-a73" },
{ 0x41, 0xd05, "armv8.2-a+fp16+dotprod", "", "Cortex-A55", "cortex-a55" },
{ 0x41, 0xd0a, "armv8.2-a+fp16+dotprod", "", "Cortex-A75", "cortex-a75" },
{ 0x41, 0xd0b, "armv8.2-a+fp16+dotprod", "", "Cortex-A76", "cortex-a76" },
{ 0x41, 0xd0e, "armv8.2-a+fp16+dotprod", "", "Cortex-A76ae", "cortex-a76ae" },
{ 0x41, 0xd0d, "armv8.2-a+fp16+dotprod", "", "Cortex-A77", "cortex-a77" },
{ 0x41, 0xd41, "armv8.2-a+fp16+dotprod", "", "Cortex-A78", "cortex-a78" },
{ 0x41, 0xd42, "armv8.2-a+fp16+dotprod", "", "Cortex-A78ae", "cortex-a78ae" },
{ 0x41, 0xd4b, "armv8.2-a+fp16+dotprod", "", "Cortex-A78c", "cortex-a78c" },
{ 0x41, 0xd46, "armv9-a+fp16+bf16+i8mm", "", "Cortex-A510", "cortex-a510" },
{ 0x41, 0xd47, "armv9-a+fp16+bf16+i8mm", "", "Cortex-A710", "cortex-a710" },
{ 0x41, 0xd4d, "armv9-a+fp16+bf16+i8mm", "", "Cortex-A715", "cortex-a715" },
{ 0x41, 0xd4e, "armv9-a+fp16+bf16+i8mm", "", "Cortex-X3", "cortex-x3" },
{ 0x41, 0xd80, "armv9.2-a+fp16+bf16+i8mm", "", "Cortex-A520", "cortex-a520" },
{ 0x41, 0xd81, "armv9.2-a+fp16+bf16+i8mm", "", "Cortex-A720", "cortex-a720" },
{ 0x41, 0xd82, "armv9.2-a+fp16+bf16+i8mm", "", "Cortex-X4", "cortex-x4" },
{ 0x41, 0xd44, "armv8.2-a+fp16+dotprod", "", "Cortex-X1", "cortex-x1" },
{ 0x41, 0xd4c, "armv8.2-a+fp16+dotprod", "", "Cortex-X1c", "cortex-x1c" },
{ 0x41, 0xd0c, "armv8.2-a+fp16+dotprod", "", "Neoverse-N1", "neoverse-n1" },
{ 0x41, 0xd40, "armv8.4-a+fp16+bf16+i8mm", "", "Neoverse-V1", "neoverse-v1" },
{ 0x41, 0xd49, "armv8.5-a+fp16+bf16+i8mm", "", "Neoverse-N2", "neoverse-n2" },
{ 0x41, 0xd23, "armv8.1-m.main+pacbti+mve.fp+fp.dp", "", "Cortex-M85", "cortex-m85" },
{ 0x41, 0xd13, "armv8-r+crc+simd", "", "Cortex-R52", "cortex-r52" },
{ 0x41, 0xd16, "armv8-r+crc+simd", "", "Cortex-R52+", "cortex-r52plus" },
// APPLE
{ 0x61, 0x22, "armv8.5-a", "M1", "Firestorm" },
{ 0x61, 0x23, "armv8.5-a", "M1", "IceStorm" },
{ 0x61, 0x28, "armv8.5-a", "M1 Max", "Firestorm" },
{ 0x61, 0x29, "armv8.5-a", "M1 Max", "Icestorm" },
{ 0x61, 0x24, "armv8.5-a", "M1 Pro", "Firestorm" },
{ 0x61, 0x25, "armv8.5-a", "M1 Pro", "Icestorm" },
{ 0x61, 0x32, "armv8.5-a", "M2", "Avalanche" },
{ 0x61, 0x33, "armv8.5-a", "M2", "Blizzard" },
{ 0x61, 0x22, "armv8.5-a", "M1", "Firestorm", "apple-m1" },
{ 0x61, 0x23, "armv8.5-a", "M1", "IceStorm", "apple-m1" },
{ 0x61, 0x28, "armv8.5-a", "M1 Max", "Firestorm", "apple-m1" },
{ 0x61, 0x29, "armv8.5-a", "M1 Max", "Icestorm", "apple-m1" },
{ 0x61, 0x24, "armv8.5-a", "M1 Pro", "Firestorm", "apple-m1" },
{ 0x61, 0x25, "armv8.5-a", "M1 Pro", "Icestorm", "apple-m1" },
{ 0x61, 0x32, "armv8.5-a", "M2", "Avalanche", "apple-m2" },
{ 0x61, 0x33, "armv8.5-a", "M2", "Blizzard", "apple-m2" },
// QUALCOMM
{ 0x51, 0x01, "armv8.5-a", "Snapdragon", "X-Elite" },
// MIDR 0x51/0x001 only identifies an Oryon core; it appears in X Elite and
// 8 Elite/QCS9075-class SoCs alike, so the display name stays generic.
{ 0x51, 0x01, "armv8.5-a", "Snapdragon", "Oryon", "oryon-1" },
};
static const cpu_vendor_t* find_cpu_vendor(u64 id)
@@ -173,7 +182,7 @@ namespace aarch64
}
}
return lowest_part_info ? lowest_part_info->name : "";
return lowest_part_info ? lowest_part_info->llvm_name : "";
}
std::string get_cpu_brand()
+14
View File
@@ -580,6 +580,20 @@ namespace vk
float queue_priorities[1] = { 0.f };
pgpu = &pdev;
// Verdict for the adapter actually in use. Logged here rather than where the
// flag is resolved, because physical_device::create() runs for every GPU of
// every VkInstance (system-info queries make their own), and rather than in
// TextureUtils, whose fallback branches run per texture and per mip level.
// Reads the resolved flag, so the V3DV/PanVK exceptions still apply.
if (get_texture_compression_bc_support())
{
rsx_log.notice("BC1-BC3 texture compression supported; compressed DXT uploads use the GPU path.");
}
else
{
rsx_log.warning("BC1-BC3 texture compression unavailable; compressed DXT textures use CPU decoding.");
}
ensure(graphics_queue_idx == present_queue_idx || present_queue_idx == umax); // TODO
std::vector<VkDeviceQueueCreateInfo> device_queues;