mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
quality presets: an unrecognised GPU gets Medium, not Ultra; honest docs
Nothing is measured about an unknown GPU, so the fallback no longer assumes Ultra's extra work (supersampling above the display, title Ultra extras); Low would drop Smooth motion and the PGXP extras on what is usually capable new hardware. Medium keeps the display's resolution with dynamic resolution under it. Covers unnamed renderers, Linux with only an AMD PCI id, and unnamed nouveau chips. docs/QUALITY_PRESETS.md states plainly that autodetect is a static heuristic over name, threads and memory with no benchmark, and that the dynamic systems keep the frame rate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+25
-16
@@ -58,29 +58,38 @@ name is the fallback when the probe fails, and the probe is skipped under the
|
||||
renderer too.
|
||||
|
||||
`quality_tier.c` maps the facts to a tier. It is a pure function, unit-tested in
|
||||
`recompiler/tests/quality_presets_test.cpp`. **Autodetect is a static
|
||||
heuristic that picks only Low or Ultra**: it classifies the hardware it reads
|
||||
and measures nothing. A GPU it does not recognise gets Ultra. Medium and High
|
||||
are manual choices. Low-end machines start on Low.
|
||||
Every other machine starts on Ultra, and the dynamic systems are its safety
|
||||
net: dynamic resolution (a title can floor it at native x1), Smooth motion's
|
||||
in-between frames (made from surplus only) and the adaptive aspect.
|
||||
`recompiler/tests/quality_presets_test.cpp` against a table of real
|
||||
`GL_RENDERER` strings from Windows drivers, Mesa and macOS.
|
||||
|
||||
**What it is, and what it is not.** Autodetect is a static heuristic over the
|
||||
GPU name, the CPU thread count and the memory size. It measures nothing:
|
||||
there is no benchmark, and a name says nothing about clocks, thermals or the
|
||||
driver. It is a first-launch starting point, and the dynamic systems
|
||||
(dynamic resolution down to the title's floor, Smooth motion's in-between
|
||||
frames made from surplus only, the adaptive aspect) are what actually keep
|
||||
the frame rate.
|
||||
|
||||
| Class | Detected |
|
||||
| --- | --- |
|
||||
| Software GL, Steam Deck (Van Gogh), mobile GPUs, every integrated GPU up to the Radeon 890M / Iris Xe / Arc iGPU class, Apple M1 and M2 base chips, GeForce MX/GT | Low |
|
||||
| Everything else: discrete GPUs, Apple M3 and later, any Pro/Max/Ultra chip, Strix Halo (8050S/8060S), unknown GPUs | Ultra |
|
||||
| A GPU the rules do not recognise (including Linux with only an AMD PCI id, and unnamed nouveau chips) | Medium |
|
||||
| Recognised capable GPUs: discrete RX/RTX/GTX/Arc A/B cards, Apple M3 and later, any Pro/Max/Ultra chip, Strix Halo (8050S/8060S) | Ultra |
|
||||
|
||||
Fewer than 5 CPU threads, or under 6 GB of memory, also gives Low. No mid
|
||||
class is detected as Medium: on every in-between part measured, either Low's
|
||||
savings or Ultra's dynamic floor decided it. There is no timed benchmark
|
||||
yet; the probe is the GPU class, thread count and memory.
|
||||
Fewer than 5 CPU threads, or under 6 GB of memory, also gives Low. High is a
|
||||
manual choice. If the detected tier is not offered, the highest offered tier
|
||||
below it is used, or failing that the lowest one above it.
|
||||
|
||||
**Why unknown is Medium.** Nothing about an unrecognised GPU is known, so the
|
||||
fallback must not assume Ultra's extra work (supersampling above the display,
|
||||
and whatever a title adds there, such as R4's mipmaps, 16x aniso and bloom).
|
||||
Low would also be wrong for what is usually new hardware: it gives up
|
||||
Smooth motion and the PGXP extras on machines that can almost always run
|
||||
them. Medium keeps the display's own resolution with dynamic resolution
|
||||
under it, which is the safe middle. A player can pick any preset at any
|
||||
time.
|
||||
|
||||
The classifier reads the `GL_RENDERER` string as Windows drivers, Mesa and
|
||||
macOS report it; the unit test holds a table of real strings from all three.
|
||||
On Linux, when the GL probe fails, the sysfs PCI id is used instead (Steam
|
||||
Deck parts, Intel integrated vs Arc, NVIDIA); an AMD id alone cannot tell an
|
||||
APU from a card, so it falls through to Ultra.
|
||||
Deck parts, Intel integrated vs Arc, NVIDIA).
|
||||
|
||||
## When detection runs, and what is saved
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ static void test_classify() {
|
||||
PSX_QUALITY_ULTRA, "RTX 4080: Ultra");
|
||||
check(tier(host("x", "llvmpipe (LLVM 17.0.6, 256 bits)", 16, 32)) == PSX_QUALITY_LOW,
|
||||
"software GL: Low");
|
||||
check(tier(host("x", "Some Future GPU", 16, 32)) == PSX_QUALITY_ULTRA, "unknown GPU: Ultra");
|
||||
check(tier(host("x", "Some Future GPU", 16, 32)) == PSX_QUALITY_MEDIUM, "unknown GPU: Medium (conservative)");
|
||||
check(tier(host("AMD Ryzen 7 9800X3D 8-Core Processor", "AMD Radeon(TM) Graphics", 16, 48)) ==
|
||||
PSX_QUALITY_LOW, "2-CU Radeon iGPU: Low");
|
||||
check(tier(host("x", "NVIDIA GeForce RTX 3060", 4, 16)) == PSX_QUALITY_LOW,
|
||||
@@ -208,7 +208,8 @@ static void test_renderer_table() {
|
||||
{"Mesa Intel(R) Arc(tm) Graphics (MTL)", PSX_QUALITY_LOW},
|
||||
{"Mesa Intel(R) Arc(tm) A750 Graphics (DG2)", PSX_QUALITY_ULTRA},
|
||||
{"NVIDIA GeForce RTX 3060/PCIe/SSE2", PSX_QUALITY_ULTRA},
|
||||
{"NV167 (nouveau)", PSX_QUALITY_ULTRA},
|
||||
{"NV167 (nouveau)", PSX_QUALITY_MEDIUM}, /* unnamed chip: unknown */
|
||||
{"Virtio-GPU Venus (Some Future GPU)", PSX_QUALITY_MEDIUM},
|
||||
{"llvmpipe (LLVM 17.0.6, 256 bits)", PSX_QUALITY_LOW},
|
||||
{"zink Vulkan 1.3(AMD Radeon Graphics (RADV RENOIR) (MESA_RADV))", PSX_QUALITY_LOW},
|
||||
/* macOS */
|
||||
|
||||
@@ -38,7 +38,7 @@ int psx_quality_from_name(const char *name);
|
||||
|
||||
/* The preset this host should start from, and one line saying why
|
||||
* ("AMD integrated GPU: Low"). Ultra unless the class cannot hold 60 Hz even
|
||||
* at the dynamic floor; unknown hardware gets Ultra. */
|
||||
* at the dynamic floor; unknown hardware gets Medium. */
|
||||
int psx_quality_classify(const PsxHostInfo *h, char *reason, size_t reason_cap);
|
||||
|
||||
/* Nearest preset the title offers (bit i of offered_mask = tier i): the
|
||||
|
||||
@@ -51,9 +51,10 @@ static int apple_gen(const char *s, int *variant) {
|
||||
/* Autodetect picks between Low and Ultra only (owner decision 2026-10-08):
|
||||
* low-end machines -- software GL, the Steam Deck's APU, mobile GPUs, every
|
||||
* integrated GPU up to the 890M class, Apple M1/M2 base chips, GeForce MX/GT
|
||||
* -- start on Low; everything else, unknown GPUs included, starts on Ultra
|
||||
* -- start on Low; recognised capable GPUs start on Ultra
|
||||
* with dynamic resolution, Smooth motion from surplus and the adaptive aspect
|
||||
* as the safety net. Medium and High are manual choices.
|
||||
* as the safety net. A GPU the rules do not recognise gets Medium (see
|
||||
* psx_quality_classify). High is a manual choice.
|
||||
*
|
||||
* The input is a GL_RENDERER string as Windows drivers, Mesa and macOS
|
||||
* report it ("AMD Radeon(TM) Graphics", "AMD Radeon RX Vega 11 Graphics",
|
||||
@@ -154,7 +155,7 @@ static int pci_tier(const char *id, const char **why) {
|
||||
return PSX_QUALITY_LOW;
|
||||
}
|
||||
if (vendor == 0x10de) { *why = "NVIDIA GPU (PCI id)"; return PSX_QUALITY_ULTRA; }
|
||||
return -1; /* AMD: the id alone does not tell an APU from a card */
|
||||
return -1; /* AMD: the id alone does not tell an APU from a card (=> Medium) */
|
||||
}
|
||||
|
||||
int psx_quality_classify(const PsxHostInfo *h, char *reason, size_t reason_cap) {
|
||||
@@ -171,7 +172,13 @@ int psx_quality_classify(const PsxHostInfo *h, char *reason, size_t reason_cap)
|
||||
if (tier < 0 && g[0]) tier = gpu_tier(g, &why);
|
||||
if (tier < 0 && !g[0] && h && h->gpu_id[0]) tier = pci_tier(h->gpu_id, &why);
|
||||
if (tier < 0) tier = gpu_tier(c, &why); /* Apple: the CPU names the GPU */
|
||||
if (tier < 0) { tier = PSX_QUALITY_ULTRA; why = "unknown GPU"; }
|
||||
/* Unrecognised GPU: Medium, not Ultra. Nothing was measured, so the
|
||||
* expensive Ultra-only work (1.5x supersampling, mipmaps + 16x aniso,
|
||||
* bloom) is not assumed; Medium keeps the display's own resolution,
|
||||
* Smooth motion from surplus and the PGXP extras, which Low would drop
|
||||
* on what is often new, capable hardware. A title without Medium falls
|
||||
* to the nearest lower preset (psx_quality_pick_offered). */
|
||||
if (tier < 0) { tier = PSX_QUALITY_MEDIUM; why = "unknown GPU"; }
|
||||
|
||||
/* Only what the dynamic systems cannot absorb: too few CPU threads for
|
||||
* the emulation + render threads, or too little memory. */
|
||||
|
||||
Reference in New Issue
Block a user