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.

This was adapted to 3.3-stable from
3b3d58df47 and
84e165ef64.
This commit is contained in:
Camilla Löwy
2022-07-06 23:07:20 +02:00
parent 2568d703cd
commit 109f836675
2 changed files with 116 additions and 87 deletions
+101 -78
View File
@@ -210,30 +210,6 @@ static void list_context_extensions(int client, int major, int minor)
}
}
static void list_vulkan_instance_extensions(void)
{
uint32_t i, ep_count = 0;
VkExtensionProperties* ep;
printf("Vulkan instance extensions:\n");
if (vkEnumerateInstanceExtensionProperties(NULL, &ep_count, NULL) != VK_SUCCESS)
return;
ep = calloc(ep_count, sizeof(VkExtensionProperties));
if (vkEnumerateInstanceExtensionProperties(NULL, &ep_count, ep) != VK_SUCCESS)
{
free(ep);
return;
}
for (i = 0; i < ep_count; i++)
printf(" %s (v%u)\n", ep[i].extensionName, ep[i].specVersion);
free(ep);
}
static void list_vulkan_instance_layers(void)
{
uint32_t i, lp_count = 0;
@@ -263,30 +239,6 @@ static void list_vulkan_instance_layers(void)
free(lp);
}
static void list_vulkan_device_extensions(VkInstance instance, VkPhysicalDevice device)
{
uint32_t i, ep_count;
VkExtensionProperties* ep;
printf("Vulkan device extensions:\n");
if (vkEnumerateDeviceExtensionProperties(device, NULL, &ep_count, NULL) != VK_SUCCESS)
return;
ep = calloc(ep_count, sizeof(VkExtensionProperties));
if (vkEnumerateDeviceExtensionProperties(device, NULL, &ep_count, ep) != VK_SUCCESS)
{
free(ep);
return;
}
for (i = 0; i < ep_count; i++)
printf(" %s (v%u)\n", ep[i].extensionName, ep[i].specVersion);
free(ep);
}
static void list_vulkan_device_layers(VkInstance instance, VkPhysicalDevice device)
{
uint32_t i, lp_count;
@@ -346,11 +298,6 @@ static void print_version(void)
printf("GLFW library version string: \"%s\"\n", glfwGetVersionString());
}
static GLADapiproc glad_vulkan_callback(const char* name, void* user)
{
return glfwGetInstanceProcAddress((VkInstance) user, name);
}
int main(int argc, char** argv)
{
int ch, client, major, minor, revision, profile;
@@ -812,14 +759,16 @@ int main(int argc, char** argv)
if (glfwVulkanSupported())
{
uint32_t loader_version = VK_API_VERSION_1_0;
uint32_t i, re_count, pd_count;
int portability_enumeration = GLFW_FALSE;
uint32_t i, j, glfw_re_count, re_count, pd_count, ep_count;
const char** glfw_re;
const char** re;
VkApplicationInfo ai = {0};
VkInstanceCreateInfo ici = {0};
VkInstance instance;
VkPhysicalDevice* pd;
gladLoadVulkanUserPtr(NULL, glad_vulkan_callback, NULL);
gladLoadVulkanUserPtr(NULL, (GLADuserptrloadfunc) glfwGetInstanceProcAddress, NULL);
if (vkEnumerateInstanceVersion)
{
@@ -832,20 +781,47 @@ int main(int argc, char** argv)
VK_VERSION_MAJOR(loader_version),
VK_VERSION_MINOR(loader_version));
re = glfwGetRequiredInstanceExtensions(&re_count);
glfw_re = glfwGetRequiredInstanceExtensions(&glfw_re_count);
printf("Vulkan required instance extensions:");
if (re)
re_count = glfw_re_count;
re = calloc(glfw_re_count, sizeof(char*));
printf("Vulkan window surface required instance extensions:\n");
if (glfw_re)
{
for (i = 0; i < re_count; i++)
printf(" %s", re[i]);
putchar('\n');
for (i = 0; i < glfw_re_count; i++)
{
printf(" %s\n", glfw_re[i]);
re[i] = glfw_re[i];
}
}
else
printf(" missing\n");
vkEnumerateInstanceExtensionProperties(NULL, &ep_count, NULL);
VkExtensionProperties* ep = calloc(ep_count, sizeof(VkExtensionProperties));
vkEnumerateInstanceExtensionProperties(NULL, &ep_count, ep);
if (list_extensions)
list_vulkan_instance_extensions();
{
printf("Vulkan instance extensions:\n");
for (i = 0; i < ep_count; i++)
printf(" %s (spec version %u)\n", ep[i].extensionName, ep[i].specVersion);
}
for (i = 0; i < ep_count; i++)
{
if (strcmp(ep[i].extensionName, "VK_KHR_portability_enumeration") != 0)
continue;
re_count++;
re = realloc((void*) re, sizeof(char*) * re_count);
re[re_count - 1] = "VK_KHR_portability_enumeration";
portability_enumeration = GLFW_TRUE;
}
free(ep);
if (list_layers)
list_vulkan_instance_layers();
@@ -866,34 +842,27 @@ int main(int argc, char** argv)
ici.enabledExtensionCount = re_count;
ici.ppEnabledExtensionNames = re;
if (portability_enumeration)
ici.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
if (vkCreateInstance(&ici, NULL, &instance) != VK_SUCCESS)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
gladLoadVulkanUserPtr(NULL, glad_vulkan_callback, instance);
free((void*) re);
if (vkEnumeratePhysicalDevices(instance, &pd_count, NULL) != VK_SUCCESS)
{
vkDestroyInstance(instance, NULL);
glfwTerminate();
exit(EXIT_FAILURE);
}
gladLoadVulkanUserPtr(NULL, (GLADuserptrloadfunc) glfwGetInstanceProcAddress, instance);
vkEnumeratePhysicalDevices(instance, &pd_count, NULL);
pd = calloc(pd_count, sizeof(VkPhysicalDevice));
if (vkEnumeratePhysicalDevices(instance, &pd_count, pd) != VK_SUCCESS)
{
free(pd);
vkDestroyInstance(instance, NULL);
glfwTerminate();
exit(EXIT_FAILURE);
}
vkEnumeratePhysicalDevices(instance, &pd_count, pd);
for (i = 0; i < pd_count; i++)
{
VkPhysicalDeviceProperties pdp;
uint32_t qfp_count, ep_count;
vkGetPhysicalDeviceProperties(pd[i], &pdp);
@@ -903,8 +872,62 @@ int main(int argc, char** argv)
VK_VERSION_MAJOR(pdp.apiVersion),
VK_VERSION_MINOR(pdp.apiVersion));
vkGetPhysicalDeviceQueueFamilyProperties(pd[i], &qfp_count, NULL);
vkEnumerateDeviceExtensionProperties(pd[i], NULL, &ep_count, NULL);
VkExtensionProperties* ep = calloc(ep_count, sizeof(VkExtensionProperties));
vkEnumerateDeviceExtensionProperties(pd[i], NULL, &ep_count, ep);
if (portability_enumeration)
{
int conformant = GLFW_TRUE;
for (j = 0; j < ep_count; j++)
{
if (strcmp(ep[j].extensionName, "VK_KHR_portability_subset") == 0)
{
conformant = GLFW_FALSE;
break;
}
}
printf("Vulkan %s %s device: \"%s\" (API version %i.%i)\n",
conformant ? "conformant" : "non-conformant",
get_device_type_name(pdp.deviceType),
pdp.deviceName,
VK_VERSION_MAJOR(pdp.apiVersion),
VK_VERSION_MINOR(pdp.apiVersion));
}
else
{
printf("Vulkan %s device: \"%s\" (API version %i.%i)\n",
get_device_type_name(pdp.deviceType),
pdp.deviceName,
VK_VERSION_MAJOR(pdp.apiVersion),
VK_VERSION_MINOR(pdp.apiVersion));
}
if (glfw_re_count)
{
printf("Vulkan device queue family presentation support:\n");
for (j = 0; j < qfp_count; j++)
{
printf(" %u: ", j);
if (glfwGetPhysicalDevicePresentationSupport(instance, pd[i], j))
printf("supported\n");
else
printf("no\n");
}
}
if (list_extensions)
list_vulkan_device_extensions(instance, pd[i]);
{
printf("Vulkan device extensions:\n");
for (j = 0; j < ep_count; j++)
printf(" %s (spec version %u)\n", ep[j].extensionName, ep[j].specVersion);
}
free(ep);
if (list_layers)
list_vulkan_device_layers(instance, pd[i]);