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:
Camilla Berglund
2015-08-10 20:19:04 +02:00
parent c2efe87cff
commit 9b75bffc88
35 changed files with 7823 additions and 51 deletions

View File

@@ -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);