Search code examples
c++vulkan

Vulkan extension function vkCmdPushDescriptorSetKHR is undefined


My renderer project fails to build. I am trying to add the device extension for push descriptor sets. Any help or point in the appropriate direction is appreciated. I am directly linking using CMake. I am using Vulkan 1.3 specification.

I get the error:

undefined reference to 'vkCmdPushDescriptorSetKHR'

I have added the appropriate Extension name to my list of Device extensions.

const std::vector<const char*> DeviceExtensions = {
    VK_KHR_SWAPCHAIN_EXTENSION_NAME,
    VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME
};

The documentation says it has VK_KHR_get_physical_device_properties_2 as a dependency. I have added it like so:

instance_extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);

Looking at Sascha Willems Vulkan samples I saw he added an empty VkPhysicalDevicePushDescriptorPropertiesKHR struct to the pNext member of VkPhysicalDeviceProperties2KHR struct.

VkPhysicalDevicePushDescriptorPropertiesKHR pushDescriptorProperties{};
pushDescriptorProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR;

m_physicalDeviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
m_physicalDeviceProperties.pNext = &pushDescriptorProperties;

vkGetPhysicalDeviceProperties2(PhysDevice, &m_physicalDeviceProperties);

UPDATE:

If I uncomment the below line, I will get the error that expression must be a modifiable lvalue.

// vkCmdPushDescriptorSetKHR = (PFN_vkCmdPushDescriptorSetKHR)vkGetDeviceProcAddr(m_device, "vkCmdPushDescriptorSetKHR");

I am directly linking against vulkan. Is there no way to set these function pointers without '#define VK_NO_PROTOTYPES' ?


Solution

  • Alright so as for my findings, the reason the above direct linked vulkan project doesn't work is that the extension 'VK_KHR_push_descriptor' hasn't been promoted to Vulkan specification yet. There's just no way to 'vkCmdPushDescriptorSet' function pointer directly. My solution currently is to stick the 'vkCmdPushDescriptorSetKHR' function pointer into a "vk_ext" (could be any name of course) namespace and assign with vkGetDeviceProcAddr. If it ever does get promoted, I'll just remove from the namespace.

    If you want to use 'vkCmdPushDescriptor' function pointer as is, as of right now, the only way I know of doing it, is by indirect linking. The Vulkan Cookbook by Packt goes into how to do this using the "VK_NO_PROTOTYPES" definition. Doing it this way, however, will require you to use vkGetInstanceProcAddr and vkGetDeviceProcAddr to retrieve all funtion pointers for all functions.