From 54155bd73bfb1957a7ab5bd36c72a2e601f674b0 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sat, 29 Sep 2018 21:03:06 -0400 Subject: [PATCH] Add Vulkan swapchain creation --- include/platform.h | 7 ++++++ include/renderer.h | 18 +++++++++++++ src/main.cpp | 23 ++++++++++++++++- src/renderer.cpp | 63 ++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 103 insertions(+), 8 deletions(-) create mode 100644 include/platform.h diff --git a/include/platform.h b/include/platform.h new file mode 100644 index 0000000..e2fe497 --- /dev/null +++ b/include/platform.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +namespace platform { + std::vector getRequiredExtensions(); +} diff --git a/include/renderer.h b/include/renderer.h index 3874a19..4b502d3 100644 --- a/include/renderer.h +++ b/include/renderer.h @@ -2,11 +2,23 @@ #include +struct RenderTarget { + VkSurfaceKHR surface = nullptr; + VkSwapchainKHR swapchain = nullptr; +}; + class Renderer { public: Renderer(); ~Renderer(); + RenderTarget* createSurfaceRenderTarget(VkSurfaceKHR surface); + void destroyRenderTarget(RenderTarget* target); + + VkInstance getInstance() const { + return instance_; + } + private: void createInstance(); #ifdef DEBUG @@ -25,6 +37,12 @@ private: VkDebugUtilsMessengerEXT messenger_ = nullptr; #endif + VkPhysicalDevice physicalDevice_ = nullptr; VkDevice device_ = nullptr; + + struct { + uint32_t graphics = 0, presentation = 0; + } queueIndices; + VkQueue graphicsQueue_ = nullptr; }; diff --git a/src/main.cpp b/src/main.cpp index d556a9b..a84dc31 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,14 +1,33 @@ #include +#include #include "renderer.h" +#include "platform.h" + +SDL_Window* window = nullptr; + +std::vector platform::getRequiredExtensions() { + uint32_t count = 0; + SDL_Vulkan_GetInstanceExtensions(window, &count, nullptr); + + std::vector names(count); + SDL_Vulkan_GetInstanceExtensions(window, &count, names.data()); + + return names; +} int main(int, char*[]) { - SDL_Window* window = SDL_CreateWindow("Graph", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, 0); + window = SDL_CreateWindow("Graph", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_VULKAN); if(!window) return -1; Renderer* renderer = new Renderer(); + VkSurfaceKHR surface = nullptr; + SDL_Vulkan_CreateSurface(window, renderer->getInstance(), &surface); + + RenderTarget* target = renderer->createSurfaceRenderTarget(surface); + bool running = true; while(running) { SDL_Event event = {}; @@ -18,6 +37,8 @@ int main(int, char*[]) { } } + renderer->destroyRenderTarget(target); + delete renderer; SDL_DestroyWindow(window); diff --git a/src/renderer.cpp b/src/renderer.cpp index 85078f0..6249073 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -5,6 +5,8 @@ #include #include +#include "platform.h" + Renderer::Renderer() { createInstance(); #ifdef DEBUG @@ -24,6 +26,48 @@ Renderer::~Renderer() { vkDestroyInstance(instance_, nullptr); } +RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface) { + RenderTarget* target = new RenderTarget(); + target->surface = surface; + + VkSurfaceCapabilitiesKHR surfaceCapabilities = {}; + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice_, surface, &surfaceCapabilities); + + uint32_t surfaceFormatCount = 0; + vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice_, surface, &surfaceFormatCount, nullptr); + + VkSurfaceFormatKHR* surfaceFormats = new VkSurfaceFormatKHR[surfaceFormatCount]; + vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice_, surface, &surfaceFormatCount, surfaceFormats); + + VkBool32 supported = false; + vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice_, queueIndices.presentation, surface, &supported); + + VkSwapchainCreateInfoKHR swapchainCreateInfo = {}; + swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; + swapchainCreateInfo.surface = surface; + swapchainCreateInfo.minImageCount = surfaceCapabilities.minImageCount; + swapchainCreateInfo.imageColorSpace = surfaceFormats[0].colorSpace; + swapchainCreateInfo.imageFormat = surfaceFormats[0].format; + swapchainCreateInfo.imageExtent = surfaceCapabilities.currentExtent; + swapchainCreateInfo.imageArrayLayers = 1; + swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + swapchainCreateInfo.queueFamilyIndexCount = 1; + swapchainCreateInfo.pQueueFamilyIndices = &queueIndices.presentation; + swapchainCreateInfo.preTransform = surfaceCapabilities.currentTransform; + swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + swapchainCreateInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR; + swapchainCreateInfo.clipped = true; + + vkCreateSwapchainKHR(device_, &swapchainCreateInfo, nullptr, &target->swapchain); + + return target; +} + +void Renderer::destroyRenderTarget(RenderTarget* target) { + vkDestroySwapchainKHR(device_, target->swapchain, nullptr); + vkDestroySurfaceKHR(instance_, target->surface, nullptr); +} + void Renderer::createInstance() { uint32_t layerCount = 0; vkEnumerateInstanceLayerProperties(&layerCount, nullptr); @@ -59,6 +103,9 @@ void Renderer::createInstance() { delete[] availableExtensions; + auto requiredExtensions = platform::getRequiredExtensions(); + enabledExtensions.insert(enabledExtensions.end(), requiredExtensions.begin(), requiredExtensions.end()); + VkInstanceCreateInfo instanceCreateInfo = {}; instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; instanceCreateInfo.enabledLayerCount = enabledLayers.size(); @@ -94,23 +141,21 @@ void Renderer::createLogicalDevice() { VkPhysicalDevice* physicalDevices = new VkPhysicalDevice[physicalDeviceCount]; vkEnumeratePhysicalDevices(instance_, &physicalDeviceCount, physicalDevices); - - VkPhysicalDevice physicalDevice = nullptr; - + for(uint32_t i = 0; i < physicalDeviceCount; i++) { VkPhysicalDeviceProperties properties = {}; vkGetPhysicalDeviceProperties(physicalDevices[i], &properties); - physicalDevice = physicalDevices[i]; + physicalDevice_ = physicalDevices[i]; } delete[] physicalDevices; uint32_t queueFamilyPropertiesCount = 0; - vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertiesCount, nullptr); + vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice_, &queueFamilyPropertiesCount, nullptr); VkQueueFamilyProperties* queueFamilyProperties = new VkQueueFamilyProperties[queueFamilyPropertiesCount]; - vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertiesCount, queueFamilyProperties); + vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice_, &queueFamilyPropertiesCount, queueFamilyProperties); uint32_t graphicsFamilyIndex = 0; @@ -135,12 +180,16 @@ void Renderer::createLogicalDevice() { deviceQueueCreateInfos.push_back(queueCreateInfo); } + const std::vector enabledExtensions = {"VK_KHR_swapchain"}; + VkDeviceCreateInfo deviceCreateInfo = {}; deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; deviceCreateInfo.queueCreateInfoCount = deviceQueueCreateInfos.size(); deviceCreateInfo.pQueueCreateInfos = deviceQueueCreateInfos.data(); + deviceCreateInfo.enabledExtensionCount = enabledExtensions.size(); + deviceCreateInfo.ppEnabledExtensionNames = enabledExtensions.data(); - vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device_); + vkCreateDevice(physicalDevice_, &deviceCreateInfo, nullptr, &device_); vkGetDeviceQueue(device_, graphicsFamilyIndex, 0, &graphicsQueue_); }