Vulkan-zig & glfw getInstanceProcAddress issue

I use the vulkan-zig bindings and this glfw implantation: GitHub - IridescenceTech/zglfw: A thin, idiomatic wrapper for GLFW. Written in Zig, for Zig! I also tried ow the zig-gamdev version I saw an earlier forum post here: ⁠ismeretlen There was this solution:

self.vkb = BaseWrapper.load(@as(vk.PfnGetInstanceProcAddr, @ptrCast(&glfw.getInstanceProcAddress)));

My code looks like this:

const Application = struct {
    const Self = @This();
    vkb: vk.BaseWrapper,
    vki: InstanceWrapper,
    window: ?*glfw.Window = null,
    instance: Instance,

    pub fn init() !Self {
        try glfw.init();
        std.debug.print("GLFW initialized\n", .{});
        glfw.windowHint(glfw.ClientAPI, glfw.NoAPI);
        glfw.windowHint(glfw.Resizable, 0);

        return Self{
            .vkb = vk.BaseWrapper.load(@as(vk.PfnGetInstanceProcAddr, @ptrCast(&glfw.getInstanceProcAddress))),
            .vki = undefined,
            .window = null,
            .instance = undefined,
        };
}

And I get this error:

.zig-cache/o/9341b804d5f904198a244fe709f7edfb/vk.zig:27512:21: error: cannot call optional type '?*const fn (vk.Instance, [*:0]const u8) callconv(.c) ?*const fn () callconv(.c) void'
                if (loader(instance, field.name.ptr)) |cmd_ptr| {
                    ^~~~~~
.zig-cache/o/9341b804d5f904198a244fe709f7edfb/vk.zig:27512:21: note: consider using '.?', 'orelse' or 'if'

I looked up for other solutuins like:

pub extern fn glfwGetInstanceProcAddress(instance: vk.Instance, procname: [*:0]const u8) vk.PfnVoidFunction;

From here: GitHub - Avokadoen/zig_vulkan: Toying with vulkan and zig

or:

const vk_proc = @ptrCast(*const fn (instance: vk.Instance, procname: [*:0]const u8) callconv(.C) vk.PfnVoidFunction, &glfw.getInstanceProcAddress);
``` but i converted it to 0.15.1 to
```zig
const vk_proc = @as(*const fn (instance: vk.Instance, procname: [*:0]const u8) callconv(.c) vk.PfnVoidFunction, @ptrCast(&glfw.getInstanceProcAddress));

These are some not working.

I only find that solution to change the code in the cache but I am not satisfied with it because than I would need to fork the git to change there as well. This is a issue of me or the vulkan-zig implementazion?

EDIT:
I find this on the dc server but this isnt working as well

true, but unfortunately it doesn’t solve the base problem

I had a similiar issue when trying to use zigglgen with zig-gamedevs zglfw a while ago.

The solution to it was to just wrap it in a function that’s returning the correct type, see:
github.com/zig-gamedev/zig-gamedev/pull/646#issuecomment-2252511104

So most likely if you just create your own function that’s returning the non-optional type, it might work. Sth. like this:

// ! Just blindly typed this here, so it's more pseudo code
fn getInstanceProcAddress(instance: VkInstance, procname: [*:0]const u8)  VKproc {
   return &glfw.getInstanceProcAddress(instance: VkInstance, procname: [*:0]const u8).?;
}

return Self{
            .vkb = vk.BaseWrapper.load(getInstanceProcAddress()),
            .vki = undefined,
            .window = null,
            .instance = undefined,
        };

not quite sure if I got that correct, hopefully it helps though?

2 Likes

Thanks a lot for the hint! That really helped wrapping it in a small helper function did work.
End this is the end result of the code:

fn getInstanceProcAddress(instance: vk.Instance, procname: [*:0]const u8) vk.PfnVoidFunction {
        return glfw.getInstanceProcAddress(@intFromEnum(instance), procname);
    }
1 Like