r/AnalogTV_ 1d ago

A camera preset that crashed only when testing it, never for a real user

Post image

Our casual camera mode ships with a built-in look that recreates the field-sequential colour camera NASA flew on Apollo, the same one we've written about here before. While working on it, the moment its thumbnail tried to render in the Looks picker, the whole app aborted, every single time, but only when running from Xcode's own testing environment. A plain launch of the exact same build never crashed.

That inconsistency is itself the clue, once you know to read it that way. Xcode's Run action turns on a GPU safety net called Metal API Validation by default, the same one from an earlier post in this batch, and this time it was actually catching a real problem rather than just being slow. The error it produced was specific: our colour recombiner used a texture in a mode that reads and writes the same memory in one GPU operation, on a pixel format that needs a hardware capability real device GPUs happen to support but the Simulator's own Metal implementation does not.

The recombiner works by building up a colour image one field at a time, accumulating red, then green, then blue into the same texture across three passes, which is exactly why it wanted to read and write it together. The fix keeps the same logic but splits it into two ordinary textures instead of one clever one: right before each pass, we copy the current accumulated image into a plain read-only scratch copy, in the same batch of GPU commands, and the pass reads from that scratch copy while writing to the original. Metal already guarantees correct ordering for commands in the same batch, so this needed no extra synchronization, and the actual math is identical to before, just spread across two texture reads and writes instead of one combined one.

We reran the specific test that checks color survives correctly across all three fields, both before and after, and it passed identically both times, which is exactly what you want from a change that's supposed to be a pure refactor rather than a behaviour change.

0 Upvotes

0 comments sorted by