Handmade Rust Part 4: Generating Vulkan bindings

Vulkan is a C API so we’ll need some kind of bindings to be able to use it in Rust. The API is defined in a XML file distributed by Khronos. This file describes the structs, enums, constants, and functions for each version of the API, and all published extensions. The functions can then be loaded from the Vulkan dynamic library and other functions from the API. However using a raw C API isn’t easy in Rust because it requires using a lot of unsafe code.

Read More

Handmade Rust Part 3: Containers

The most commonly used kinds of containers are arrays and maps. Pretty much any other container type can be built using those two, so that’s what we’ll build today! The Rust standard library has Vec which is a dynamic array and HashMap and BTreeMap which are two kind of maps, the first one relying on the key being hashable, and the second one relying on the key being sortable.

Read More

Handmade Rust Part 2: Unq, an allocator-aware Box

In the Rust standard library, Box is a RAII wrapper for an object on the heap. It’s actually a special type that’s not implemented purely in the library, but also use special features called lang items. It uses the global allocator to allocate its memory. We want a similar type that also has an allocator associated to it. We’ll call it Unq, which mirror C++’s unique_ptr. Defining Unq pub struct Unq<T: ?

Read More

Handmade Rust Part 1: Introduction & Allocators

Welcome to Handmade Rust, a series (hopefully) where I will be developing a Vulkan rendering engine in Rust the Handmade way. By this, I mean using no external libraries, not even the Rust standard library, only the core lib. I am doing this mainly for my own enjoyment but also because I want to get better at writing Rust, and sometimes the best way to really understand something is to just do it yourself.

Read More

"Zero-overhead" objects pool

Sometimes I just feel stupid. For the longest time, whenever I implemented an object pool, I always had some kind of variable length array to store my list of free objects in additional to the backing memory of the objects. This meant that I had additional memory allocations to store and potentially resize this list. struct Pool { Type * backing_memory; DynArray<Type *> free_objects; // Some more housekeeping stuff }; Today I just realized that, as long as the objects are larger than the size of a pointer (which is pretty much always the case), you can just store the pointer to the next free object in it and essentially build a linked list.

Read More

Find lowest set bit

So today I was working with Vulkan and needed to somehow stringify the state of a VkDebugReportFlagsEXT. I was too lazy to concatenate strings so I decided to only take into account the first bit, and ignore the rest (this is for internal debugging purposes so… meh). So I needed a way to find the lowest set bit in an unsigned integer. Here’s what I came up with: uint find_lowest_set_bit(uint n) { return (~(n - 1)) & n; } Now for a step-by-step explanation of what’s going on, with A = 01001100.

Read More