Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Any reason to use raw function's pointer? #682

Closed
Jerrody opened this issue Nov 20, 2022 · 3 comments
Closed

Any reason to use raw function's pointer? #682

Jerrody opened this issue Nov 20, 2022 · 3 comments

Comments

@Jerrody
Copy link

Jerrody commented Nov 20, 2022

For example, in C/C++ headers if we call a PFN we skip the step when loader choose what driver to call.

Do I need to call a PFN or ash does all work?

@Jerrody Jerrody changed the title Any to use raw function's pointer? Any reason to use raw function's pointer? Nov 20, 2022
@MarijnS95
Copy link
Collaborator

@Jerrody Are you referring whether a function is loaded generically through vkGetInstanceProcAddr with or without VkInstance, either resulting in an ICD loader dispatch wrapper or a function specific for that instance?

https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetInstanceProcAddr.html#_description

Same for vkGetDeviceProcAddr: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetDeviceProcAddr.html#_description

@Jerrody
Copy link
Author

Jerrody commented Nov 20, 2022

@MarijnS95

I'm not big professional I refer to this article where shown that calling of vkCmdDraw is an overhead, instead we call directly PFN_vkCmdDraw at this case we remove this overhead.

https://gpuopen.com/learn/reducing-vulkan-api-call-overhead/

So, my question is does ash call directly this PFN where we call device. cmd_draw()?

@MarijnS95
Copy link
Collaborator

@Jerrody PFN_vkCmdDraw it the type of a function pointer. The loader exports a function with this signature as vkCmdDraw, to be linked against directly but with aforementioned dispatch table overhead. Ash does not use those and instead loads it via vkGetDeviceProcAddr(device, "vkCmdDraw") directly, as written in that article:

ash/ash/src/vk/features.rs

Lines 3051 to 3052 in 29b935b

let cname = ::std::ffi::CStr::from_bytes_with_nul_unchecked(b"vkCmdDraw\0");
let val = _f(cname);

_f here is the loader function:

ash/ash/src/device.rs

Lines 22 to 24 in 29b935b

let load_fn = |name: &std::ffi::CStr| {
mem::transmute((instance_fn.get_device_proc_addr)(device, name.as_ptr()))
};

Which is used when creating a device:

ash/ash/src/instance.rs

Lines 341 to 357 in 29b935b

#[inline]
pub unsafe fn create_device(
&self,
physical_device: vk::PhysicalDevice,
create_info: &vk::DeviceCreateInfo,
allocation_callbacks: Option<&vk::AllocationCallbacks>,
) -> VkResult<Device> {
let mut device = mem::zeroed();
(self.instance_fn_1_0.create_device)(
physical_device,
create_info,
allocation_callbacks.as_raw_ptr(),
&mut device,
)
.result()?;
Ok(Device::load(&self.instance_fn_1_0, device))
}

tl;dr: Ash uses optimized function pointers (specific to an instance/device) in almost all cases 1.

Footnotes

  1. Some extensions combine device-level and instance-level functions: the latter cannot be loaded for a device, hence the entire extension is loaded via the instance and we take the dispatch table hit until our generator is capable of separating them out (https://github.com/ash-rs/ash/pull/556#discussion_r784237840).

@ash-rs ash-rs locked and limited conversation to collaborators Nov 20, 2022
@MarijnS95 MarijnS95 converted this issue into discussion #683 Nov 20, 2022

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants