Reputation: 3287
So I am attempting to follow the Vulkan tutorial on a mac with an M1 processor, and I am running into an issue with device creation.
So as per the tutorial I am setting the device enabled extensions like so:
const std::vector<const char*> deviceExtensions = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
};
VkDeviceCreateInfo createInfo = {};
createInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
createInfo.ppEnabledExtensionNames = deviceExtensions.data();
When I run this, I get the following validation errors:
validation layer: Validation Error: [ VUID-VkDeviceCreateInfo-pProperties-04451 ] Object 0: handle = 0x11bd84d40, type = VK_OBJECT_TYPE_PHYSICAL_DEVICE; | MessageID = 0x3a3b6ca0 | vkCreateDevice: VK_KHR_portability_subset must be enabled because physical device VkPhysicalDevice 0x11bd84d40[] supports it The Vulkan spec states: If the VK_KHR_portability_subset extension is included in pProperties of vkEnumerateDeviceExtensionProperties, ppEnabledExtensionNames must include "VK_KHR_portability_subset" (https://vulkan.lunarg.com/doc/view/1.3.211.0/mac/1.3-extensions/vkspec.html#VUID-VkDeviceCreateInfo-pProperties-04451)
validation layer: vkCreateDevice: Attempting to create a VkDevice from a VkPhysicalDevice which is from a portability driver without the VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR bit in the VkInstanceCreateInfo flags being set and the VK_KHR_portability_enumeration extension enabled. In future versions of the loader this VkPhysicalDevice will not be enumerated.
So I have tried adding the VK_KHR_portability_subset
extension mentioned in the first error:
const std::vector<const char*> deviceExtensions = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
"VK_KHR_portability_subset",
};
And then I get the following validation errors:
validation layer: Validation Error: [ VUID-vkCreateDevice-ppEnabledExtensionNames-01387 ] Object 0: handle = 0x106849800, type = VK_OBJECT_TYPE_INSTANCE; | MessageID = 0x12537a2c | Missing extension required by the device extension VK_KHR_portability_subset: VK_KHR_get_physical_device_properties2. The Vulkan spec states: All required device extensions for each extension in the VkDeviceCreateInfo::ppEnabledExtensionNames list must also be present in that list (https://vulkan.lunarg.com/doc/view/1.3.211.0/mac/1.3-extensions/vkspec.html#VUID-vkCreateDevice-ppEnabledExtensionNames-01387)
validation layer: vkCreateDevice: Attempting to create a VkDevice from a VkPhysicalDevice which is from a portability driver without the VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR bit in the VkInstanceCreateInfo flags being set and the VK_KHR_portability_enumeration extension enabled. In future versions of the loader this VkPhysicalDevice will not be enumerated.
validation layer: vkGetPhysicalDeviceProperties2KHR: Emulation found unrecognized structure type in pProperties->pNext - this struct will be ignored
So it looks like it's missing the VK_KHR_get_physical_device_properties2
and I tried adding that as well:
const std::vector<const char*> deviceExtensions = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
"VK_KHR_portability_subset",
"VK_KHR_get_physical_device_properties2"
};
And after adding this, device creation actually fails with this error:
validation layer: loader_validate_device_extensions: Device extension VK_KHR_get_physical_device_properties2 not supported by selected physical device or enabled layers.
So it seems like it's impossible to satisfy the validation layers. What's the correct way to initialize a logical device on an M1 mac?
Upvotes: 5
Views: 3359
Reputation: 1
const std::vector<const char *> deviceExtensions = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME <-- add here
};
createInfo.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
std::vector<const char *> MyEngineDevice::getRequiredExtensions() {
uint32_t glfwExtensionCount = 0;
const char **glfwExtensions;
glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
std::vector<const char *> extensions(glfwExtensions, glfwExtensions + glfwExtensionCount);
if (enableValidationLayers) {
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
}
extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); <-- add
extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);<-- add
return extensions;
}
Add in these 3 places, I solve the error!!
Upvotes: 0
Reputation: 3219
The key observation is that the error message (likely autogenerated) is wrong. VK_KHR_get_physical_device_properties2
is an instance extension and not a device extension. Thus the solution is to define VK_KHR_get_physical_device_properties2
and VK_KHR_portability_enumeration
in your instance extensions and define VK_KHR_portability_subset
in your device extensions. Doing this, I was able to make the error message go away.
Upvotes: 0
Reputation: 31
It does work for me, but ...
you have to add VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME in VkInstanceCreateInfo.ppEnabledExtensionNames when creating the Vulkan instance first (the vkCreateInstance call), before creating the device, together with whatever other extensions you are using:
VkInstanceCreateInfo createInfo{};
...
const std::vector<const char*> exts =
{
...
VK_KHR_SURFACE_EXTENSION_NAME,
VK_EXT_METAL_SURFACE_EXTENSION_NAME,
VK_MVK_MACOS_SURFACE_EXTENSION_NAME,
VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, // <--
...
};
ppEnabledExtensionNames = exts.data();
...
and also add the flag bit that validation layer also tells you about:
createInfo.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
Create the instance and then DON'T include VK_KHR_get_physical_device_properties2, but add VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME when you create the device and you are done.
All this seems to be needed starting with 1.3.216.0 Vulkan SDK.
Upvotes: 3