Debugging 101
Back to my beautiful triangle. I noticed that when I run the application on my Steam Machine, sometimes it renders the triangle, but other times it's a blank screen. I couldn't find a reliable way to reproduce it, but it's about 50:50 for seeing the triangle in all its glory.
The triangle demo renders in response to events rather than continuously redrawing. I suspect that there are events we're not listening to that indicate when the screen is ready, and we're presenting a frame before that happens. In winit, this likely maps to the resumed event which we're already handling, so I'd expect it to work correctly.
I'll add some logs to see what's happening. As far as I know, there isn't a built-in way to ship logs from a Steam developer build back to my workstation, so I'll have to go in there and get them myself. My Steam Machine and my workstation run on the same local network, so enabling SSH on the Steam Machine means I should be able to scp the log files back to my desktop, or even just ssh in and view them manually.
Enabling SSH on the Steam Machine was fairly straightforward.
- From the Steam power menu, switch to "Desktop Mode".
- Open up "Konsole".
- Run
passwdto set a password for the current user. - Run
sudo systemctl enable --now sshd.
After that, I was able to connect with ssh deck@steamdeck (even though we're using the Steam Machine, SteamOS uses steamdeck and deck as the default hostname and user).
I didn't configure anything on my workstation to find the host steamdeck, so I was curious how it worked so seamlessly. Apparently, there's a protocol named Link-Local Multicast Name Resolution (LLMNR) that only works within the local network. When my workstation attempts to resolve steamdeck, it sends a multicast query on my LAN to see if anyone goes by that name, and the Steam Machine responds with its IP address. Pretty neat, and one less thing for me to configure on my workstation. On Linux with systemd, you can test this out with resolvectl query steamdeck.
Back to the logging. My main hypothesis was that the window was occluded initially when we rendered the triangle, and when it became unoccluded we didn't render again. The code was instrumented to log relevant winit events to see if this was the case, but the logs looked near identical in both the success and failure cases.
We then checked if any of the Vulkan operations to present to the screen had errors that we were silently discarding. No errors detected there.
Finally, we adjusted the clear color from black to magenta. This would distinguish nothing being presented (black screen) from a frame being presented with a failed triangle draw (magenta screen). When deployed, we just saw a black screen, so this confirmed that the frame wasn't presented at all, even though the present operation completed successfully.
At this point, we still don't know why the initial render isn't displaying sometimes, which is disappointing, but we do have some debugging tools in place. I assume that when we switch to rendering continuously this will just go away, although it would have been nice to know the root cause of this issue.