Ok, so hi everyone! I have another weird issue with Vulkan and Swift. So the quick rundown is I have made the very different decision to write an Open Source game & engine in Swift using the Vulkan API. Vulkan is a C API and I absolutely love swift's way of handling the interpolation between the two. As of today, I ran into an issue with trying to get the proc address to one of the functions from the C API. The code for the project, including the bug discussed here is on GITHUB
So basically, the issue all arises from this C API call from the vulkan 1.1.130 spec:
PFN_vkVoidFunction vkGetInstanceProcAddr(
VkInstance instance,
const char* pName);
As you can see, this function returns a pointer C function which is normally ok, but the specification states this:
vkGetInstanceProcAddr
itself is obtained in a platform- and loader- specific manner. Typically, the loader library will export this command as a function symbol, so applications can link against the loader library, or load it dynamically and look up the symbol using platform-specific APIs.
The table below defines the various use cases for vkGetInstanceProcAddr
and expected return value (“fp” is “function pointer”) for each case.
The returned function pointer is of type PFN_vkVoidFunction
, and must be cast to the type of the command being queried.
So the spec states that you must cast the type PFN_vkVoidFunction to the type of the command that you are fetching for.
Swift imports the PFN_vkVoidFunction
type as () -> Void
I need to cast this type to the type of the function that will be returned, which is a PFN_vkCreateAccelerationStructureNV
(which is imported as (VkDevice?, UnsafePointer<VkAccelerationStructureCreateInfoNV>?, UnsafePointer<VkAllocationCallbacks>?, UnsafeMutablePointer<VkAccelerationStructureNV?>?) -> VkResult
in swift). The problem is I don't know any way I can go about casting this type in Swift to the needed function type.
I tried this snippet of code in a function of a class:
let vkCreateAccelerationStructureNV = self.device.instance.getProcAddr(name: "vkCreateAccelerationStructureNV") as! PFN_vkCreateAccelerationStructureNV
vkCreateAccelerationStructureNV(self.device.handle, &createInfo, nil, &self.handle)
which errors out when run: Could not cast value of type '@convention(c) () -> ()' (0x7faaaf9dbe60) to '@convention(c) (Swift.Optional<Swift.OpaquePointer>, Swift.Optional<Swift.UnsafePointer<__C.VkAccelerationStructureCreateInfoNV>>, Swift.Optional<Swift.UnsafePointer<__C.VkAllocationCallbacks>>, Swift.Optional<Swift.UnsafeMutablePointer<Swift.Optional<Swift.OpaquePointer>>>) -> __C.VkResult' (0x7faaaf9dc258).
The page of the vulkan spec that states this can be found HERE.
So basically my quesion is, how would I go about getting that function returned converted or casted into the function that I need it to be. In C++, the solution would be something like this:
PFN_vkGetPhysicalDeviceFeatures2KHR pvkGetPhysicalDeviceFeatures2KHR = vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures2KHR");
// use pvkGetPhysicalDeviceFeatures2KHR
But in swift I cannot cast the value from the returned PFN_vkVoidFunction
to the PFN_vkCreateAccelerationStructureNV
. I know this is a long post super sorry about the rambling I just have no idea how to go about fixing this issue in Swift. Any ideas on how I can get that type to cast properly? Again thank you all so much for the help!