github RenanQueiroz/mcla-recomp v0.2.1

3 hours ago

This release goes on top of v0.2.0 and fixes four things: the rain that was missing at 2x and 3x resolution, the blocky vinyls on the opponents' cars at 2x and 3x, the smear over your car's plate on Vulkan, and the game running out of video memory at 2x and 3x on cards with 6 GB or less. The last one comes with three video memory options, on by default, each with an off switch. There is no other new option and no other performance work (that is for the next release). As before, the launcher and setup wizard build Midnight Club: Los Angeles Complete Edition (Xbox 360, USA/Europe, title 545407F8) from your own disc image, and no game data is in any of the files below.

What changed

The rain is back at 2x and 3x resolution (#17). With the resolution scale above 1 no rain was drawn, on Direct3D 12 and on Vulkan, by day or by night, in races with rain. The game simulates the rain's drops on the graphics card, in four small pictures that it then reads back as the rain's vertex data; with a scaled resolution the emulator kept those pictures only in its own enlarged buffer, so the rain's draw found zeros and drew nothing. The game now also writes the normal-size version of those four pictures where the draw reads them, on the graphics card and without waiting. It is done only above 1x and only for those four pictures. --mcla_rain_unscaled_copy=false turns it off.

  • Checked in the arcade race with rain (RTX 5080): at 2x and 3x, on Direct3D 12 and on Vulkan, the rain streaks are there again (the share of the picture's smooth pixels that change within 3 frames is 0.14 to 0.18, against 0.003 to 0.02 without the fix; the graphics card's own count of the rain draw's pixels went from 0 to 1.9 million at 2x and 4.3 million at 3x). At native resolution nothing changes. The release build was checked again the same way: 0.17 (Direct3D 12 at 2x), 0.17 (Vulkan at 2x), 0.21 (Direct3D 12 at 3x) and 0.17 (Vulkan at 3x), against 0.15 at native resolution and 0.01 with the fix switched off at 2x. The final build, with the video memory changes on: 0.15 (Direct3D 12 at 2x).
  • The cost could not be measured: in one session with the copies switched on and off every 10 seconds the graphics card's time per frame was the same within 2% (4.15 ms with the copies, 4.17 ms without, Direct3D 12 at 2x), and in separate runs the difference (+0.7%) was smaller than the 4% between two runs of the same kind. The game issues those four pictures only in rain: they are not in the logs of the clear races and of 40 seconds of free roam that we looked at.
  • Not checked: that the rain keeps looking right over a long rain (the runs were about 25 seconds), and anything on a weaker graphics card.

The opponents' vinyls are no longer blocky at 2x and 3x (#11, #14). v0.2.0 brought the cars' vinyls back by reading the picture the game paints them in. Above 1x the emulator first shrinks that enlarged picture to the normal size, and the pass that does it read the wrong pixel for half of the pixels at 2x (every second pixel repeated its left neighbour) and for most at 3x. The livery came out coarse. The pass now finds the right pixel (--resolve_downscale_unit_layout=false is the old pass). The same pass is used for the rain above.

  • Checked in the arcade race Sunset and Vine (RTX 5080): at 2x v0.2.0's liveries were stair-stepped (the edges of the 6, PIRELLI and WORK letters on Direct3D 12, the teeth of the green stripes on a hood on Vulkan) and with the fix they are smooth, on both APIs; side by side pictures in launcher/dev/vinyl-downscale-2026-10-28.md in the source. With the release build: at 2x the liveries are smooth on both APIs (the 6, PIRELLI and WORK of the same car on Vulkan), and at 3x on Direct3D 12 the same car's lettering ("brembo" on the rear quarter) is whole in this release and broken up in v0.2.0. Vulkan at 3x was not caught in frame. The final build, with the video memory changes on, showed that car's livery at 2x on Direct3D 12 the same as the build before them at the same moment of the race's intro.
  • Not seen: the vinyls you make in the editor and the story's cars (as in v0.2.0).

The smear over your car's plate is gone on Vulkan (#11). While the camera turned round a moving car, a soft smear covered the plate and the taillights next to the speedometer; Direct3D 12 did not have it. It came from the car's four wheels: the game draws them into the stencil with a pixel shader that writes its own depth, and on Vulkan that depth was twice what the depth buffer holds, so the wheels passed the depth test over the car's body and the game's motion blur smeared what they had marked. Vulkan now scales that depth output as Direct3D 12 does (--vulkan_odepth_float24_scale=false is the old behaviour). The first start after the update compiles the pipelines of the shaders that write depth again.

  • Checked on Vulkan at dusk with the camera orbiting the creeping car (RTX 5080 and the Ryzen's integrated Radeon): with the fix the plate's text is readable in every picture, as on Direct3D 12; with the fix off it is cut off or faded in most pictures from the third of an orbit on. With the car standing there is no smear either way. The release build passed the same orbit on Vulkan.
  • The cost is not measurable: +0.5% (RTX 5080, Vulkan at 3x) and +0.9% (the Radeon, Vulkan at native resolution) in the median frame, against 0.5% to 3% between two runs of the same kind. The older mcla_vulkan_depth_convert option (+21% to +36% of the frame) is no longer needed for this and stays off.
  • Not tested: the reporter's GTX 1060, other drivers, and other scenes: the pictures of the city and of a race with and without the fix differ as much between two runs with the fix as between the fix and off (the traffic is not the same), so they show nothing either way.

The game no longer runs out of video memory at 2x and 3x (#19). Above native resolution the game takes a lot of video memory. On an RTX 5080, v0.2.0 used 1.7 GB at native resolution, 3.9 to 4.0 GB at 2x and 7.5 GB at 3x (Direct3D 12 and Vulkan alike). On a card with 6 GB (the reporter's RTX 3060 laptop) the game ran at 2x at 30 to 60 FPS in free roam and fell to about 5 FPS in the pause menu and at camera cuts (starting a race, crossing the finish line). We believe Windows then moves the game's memory to system memory (we saw that in an imitation, below, not on their card). The biggest part was the picture buffers the emulator makes for each way the game draws: it made each one as tall as the console's whole video memory (up to 8,192 rows) although the game draws at most 736 rows, and it never gave one back. Three changes, each with an off switch, on by default:

  • No picture buffer taller than 1,024 rows (--render_target_max_height=0 turns it off).
  • Buffers that hold no data and were not used for 60 seconds are freed and made again when needed (--render_target_trim_seconds=0).
  • When the game uses 90% of the video memory Windows gives it, buffers idle for 2 seconds are freed and the texture cache's limits are halved (--gpu_memory_pressure_percent=0). --gpu_memory_log_ms=1000 writes what Windows says and what the game holds, once a second, to the log.
  • Checked on an RTX 5080 with 16 GB, Direct3D 12, at 2x, in a run of free roam, a minute of driving, the pause menu and the map, with Windows' own counters for the game's memory (one run of each kind): the game's peak went from 4.1 GB with the three changes off to 3.0 GB with them on (-26%; v0.2.0: 4.0 GB), the picture buffers from 2.2 GB to 1.1 GB, and after a minute of driving the freeing of unused buffers had taken another 0.3 GB. To imitate a small card we held 12 GB of the card's memory out of the game's reach (a development option, --gpu_memory_emulate_mb=3200, Direct3D 12 only), so that Windows had to page the game's memory. With the three changes off, free roam ran at 12 FPS and the pause menu and the map at 0.6 to 0.8 FPS (frames of 1.6 seconds), the report's shape (not its 5 FPS: another card and bus). With them on: 167 to 186 FPS in free roam, 138 FPS in the pause menu, 92 FPS in the map. With plenty of memory the median frame in free roam went from 6.88 to 5.82 ms, and in the pause menu from 7.5 to 9.7 ms in one run and 7.1 ms in another: no cost that could be told from the variation between runs. No draw of the game reached past the 1,024 rows in these runs. The final build, the same run with the three changes on, at 2x and 3x on both APIs (v0.2.0's peaks from the runs above):
Peak video memory of the game v0.2.0 v0.2.1
Direct3D 12, 2x 3,972 MB 2,735 MB (-31%)
Direct3D 12, 3x 7,457 MB 4,954 MB (-34%)
Vulkan, 2x 3,907 MB 2,739 MB (-30%)
Vulkan, 3x 7,460 MB 4,772 MB (-36%)

Free roam's median frame was no longer than v0.2.0's in all four (Direct3D 12: 6.05 against 6.89 ms at 2x, 7.59 against 8.49 at 3x; Vulkan: 5.37 against 6.52, 7.71 against 8.32) and the map's the same within 3%; v0.2.0's numbers come from another session, and the side-by-side comparison under Performance below finds the same frame times, so this is not a speed-up. The pause menu's median varies between runs of one build more than between the builds (6.4 to 12.5 ms in three runs of this build at 2x on Direct3D 12, two of them with the imitated cards below), so these runs say nothing there either way. Again no draw reached the 1,024 rows.

  • A smaller imitated card, 2.6 GB, so that the game reaches 90% of it: the third change triggered (the game's memory went from 90% back to 77 to 80%, twice), and free roam ran at 173 to 217 FPS, the pause menu at 110 FPS and the map at 100. The same with only that part switched off (--gpu_memory_pressure_percent=0): free roam 36 to 50 FPS, the pause menu 36 FPS. With the 3.2 GB imitation the final build ran free roam at 171 to 196 FPS, the pause menu at 155 FPS and the map at 104.
  • Pictures of the city, the pause menu and the map at 2x with the 1,024-row limit on and off (fixed time per frame): no edge, tone or missing object that we could see. The pause menu differs in the swaying palm leaves; the map differs in scattered single pixels (2.3% of them by more than 8 of 255). With the final build each setting was pictured twice: two runs with the limit off differ from each other as much as from a run with it on (the map: 2.0% of the pixels by more than 8 of 255 between the two runs off, 2.0% and 2.4% between those and the run on), so the scattered pixels are the game's own variation between runs. (One more run with the limit on had a different time of day, the sky's colour, in all its pictures, and was left out of this comparison.)
  • Not tested: a real card with 6 GB (the reporter's, which has to say whether it is fixed), the imitated small card on Vulkan (that development option is Direct3D 12 only), the memory at native resolution with the changes, a race with the limit on and off by picture, FSR anti-aliasing, HDR and frame generation with the limit by picture (they ran without errors in the smoke check below), and Linux and the PS5 (the PS5 build applies the same patches but sets none of the options on).

Performance against v0.2.0 on our test PC (Ryzen 7 9800X3D, RTX 5080, Windows 11; the same free-roam and driving route, uncapped, a warm-up and then v0.2.0, v0.2.1, v0.2.1, v0.2.0 in turn; median frame time). The final build, with the three video memory changes on (they act at every scale: the smaller picture buffers and the freeing run all the time), on Direct3D 12: native, free roam 4.47 -> 4.51 ms (one slow run of v0.2.1 at 4.77; the other two 4.45 and 4.51) and driving 4.31 -> 4.30 ms; 2x, 5.74 -> 5.75 and 5.55 -> 5.56 ms; 3x, free roam 8.01 -> 8.00 ms. The drive at 3x ends in one of two places in every build, with the same inputs: into a wall in a dark corner (7.7 to 7.9 ms) or down Highland Avenue with the city in view (8.1 to 8.8 ms). Over 33 runs of v0.2.0, the build without the video memory changes and this one with each change on and off, the frame time was the same within each (7.79 ms with the 1,024-row limit against 7.83 without; 8.27 against 8.29), and which of the two a run got was chance (the slower in 8 of 16 runs with the limit and 4 of 17 without; in the last 12, alternating, 2 of 6 each). The other rows were measured on the build without the video memory changes (the first three fixes only: no change beyond the variation between runs, as expected, since they act only while a car's vinyl is read back, in rain above 1x, and in four draws a frame on Vulkan) and were not repeated with them:

Free roam Driving
RTX 5080, Direct3D 12, native (the build without the video memory changes) 4.45 -> 4.49 ms (one slow run of v0.2.1 at 4.78; the other two 4.49 and 4.46) 4.51 -> 4.34 ms
RTX 5080, Vulkan, native 4.19 -> 4.20 ms 4.42 -> 4.50 ms
RTX 5080, Direct3D 12, 3x (the build without them) 7.99 -> 8.02 ms 7.95 -> 7.77 ms
RTX 5080, Vulkan, 3x 7.86 -> 7.84 ms 8.30 -> 7.92 ms
Integrated Radeon, Direct3D 12, native 38.9 -> 36.7 ms (the first v0.2.0 run was in the iGPU's slow state; the other pair 36.8 and 36.7) 37.7 -> 36.2 ms

Issues this release answers

  • #17 rain missing at 2x and 3x: fixed (Direct3D 12 and Vulkan).
  • #11 the soft smear over the plate and taillights on Vulkan: fixed; the vinyls of the opponents are smooth at 2x and 3x, not only at native resolution.
  • #14 the vinyls: the same fix for 2x and 3x (the story's cars are still not checked).
  • #19 the FPS dropping to about 5 at 2x on a 6 GB card (RTX 3060 laptop): fix added, measured on an RTX 5080 only (the game's peak video memory from 4.0 to 2.7 GB at 2x and from 7.5 to 4.8 to 5.0 GB at 3x, on both APIs; an imitated 3.2 GB card at 138 to 155 FPS in the pause menu instead of 0.8). Not confirmed on a real small card: we need the reporter to say.

Known problems

  • Fine dots may remain at the edges of palm leaves against the sky and in some soft shadows; we could not tell yet whether that is the same problem as #8 or the game's own dithering (as in v0.2.0).
  • The vinyls at 3x on Vulkan were not caught in frame by the check (Direct3D 12 at 3x was); the fix is the same code on both APIs.
  • The video memory fix is not confirmed on a real card with 6 GB. We measured it on an RTX 5080 and an imitation of a small card (Direct3D 12 only). On Vulkan and at 3x we measured the memory and the frame times (above) but did not imitate a small card. If a game still drops to a few FPS in the pause menu or the map at 2x, --gpu_memory_log_ms=1000 (typed under the launcher's Advanced -> More mcla.exe options) puts what the game holds in the log; please attach it to the issue.

Not tested

Tested on Windows with an NVIDIA RTX 5080 and a Ryzen 7 9800X3D, and (the plate, the performance) on the Ryzen's integrated AMD Radeon graphics. Nothing has been run on Intel graphics, on a discrete AMD card, on the older Vega graphics (Ryzen 5700G), on a GTX 1060 (the reporter of the plate), on a card with 6 GB or less (the reporter of the video memory), on a laptop with switchable graphics, on Linux or on the PS5 (the PS5 build applies the same patches and lists them, untested). The smoke check of the whole release (boot, free roam, a drive and the pause menu on both APIs at 1x, 2x and 3x, FSR, frame generation, HDR, the low-end preset, a French profile and the D3D12 debug layer) passed: 24 runs, no errors in the game's log; the same 24 runs passed again on the final build, with the video memory changes on. If you try it, please report how it went in the issues, whether it works or not.

Installing or updating

Already have v0.2.0? Open the launcher. It shows An update is available. Press Update and rebuild; it downloads the new SDK bundle (the fixes are SDK patches) and rebuilds the game. How long that takes from v0.2.0 was not measured (a full build from source took about 2.6 minutes on our test PC). The launcher's own features are unchanged in this release. The first start afterwards compiles some pipelines again on Vulkan (the shaders that write depth), which the launcher's Prepare shaders does before Play.

New install: download MCLA-Setup.exe and run it. It is unsigned, so Windows SmartScreen may stop it the first time; click More info, then Run anyway. The launcher's setup wizard then builds the game from your .iso. It needs the internet and about 10 GB of disk.

Files

Release v0.2.1, built from commit a95aedbe3fbaa1eb3e81bd3ba22ce08c709e14a2 by https://github.com/RenanQueiroz/mcla-recomp/actions/runs/40751785325.

Asset Size SHA-256
MCLA-Setup.exe 58.6 MB 04e4e9fe4918eb9f698e08124cb281e2989dac9293422e7e46007219bbbb23f1
MCLA-Launcher-v0.2.1-win-x64.zip 70.3 MB 1e2adc9f387e0c5ada8c8e2f0ee16213f8bca5c2bf6542b00cd16d78cff32e2f
rexglue-sdk-f5337cdc-a98984561879-llvm-mingw-20250709.zip 28.0 MB 50df0ae675d3a0802bfbc6020343b17dcf9fdf7a29300ed26efe41a4df702dc4
rexglue-sdk-source-f5337cdc-a98984561879.tar.xz 73.0 MB eabe0c09e83e65cca2ef966845e796157a46c7e4318b2b2e89e3d40552d2e7d4
release.json 8.1 KB 67679ffffa5774fd0f710155352d2b828fb2a9bff43c1eaaebc8e92c3791f070
NOTICES.txt 31.9 KB c54f20fb6cf44d98c6676d0c0c4df65d7fba4c1015c93aca20b750190668484e
SHA256SUMS the sums of the six above

release.json is what the launcher's installer reads; NOTICES.txt has the licences and notices of everything in the assets. Every asset has a build-provenance attestation (gh attestation verify <file> -R RenanQueiroz/mcla-recomp).

  • MCLA-Setup.exe: the one file a player downloads. Run it: it installs the launcher for the current user (no administrator rights asked for) in %LOCALAPPDATA%\Programs\MCLA, makes a Start menu and a desktop shortcut and starts it; the launcher's setup wizard then builds the game from the player's own disc image. Unsigned, so Windows SmartScreen may warn (the README says how to go on). The launcher updates itself by downloading this asset (SHA-256 in release.json) and running it with --update.
  • Launcher zip: the same launcher folder as a zip, for anyone who wants it without the installer: unzip and run MclaLauncher.exe; .NET and the Windows App SDK are inside. Unsigned.
  • SDK bundle: the ReXGlue SDK (f5337cdc) with the fork's 64 patches (digest a98984561879), built with llvm-mingw 20250709, and FSR's two runtimes (FidelityFX eee08db1, built with the C runtime linked in, so no Visual C++ Redistributable is needed). scripts/make_pc.ps1 -Toolchain mingw -SdkBundle <this zip> -SdkBundleSha256 <the hash> uses it.
  • Source archive: the corresponding source of the bundle's GPL and LGPL parts (the SDK tree at the pinned commits with the patches applied, and the fork at this commit).
  • game in release.json holds the fingerprints of the supported game (names, sizes and SHA-256 of its files: no content) for the launcher's setup wizard.
  • No game data is in any asset. The game is built on the player's PC, from their own disc.

When publishing: leave the Target as it is (a95aedbe), so that the tag is made on the commit this was built from. The tag must point at a95aedbe3fbaa1eb3e81bd3ba22ce08c709e14a2, which release.json names; the launcher's installer checks that.

Don't miss a new mcla-recomp release

NewReleases is sending notifications on new releases.