#include #include #define GLFW_INCLUDE_VULKAN #include #include "vulkan/vulkan.h" #include #include 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() { 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 validationLayers = { "VK_LAYER_NV_optimus" }; uint32_t amountOfGlfwExtensins = 0; auto glfWExtensions = glfwGetRequiredInstanceExtensions(&amountOfGlfwExtensins); 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(); instanceInfo.enabledExtensionCount = amountOfGlfwExtensins; instanceInfo.ppEnabledExtensionNames = glfWExtensions; // create vulkan instance if (vkCreateInstance(&instanceInfo, nullptr, &instance) != VK_SUCCESS) { std::cout << "error on creating vkinstance" << std::endl; } if (glfwCreateWindowSurface(instance, window, nullptr, &surface) != VK_SUCCESS) { std::cout << "error on creating surface" << std::endl; } 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 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; } 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; } uint32_t amountOfExtensions = 0; vkEnumerateInstanceExtensionProperties(nullptr, &amountOfExtensions, nullptr); auto *extensions = new VkExtensionProperties[amountOfExtensions]; vkEnumerateInstanceExtensionProperties(nullptr, &amountOfExtensions, extensions); 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; if (vkCreateDevice(physicalDevices.at(0), &deviceCreateInfo, NULL, &device) != VK_SUCCESS) { // todo select right physicaldevice std::cout << "create logical device failed." << std::endl; } delete[] layers; delete[] extensions; } void gameLoop() { while (!glfwWindowShouldClose(window)) { auto start = std::chrono::steady_clock::now(); std::chrono::system_clock::now().time_since_epoch(); glfwPollEvents(); auto end = std::chrono::steady_clock::now(); std::cout << "Frequency : " << 1000000 / (int)(std::chrono::duration_cast(end - start).count()) << " fps" << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(20)); } } void shutdownVulkan() { vkDeviceWaitIdle(device); // waits until any work has finished vkDestroyDevice(device, nullptr); vkDestroySurfaceKHR(instance, surface, nullptr); vkDestroyInstance(instance, nullptr); } void shutdownGlfw() { glfwDestroyWindow(window); } int main() { startGlfw(); startVulkan(); gameLoop(); shutdownVulkan(); shutdownGlfw(); return 0; }