GT4Recomp 1.3.0-rc15
Release candidate. An optimised build of both games: profile-guided optimisation (PGO) and ThinLTO. The wheel has been
tested on one setup so far.
A release candidate of 1.3.0: racing wheels drive a virtual Logitech Driving Force Pro with the game's own force
feedback, set up on a new Wheel page; the performance HUD gets FPS only and Full modes; the Steam Deck no longer makes the game
wait for the screen; the launcher repeats an interrupted shader preparation by itself; a richer system report; Vulkan
correctness fixes; and a little less processor work in races. The race itself is unchanged.
New
-
Built with a profile (PGO and ThinLTO). Both game executables are compiled with profile-guided optimisation and ThinLTO
from a fresh profile of each game (the recorded Spec II and v2.00 scenes: the George V Paris lap at 1x and 2x, the two night
races and the Arcade path), and the EE library is rebuilt with the same profile. The code is the rc15 code; only its
generated machine code is better chosen. -
Native Driving Force Pro wheel (TASK-018, pull request #205 by WaimateWihongi; TASK-181). Gran Turismo 4 sees a Logitech
Driving Force Pro on its own USB port and runs its own wheel driver unchanged: an OHCI USB controller model and a virtual DFP
(descriptors, the 8-byte input report, the force command decoder) built into the game, with the game's USB code reaching the
model through a pinned USB capsule (private/slice409-usb-runtime,docs/inputs/slice409-usb-runtime.json). Steering is native
14-bit over the 900 degrees the game sets; the game's own force feedback (its aligning force, the menu centring spring,
friction) is played on the host wheel through SDL3 haptics. Any SDL3 wheel goes through the DFP: there is no pad bridge any
more (mode = "pad", the withdrawn 1.2.x bridge, is refused; 1.2.xwheel.tomlfiles load and are migrated). Force feedback
has one owner thread, sends only the effects whose parameters changed (at most one call per game command while racing,
instead of about 400 a second), stops once on focus loss and closes the device before the joysticks at exit. Awheel.toml
the game refuses never stops the game: it runs without the wheel and says why in its log. Details and limits:
docs/WHEEL-NATIVE-DFP.md. -
Effect toggles in place of Performance Mode (TASK-186). Performance Mode is gone: each thing it changed is its own
switch on Settings > Graphics, on by default (the game drawn exactly as the original). Sun glare and light flares (both
renderers: the game answers the flare visibility table with zeros itself, so nothing is drawn and the processor never waits
for the table), Road sheen (CoreGS 2.0: the full-screen sheen pass and the alpha fills that fed it), Small effects
(CoreGS 2.0: Full resolution, the default, or Lower, the preset's 1x for the small effect pictures inside a scaled frame),
and, for GSdx, the two settings the old preset also wrote: Blending accuracy (High, the default, or Minimum, about 1.5 ms
less per frame on the weak laptop, measured in TASK-118) and Readbacks (Accurate again by default, or No readbacks, with
the side effects of the non-accurate value in the help text; the other three values of the row before TASK-091 are not
offered because the gt4-gs 1.2.1 the launcher runs ignores them, and they come back when a gt4-gs build accepts them). A
stored Performance Mode = On migrates to every effect off, Lower small effects, Minimum blending and Accurate readbacks
(settings schema 8 to 9); no
effect toggle touches the readback mode. -
The launcher's Wheel page (TASK-181; Settings > Wheel). An on-screen wheel that turns at the real wheel's angle, and live
accelerator, brake, clutch and handbrake travel with what the game receives; "Set up the wheel" captures the steering, the
three pedals and every DFP button, one press each, for any wheel. Pedal direction, dead zone, saturation and curve; force
feedback on/off, strength, damping and direction, a Test force button, and "force feedback in the last game", read from the
newest session log. Presets can be saved and shared. Play passes the wheel file (GT4_WHEEL_FILE, andwheel_file=in
game.ini) and releases every SDL joystick and haptic handle so the game owns the wheel. Built on the 1.2.x wheel UI by
JulioHeroZ with luanantony (pull request #101). -
Wheel page after the owner's G27 test (TASK-189; the rc15 wheel review). Mapping is one action: a click on a control of
the drawing (or on its Map button, or A on the pad) opens a small capture popup named for that control, which waits for the
button, the axis or the pedal, offers Clear in the same popup, and closes on Esc, B or Cancel. Nothing is guessed any more: a
wheel the launcher has no preset for starts with every control unassigned (the old family template's guessed indices are gone;
genericmaps nothing), and the two cards that repeated what the top-right badge already said are gone: "Your wheel" is
removed and the 900-degree advice is now the Rotation row's tooltip, while the badge reads "Connected" without the USB ID.
The launcher ships a preset for the Logitech G27 (USB046D:C29B, the owner's own mapping,crates/gt4l-core/assets/wheel-presets/)
that applies by itself when a G27 is detected and the player has no mapping of their own, and the page says which preset was
applied; the mechanism is a table, so another wheel gets one by adding an entry. The "Racing wheel in the game" switch is gone:
Play plugs the virtual DFP in exactly when a wheel is connected and leaves it out when none is (the stored[wheel] enabled
value of an earlier file is no longer a player setting, and is rewritten at Play, logged); SDL3 without a device list keeps the
stored value so a Start right at boot does not lose the wheel. The force feedback card is tidy at 1366x768 and at 1920x1080:
one compact result line under Test force, and the "force feedback in the last game" row is only drawn when the game actually
reported it. -
Performance HUD modes (TASK-175). Graphics > Performance HUD is now Off, FPS only or Full (
GT4_HW_HUD=fpsor1; a stored
"on" reads as Full). Full shows the graphics card and processor names in full (they wrap, never cut) and a Report line (Idle,
Recording during an F7 interval, Saved for 3 s after F8) when the performance report is on. -
Presentation off the GS thread on one-queue graphics cards (TASK-174, TASK-174b; issue #204, Steam Deck). On a GPU whose
graphics family has a single queue (RADV on the Steam Deck), CoreGS 2.0 used to acquire the swapchain image and present on its
GS thread, so the display's waits fell on the game. The GS thread now draws the frame into its own picture and hands it to the
presentation thread, which acquires, copies and presents on the same queue under one lock; a frame the presentation side
cannot take is left out and counted. Graphics > "Presentation thread (one-queue GPUs)", on by default; it is shown as already
active on cards with two or more graphics queues, and off passesGT4_HW_PRESENT_SHARED_QUEUE=0(the old path). Desktop test
with one queue forced (v2.00 night race at 2x, indicative): the GS thread's presentation step 0.04 ms instead of about 0.5 ms.
Design and limits:docs/PRESENTATION-ONE-QUEUE.md. -
Richer system report (TASK-174b). The log bundle's
system.txtadds the CPU model, cores and threads with SSE4.1 and
AVX2, total and available RAM, the Windows edition, Wine or Proton with the host system, a readable Vulkan driver version and
the Windows driver version, each monitor's refresh rate and scale, free space on the game data drive, power source and battery,
the graphics family's queue count, the connected controllers and (TASK-181) the connected wheels and whether the virtual DFP is
on. No computer name, user name, serial number or path. The bundle also carrieswheel.toml. -
Fractional GSdx render scales and OpenGL (TASK-200). The Render scale is a percentage of the screen's automatic
multiplier (k = ceil(max(W / 640, H / 448)): 3x at 1080p, 6x at 4K). 100% is exactlykand never below the screen; a
lower percentage scales it and lands on the accepted multiplier closest tok x percentage / 100(an exact tie goes up).
The new gt4-gs 1.3.0 adds 1.25x, 1.5x, 1.75x and 2.5x to the whole values, so 1080p at 75% gives 2.5x instead of 2x and
4K at 50% gives 3x; the labels name the 16:9 picture (2x = 1280x720, 2.5x = 1600x900). The same gt4-gs allows OpenGL
(Renderer = 12), offered after Direct3D 11 for older PCs; Automatic still resolves to Vulkan or Direct3D 11. The
launcher installs gt4-gs 1.3.0 from its pre-release (no other launcher's automatic picker takes a pre-release) and keeps
whole numbers and the three APIs until it is installed. gt4-gs stays a separate GPL process (decision 0070).
Fixes
-
Integrated graphics now start at the screen's resolution (TASK-200). The TASK-105 default that played an untouched
100% at 1x on an integrated GPU is gone: 100% is the screen's automatic multiplier on every card, and the player lowers
the Render scale (now with the finer steps) when a race is too heavy. -
The wheel no longer pulls itself to the centre (TASK-192). GT4 centres the wheel with a spring of its own in the menus.
The game sent it and it was played exactly as asked, which some wheels read as a slow return to the centre that never stops
(the owner's Logitech G27, 2026-11-06: "from the moment the game opens, the wheel keeps slowly coming back to the centre,
all the time"; the game's own 15% damping floor in that session'swheel.tomlmade it slow and the steering heavy). It is
off by default now through a new[ffb] centering_spring = "off" | "game"key inwheel.toml(gamerestores the old
behaviour, and 1.2.x files still load). Everything else is unchanged: the tyres' aligning force, the kerbs, the bumps, the
friction, GT4's own force feedback strength setting and the damping setting.game.lognow ends with a census of the force
commands the game sent (each command and effect type with its count), so a later report says which effects a session used
without turning the trace on. -
Force feedback now follows PCSX2's behaviour (TASK-194). Four differences from the reference were removed, on the owner's
G27 report that PCSX2 does not pull the wheel to the centre in a race:- the DFP's "default spring on" command (
F4) is ignored completely, as PCSX2 ignores it, and no default spring is ever
played; a USB reset no longer brings one back (F5and the "set default spring" command stay harmless); - with
[ffb] centering_spring = "game", GT4's own spring now really stops when the game stops it (23 0B): the SDL spring
effect is stopped, instead of a zero-saturation spring being sent, and a spring downloaded on another slot replaces the
old parameters instead of the last active slot's parameters keeping the wheel; - friction uses the two coefficient bytes separately:
21 0E 80 FF 20is 0.5 on the left, 1.0 on the right and a 0.125
clip (the max of the two used to double the left side); - the damping floor defaults to 0 (PCSX2 applies no damper, and GT4 sends none in a race), and the shipped G27 preset sets
damper = 0.0.
centering_springstaysoffby default, and Settings > Wheel > Force feedback has the matching row, Centring spring:
Off (the default) or Follow the game, with its tooltip.
- the DFP's "default spring on" command (
-
A settings option changes only through its arrows (TASK-193). An option row (
< value >) treated its whole control as one
tap target, so a tap next to the small arrow stepped to the next value, in the wrong direction from the player's point of
view. With a mouse or a finger, only the arrows change a value now: the left arrow steps back and the right arrow forward,
and a click on the row's label or value writes nothing. The keyboard and the pad are unchanged (Left/Right step the row, A
goes to the next value). Each arrow keeps its 24 px drawing but gets an invisible hit area of 32 x 32 px with a mouse and
44 x 44 px with a finger, so the row looks exactly as before. A row label also never splits a word any more: it wraps
between words only. -
The shader preparation is repeated by the launcher (TASK-170b, TASK-170c). After rc14's guard, a graphics driver that
closed the game inside a shader compile cost the player one game start per left-out shader. The launcher now runs the
preparation again by itself while each attempt gets further (up to 20 attempts, "Preparing shaders again, attempt N"), and
starts the game only when it finished or stopped making progress. A shader is left out only after it ended two runs (a
first end makes it a suspect, compiled again; a normal end clears it), so an intermittent driver crash no longer costs a
shader. Suspects and left-out shaders are logged with their decoded fields, and the log bundle carries
logs/shader-guard.txt(the guard files' headers and keys) and every attempt inlogs/shaders.log. -
Vulkan correctness (TASK-179, Android plan stage A1, on Windows). Two device features CoreGS 2.0 used without enabling them
are now enabled where present, with exact fallbacks where not: wide points (largePoints; else each point is drawn as two
triangles) and indexed history images in the deinterlace kernel (else a constant-index build). The device check no longer
requires four formats nothing creates. The swapchain's pre-transform is the identity wherever the surface takes it
(rotation-safe; unchanged on Windows). CoreGS 2.0's mapped rings are sized from the heap's budget (VK_EXT_memory_budget),
with today's sizes as the cap. A[hw] device profileline records the device's capabilities. On the RX 9060 XT nothing
changes: every feature is present and the shader modules are byte-identical. -
Saves work when the install and the save library are on different drives (TASK-188, issue #208). The runtime card the game
reads lives in the install'sdatafolder and the save library with its card backups lives in%APPDATA%, so on a PC whose
game is on one drive and Windows on another the launcher moved the card between volumes with a plain rename, which Windows
refuses (os error 17, "the system cannot move the file to a different disk drive"). Deleting the active save therefore did
nothing, pressing New save failed with that error, and the card left in place was harvested again at the next Play, so a save
deleted by hand came back. Every move of the card now goes through one helper: it renames when both places are on one volume
(unchanged, atomic, and it still replaces the target in one step) and, across volumes, copies, checks every file against its
source (size and SHA-256 for card images and folders) and only then removes the source. Deleting the active save now clears
the card wherever it lives, and a save deleted by hand in%APPDATA%no longer returns because the stale card was harvested.
The same helper parks the pre-1.0 save library when that move crosses drives. Found by reading the code and reproduced by unit
and flow tests that injectERROR_NOT_SAME_DEVICE.
Performance
- Less work on GT4's tone passes (TASK-168, TASK-168b). About 1,500 draws per VBlank in the player's view belong to the game's
colour-tone passes, which CoreGS 2.0 already replaces with one GPU pass. Those draws are now dropped as the front end emits
them, and a palette load walks the drawn targets once instead of three times. On the Avell (RTX 3060 laptop), George V Paris
replay at 1x, medians of three runs each against the code without these changes: wall time per VBlank 12.55 ms instead of
12.94 ms, the GS thread 10.86 ms instead of 11.02 ms, the palette-load stage 0.92 ms instead of 1.17 ms; at 6x the difference
is within the run-to-run spread.
Palette segments (several palettes in one batch, TASK-168) are built in but off by default (GT4_CORE2_PALETTE_SEGMENTS=1
turns them on): on GT4 they gave no gain. - Submission after a waited readback (TASK-178), off by default.
GT4_CORE2_SUBMIT_AFTER_WAIT=Ksubmits after K batches
following the per-frame light-flare read. Measured on the Avell (18 runs at 6x) it gave no gain, so it stays off; its
counters (drains, GPU idle after a drain, flare reply hashes) stay for the next study.
The same game
Against the published rc14 builds (PGO), on this optimised build of both games (PGO and ThinLTO from a fresh profile of each
game, the EE libraries rebuilt with that profile, the USB capsule built in; no wheel file, so the virtual wheel is not plugged
in):
- Code generation only: this build is the rc15 code with a profile; the pins name the executable, the profile and the EE
library of each target, and the gates below show the game itself behaves as before. - Physics: the race clock at every VBlank and the whole simulation state, byte for byte, on three recorded Spec II laps
(George V Paris, El Capitan, Tokyo R246) and on the v2.00 night race with 5 AI cars. - Frames: every compared frame identical: 24, 35 and 35 on the three Spec II laps at 1x, 12 of 12 on a lap at 6x, 10 of 10
on the v2.00 night race at 3x and 14 of 14 on the v2.00 Arcade path at 3x. - Checks while running, against the exact interpreter: 236,448 VU1 samples and 39,731 VU0 samples on Spec II, 355,388 VU1
and 56,156 VU0 on v2.00, and the MTVU check over 8,032 frames, all with 0 differences. - Effect toggles (TASK-186): with every effect on (the default) the frames and the flare replies are the rc15 ones; with every
effect off they are the old Performance Mode's; each toggle alone changes only its own effect and keeps the race clock and the
simulation state. The CoreGS 2.0 fixturehw_core2_effect_toggleschecks each switch against its older A/B, the whole set
againstGT4_CORE2_PERFORMANCE=1and the flare table answered as zeros; the GSdx stream fixture does the same for the
game-side flare answer. (Measured on the plain rc15 test build; the renderer code is the same here.) - Tests: native tests 318 of 319 on each game (one texture-replacement case skipped without its dumps; 605.7 s and 584.4 s),
Python 804 (57 skipped); launcher 778 tests (9 ignored), focus checks 396/396 (en-US) and 403/403 (pt-BR), navigation tests
265/265; locale keys identical in both languages (917).
Known issues
- Racing wheels: tested on hardware on one setup so far (a MOZA R5 with v2.00); Spec II and other wheels are not tested on
hardware yet. On fast straights a strong direct-drive base can oscillate at about 2 Hz, as the original DFP did (GT4's force
near the centre lags the wheel by about 40 ms). The wheel must be set to 900 degrees in its own software. - Photo mode on slower graphics cards (CoreGS 2.0): each picture still waits for the graphics card twice, so frame times can
be uneven (TASK-162). - An earlier Spec II release (not 1.10) is refused at setup: its mod code differs from 1.10's (TASK-172).
Thanks
- WaimateWihongi, for the native Driving Force Pro wheel (pull request #205).
- JulioHeroZ and luanantony, whose 1.2.x wheel page (pull request #101) the new Wheel page is built on.
- The Steam Deck player who reported issue #204, and the player on Discord whose shader logs led to the guard and its retry.
Install or update
- From an earlier 1.3.0 build: run the installer below, or update from the launcher's Beta channel; settings, saves and
replays are kept. - Installer: run
GT4Recomp-Setup-1.3.0-rc15.exe. - Portable: unpack
GT4Recomp-1.3.0-rc15-portable.zipanywhere. Settings, saves and data stay inside the folder. - After the update, Play may compile CoreGS 2.0's shaders once, as after every update.
- Racing wheel: connect it, start its own software (G HUB, Logitech Profiler, Pit House...) with 900 degrees, then open
Settings > Wheel, check the detected model and run "Set up the wheel" if it is not mapped. The wheel goes into the game by
itself while it is connected. - Disc images: you need your own: Gran Turismo 4 (USA, v2.00), and your own Spec II 1.10 image for the mod. GT4Recomp ships no
copyrighted game files.
Requirements
Windows 10 or 11, 64-bit, a processor with SSE4.1. CoreGS 2.0 needs a graphics card with Vulkan 1.2.
Credits and legal
Our code is MIT. GSdx is the PCSX2 GS (GPL-3.0-or-later), downloaded by the launcher and run in its own process; the game
executable contains no GPL code. The OHCI controller model is written from the public OpenHCI specification, and the DFP's
descriptors are written fresh. FSR1 sharpening is written from AMD's published MIT design.