Ralith/openxrs

How does the openxr-sys generation layer handle memory allocation for return values?

str4d opened this issue · 3 comments

str4d commented

Using a specific function as an example:

The OpenXR specification states that for valid usage of xrGetVulkanGraphicsDeviceKHR, vkPhysicalDevice must be a pointer to a VkPhysicalDevice value to be populated. However, openxr::Instance::vulkan_graphics_device passes in std::ptr::null():

let mut out = ptr::null();
unsafe {
cvt((self.vulkan().get_vulkan_graphics_device)(
self.as_raw(),
system,
vk_instance,
&mut out,
))?;
}
Ok(out)

This suggests that there is an intermediate Rust layer that allocates the required memory for VkPhysicalDevice, and sets &mut out to point to it. What I can't figure out is, where is the memory allocated?

However, openxr::Instance::vulkan_graphics_device passes in std::ptr::null():

This is incorrect. The code you cited is passing in a pointer to a variable on the stack, which initially contains null. That variable is, on success, overwritten by the OpenXR implementation. There is no heap allocation.

str4d commented

Yes, it's passing an &mut VkPhysicalDevice, which per openxr-sys is a typedef for &mut *const c_void, which is not a C-repr struct on the stack, but a pointer on the stack. So when I read:

vkPhysicalDevice is a pointer to a VkPhysicalDevice value to populate.

in the OpenXR spec, I should read that as "a pointer to a pointer"? And the OpenXR runtime sets it to be a pointer to the actual structure in its own memory?

str4d commented

Ahh, I see: the Vulkan spec defines VkPhysicalDevice as simply a handle, so its structure is a pointer.