window resize handled, instance improved a bit

This commit is contained in:
Blue 2023-10-14 19:57:47 -03:00
parent e114c36690
commit 2b33897b4a
Signed by: blue
GPG Key ID: 9B203B252A63EE38
16 changed files with 182 additions and 115 deletions

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.5)
project(stories VERSION 0.0.1 LANGUAGES CXX) project(stories VERSION 0.0.1 LANGUAGES CXX)
cmake_policy(SET CMP0076 NEW) cmake_policy(SET CMP0076 NEW)

View File

@ -1,51 +1,23 @@
#include "engine.h" #include "engine.h"
#include "instance.h"
constexpr const char* validationLayerName("VK_LAYER_KHRONOS_validation");
Engine::Engine::Engine() : Engine::Engine::Engine() :
initialized(false), initialized(false),
window(new Window()), window(new Window()),
instance(nullptr), instance(new Instance()),
surface(nullptr), surface(nullptr),
physicalDevice(nullptr), physicalDevice(nullptr),
logicalDevice(nullptr), logicalDevice(nullptr),
layerNames(),
instanceExtensionNames(),
deviceExtensionNames(), deviceExtensionNames(),
layers(),
instanceExtensions(),
deviceExtensions() deviceExtensions()
{ {
addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); addDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
} }
Engine::Engine::~Engine() { Engine::Engine::~Engine() {
delete instance;
delete window; delete window;
} }
bool Engine::Engine::enableValidationLayers() const {
return instanceExtensionNames.count(VK_EXT_DEBUG_REPORT_EXTENSION_NAME) > 0 &&
instanceExtensionNames.count(VK_EXT_DEBUG_UTILS_EXTENSION_NAME) > 0 &&
layerNames.count(validationLayerName) > 0;
}
void Engine::Engine::addLayer(const std::string& layerName) {
if (initialized)
throw std::runtime_error("Adding layers to an initialized engine is not supported yet");
layerNames.insert(layerName);
}
void Engine::Engine::addInstanceExtension(const std::string& extensionName) {
if (initialized)
throw std::runtime_error("Adding extension to an initialized engine is not supported yet");
std::pair<std::set<std::string>::const_iterator, bool> pair = instanceExtensionNames.insert(extensionName);
if (pair.second)
instanceExtensions.push_back(pair.first->c_str());
}
void Engine::Engine::addDeviceExtension(const std::string& extensionName) { void Engine::Engine::addDeviceExtension(const std::string& extensionName) {
if (initialized) if (initialized)
throw std::runtime_error("Adding extension to an initialized engine is not supported yet"); throw std::runtime_error("Adding extension to an initialized engine is not supported yet");
@ -56,17 +28,15 @@ void Engine::Engine::addDeviceExtension(const std::string& extensionName) {
} }
void Engine::Engine::enableDebug() { void Engine::Engine::enableDebug() {
addLayer(validationLayerName); instance->enableDebug();
addInstanceExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
addInstanceExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
} }
void Engine::Engine::initVulkan() { void Engine::Engine::initVulkan() {
instance = new Instance(this); instance->initialize(window->getRequiredVulkanExtensions());
surface = new Surface(instance, window); surface = new Surface(instance, window);
pickPhysicalDevice(); pickPhysicalDevice();
logicalDevice = new LogicalDevice(physicalDevice, surface, deviceExtensions, layers); logicalDevice = new LogicalDevice(physicalDevice, surface, deviceExtensions, instance->getLayers());
logicalDevice->createGraphicsPipeline("shaders/shader.vert.spv", "shaders/shader.frag.spv"); logicalDevice->createGraphicsPipeline("shaders/shader.vert.spv", "shaders/shader.frag.spv");
logicalDevice->createSwapChain(); logicalDevice->createSwapChain();
@ -82,8 +52,7 @@ void Engine::Engine::cleanup() {
delete surface; delete surface;
surface = nullptr; surface = nullptr;
delete instance; instance->deinitialize();
instance = nullptr;
} }
void Engine::Engine::pickPhysicalDevice() { void Engine::Engine::pickPhysicalDevice() {
@ -108,10 +77,6 @@ void Engine::Engine::pickPhysicalDevice() {
throw std::runtime_error("failed to find a suitable GPU!"); throw std::runtime_error("failed to find a suitable GPU!");
} }
std::vector<const char *> Engine::Engine::getRequiredVulkanExtensions() const {
return window->getRequiredVulkanExtensions();
}
void Engine::Engine::run() { void Engine::Engine::run() {
initVulkan(); initVulkan();
mainLoop(); mainLoop();
@ -127,8 +92,14 @@ void Engine::Engine::mainLoop() {
//Handle events on queue //Handle events on queue
while (SDL_PollEvent(&e) != 0) { while (SDL_PollEvent(&e) != 0) {
//close the window when user clicks the X button or alt-f4s //close the window when user clicks the X button or alt-f4s
if (e.type == SDL_QUIT) switch (e.type) {
case SDL_QUIT:
bQuit = true; bQuit = true;
break;
case SDL_WINDOWEVENT:
handleWindowEvent(e.window);
break;
}
} }
logicalDevice->drawFrame(); logicalDevice->drawFrame();
@ -136,3 +107,12 @@ void Engine::Engine::mainLoop() {
logicalDevice->waitIdle(); logicalDevice->waitIdle();
} }
void Engine::Engine::handleWindowEvent(const SDL_WindowEvent& e) {
switch (e.event) {
case SDL_WINDOWEVENT_RESIZED:
case SDL_WINDOWEVENT_SIZE_CHANGED:
logicalDevice->setResized();
break;
}
}

View File

@ -23,6 +23,7 @@
#include "window.h" #include "window.h"
#include "surface.h" #include "surface.h"
#include "instance.h"
#include "physicaldevice.h" #include "physicaldevice.h"
#include "logicaldevice.h" #include "logicaldevice.h"
@ -30,21 +31,21 @@ namespace Engine {
const int MAX_FRAMES_IN_FLIGHT = 2; const int MAX_FRAMES_IN_FLIGHT = 2;
class Instance;
class Engine { class Engine {
friend class Instance;
public: public:
Engine(); Engine();
~Engine(); ~Engine();
void run(); void run();
bool enableValidationLayers() const;
void addLayer(const std::string& layerName);
void addInstanceExtension(const std::string& extensionName);
void addDeviceExtension(const std::string& extensionName); void addDeviceExtension(const std::string& extensionName);
void enableDebug(); void enableDebug();
std::vector<const char *> getRequiredVulkanExtensions() const;
private:
void initVulkan();
void mainLoop();
void cleanup();
void pickPhysicalDevice();
void handleWindowEvent(const SDL_WindowEvent& e);
private: private:
bool initialized; bool initialized;
@ -53,17 +54,9 @@ private:
Surface* surface; Surface* surface;
PhysicalDevice* physicalDevice; PhysicalDevice* physicalDevice;
LogicalDevice* logicalDevice; LogicalDevice* logicalDevice;
std::set<std::string> layerNames;
std::set<std::string> instanceExtensionNames;
std::set<std::string> deviceExtensionNames; std::set<std::string> deviceExtensionNames;
std::vector<const char*> layers;
std::vector<const char*> instanceExtensions;
std::vector<const char*> deviceExtensions; std::vector<const char*> deviceExtensions;
void initVulkan();
void mainLoop();
void cleanup();
void pickPhysicalDevice();
}; };
} }

View File

@ -1,13 +1,26 @@
#include "instance.h" #include "instance.h"
#include "engine.h" constexpr const char* validationLayerName("VK_LAYER_KHRONOS_validation");
Engine::Instance::Instance(Engine* eng) : Engine::Instance::Instance() :
initialized(false),
validationLayersEnabledAndSupported(false), validationLayersEnabledAndSupported(false),
engine(eng), layerNames(),
extensionNames(),
layers(),
extensions(),
vk(), vk(),
debugMessenger() debugMessenger()
{ {}
Engine::Instance::~Instance() {
deinitialize();
}
void Engine::Instance::initialize(const std::vector<const char*>& requiredExtensions) {
if (initialized)
return;
VkApplicationInfo appInfo {}; VkApplicationInfo appInfo {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "Hello Triangle"; appInfo.pApplicationName = "Hello Triangle";
@ -18,19 +31,19 @@ Engine::Instance::Instance(Engine* eng) :
appInfo.pNext = nullptr; appInfo.pNext = nullptr;
//TODO handle exception //TODO handle exception
Support exts = getVulkanExtensions(engine->instanceExtensionNames, engine->getRequiredVulkanExtensions()); Support exts = getVulkanExtensions(extensionNames, requiredExtensions);
if (exts.unsupportedCritical.size() > 0) { if (exts.unsupportedCritical.size() > 0) {
std::string error("Unable to create Vulkan instance, following critical extensions are unsupported:\n"); std::string error("Unable to create Vulkan instance, following critical extensions are unsupported:\n");
for (const char* ext : exts.unsupportedCritical) { for (const char* ext : exts.unsupportedCritical)
error += "\t" + std::string(ext) + "\n"; error += "\t" + std::string(ext) + "\n";
}
throw std::runtime_error(error); throw std::runtime_error(error);
} }
//TODO log unsupported; //TODO log unsupported;
exts.logSupported("Applying extensions:"); exts.logSupported("Applying extensions:");
//TODO handle exception //TODO handle exception
Support layers = getVulkanLayers(engine->layerNames); Support layers = getVulkanLayers(layerNames);
//TODO log unsupported //TODO log unsupported
layers.logSupported("Applying layers:"); layers.logSupported("Applying layers:");
@ -44,7 +57,7 @@ Engine::Instance::Instance(Engine* eng) :
createInfo.ppEnabledLayerNames = layers.supported.data(); createInfo.ppEnabledLayerNames = layers.supported.data();
VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo {}; VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo {};
if (engine->enableValidationLayers()) { if (hasValidationLayers()) {
validationLayersEnabledAndSupported = true; //TODO make sure it's actually supported, this shows that they are just enabled; validationLayersEnabledAndSupported = true; //TODO make sure it's actually supported, this shows that they are just enabled;
populateDebugMessengerCreateInfo(debugCreateInfo, debugCallback); populateDebugMessengerCreateInfo(debugCreateInfo, debugCallback);
createInfo.pNext = (VkDebugUtilsMessengerCreateInfoEXT*) &debugCreateInfo; createInfo.pNext = (VkDebugUtilsMessengerCreateInfoEXT*) &debugCreateInfo;
@ -72,13 +85,49 @@ Engine::Instance::Instance(Engine* eng) :
if (validationLayersEnabledAndSupported) if (validationLayersEnabledAndSupported)
setupDebugMessenger(); setupDebugMessenger();
initialized = true;
} }
Engine::Instance::~Instance() { void Engine::Instance::deinitialize() {
if (!initialized)
return;
if (validationLayersEnabledAndSupported) if (validationLayersEnabledAndSupported)
destroyDebugUtilsMessengerEXT(vk, debugMessenger, nullptr); destroyDebugUtilsMessengerEXT(vk, debugMessenger, nullptr);
vkDestroyInstance(vk, nullptr); vkDestroyInstance(vk, nullptr);
initialized = false;
}
void Engine::Instance::addExtension(const std::string& extensionName) {
if (initialized)
throw std::runtime_error("Adding extension to an initialized engine is not supported yet");
std::pair<std::set<std::string>::const_iterator, bool> pair = extensionNames.insert(extensionName);
if (pair.second)
extensions.push_back(pair.first->c_str());
}
void Engine::Instance::addLayer(const std::string& layerName) {
if (initialized)
throw std::runtime_error("Adding layers to an initialized engine is not supported yet");
std::pair<std::set<std::string>::const_iterator, bool> pair = layerNames.insert(layerName);
if (pair.second)
layers.push_back(pair.first->c_str());
}
bool Engine::Instance::hasValidationLayers() {
return extensionNames.count(VK_EXT_DEBUG_REPORT_EXTENSION_NAME) > 0 &&
extensionNames.count(VK_EXT_DEBUG_UTILS_EXTENSION_NAME) > 0 &&
layerNames.count(validationLayerName) > 0;
}
void Engine::Instance::enableDebug() {
addLayer(validationLayerName);
addExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
addExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
} }
void Engine::Instance::setupDebugMessenger() { void Engine::Instance::setupDebugMessenger() {
@ -108,3 +157,6 @@ std::vector<VkPhysicalDevice> Engine::Instance::enumeratePhysicalDevices() const
return devices; return devices;
} }
std::vector<const char *> Engine::Instance::getLayers() const {
return layers;
}

View File

@ -2,30 +2,40 @@
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include <vector> #include <vector>
#include <set>
#include "utils.h" #include "utils.h"
namespace Engine { namespace Engine {
class Engine;
class Window;
class Surface; class Surface;
class Instance { class Instance {
friend class Engine;
friend class Surface; friend class Surface;
public: public:
Instance(Engine* engine); Instance();
~Instance(); ~Instance();
void initialize(const std::vector<const char*>& requiredExtensions);
void deinitialize();
void addLayer(const std::string& layerName);
void addExtension(const std::string& extensionName);
void enableDebug();
std::vector<const char*> getLayers() const;
std::vector<VkPhysicalDevice> enumeratePhysicalDevices() const; std::vector<VkPhysicalDevice> enumeratePhysicalDevices() const;
private: private:
void setupDebugMessenger(); void setupDebugMessenger();
bool hasValidationLayers();
private: private:
bool initialized;
bool validationLayersEnabledAndSupported; bool validationLayersEnabledAndSupported;
Engine* engine; std::set<std::string> layerNames;
std::set<std::string> extensionNames;
std::vector<const char*> layers;
std::vector<const char*> extensions;
VkInstance vk; VkInstance vk;
VkDebugUtilsMessengerEXT debugMessenger; VkDebugUtilsMessengerEXT debugMessenger;
}; };

View File

@ -1,6 +1,7 @@
#include "logicaldevice.h" #include "logicaldevice.h"
#include "swapchain.h" #include "swapchain.h"
#include <iostream>
constexpr int MAX_FRAMES_IN_FLIGHT = 2; constexpr int MAX_FRAMES_IN_FLIGHT = 2;
constexpr float queuePriority = 1.0f; constexpr float queuePriority = 1.0f;
@ -269,6 +270,10 @@ void Engine::LogicalDevice::drawFrame() {
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT; currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
} }
void Engine::LogicalDevice::setResized() {
framebufferResized = true;
}
VkExtent2D Engine::LogicalDevice::chooseSwapExtent() const { VkExtent2D Engine::LogicalDevice::chooseSwapExtent() const {
return surface->chooseSwapExtent(phys->swapChainSupport.capabilities); return surface->chooseSwapExtent(phys->swapChainSupport.capabilities);
} }
@ -564,5 +569,6 @@ void Engine::LogicalDevice::recordCommandBuffer(VkCommandBuffer commandBuffer, u
void Engine::LogicalDevice::recreateSwapChain() { void Engine::LogicalDevice::recreateSwapChain() {
surface->waitForResize(); surface->waitForResize();
waitIdle(); waitIdle();
phys->recreateSwapChainSupportDetails(surface);
createSwapChain(); createSwapChain();
} }

View File

@ -10,11 +10,9 @@
#include "surface.h" #include "surface.h"
namespace Engine { namespace Engine {
class Engine;
class SwapChain; class SwapChain;
class LogicalDevice { class LogicalDevice {
friend class Engine;
public: public:
LogicalDevice( LogicalDevice(
PhysicalDevice* physicalDevice, PhysicalDevice* physicalDevice,
@ -28,6 +26,7 @@ public:
void clearSwapChain(); void clearSwapChain();
void createGraphicsPipeline(const std::string& vertexShaderPath, const std::string& fragmentShaderPath); void createGraphicsPipeline(const std::string& vertexShaderPath, const std::string& fragmentShaderPath);
void recreateSwapChain(); void recreateSwapChain();
void setResized();
void drawFrame(); void drawFrame();

View File

@ -32,3 +32,7 @@ bool Engine::PhysicalDevice::checkDeviceExtensionSupport(VkPhysicalDevice device
return requiredExtensions.empty(); return requiredExtensions.empty();
} }
void Engine::PhysicalDevice::recreateSwapChainSupportDetails(const Surface* surface) {
swapChainSupport = surface->querySwapChainSupport(vk);
}

View File

@ -7,21 +7,22 @@
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include "utils.h" #include "utils.h"
#include "surface.h"
namespace Engine { namespace Engine {
class Engine;
class LogicalDevice; class LogicalDevice;
class PhysicalDevice { class PhysicalDevice {
friend class Engine;
friend class LogicalDevice; friend class LogicalDevice;
public: public:
PhysicalDevice(VkPhysicalDevice raw, const QueueFamilyIndices& indices, const SwapChainSupportDetails& swapChainSupport); PhysicalDevice(VkPhysicalDevice raw, const QueueFamilyIndices& indices, const SwapChainSupportDetails& swapChainSupport);
void recreateSwapChainSupportDetails(const Surface* surface);
static bool checkDeviceExtensionSupport(VkPhysicalDevice device, std::set<std::string> requiredExtensions); static bool checkDeviceExtensionSupport(VkPhysicalDevice device, std::set<std::string> requiredExtensions);
const QueueFamilyIndices indices; const QueueFamilyIndices indices;
const SwapChainSupportDetails swapChainSupport; SwapChainSupportDetails swapChainSupport;
private: private:
VkPhysicalDevice vk; VkPhysicalDevice vk;

View File

@ -86,3 +86,6 @@ VkExtent2D Engine::Surface::waitForResize() const {
return window->waitForResize(); return window->waitForResize();
} }
VkExtent2D Engine::Surface::getSize() const {
return window->getSize();
}

View File

@ -20,6 +20,7 @@ public:
VkExtent2D waitForResize() const; VkExtent2D waitForResize() const;
VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities) const; VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities) const;
VkExtent2D getSize() const;
VkSurfaceFormatKHR chooseSwapSurfaceFormat(const SwapChainSupportDetails& swapChainSupport) const; VkSurfaceFormatKHR chooseSwapSurfaceFormat(const SwapChainSupportDetails& swapChainSupport) const;
bool isDeviceSutable(VkPhysicalDevice device) const; bool isDeviceSutable(VkPhysicalDevice device) const;
SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device) const; SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device) const;

View File

@ -10,6 +10,21 @@ Engine::SwapChain::SwapChain(LogicalDevice* logical):
imageViews(), imageViews(),
frameBuffers() frameBuffers()
{ {
create();
}
Engine::SwapChain::SwapChain(LogicalDevice* logical, const VkExtent2D& extent):
logical(logical),
vk(),
images(),
extent(extent),
imageViews(),
frameBuffers()
{
create();
}
void Engine::SwapChain::create() {
VkResult result = logical->createVkSwapChain(extent, vk); VkResult result = logical->createVkSwapChain(extent, vk);
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
@ -31,6 +46,7 @@ Engine::SwapChain::SwapChain(LogicalDevice* logical):
} }
} }
Engine::SwapChain::~SwapChain() { Engine::SwapChain::~SwapChain() {
for (VkFramebuffer& buffer : frameBuffers) for (VkFramebuffer& buffer : frameBuffers)
logical->destroyVkFrameBuffer(buffer); logical->destroyVkFrameBuffer(buffer);

View File

@ -11,11 +11,15 @@ class SwapChain {
friend class LogicalDevice; friend class LogicalDevice;
public: public:
SwapChain(LogicalDevice* logical); SwapChain(LogicalDevice* logical);
SwapChain(LogicalDevice* logical, const VkExtent2D& extent);
~SwapChain(); ~SwapChain();
VkExtent2D getExtent() const; VkExtent2D getExtent() const;
VkFramebuffer getFrameBuffer(uint32_t index); VkFramebuffer getFrameBuffer(uint32_t index);
private:
void create();
private: private:
LogicalDevice* logical; LogicalDevice* logical;
VkSwapchainKHR vk; VkSwapchainKHR vk;

View File

@ -10,19 +10,18 @@ Engine::Support Engine::getVulkanLayers(const std::set<std::string>& requestedLa
Engine::Support result; Engine::Support result;
if (!discoveredLayers) { if (!discoveredLayers) {
std::vector<VkLayerProperties> props = getAvailableVulkanLayers(); std::vector<VkLayerProperties> props = getAvailableVulkanLayers();
for (const VkLayerProperties& prop : props) { for (const VkLayerProperties& prop : props)
availableLayers.insert(std::make_pair(prop.layerName, prop)); availableLayers.insert(std::make_pair(prop.layerName, prop));
}
discoveredLayers = true; discoveredLayers = true;
} }
for (const std::string& ext : requestedLayers) { for (const std::string& ext : requestedLayers) {
if (availableLayers.count(ext) > 0) { if (availableLayers.count(ext) > 0)
result.supported.push_back(ext.c_str()); result.supported.push_back(ext.c_str());
} else { else
result.unsupported.push_back(ext.c_str()); result.unsupported.push_back(ext.c_str());
} }
}
return result; return result;
} }
@ -34,27 +33,25 @@ Engine::Support Engine::getVulkanExtensions(
Support result; Support result;
if (!discoveredExtensions) { if (!discoveredExtensions) {
std::vector<VkExtensionProperties> props = getAvailableVulkanExtensions(); std::vector<VkExtensionProperties> props = getAvailableVulkanExtensions();
for (const VkExtensionProperties& prop : props) { for (const VkExtensionProperties& prop : props)
availableExtensions.insert(std::make_pair(prop.extensionName, prop)); availableExtensions.insert(std::make_pair(prop.extensionName, prop));
}
discoveredExtensions = true; discoveredExtensions = true;
} }
for (const char* ext : criticalExtensions) { for (const char* ext : criticalExtensions) {
if (availableExtensions.count(ext) > 0) { if (availableExtensions.count(ext) > 0)
result.supported.push_back(ext); result.supported.push_back(ext);
} else { else
result.unsupportedCritical.push_back(ext); result.unsupportedCritical.push_back(ext);
} }
}
for (const std::string& ext : requestedExtensions) { for (const std::string& ext : requestedExtensions) {
if (availableExtensions.count(ext) > 0) { if (availableExtensions.count(ext) > 0)
result.supported.push_back(ext.c_str()); result.supported.push_back(ext.c_str());
} else { else
result.unsupported.push_back(ext.c_str()); result.unsupported.push_back(ext.c_str());
} }
}
return result; return result;
} }
@ -62,15 +59,13 @@ Engine::Support Engine::getVulkanExtensions(
std::vector<VkExtensionProperties> Engine::getAvailableVulkanExtensions() { std::vector<VkExtensionProperties> Engine::getAvailableVulkanExtensions() {
unsigned int extCount = 0; unsigned int extCount = 0;
VkResult res = vkEnumerateInstanceExtensionProperties(nullptr, &extCount, nullptr); VkResult res = vkEnumerateInstanceExtensionProperties(nullptr, &extCount, nullptr);
if (res != VK_SUCCESS) { if (res != VK_SUCCESS)
throw std::runtime_error("unable to query vulkan extension property count"); throw std::runtime_error("unable to query vulkan extension property count");
}
std::vector<VkExtensionProperties> extensions(extCount); std::vector<VkExtensionProperties> extensions(extCount);
res = vkEnumerateInstanceExtensionProperties(nullptr, &extCount, extensions.data()); res = vkEnumerateInstanceExtensionProperties(nullptr, &extCount, extensions.data());
if (res != VK_SUCCESS) { if (res != VK_SUCCESS)
throw std::runtime_error("unable to retrieve vulkan instance layer names"); throw std::runtime_error("unable to retrieve vulkan instance layer names");
}
return extensions; return extensions;
} }
@ -95,15 +90,13 @@ void Engine::populateDebugMessengerCreateInfo(
std::vector<VkLayerProperties> Engine::getAvailableVulkanLayers() { std::vector<VkLayerProperties> Engine::getAvailableVulkanLayers() {
unsigned int layerCount = 0; unsigned int layerCount = 0;
VkResult res = vkEnumerateInstanceLayerProperties(&layerCount, nullptr); VkResult res = vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
if (res != VK_SUCCESS) { if (res != VK_SUCCESS)
throw std::runtime_error("unable to query vulkan instance layer property count"); throw std::runtime_error("unable to query vulkan instance layer property count");
}
std::vector<VkLayerProperties> layers(layerCount); std::vector<VkLayerProperties> layers(layerCount);
res = vkEnumerateInstanceLayerProperties(&layerCount, layers.data()); res = vkEnumerateInstanceLayerProperties(&layerCount, layers.data());
if (res != VK_SUCCESS) { if (res != VK_SUCCESS)
throw std::runtime_error("unable to retrieve vulkan instance layer names"); throw std::runtime_error("unable to retrieve vulkan instance layer names");
}
return layers; return layers;
} }
@ -175,20 +168,18 @@ std::vector<char> Engine::readFile(const std::string& filename) {
VkSurfaceFormatKHR Engine::chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats) { VkSurfaceFormatKHR Engine::chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats) {
for (const VkSurfaceFormatKHR& availableFormat : availableFormats) { for (const VkSurfaceFormatKHR& availableFormat : availableFormats) {
if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
return availableFormat; return availableFormat;
} }
}
return availableFormats[0]; return availableFormats[0];
} }
VkPresentModeKHR Engine::chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes) { VkPresentModeKHR Engine::chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes) {
for (const auto& availablePresentMode : availablePresentModes) { for (const auto& availablePresentMode : availablePresentModes) {
if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) { if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR)
return availablePresentMode; return availablePresentMode;
} }
}
return VK_PRESENT_MODE_FIFO_KHR; return VK_PRESENT_MODE_FIFO_KHR;
} }

View File

@ -1,18 +1,11 @@
#include "window.h" #include "window.h"
#include <iostream>
Engine::Window::Window(uint32_t width, uint32_t height) : Engine::Window::Window(uint32_t width, uint32_t height) :
sdl(createWindow(width, height)), sdl(createWindow(width, height)),
extent({width, height}) extent({width, height})
{ {}
//glfwSetWindowUserPointer(window, this);
//glfwSetFramebufferSizeCallback(window, framebufferResizeCallback);
}
// static void framebufferResizeCallback(SDL_Window* window, int width, int height) {
// auto app = reinterpret_cast<HelloTriangleApplication*>(glfwGetWindowUserPointer(window));
// app->framebufferResized = true;
// }
Engine::Window::~Window() { Engine::Window::~Window() {
SDL_DestroyWindow(sdl); SDL_DestroyWindow(sdl);
@ -27,7 +20,7 @@ SDL_Window* Engine::Window::createWindow(uint32_t width, uint32_t height) {
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
width, width,
height, height,
SDL_WINDOW_VULKAN SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE
); );
return wnd; return wnd;
@ -59,6 +52,18 @@ VkExtent2D Engine::Window::getDrawableSize() const {
return actualExtent; return actualExtent;
} }
VkExtent2D Engine::Window::getSize() const {
int width, height;
SDL_GetWindowSize(sdl, &width, &height);
VkExtent2D actualExtent = {
static_cast<uint32_t>(width),
static_cast<uint32_t>(height)
};
return actualExtent;
}
void Engine::Window::createSurface(VkInstance instance, VkSurfaceKHR* out) const { void Engine::Window::createSurface(VkInstance instance, VkSurfaceKHR* out) const {
if (SDL_Vulkan_CreateSurface(sdl, instance, out) != SDL_TRUE) { if (SDL_Vulkan_CreateSurface(sdl, instance, out) != SDL_TRUE) {
throw std::runtime_error("failed to create window surface!"); throw std::runtime_error("failed to create window surface!");
@ -74,6 +79,7 @@ VkExtent2D Engine::Window::chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capa
actualExtent.width = std::clamp(actualExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width); actualExtent.width = std::clamp(actualExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
actualExtent.height = std::clamp(actualExtent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height); actualExtent.height = std::clamp(actualExtent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
std::cout << actualExtent.width << ":" << actualExtent.height << std::endl;
return actualExtent; return actualExtent;
} }
} }

View File

@ -21,6 +21,7 @@ public:
std::vector<const char *> getRequiredVulkanExtensions() const; std::vector<const char *> getRequiredVulkanExtensions() const;
VkExtent2D waitForResize() const; VkExtent2D waitForResize() const;
VkExtent2D getSize() const;
VkExtent2D getDrawableSize() const; VkExtent2D getDrawableSize() const;
VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities) const; VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities) const;
void createSurface(VkInstance instance, VkSurfaceKHR* out) const; void createSurface(VkInstance instance, VkSurfaceKHR* out) const;