Skip to content

Commit 3b3d58d

Browse files
committed
Add support for VK_KHR_portability_enumeration
The use of this extension is required to enable the MoltenVK physical device as of Vulkan SDK 1.3.216.0. This is because MoltenVK is still very (very) slightly non-conformant.
1 parent 510a08c commit 3b3d58d

File tree

2 files changed

+96
-45
lines changed

2 files changed

+96
-45
lines changed

tests/glfwinfo.c

+85-45
Original file line numberDiff line numberDiff line change
@@ -255,21 +255,6 @@ static void list_context_extensions(int client, int major, int minor)
255255
}
256256
}
257257

258-
static void list_vulkan_instance_extensions(void)
259-
{
260-
printf("Vulkan instance extensions:\n");
261-
262-
uint32_t ep_count;
263-
vkEnumerateInstanceExtensionProperties(NULL, &ep_count, NULL);
264-
VkExtensionProperties* ep = calloc(ep_count, sizeof(VkExtensionProperties));
265-
vkEnumerateInstanceExtensionProperties(NULL, &ep_count, ep);
266-
267-
for (uint32_t i = 0; i < ep_count; i++)
268-
printf(" %s (spec version %u)\n", ep[i].extensionName, ep[i].specVersion);
269-
270-
free(ep);
271-
}
272-
273258
static void list_vulkan_instance_layers(void)
274259
{
275260
printf("Vulkan instance layers:\n");
@@ -290,21 +275,6 @@ static void list_vulkan_instance_layers(void)
290275
free(lp);
291276
}
292277

293-
static void list_vulkan_device_extensions(VkInstance instance, VkPhysicalDevice device)
294-
{
295-
printf("Vulkan device extensions:\n");
296-
297-
uint32_t ep_count;
298-
vkEnumerateDeviceExtensionProperties(device, NULL, &ep_count, NULL);
299-
VkExtensionProperties* ep = calloc(ep_count, sizeof(VkExtensionProperties));
300-
vkEnumerateDeviceExtensionProperties(device, NULL, &ep_count, ep);
301-
302-
for (uint32_t i = 0; i < ep_count; i++)
303-
printf(" %s (spec version %u)\n", ep[i].extensionName, ep[i].specVersion);
304-
305-
free(ep);
306-
}
307-
308278
static void list_vulkan_device_layers(VkInstance instance, VkPhysicalDevice device)
309279
{
310280
printf("Vulkan device layers:\n");
@@ -953,20 +923,51 @@ int main(int argc, char** argv)
953923
VK_VERSION_MAJOR(loader_version),
954924
VK_VERSION_MINOR(loader_version));
955925

956-
uint32_t re_count;
957-
const char** re = glfwGetRequiredInstanceExtensions(&re_count);
926+
uint32_t glfw_re_count;
927+
const char** glfw_re = glfwGetRequiredInstanceExtensions(&glfw_re_count);
928+
929+
uint32_t re_count = glfw_re_count;
930+
const char** re = calloc(glfw_re_count, sizeof(char*));
958931

959-
if (re)
932+
if (glfw_re)
960933
{
961934
printf("Vulkan window surface required instance extensions:\n");
962-
for (uint32_t i = 0; i < re_count; i++)
963-
printf(" %s\n", re[i]);
935+
for (uint32_t i = 0; i < glfw_re_count; i++)
936+
{
937+
printf(" %s\n", glfw_re[i]);
938+
re[i] = glfw_re[i];
939+
}
964940
}
965941
else
966942
printf("Vulkan window surface extensions missing\n");
967943

944+
uint32_t ep_count;
945+
vkEnumerateInstanceExtensionProperties(NULL, &ep_count, NULL);
946+
VkExtensionProperties* ep = calloc(ep_count, sizeof(VkExtensionProperties));
947+
vkEnumerateInstanceExtensionProperties(NULL, &ep_count, ep);
948+
968949
if (list_extensions)
969-
list_vulkan_instance_extensions();
950+
{
951+
printf("Vulkan instance extensions:\n");
952+
953+
for (uint32_t i = 0; i < ep_count; i++)
954+
printf(" %s (spec version %u)\n", ep[i].extensionName, ep[i].specVersion);
955+
}
956+
957+
bool portability_enumeration = false;
958+
959+
for (uint32_t i = 0; i < ep_count; i++)
960+
{
961+
if (strcmp(ep[i].extensionName, "VK_KHR_portability_enumeration") != 0)
962+
continue;
963+
964+
re_count++;
965+
re = realloc(re, sizeof(char*) * re_count);
966+
re[re_count - 1] = "VK_KHR_portability_enumeration";
967+
portability_enumeration = true;
968+
}
969+
970+
free(ep);
970971

971972
if (list_layers)
972973
list_vulkan_instance_layers();
@@ -987,6 +988,9 @@ int main(int argc, char** argv)
987988
ici.enabledExtensionCount = re_count;
988989
ici.ppEnabledExtensionNames = re;
989990

991+
if (portability_enumeration)
992+
ici.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
993+
990994
VkInstance instance = VK_NULL_HANDLE;
991995

992996
if (vkCreateInstance(&ici, NULL, &instance) != VK_SUCCESS)
@@ -995,9 +999,11 @@ int main(int argc, char** argv)
995999
exit(EXIT_FAILURE);
9961000
}
9971001

1002+
free(re);
1003+
9981004
gladLoadVulkanUserPtr(NULL, (GLADuserptrloadfunc) glfwGetInstanceProcAddress, instance);
9991005

1000-
if (re)
1006+
if (glfw_re_count)
10011007
{
10021008
VkSurfaceKHR surface = VK_NULL_HANDLE;
10031009

@@ -1020,16 +1026,44 @@ int main(int argc, char** argv)
10201026
VkPhysicalDeviceProperties pdp;
10211027
vkGetPhysicalDeviceProperties(pd[i], &pdp);
10221028

1023-
printf("Vulkan %s device: \"%s\" (API version %i.%i)\n",
1024-
get_device_type_name(pdp.deviceType),
1025-
pdp.deviceName,
1026-
VK_VERSION_MAJOR(pdp.apiVersion),
1027-
VK_VERSION_MINOR(pdp.apiVersion));
1028-
10291029
uint32_t qfp_count;
10301030
vkGetPhysicalDeviceQueueFamilyProperties(pd[i], &qfp_count, NULL);
10311031

1032-
if (re)
1032+
uint32_t ep_count;
1033+
vkEnumerateDeviceExtensionProperties(pd[i], NULL, &ep_count, NULL);
1034+
VkExtensionProperties* ep = calloc(ep_count, sizeof(VkExtensionProperties));
1035+
vkEnumerateDeviceExtensionProperties(pd[i], NULL, &ep_count, ep);
1036+
1037+
if (portability_enumeration)
1038+
{
1039+
bool conformant = true;
1040+
1041+
for (uint32_t j = 0; j < ep_count; j++)
1042+
{
1043+
if (strcmp(ep[j].extensionName, "VK_KHR_portability_subset") == 0)
1044+
{
1045+
conformant = false;
1046+
break;
1047+
}
1048+
}
1049+
1050+
printf("Vulkan %s %s device: \"%s\" (API version %i.%i)\n",
1051+
conformant ? "conformant" : "non-conformant",
1052+
get_device_type_name(pdp.deviceType),
1053+
pdp.deviceName,
1054+
VK_VERSION_MAJOR(pdp.apiVersion),
1055+
VK_VERSION_MINOR(pdp.apiVersion));
1056+
}
1057+
else
1058+
{
1059+
printf("Vulkan %s device: \"%s\" (API version %i.%i)\n",
1060+
get_device_type_name(pdp.deviceType),
1061+
pdp.deviceName,
1062+
VK_VERSION_MAJOR(pdp.apiVersion),
1063+
VK_VERSION_MINOR(pdp.apiVersion));
1064+
}
1065+
1066+
if (glfw_re_count)
10331067
{
10341068
printf("Vulkan device queue family presentation support:\n");
10351069
for (uint32_t j = 0; j < qfp_count; j++)
@@ -1043,7 +1077,13 @@ int main(int argc, char** argv)
10431077
}
10441078

10451079
if (list_extensions)
1046-
list_vulkan_device_extensions(instance, pd[i]);
1080+
{
1081+
printf("Vulkan device extensions:\n");
1082+
for (uint32_t j = 0; j < ep_count; j++)
1083+
printf(" %s (spec version %u)\n", ep[j].extensionName, ep[j].specVersion);
1084+
}
1085+
1086+
free(ep);
10471087

10481088
if (list_layers)
10491089
list_vulkan_device_layers(instance, pd[i]);

tests/triangle-vulkan.c

+11
Original file line numberDiff line numberDiff line change
@@ -1561,6 +1561,7 @@ static VkBool32 demo_check_layers(uint32_t check_count, const char **check_names
15611561

15621562
static void demo_init_vk(struct demo *demo) {
15631563
VkResult err;
1564+
VkBool32 portability_enumeration = VK_FALSE;
15641565
uint32_t i = 0;
15651566
uint32_t required_extension_count = 0;
15661567
uint32_t instance_extension_count = 0;
@@ -1668,6 +1669,13 @@ static void demo_init_vk(struct demo *demo) {
16681669
}
16691670
}
16701671
assert(demo->enabled_extension_count < 64);
1672+
if (!strcmp(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME,
1673+
instance_extensions[i].extensionName)) {
1674+
demo->extension_names[demo->enabled_extension_count++] =
1675+
VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME;
1676+
portability_enumeration = VK_TRUE;
1677+
}
1678+
assert(demo->enabled_extension_count < 64);
16711679
}
16721680

16731681
free(instance_extensions);
@@ -1692,6 +1700,9 @@ static void demo_init_vk(struct demo *demo) {
16921700
.ppEnabledExtensionNames = (const char *const *)demo->extension_names,
16931701
};
16941702

1703+
if (portability_enumeration)
1704+
inst_info.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
1705+
16951706
uint32_t gpu_count;
16961707

16971708
err = vkCreateInstance(&inst_info, NULL, &demo->inst);

0 commit comments

Comments
 (0)