2020-05-02 20:21:51 +00:00
|
|
|
#include <iostream>
|
|
|
|
#include <vector>
|
2020-05-02 22:33:11 +00:00
|
|
|
|
|
|
|
#define GLFW_INCLUDE_VULKAN
|
|
|
|
|
|
|
|
#include <GLFW/glfw3.h>
|
2020-05-02 20:21:51 +00:00
|
|
|
#include "vulkan/vulkan.h"
|
|
|
|
|
2020-05-02 22:33:11 +00:00
|
|
|
VkInstance instance;
|
|
|
|
VkDevice device;
|
|
|
|
VkSurfaceKHR surface;
|
|
|
|
GLFWwindow *window;
|
|
|
|
|
|
|
|
void startGlfw() {
|
|
|
|
glfwInit();
|
|
|
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
|
|
|
glfwWindowHint(GLFW_RESIZABLE, false);
|
|
|
|
|
|
|
|
window = glfwCreateWindow(400, 300, "Vulkan Test", nullptr, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void startVulkan() {
|
2020-05-02 20:21:51 +00:00
|
|
|
VkApplicationInfo appinfo; // general app info
|
|
|
|
appinfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
|
|
|
appinfo.pNext = nullptr;
|
|
|
|
appinfo.pApplicationName = "Test Vulkan";
|
|
|
|
appinfo.applicationVersion = VK_MAKE_VERSION(0, 1, 0);
|
|
|
|
appinfo.pEngineName = "volukanEngine";
|
|
|
|
appinfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
|
|
|
|
appinfo.apiVersion = VK_API_VERSION_1_1;
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t amountOfLayers = 0;
|
|
|
|
vkEnumerateInstanceLayerProperties(&amountOfLayers, NULL);
|
|
|
|
VkLayerProperties *layers = new VkLayerProperties[amountOfLayers];
|
|
|
|
vkEnumerateInstanceLayerProperties(&amountOfLayers, layers);
|
|
|
|
|
|
|
|
std::cout << "amount of instance layers: " << amountOfLayers << std::endl;
|
|
|
|
for (int i = 0; i < amountOfLayers; i++) {
|
|
|
|
std::cout << "Name: " << layers[i].layerName << std::endl;
|
|
|
|
std::cout << "Spec Version: " << layers[i].specVersion << std::endl;
|
|
|
|
std::cout << "Description: " << layers[i].description << std::endl << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::vector<const char *> validationLayers = {
|
|
|
|
"VK_LAYER_NV_optimus"
|
|
|
|
};
|
|
|
|
|
2020-05-02 22:33:11 +00:00
|
|
|
uint32_t amountOfGlfwExtensins = 0;
|
|
|
|
auto glfWExtensions = glfwGetRequiredInstanceExtensions(&amountOfGlfwExtensins);
|
|
|
|
|
2020-05-02 20:21:51 +00:00
|
|
|
VkInstanceCreateInfo instanceInfo;
|
|
|
|
instanceInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
|
|
|
instanceInfo.pNext = nullptr;
|
|
|
|
instanceInfo.flags = 0;
|
|
|
|
instanceInfo.pApplicationInfo = &appinfo;
|
|
|
|
instanceInfo.enabledLayerCount = validationLayers.size();
|
|
|
|
instanceInfo.ppEnabledLayerNames = validationLayers.data();
|
2020-05-02 22:33:11 +00:00
|
|
|
instanceInfo.enabledExtensionCount = amountOfGlfwExtensins;
|
|
|
|
instanceInfo.ppEnabledExtensionNames = glfWExtensions;
|
2020-05-02 20:21:51 +00:00
|
|
|
|
|
|
|
// create vulkan instance
|
|
|
|
if (vkCreateInstance(&instanceInfo, nullptr, &instance) != VK_SUCCESS) {
|
|
|
|
std::cout << "error on creating vkinstance" << std::endl;
|
|
|
|
}
|
|
|
|
|
2020-05-02 22:33:11 +00:00
|
|
|
if (glfwCreateWindowSurface(instance, window, nullptr, &surface) != VK_SUCCESS) {
|
|
|
|
std::cout << "error on creating surface" << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-05-02 20:21:51 +00:00
|
|
|
std::cout << "detecting gpus." << std::endl;
|
|
|
|
|
|
|
|
uint32_t physicaldevicesnumber = 0;
|
|
|
|
if (vkEnumeratePhysicalDevices(instance, &physicaldevicesnumber, nullptr) != VK_SUCCESS) {
|
|
|
|
std::cout << "error getting graphics number" << std::endl;
|
|
|
|
}
|
|
|
|
std::cout << "found " << physicaldevicesnumber << " GPUs" << std::endl;
|
|
|
|
|
|
|
|
std::vector<VkPhysicalDevice> physicalDevices;
|
|
|
|
physicalDevices.resize(physicaldevicesnumber);
|
|
|
|
|
|
|
|
// VkPhysicalDevice *physicalDevice = new VkPhysicalDevice[physicaldevicesnumber];
|
|
|
|
if (vkEnumeratePhysicalDevices(instance, &physicaldevicesnumber, physicalDevices.data()) != VK_SUCCESS) {
|
|
|
|
std::cout << "error getting graphics cards" << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
VkPhysicalDeviceProperties properties;
|
|
|
|
for (int i = 0; i < physicaldevicesnumber; i++) {
|
|
|
|
vkGetPhysicalDeviceProperties(physicalDevices.at(i), &properties);
|
|
|
|
std::cout << "Device name: " << properties.deviceName << std::endl;
|
|
|
|
std::cout << "API Version: " << VK_VERSION_MAJOR(properties.apiVersion) << "."
|
|
|
|
<< VK_VERSION_MINOR(properties.apiVersion) << "." << VK_VERSION_PATCH(properties.apiVersion)
|
|
|
|
<< std::endl;
|
|
|
|
std::cout << "Driver Version: " << VK_VERSION_MAJOR(properties.driverVersion) << "."
|
|
|
|
<< VK_VERSION_MINOR(properties.driverVersion) << "." << VK_VERSION_PATCH(properties.driverVersion)
|
|
|
|
<< std::endl;
|
|
|
|
|
|
|
|
std::cout << std::endl;
|
|
|
|
}
|
|
|
|
|
2020-05-02 22:33:11 +00:00
|
|
|
VkSurfaceCapabilitiesKHR surfaceCapabilities;
|
|
|
|
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevices.at(0), surface, &surfaceCapabilities);
|
|
|
|
std::cout << "\tminImageCount: " << surfaceCapabilities.minImageCount << std::endl;
|
|
|
|
std::cout << "\tmaxImageCount: " << surfaceCapabilities.maxImageCount << std::endl;
|
|
|
|
std::cout << "\tcurrentExtent: " << surfaceCapabilities.currentExtent.height << "/"
|
|
|
|
<< surfaceCapabilities.currentExtent.width << std::endl;
|
|
|
|
std::cout << "\tminImageExtent: " << surfaceCapabilities.minImageExtent.height << "/"
|
|
|
|
<< surfaceCapabilities.minImageExtent.width << std::endl;
|
|
|
|
std::cout << "\tmaxImageExtent: " << surfaceCapabilities.maxImageExtent.height << "/"
|
|
|
|
<< surfaceCapabilities.maxImageExtent.width << std::endl;
|
|
|
|
std::cout << "\tmaxImageArrayLayers: " << surfaceCapabilities.maxImageArrayLayers << std::endl;
|
|
|
|
std::cout << "\tsupportedTransforms: " << surfaceCapabilities.supportedTransforms << std::endl;
|
|
|
|
std::cout << "\tcurrentTransform: " << surfaceCapabilities.currentTransform << std::endl;
|
|
|
|
std::cout << "\tsupportedCompositeAlpha: " << surfaceCapabilities.supportedCompositeAlpha << std::endl;
|
|
|
|
std::cout << "\tsupportedUsageFlags: " << surfaceCapabilities.supportedUsageFlags << std::endl;
|
|
|
|
|
|
|
|
uint32_t amountOfFormats = 0;
|
|
|
|
vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevices.at(0), surface, &amountOfFormats, nullptr);
|
|
|
|
auto *surfaceFormats = new VkSurfaceFormatKHR[amountOfFormats];
|
|
|
|
vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevices.at(0), surface, &amountOfFormats, surfaceFormats);
|
|
|
|
|
|
|
|
for(int i = 0; i < amountOfFormats; i++){
|
|
|
|
std::cout << "format supported: " << surfaceFormats[i].format << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-05-02 20:21:51 +00:00
|
|
|
uint32_t amountOfExtensions = 0;
|
2020-05-02 22:33:11 +00:00
|
|
|
vkEnumerateInstanceExtensionProperties(nullptr, &amountOfExtensions, nullptr);
|
|
|
|
auto *extensions = new VkExtensionProperties[amountOfExtensions];
|
|
|
|
vkEnumerateInstanceExtensionProperties(nullptr, &amountOfExtensions, extensions);
|
2020-05-02 20:21:51 +00:00
|
|
|
std::cout << "found " << amountOfExtensions << " extensions" << std::endl;
|
|
|
|
|
|
|
|
for (int i = 0; i < amountOfExtensions; i++) {
|
|
|
|
std::cout << "Name: " << extensions[i].extensionName << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkDeviceQueueCreateInfo deviceQueueCreateInfo;
|
|
|
|
deviceQueueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
|
|
|
deviceQueueCreateInfo.pNext = nullptr;
|
|
|
|
deviceQueueCreateInfo.flags = 0;
|
|
|
|
deviceQueueCreateInfo.queueFamilyIndex = 0; // todo choose best queue family index
|
|
|
|
deviceQueueCreateInfo.queueCount = 4; // todo check if 4 supported
|
|
|
|
float queuePrios[] = {1.0f, 1.0f, 1.0f, 1.0f};
|
|
|
|
deviceQueueCreateInfo.pQueuePriorities = queuePrios;
|
|
|
|
VkPhysicalDeviceFeatures usedFeatures = {};
|
|
|
|
// set features here
|
|
|
|
|
|
|
|
VkDeviceCreateInfo deviceCreateInfo;
|
|
|
|
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
|
|
|
deviceCreateInfo.pNext = nullptr;
|
|
|
|
deviceCreateInfo.flags = 0;
|
|
|
|
deviceCreateInfo.queueCreateInfoCount = 1;
|
|
|
|
deviceCreateInfo.pQueueCreateInfos = &deviceQueueCreateInfo;
|
|
|
|
deviceCreateInfo.enabledLayerCount = 0;
|
|
|
|
deviceCreateInfo.ppEnabledLayerNames = nullptr;
|
|
|
|
deviceCreateInfo.enabledExtensionCount = 0;
|
|
|
|
deviceCreateInfo.ppEnabledExtensionNames = nullptr;
|
|
|
|
deviceCreateInfo.pEnabledFeatures = &usedFeatures;
|
|
|
|
|
|
|
|
std::cout << "creating logical device" << std::endl;
|
2020-05-02 22:33:11 +00:00
|
|
|
|
2020-05-02 20:21:51 +00:00
|
|
|
if (vkCreateDevice(physicalDevices.at(0), &deviceCreateInfo, NULL, &device) !=
|
|
|
|
VK_SUCCESS) { // todo select right physicaldevice
|
|
|
|
std::cout << "create logical device failed." << std::endl;
|
|
|
|
}
|
|
|
|
|
2020-05-02 22:33:11 +00:00
|
|
|
delete[] layers;
|
|
|
|
delete[] extensions;
|
|
|
|
}
|
|
|
|
|
|
|
|
void gameLoop() {
|
|
|
|
while (!glfwWindowShouldClose(window)) {
|
|
|
|
glfwPollEvents();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void shutdownVulkan() {
|
2020-05-02 20:21:51 +00:00
|
|
|
vkDeviceWaitIdle(device); // waits until any work has finished
|
|
|
|
vkDestroyDevice(device, nullptr);
|
2020-05-02 22:33:11 +00:00
|
|
|
vkDestroySurfaceKHR(instance, surface, nullptr);
|
2020-05-02 20:21:51 +00:00
|
|
|
vkDestroyInstance(instance, nullptr);
|
2020-05-02 22:33:11 +00:00
|
|
|
}
|
2020-05-02 20:21:51 +00:00
|
|
|
|
2020-05-02 22:33:11 +00:00
|
|
|
void shutdownGlfw() {
|
|
|
|
glfwDestroyWindow(window);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
startGlfw();
|
|
|
|
startVulkan();
|
|
|
|
gameLoop();
|
|
|
|
shutdownVulkan();
|
|
|
|
shutdownGlfw();
|
2020-05-02 20:21:51 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|