mirror of
https://github.com/glfw/glfw.git
synced 2026-02-17 21:12:34 +01:00
Add basic Vulkan support
Added GLFW_INCLUDE_VULKAN. Added glfwVulkanSupported, glfwGetRequiredInstanceExtensions, glfwGetInstanceProcAddress, glfwGetPhysicalDevicePresentationSupport and glfwCreateWindowSurface. Added port of LunarG SDK tri example.
This commit is contained in:
254
tests/glfwinfo.c
254
tests/glfwinfo.c
@@ -24,6 +24,7 @@
|
||||
//========================================================================
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -61,7 +62,8 @@ static void usage(void)
|
||||
printf(" -d, --debug request a debug context\n");
|
||||
printf(" -f, --forward require a forward-compatible context\n");
|
||||
printf(" -h, --help show this help\n");
|
||||
printf(" -l, --list-extensions list all client API extensions\n");
|
||||
printf(" -l, --list-extensions list all Vulkan and client API extensions\n");
|
||||
printf(" --list-layers list all Vulkan layers\n");
|
||||
printf(" -m, --major=MAJOR the major number of the required "
|
||||
"client API version\n");
|
||||
printf(" -n, --minor=MINOR the minor number of the required "
|
||||
@@ -96,6 +98,22 @@ static void error_callback(int error, const char* description)
|
||||
fprintf(stderr, "Error: %s\n", description);
|
||||
}
|
||||
|
||||
static const char* get_device_type_name(VkPhysicalDeviceType type)
|
||||
{
|
||||
if (type == VK_PHYSICAL_DEVICE_TYPE_OTHER)
|
||||
return "other";
|
||||
else if (type == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU)
|
||||
return "integrated GPU";
|
||||
else if (type == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
|
||||
return "discrete GPU";
|
||||
else if (type == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU)
|
||||
return "virtual GPU";
|
||||
else if (type == VK_PHYSICAL_DEVICE_TYPE_CPU)
|
||||
return "CPU";
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static const char* get_api_name(int api)
|
||||
{
|
||||
if (api == GLFW_OPENGL_API)
|
||||
@@ -146,13 +164,13 @@ static const char* get_strategy_name_glfw(int strategy)
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static void list_extensions(int api, int major, int minor)
|
||||
static void list_context_extensions(int api, int major, int minor)
|
||||
{
|
||||
int i;
|
||||
GLint count;
|
||||
const GLubyte* extensions;
|
||||
|
||||
printf("%s context supported extensions:\n", get_api_name(api));
|
||||
printf("%s context extensions:\n", get_api_name(api));
|
||||
|
||||
if (api == GLFW_OPENGL_API && major > 2)
|
||||
{
|
||||
@@ -182,6 +200,124 @@ static void list_extensions(int api, int major, int minor)
|
||||
}
|
||||
}
|
||||
|
||||
static void list_vulkan_instance_extensions(void)
|
||||
{
|
||||
uint32_t i, ep_count = 0;
|
||||
VkExtensionProperties* ep;
|
||||
PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties =
|
||||
(PFN_vkEnumerateInstanceExtensionProperties)
|
||||
glfwGetInstanceProcAddress(NULL, "vkEnumerateInstanceExtensionProperties");
|
||||
|
||||
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;
|
||||
VkLayerProperties* lp;
|
||||
PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties =
|
||||
(PFN_vkEnumerateInstanceLayerProperties)
|
||||
glfwGetInstanceProcAddress(NULL, "vkEnumerateInstanceLayerProperties");
|
||||
|
||||
printf("Vulkan instance layers:\n");
|
||||
|
||||
if (vkEnumerateInstanceLayerProperties(&lp_count, NULL) != VK_SUCCESS)
|
||||
return;
|
||||
|
||||
lp = calloc(lp_count, sizeof(VkLayerProperties));
|
||||
|
||||
if (vkEnumerateInstanceLayerProperties(&lp_count, lp) != VK_SUCCESS)
|
||||
{
|
||||
free(lp);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < lp_count; i++)
|
||||
{
|
||||
printf(" %s (v%u) \"%s\"\n",
|
||||
lp[i].layerName,
|
||||
lp[i].specVersion >> 22,
|
||||
lp[i].description);
|
||||
}
|
||||
|
||||
free(lp);
|
||||
}
|
||||
|
||||
static void list_vulkan_device_extensions(VkInstance instance, VkPhysicalDevice device)
|
||||
{
|
||||
uint32_t i, ep_count;
|
||||
VkExtensionProperties* ep;
|
||||
PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties =
|
||||
(PFN_vkEnumerateDeviceExtensionProperties)
|
||||
glfwGetInstanceProcAddress(instance, "vkEnumerateDeviceExtensionProperties");
|
||||
|
||||
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;
|
||||
VkLayerProperties* lp;
|
||||
PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties =
|
||||
(PFN_vkEnumerateDeviceLayerProperties)
|
||||
glfwGetInstanceProcAddress(instance, "vkEnumerateDeviceLayerProperties");
|
||||
|
||||
printf("Vulkan device layers:\n");
|
||||
|
||||
if (vkEnumerateDeviceLayerProperties(device, &lp_count, NULL) != VK_SUCCESS)
|
||||
return;
|
||||
|
||||
lp = calloc(lp_count, sizeof(VkLayerProperties));
|
||||
|
||||
if (vkEnumerateDeviceLayerProperties(device, &lp_count, lp) != VK_SUCCESS)
|
||||
{
|
||||
free(lp);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < lp_count; i++)
|
||||
{
|
||||
printf(" %s (v%u) \"%s\"\n",
|
||||
lp[i].layerName,
|
||||
lp[i].specVersion >> 22,
|
||||
lp[i].description);
|
||||
}
|
||||
|
||||
free(lp);
|
||||
}
|
||||
|
||||
static int valid_version(void)
|
||||
{
|
||||
int major, minor, revision;
|
||||
@@ -216,10 +352,10 @@ int main(int argc, char** argv)
|
||||
{
|
||||
int ch, api, major, minor, revision, profile;
|
||||
GLint redbits, greenbits, bluebits, alphabits, depthbits, stencilbits;
|
||||
int list = GLFW_FALSE;
|
||||
int list_extensions = GLFW_FALSE, list_layers = GLFW_FALSE;
|
||||
GLFWwindow* window;
|
||||
|
||||
enum { API, BEHAVIOR, DEBUG, FORWARD, HELP, EXTENSIONS,
|
||||
enum { API, BEHAVIOR, DEBUG, FORWARD, HELP, EXTENSIONS, LAYERS,
|
||||
MAJOR, MINOR, PROFILE, ROBUSTNESS, VERSION,
|
||||
REDBITS, GREENBITS, BLUEBITS, ALPHABITS, DEPTHBITS, STENCILBITS,
|
||||
ACCUMREDBITS, ACCUMGREENBITS, ACCUMBLUEBITS, ACCUMALPHABITS,
|
||||
@@ -232,6 +368,7 @@ int main(int argc, char** argv)
|
||||
{ "forward", 0, NULL, FORWARD },
|
||||
{ "help", 0, NULL, HELP },
|
||||
{ "list-extensions", 0, NULL, EXTENSIONS },
|
||||
{ "list-layers", 0, NULL, LAYERS },
|
||||
{ "major", 1, NULL, MAJOR },
|
||||
{ "minor", 1, NULL, MINOR },
|
||||
{ "profile", 1, NULL, PROFILE },
|
||||
@@ -314,7 +451,10 @@ int main(int argc, char** argv)
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'l':
|
||||
case EXTENSIONS:
|
||||
list = GLFW_TRUE;
|
||||
list_extensions = GLFW_TRUE;
|
||||
break;
|
||||
case LAYERS:
|
||||
list_layers = GLFW_TRUE;
|
||||
break;
|
||||
case 'm':
|
||||
case MAJOR:
|
||||
@@ -564,7 +704,7 @@ int main(int argc, char** argv)
|
||||
glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
}
|
||||
|
||||
printf("Framebuffer:\n");
|
||||
printf("%s framebuffer:\n", get_api_name(api));
|
||||
|
||||
if (api == GLFW_OPENGL_API && profile == GLFW_OPENGL_CORE_PROFILE)
|
||||
{
|
||||
@@ -632,9 +772,103 @@ int main(int argc, char** argv)
|
||||
accumredbits, accumgreenbits, accumbluebits, accumalphabits, auxbuffers);
|
||||
}
|
||||
|
||||
// Report client API extensions
|
||||
if (list)
|
||||
list_extensions(api, major, minor);
|
||||
if (list_extensions)
|
||||
list_context_extensions(api, major, minor);
|
||||
|
||||
printf("Vulkan loader: %s\n",
|
||||
glfwVulkanSupported() ? "available" : "missing");
|
||||
|
||||
if (glfwVulkanSupported())
|
||||
{
|
||||
uint32_t i, re_count, pd_count;
|
||||
const char** re;
|
||||
VkApplicationInfo ai = {0};
|
||||
VkInstanceCreateInfo ici = {0};
|
||||
VkInstance instance;
|
||||
VkPhysicalDevice* pd;
|
||||
PFN_vkCreateInstance vkCreateInstance = (PFN_vkCreateInstance)
|
||||
glfwGetInstanceProcAddress(NULL, "vkCreateInstance");
|
||||
PFN_vkDestroyInstance vkDestroyInstance;
|
||||
PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
|
||||
PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties;
|
||||
|
||||
re = glfwGetRequiredInstanceExtensions((int*) &re_count);
|
||||
|
||||
printf("Vulkan required instance extensions:");
|
||||
for (i = 0; i < re_count; i++)
|
||||
printf(" %s", re[i]);
|
||||
putchar('\n');
|
||||
|
||||
if (list_extensions)
|
||||
{
|
||||
list_vulkan_instance_extensions();
|
||||
}
|
||||
|
||||
if (list_layers)
|
||||
list_vulkan_instance_layers();
|
||||
|
||||
ai.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
ai.pApplicationName = "glfwinfo";
|
||||
ai.applicationVersion = GLFW_VERSION_MAJOR;
|
||||
ai.pEngineName = "GLFW";
|
||||
ai.engineVersion = GLFW_VERSION_MAJOR;
|
||||
ai.apiVersion = VK_API_VERSION;
|
||||
|
||||
ici.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
ici.pApplicationInfo = &ai;
|
||||
ici.enabledExtensionCount = re_count;
|
||||
ici.ppEnabledExtensionNames = re;
|
||||
|
||||
if (vkCreateInstance(&ici, NULL, &instance) != VK_SUCCESS)
|
||||
{
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
vkDestroyInstance = (PFN_vkDestroyInstance)
|
||||
glfwGetInstanceProcAddress(instance, "vkDestroyInstance");
|
||||
vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices)
|
||||
glfwGetInstanceProcAddress(instance, "vkEnumeratePhysicalDevices");
|
||||
vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties)
|
||||
glfwGetInstanceProcAddress(instance, "vkGetPhysicalDeviceProperties");
|
||||
|
||||
if (vkEnumeratePhysicalDevices(instance, &pd_count, NULL) != VK_SUCCESS)
|
||||
{
|
||||
vkDestroyInstance(instance, NULL);
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pd = calloc(pd_count, sizeof(VkPhysicalDevice));
|
||||
|
||||
if (vkEnumeratePhysicalDevices(instance, &pd_count, pd) != VK_SUCCESS)
|
||||
{
|
||||
free(pd);
|
||||
vkDestroyInstance(instance, NULL);
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (i = 0; i < pd_count; i++)
|
||||
{
|
||||
VkPhysicalDeviceProperties pdp;
|
||||
|
||||
vkGetPhysicalDeviceProperties(pd[i], &pdp);
|
||||
|
||||
printf("Vulkan %s device: \"%s\"\n",
|
||||
get_device_type_name(pdp.deviceType),
|
||||
pdp.deviceName);
|
||||
|
||||
if (list_extensions)
|
||||
list_vulkan_device_extensions(instance, pd[i]);
|
||||
|
||||
if (list_layers)
|
||||
list_vulkan_device_layers(instance, pd[i]);
|
||||
}
|
||||
|
||||
free(pd);
|
||||
vkDestroyInstance(instance, NULL);
|
||||
}
|
||||
|
||||
glfwTerminate();
|
||||
exit(EXIT_SUCCESS);
|
||||
|
||||
Reference in New Issue
Block a user