Archived
1
Fork 0

Add Vulkan swapchain creation

This commit is contained in:
Joshua Goins 2018-09-29 21:03:06 -04:00
parent 87fa36233b
commit 54155bd73b
4 changed files with 103 additions and 8 deletions

7
include/platform.h Normal file
View file

@ -0,0 +1,7 @@
#pragma once
#include <vector>
namespace platform {
std::vector<const char*> getRequiredExtensions();
}

View file

@ -2,11 +2,23 @@
#include <vulkan/vulkan.h>
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;
};

View file

@ -1,14 +1,33 @@
#include <SDL.h>
#include <SDL_vulkan.h>
#include "renderer.h"
#include "platform.h"
SDL_Window* window = nullptr;
std::vector<const char*> platform::getRequiredExtensions() {
uint32_t count = 0;
SDL_Vulkan_GetInstanceExtensions(window, &count, nullptr);
std::vector<const char*> 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);

View file

@ -5,6 +5,8 @@
#include <iostream>
#include <cstring>
#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();
@ -95,22 +142,20 @@ 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<const char*> 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_);
}