Field defaults in vulkan-zig

I started using Snektron/vulkan-zig for Vulkan again, but what I find very cumbersome is that most of the struct fields don’t have default values, and you have to set lots of nonsensical values that in C would be set implicitly through default initialization, for example

const depth_stencil_state = vk.PipelineDepthStencilStateCreateInfo{
    .depth_test_enable = .true,
    .depth_write_enable = .true,
    .depth_compare_op = .less_or_equal,
    .depth_bounds_test_enable = .false,
    .stencil_test_enable = .false,
    .front = .{
        .fail_op = .keep,
        .pass_op = .keep,
        .compare_op = .never,
        .compare_mask = 0,
        .depth_fail_op = .keep,
        .reference = 0,
        .write_mask = 0,
    },
    .back = .{
        .write_mask = 0,
        .compare_mask = 0,
        .compare_op = .never,
        .depth_fail_op = .keep,
        .fail_op = .keep,
        .pass_op = .keep,
        .reference = 0,
    },
    .max_depth_bounds = 0,
    .min_depth_bounds = 0,
};

Everything after the first 5 fields is completely meaningless noise; it is just the configuration for things that are already disabled. And this is needed with a lot of structs; I guess the whole Vulkan API was designed with default initialization in mind, with 0 values and 0 enum constants as defaults when not using some feature.

Is there some way around this, what do people do in practice when using these bindings?

Is there some reason why vulkan-zig doesn’t just generate default values for all the struct fields that match C default initialization?

If vulkan-zig generates default values or not, depends on the optional field of the vk.xml.

Docs of the optional field:

Must be "true" or "false" . The default value if unspecified is "false" . "true" specifies that this member can contain a sentinel value indicating that no corresponding object or explicit value is referred to: NULL for pointers, VK_NULL_HANDLE for handles, or 0 for other scalar types. "false" specifies that the member must contain a value object reference or explicit value.

IMO it makes sense, that no default value is generated, if no optional="true" is present.

But the Vulkan registry, fields generally only have this “optional” flag if they are themselves needed to indicate that something is disabled or not present (with a null handle, null pointer, zero count), not if they are just meaningless/ignored depending on some other field. Is doesn’t really make sense to me that vulkan-zig uses this for generating defaults.

Ideally there would be some manual touchups so things could have decl literals like pub const off = std.mem.zeroes(@This()); or even methods that initialize part of the structs without making partial init programming errors.

Anyhow, you can do:

var depth_stencil_state = std.mem.zeroInit(vk.PipelineDepthStencilStateCreateInfo, .{
    .depth_test_enable = .true,
    .depth_write_enable = .true,
    .depth_compare_op = .less_or_equal,
    .depth_bounds_test_enable = .false,
    .stencil_test_enable = .false,
});
3 Likes