Benchmarking with Vulkan, or the curse of variable GPU clock rates

Trying to get reliable benchmarks on a GPU that keeps adapting its clock rate.

Choosing between two implementation often requires answering the age-old question “which is faster?”. Which means measuring/benchmarking. Now what do you do when your device’s default mode of operation gives you unreliable numbers?

Continue reading Benchmarking with Vulkan, or the curse of variable GPU clock rates

Designated Initializers, the best feature of C++20

Of all the features added to C++ over the past years, I think Designated Initializers is both the best and one of the least talked about. Time to right that wrong.

If you’ve been following my hot takes on C++, you might have noticed that I haven’t been the most enthusiastic person about the recent additions to the language. While some of them were nice addition, I haven’t felt like they had a significant impact on my code unless I had a somewhat niche use case. But for the past months I’ve been using C++20’s designated initializers and it’s been quite the change.

Continue reading Designated Initializers, the best feature of C++20

A Year With Graphics

Looking back at 2025 and looking forward to 2026 through the lens of graphics programming.

I had done some work with graphics while working on various titles at Paradox, but I never felt really confident about it like I would have been about C++ or multithreading or the few other topics I’ve talked about in the past. Sure I had done some work with it, figured out what the point of shaders is (the answer is: they shade) and migrated Hearts of Iron IV from DirectX 9 to 11, but it still felt a bit mystical. So I decided to use my spare time between contracts this year to catch up.

Continue reading A Year With Graphics

What makes a game tick? Part 8 - Data Driven Multi-Threading Implementation

Let’s talk about game simulations. Today we dive into the nitty-gritty bits of implementing data driven multi-threading.

In our last episode in this series we presented the concept of task-based parallelism with scheduling driven by data accesses. I recommend going back to it for a quick reminder because today we are gonna talk about implementation. Let’s get coding!

Continue reading What makes a game tick? Part 8 - Data Driven Multi-Threading Implementation

C++ Enum Class and Error Codes, part 3

Last time we explored some commonly found alternatives to using enums for error codes such as asserts, contracts and std::expected. Finally today we consider some unthinkable options.

The code examples given in part 1 and part 2 strongly focused on simple (and I’d argue, quite common) form of error handling: run a sequence of operations, and if any of them fails bail out and report an error. We tried a few alternatives but they all came with caveats. Error code returns polluted a lot of the logic with if ( error ) { return error; }, std::expected was a bit more concise but demanded we rewrite the signature of the functions we call to fit the monadic form and finally contracts allowed for cleaner user code but aren’t really made to do custom error handling (if they make it into C++26 at all) or recoverable errors (like a missing file).

Continue reading C++ Enum Class and Error Codes, part 3

Pagination