Repository navigation
Control Resonant
Two faults, one fixed by a setting and one hidden rather than fixed. The game plays through on D3DMetal; what it loses is the lit rooms behind the city's windows, which show as dark glass.
| Symptom | Faces and hair render as black boxes; the lit rooms behind windows show as flat violet, cyan and yellow, spreading to neighbouring windows as the camera moves |
| Cause | Faces: Metal 4 on. Windows: one pixel shader, interiorPS, whose non-uniform texture read D3DMetal runs as uniform, plus a second fault, outside the shaders, that shows up after about a minute of play |
| Fix | Metal 4 off for this title; the pipelines built with interiorPS are created writing nothing |
| Backend | D3DMetal, D3D12 |
| CrossOver | Stable 26.3 with Game Porting Toolkit 4.0b2 (2026-09-26) |
With D3DMetal's Metal 4 path on (the default in 4.0b2), faces, skin and hair
render as black boxes. Metal 4 off (D3DM_MTL4=0) cures all of them. It needs
nothing else: D3DM_SAMPLE_NAN_TO_ZERO and D3DM_FLUSH_POS_INF_TO_NAN each
remove part of the damage with Metal 4 on, and neither does all of it.
Keep ray tracing and path tracing off in the game's own settings. With either on the title crashes on this stack.
Found by muting pipelines, eleven rounds of them, until one pixel shader alone
removed every wrong colour from every building at every angle. Its entry point
is interiorPS. It turns a view direction into panorama coordinates and reads a
room image out of an unbounded Texture2D[], with the index marked
NonUniformResourceIndex: neighbouring pixels are meant to read different
rooms.
A rebuilt interiorPS that serves each distinct index in its own pass drew the
rooms as they look on Windows. That shows D3DMetal runs the read as if the index
were uniform, with one pixel's room used for the whole group. The "spreading" the
player sees is exactly that. The rebuilt shader was not enough, though. After
about a minute the colours came back even with every non-uniform shader in the
frame rebuilt, so a second fault lies outside the shaders. Texture streaming is
the suspect. It has not been measured.
A shader substitution that holds for one minute is not a fix, so the shipped DLL
does the one thing that measured clean for a whole session: it keeps
interiorPS from drawing. Every pipeline built with it is created with each
render target's write mask at 0. The rest of the frame is untouched.
The shader is matched by its entry-point name, interiorPS, read from the
string table in its PSV0 part. The first version matched a hash of the whole
shader, and the 2026-10-01 update recompiled it (cc6f0f9fb056f7f5 became
0da4d718f1d70142): the windows came back and the log said 0 pipelines hidden.
Matched by name, the same build hid all four of the new pipelines. An update that
renames the shader is matched by nothing, and the DLL then does nothing.
Seen by the user on 2026-10-13, on CrossOver Preview 27 through NotProton with
D3DMetal 4.0b3 and Metal 4 off: the lit rooms behind the windows drew correctly
with the fix not installed. That it was not installed was checked, not
assumed: the game's own PxFoundation_x64.dll was in place, the installer's
--status said absent, and the fix's log was last written on 2026-10-09.
So 4.0b3 changed something on the D3DMetal side. Which of the two faults above it cured has not been measured. The fix stays, because on 4.0b2 the windows are still wrong without it, and on 4.0b3 it only hides a shader that no longer needs hiding.
Ray tracing still does not work there. With the game's ReSTIR option turned on, the same run did not give working ray tracing.
NVIDIA Streamline wraps the device the game creates, so the game's own device is
never visible to a proxy. The DLL waits for d3d12.dll, creates a device of its
own three seconds later, patches the two pipeline creators of D3DMetal's device
class (CreateGraphicsPipelineState, CreatePipelineState), and releases the
device. The patch is on the class, so it covers the game's device too. Nothing
inside Streamline is touched.
It is carried on PxFoundation_x64.dll, which the game imports; every export is
forwarded to the renamed original. It logs to C:\ctl-window-fix.log in the
bottle, and two minutes in it writes how many pipelines it hid.
runtime/install-ctl-fix.sh "<…>/steamapps/common/CONTROL Resonant"
runtime/install-ctl-fix.sh "<…>/steamapps/common/CONTROL Resonant" --status
runtime/install-ctl-fix.sh "<…>/steamapps/common/CONTROL Resonant" --restore
Or pick the game in the app.
The investigation, round by round, with every candidate shader, is in
diagnostics/ctl-window-shaders.md.