griush
February 16, 2024, 6:28pm
1
I’m following the Vulkan tutorial in Zig but got stuck when calling vkGetInstanceProcAddr
.
This is my wrapper around the function:
fn CreateDebugUtilsMessengerEXT(
pCreateInfo: *const c.VkDebugUtilsMessengerCreateInfoEXT,
pAllocator: ?*const c.VkAllocationCallbacks,
pMessenger: *c.VkDebugUtilsMessengerEXT,
) c.VkResult {
const func: c.PFN_vkCreateDebugUtilsMessengerEXT = @as(c.PFN_vkCreateDebugUtilsMessengerEXT, c.vkGetInstanceProcAddr(
g_vulkan_context.instance,
"vkCreateDebugUtilsMessengerEXT",
)) orelse return c.VK_ERROR_EXTENSION_NOT_PRESENT;
return func(g_vulkan_context.instance, pCreateInfo, pAllocator, pMessenger);
}
and produces the following error:
error: expected type '?*const fn (?*cimport.struct_VkInstance_T, [*c]const cimport.struct_VkDebugUtilsMessengerCreateInfoEXT, [*c]const cimport.struct_VkAllocationCallbacks, [*c]?*cimport.struct_VkDebugUtilsMessengerEXT_T) callconv(.C) c_int', found '?*const fn () callconv(.C) void'
const func: c.PFN_vkCreateDebugUtilsMessengerEXT = @as(c.PFN_vkCreateDebugUtilsMessengerEXT, c.vkGetInstanceProcAddr(
I kind of have an idea what it means but I’ve tried a couple of things and I have no idea how to fix it.
Thanks
Try using @ptrCast
. @as
is used for coercions, meaning safe conversions to less specific types. The function pointer type you are trying to convert to is more specific than the return type of vkGetInstanceProcAddress
, so you have to use @ptrCast
.
1 Like
griush
February 16, 2024, 6:46pm
3
I already tried it, but apparently error: @ptrCast must have a known result type
. Which I don’t know why it says that because I explicitly say that the type should be c.PFN_vkCreateDebugUtilsMessengerEXT
.
dimdin
February 16, 2024, 6:50pm
4
Is this the line of code the gives you that error?
const func: c.PFN_vkCreateDebugUtilsMessengerEXT = @ptrCast(c.vkGetInstanceProcAddr(
g_vulkan_context.instance,
"vkCreateDebugUtilsMessengerEXT",
));
griush
February 16, 2024, 6:54pm
5
Yeah, plus this after the call: orelse return c.VK_ERROR_EXTENSION_NOT_PRESENT;
EDIT: I’ve removed this part and the error changed, so we are going someplace.
error: cannot call optional type '?*const fn (?*cimport.struct_VkInstance_T, [*c]const cimport.struct_VkDebugUtilsMessengerCreateInfoEXT, [*c]const cimport.struct_VkAllocationCallbacks, [*c]?*cimport.struct_VkDebugUtilsMessengerEXT_T) callconv(.C) c_int'
You need to unpack the optional first - you have an optional(*function)
.
You can directly unpack it with foo.?
to get your function pointer or use payload capture to unpack it if (foo) |bar| // use bar
.
1 Like
dimdin
February 16, 2024, 7:03pm
7
try this:
const func: c.PFN_vkCreateDebugUtilsMessengerEXT =
@as(?c.PFN_vkCreateDebugUtilsMessengerEXT,
@ptrCast(c.vkGetInstanceProcAddr(
g_vulkan_context.instance,
"vkCreateDebugUtilsMessengerEXT",
))) orelse return c.VK_ERROR_EXTENSION_NOT_PRESENT;
const func = @as(
c.PFN_vkCreateDebugUtilsMessengerEXT,
@ptrCast(c.vkGetInstanceProcAddr(
g_vulkan_context.instance,
"vkCreateDebugUtilsMessengerEXT",
),
) orelse return c.VK_ERROR_EXTENSION_NOT_PRESENT;
is probably the most concise version. vkGetInstanceProcAddr
already returns an optional pointer.