ash: Some _device_ extensions are loading (and failing) _instance_ functions via `get_device_proc_addr()`

Found a couple extensions that are erroneously loading all functions through get_device_proc_addr() despite containing some instance-level functions (i.e. not taking a device or device child as first argument, see also fn function_type() in the generator for fishing this out in a crude way), which cannot be loaded. Concretely found these extensions (by looking for explicit PhysicalDevice argument, and later validated using the generator):

  • VK_KHR_device_group: #631
  • VK_EXT_full_screen_exclusive: #399
  • VK_KHR_swapchain (new get_physical_device_present_rectangles): #629

Quick solution

Unfortunately the fix (a pattern which we apply more rigorously in other extensions) implies a slower path for device-level functions which now imply an extra dispatch table per device, “injected” by the ICD. Worse, it’s a breaking change so it might be about time to start thinking about ash 0.38.

Long-term correctness

As for the fix itself, I’ve said it before and I’ll use this issue to track it: I’d rather have the generator distinguish instance-level and device-level extension functions, either in the loader or via separate *Fn structs entirely (anything to force us to load both in a separate way). @oddhack what’s the desired way to figure this out if a function operates on device (or childs thereof)? I’m not confident this hardcoded list of "VkDevice" | "VkCommandBuffer" | "VkQueue" for the first-parameter-type will hold, does it need an extra attribute in vk.xml?

https://github.com/ash-rs/ash/blob/a9fbc7147bd2eef124d8b2153e94bbf313885420/generator/src/lib.rs#L561-L566

Random weirdness

VK_KHR_device_group_creation, added in #630, has a function named fn device() that returns vk::Instance 😅

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 17

Commits related to this issue

Most upvoted comments

@06393993 Feel free to contribute a wrapper for missing extensions, request it, or wait until our new generator is capable of emitting sensible extension wrappers automatically. Likewise for layers, I’ll be adding a helper library to ash for this and also utilize the new generator to help with dispatch tables and the like.

For now you can achieve a similar thing as https://github.com/ash-rs/ash/pull/754 by calling the ::load() function twice but it’ll still get called with every device and instance function. Properly separating them out to only load device or instance functions is exactly what this issue is about and what is already implemented in a working draft over at https://github.com/ash-rs/ash/pull/734 (see ash::vk::{KhrSwapchainDeviceFn, KhrSwapchainInstanceFn}) so you’re not requesting anything new.

However, that PR will only appear in the upcoming breaking release because this struct separation is inherently breaking, and I don’t think it is very useful to create separate loader functions that still return the same struct with known-NULL members as an “interim” workaround (to facilitate https://github.com/ash-rs/ash/pull/754 and your use-case).

@codecnotsupported it’s not related here but it’s also not an ash issue, as said above inserting the layer isn’t enough, you have to enable the extension provided by it. In other words, add ash::extensions::ext::ShaderObject::NAME to enabled_extension_names on DeviceCreateInfo.

Yep, you’re right. Sorry for the digression.