Add Vulkan swapchain creation
This commit is contained in:
parent
87fa36233b
commit
54155bd73b
4 changed files with 103 additions and 8 deletions
7
include/platform.h
Normal file
7
include/platform.h
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace platform {
|
||||||
|
std::vector<const char*> getRequiredExtensions();
|
||||||
|
}
|
|
@ -2,11 +2,23 @@
|
||||||
|
|
||||||
#include <vulkan/vulkan.h>
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
|
struct RenderTarget {
|
||||||
|
VkSurfaceKHR surface = nullptr;
|
||||||
|
VkSwapchainKHR swapchain = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
class Renderer {
|
class Renderer {
|
||||||
public:
|
public:
|
||||||
Renderer();
|
Renderer();
|
||||||
~Renderer();
|
~Renderer();
|
||||||
|
|
||||||
|
RenderTarget* createSurfaceRenderTarget(VkSurfaceKHR surface);
|
||||||
|
void destroyRenderTarget(RenderTarget* target);
|
||||||
|
|
||||||
|
VkInstance getInstance() const {
|
||||||
|
return instance_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createInstance();
|
void createInstance();
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -25,6 +37,12 @@ private:
|
||||||
VkDebugUtilsMessengerEXT messenger_ = nullptr;
|
VkDebugUtilsMessengerEXT messenger_ = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
VkPhysicalDevice physicalDevice_ = nullptr;
|
||||||
VkDevice device_ = nullptr;
|
VkDevice device_ = nullptr;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint32_t graphics = 0, presentation = 0;
|
||||||
|
} queueIndices;
|
||||||
|
|
||||||
VkQueue graphicsQueue_ = nullptr;
|
VkQueue graphicsQueue_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
23
src/main.cpp
23
src/main.cpp
|
@ -1,14 +1,33 @@
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
#include <SDL_vulkan.h>
|
||||||
|
|
||||||
#include "renderer.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*[]) {
|
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)
|
if(!window)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
Renderer* renderer = new Renderer();
|
Renderer* renderer = new Renderer();
|
||||||
|
|
||||||
|
VkSurfaceKHR surface = nullptr;
|
||||||
|
SDL_Vulkan_CreateSurface(window, renderer->getInstance(), &surface);
|
||||||
|
|
||||||
|
RenderTarget* target = renderer->createSurfaceRenderTarget(surface);
|
||||||
|
|
||||||
bool running = true;
|
bool running = true;
|
||||||
while(running) {
|
while(running) {
|
||||||
SDL_Event event = {};
|
SDL_Event event = {};
|
||||||
|
@ -18,6 +37,8 @@ int main(int, char*[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderer->destroyRenderTarget(target);
|
||||||
|
|
||||||
delete renderer;
|
delete renderer;
|
||||||
|
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
|
||||||
Renderer::Renderer() {
|
Renderer::Renderer() {
|
||||||
createInstance();
|
createInstance();
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -24,6 +26,48 @@ Renderer::~Renderer() {
|
||||||
vkDestroyInstance(instance_, nullptr);
|
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() {
|
void Renderer::createInstance() {
|
||||||
uint32_t layerCount = 0;
|
uint32_t layerCount = 0;
|
||||||
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
|
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
|
||||||
|
@ -59,6 +103,9 @@ void Renderer::createInstance() {
|
||||||
|
|
||||||
delete[] availableExtensions;
|
delete[] availableExtensions;
|
||||||
|
|
||||||
|
auto requiredExtensions = platform::getRequiredExtensions();
|
||||||
|
enabledExtensions.insert(enabledExtensions.end(), requiredExtensions.begin(), requiredExtensions.end());
|
||||||
|
|
||||||
VkInstanceCreateInfo instanceCreateInfo = {};
|
VkInstanceCreateInfo instanceCreateInfo = {};
|
||||||
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||||
instanceCreateInfo.enabledLayerCount = enabledLayers.size();
|
instanceCreateInfo.enabledLayerCount = enabledLayers.size();
|
||||||
|
@ -94,23 +141,21 @@ void Renderer::createLogicalDevice() {
|
||||||
|
|
||||||
VkPhysicalDevice* physicalDevices = new VkPhysicalDevice[physicalDeviceCount];
|
VkPhysicalDevice* physicalDevices = new VkPhysicalDevice[physicalDeviceCount];
|
||||||
vkEnumeratePhysicalDevices(instance_, &physicalDeviceCount, physicalDevices);
|
vkEnumeratePhysicalDevices(instance_, &physicalDeviceCount, physicalDevices);
|
||||||
|
|
||||||
VkPhysicalDevice physicalDevice = nullptr;
|
|
||||||
|
|
||||||
for(uint32_t i = 0; i < physicalDeviceCount; i++) {
|
for(uint32_t i = 0; i < physicalDeviceCount; i++) {
|
||||||
VkPhysicalDeviceProperties properties = {};
|
VkPhysicalDeviceProperties properties = {};
|
||||||
vkGetPhysicalDeviceProperties(physicalDevices[i], &properties);
|
vkGetPhysicalDeviceProperties(physicalDevices[i], &properties);
|
||||||
|
|
||||||
physicalDevice = physicalDevices[i];
|
physicalDevice_ = physicalDevices[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] physicalDevices;
|
delete[] physicalDevices;
|
||||||
|
|
||||||
uint32_t queueFamilyPropertiesCount = 0;
|
uint32_t queueFamilyPropertiesCount = 0;
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertiesCount, nullptr);
|
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice_, &queueFamilyPropertiesCount, nullptr);
|
||||||
|
|
||||||
VkQueueFamilyProperties* queueFamilyProperties = new VkQueueFamilyProperties[queueFamilyPropertiesCount];
|
VkQueueFamilyProperties* queueFamilyProperties = new VkQueueFamilyProperties[queueFamilyPropertiesCount];
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertiesCount, queueFamilyProperties);
|
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice_, &queueFamilyPropertiesCount, queueFamilyProperties);
|
||||||
|
|
||||||
uint32_t graphicsFamilyIndex = 0;
|
uint32_t graphicsFamilyIndex = 0;
|
||||||
|
|
||||||
|
@ -135,12 +180,16 @@ void Renderer::createLogicalDevice() {
|
||||||
deviceQueueCreateInfos.push_back(queueCreateInfo);
|
deviceQueueCreateInfos.push_back(queueCreateInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<const char*> enabledExtensions = {"VK_KHR_swapchain"};
|
||||||
|
|
||||||
VkDeviceCreateInfo deviceCreateInfo = {};
|
VkDeviceCreateInfo deviceCreateInfo = {};
|
||||||
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||||
deviceCreateInfo.queueCreateInfoCount = deviceQueueCreateInfos.size();
|
deviceCreateInfo.queueCreateInfoCount = deviceQueueCreateInfos.size();
|
||||||
deviceCreateInfo.pQueueCreateInfos = deviceQueueCreateInfos.data();
|
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_);
|
vkGetDeviceQueue(device_, graphicsFamilyIndex, 0, &graphicsQueue_);
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue