Compare commits
5 Commits
eeb0dd8024
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| e82355d05d | |||
| 65cd03961d | |||
| 0ed40a0b64 | |||
|
|
6d48ac251c | ||
|
|
969a3285e9 |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -103,4 +103,9 @@ CMakeUserPresets.json
|
||||
# Other
|
||||
.cache/
|
||||
.vscode/
|
||||
build/
|
||||
build*/
|
||||
|
||||
.kdev4/
|
||||
*.kdev4
|
||||
|
||||
*_old.*
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,6 +1,3 @@
|
||||
[submodule "thirdparty/vk-bootstrap"]
|
||||
path = thirdparty/vk-bootstrap
|
||||
url = https://github.com/charles-lunarg/vk-bootstrap.git
|
||||
[submodule "thirdparty/SDL"]
|
||||
path = thirdparty/SDL
|
||||
url = https://github.com/libsdl-org/SDL.git
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(vksdlproj VERSION 0.1.0 LANGUAGES C CXX)
|
||||
project(vksdlproj VERSION 0.2.0 LANGUAGES C CXX)
|
||||
|
||||
SET(CMAKE_BUILD_RPATH_USE_ORIGIN TRUE)
|
||||
set(EXE_NAME project)
|
||||
#set(CMAKE_BUILD_RPATH_USE_ORIGIN TRUE)
|
||||
#set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
|
||||
set(EXE_NAME sdl3vkgame)
|
||||
|
||||
set(PROGRAM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/vulkanapp.cc)
|
||||
set(PROGRAM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/vk_app.cc)
|
||||
|
||||
option(SDL3_NONSYSTEM "Use SDL3 from folder in source tree" ON)
|
||||
|
||||
@@ -31,8 +32,6 @@ else()
|
||||
find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3-shared)
|
||||
endif()
|
||||
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/vk-bootstrap)
|
||||
|
||||
find_package(Vulkan REQUIRED COMPONENTS glslc)
|
||||
|
||||
# Compile each shader
|
||||
@@ -66,7 +65,14 @@ elseif(MSVC)
|
||||
target_compile_options(${EXE_NAME} PRIVATE /W4)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
add_custom_command(
|
||||
TARGET ${EXE_NAME} POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy $<TARGET_FILE:SDL3::SDL3-shared> $<TARGET_FILE_DIR:${EXE_NAME}>
|
||||
VERBATIM
|
||||
)
|
||||
endif()
|
||||
|
||||
# Linking
|
||||
target_link_libraries(${EXE_NAME} PRIVATE SDL3::SDL3)
|
||||
target_link_libraries(${EXE_NAME} PRIVATE Vulkan::Vulkan)
|
||||
target_link_libraries(${EXE_NAME} PRIVATE vk-bootstrap::vk-bootstrap)
|
||||
target_link_libraries(${EXE_NAME} PRIVATE Vulkan::Vulkan) # TODO: change this to Vulkna::Headers and use loader
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 macmacmac
|
||||
Copyright (c) 2025 Alexander Raptis
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL3/SDL_video.h>
|
||||
#include <SDL3/SDL_events.h>
|
||||
#include <SDL3/SDL_init.h>
|
||||
#include <SDL3/SDL_log.h>
|
||||
#include <SDL3/SDL_vulkan.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <set>
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
#include "vk_types.hh"
|
||||
|
||||
const std::vector<const char*> validationLayers = {
|
||||
"VK_LAYER_KHRONOS_validation"
|
||||
@@ -19,53 +25,42 @@ const std::vector<const char*> deviceExtensions = {
|
||||
|
||||
const int MAX_FRAMES_IN_FLIGHT = 2;
|
||||
|
||||
#ifdef NDEBUG
|
||||
const bool enableValidationLayers = false;
|
||||
#else
|
||||
const bool enableValidationLayers = true;
|
||||
#endif
|
||||
|
||||
VkResult CreateDebugUtilsMessengerEXT(VkInstance, const VkDebugUtilsMessengerCreateInfoEXT*, const VkAllocationCallbacks*, VkDebugUtilsMessengerEXT*);
|
||||
void DestroyDebugUtilsMessengerEXT(VkInstance, VkDebugUtilsMessengerEXT, const VkAllocationCallbacks*);
|
||||
|
||||
struct QueueFamilyIndices {
|
||||
std::optional<uint32_t> graphicsFamily;
|
||||
std::optional<uint32_t> presentFamily;
|
||||
|
||||
bool complete() {
|
||||
return graphicsFamily.has_value() && presentFamily.has_value();
|
||||
}
|
||||
};
|
||||
|
||||
struct SwapChainSupportDetails {
|
||||
VkSurfaceCapabilitiesKHR capabilities;
|
||||
std::vector<VkSurfaceFormatKHR> formats;
|
||||
std::vector<VkPresentModeKHR> presentModes;
|
||||
};
|
||||
|
||||
class VulkanApp {
|
||||
public:
|
||||
VulkanApp(const uint32_t& _w, const uint32_t& _h) :
|
||||
mWin(nullptr), mWidth(_w), mHeight(_h) {}
|
||||
VulkanApp(const char *_t, const uint32_t& _w, const uint32_t& _h) :
|
||||
mWin(nullptr), mWidth(_w), mHeight(_h), mTitle(_t),
|
||||
mResized(false), mMinimized(false),
|
||||
mPhysicalDevice(nullptr) {}
|
||||
~VulkanApp() { cleanup(); }
|
||||
|
||||
void init();
|
||||
void loop();
|
||||
void cleanup();
|
||||
SDL_AppResult mAppState = SDL_APP_CONTINUE;
|
||||
SDL_AppResult init();
|
||||
SDL_AppResult loop();
|
||||
inline bool minimized() { return mMinimized; }
|
||||
inline void minimized(bool _v) { mMinimized = _v; }
|
||||
inline void resized(bool _v) { mResized = _v; }
|
||||
private:
|
||||
// SDL2
|
||||
// SDL3
|
||||
SDL_Window *mWin;
|
||||
SDL_Event mEvent;
|
||||
|
||||
// Not tied to library
|
||||
uint32_t mWidth;
|
||||
uint32_t mHeight;
|
||||
bool mActive = false;
|
||||
bool mResized = false;
|
||||
bool mMinimized = false;
|
||||
const char *mTitle;
|
||||
bool mResized;
|
||||
bool mMinimized;
|
||||
|
||||
#ifdef NDEBUG
|
||||
const bool mEnableValidationLayers = false;
|
||||
#else
|
||||
const bool mEnableValidationLayers = true;
|
||||
#endif
|
||||
|
||||
// Vulkan
|
||||
VkInstance mInstance;
|
||||
VkPhysicalDevice mPhysicalDevice = VK_NULL_HANDLE;
|
||||
VkPhysicalDevice mPhysicalDevice;
|
||||
VkDevice mLogicalDevice;
|
||||
VkSurfaceKHR mSurface;
|
||||
|
||||
@@ -90,7 +85,6 @@ private:
|
||||
std::vector<VkSemaphore> mRenderFinishedSemaphores;
|
||||
std::vector<VkFence> mInFlightFences;
|
||||
|
||||
|
||||
VkDebugUtilsMessengerEXT mDebugMessenger;
|
||||
|
||||
void createInstance();
|
||||
@@ -111,6 +105,7 @@ private:
|
||||
|
||||
void recordCommandBuffer(VkCommandBuffer, uint32_t);
|
||||
void drawFrame();
|
||||
void cleanup();
|
||||
|
||||
QueueFamilyIndices findQueueFamilies(VkPhysicalDevice);
|
||||
bool isDeviceSuitable(VkPhysicalDevice);
|
||||
@@ -120,6 +115,7 @@ private:
|
||||
VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>&);
|
||||
VkPresentModeKHR chooseSwapPresentMode(const std::vector<VkPresentModeKHR>&);
|
||||
VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR&);
|
||||
|
||||
// Validation layer stuff
|
||||
void setupDebugMessenger();
|
||||
bool checkValidationLayerSupport();
|
||||
@@ -129,11 +125,11 @@ private:
|
||||
(void)pUserData;
|
||||
|
||||
if(messageSeverity >= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
|
||||
fprintf(stderr, "Validation Layer [Error/Warning]: %s \n", pCallbackData->pMessage);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Validation Layer [Error/Warning]: %s \n", pCallbackData->pMessage);
|
||||
} else if(messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT) {
|
||||
fprintf(stderr, "Validation Layer [General]: %s \n", pCallbackData->pMessage);
|
||||
SDL_Log("Validation Layer [General]: %s \n", pCallbackData->pMessage);
|
||||
} else {
|
||||
fprintf(stderr, "Validation Layer: %s \n", pCallbackData->pMessage);
|
||||
SDL_Log("Validation Layer: %s \n", pCallbackData->pMessage);
|
||||
}
|
||||
|
||||
return VK_FALSE;
|
||||
18
include/vk_types.hh
Normal file
18
include/vk_types.hh
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
struct QueueFamilyIndices {
|
||||
std::optional<uint32_t> graphicsFamily;
|
||||
std::optional<uint32_t> presentFamily;
|
||||
|
||||
bool complete() {
|
||||
return graphicsFamily.has_value() && presentFamily.has_value();
|
||||
}
|
||||
};
|
||||
|
||||
struct SwapChainSupportDetails {
|
||||
VkSurfaceCapabilitiesKHR capabilities;
|
||||
std::vector<VkSurfaceFormatKHR> formats;
|
||||
std::vector<VkPresentModeKHR> presentModes;
|
||||
};
|
||||
66
src/main.cc
66
src/main.cc
@@ -1,19 +1,61 @@
|
||||
#include "vulkanapp.hh"
|
||||
#define SDL_MAIN_USE_CALLBACKS
|
||||
#include <SDL3/SDL_main.h>
|
||||
|
||||
#include <exception>
|
||||
#include "vk_app.hh"
|
||||
|
||||
int main() {
|
||||
VulkanApp app(1024, 1024);
|
||||
constexpr uint32_t winInitWidth = 1024;
|
||||
constexpr uint32_t winInitHeight = 1024;
|
||||
|
||||
try {
|
||||
app.init();
|
||||
app.loop();
|
||||
app.cleanup();
|
||||
} catch(const std::exception& except) {
|
||||
fprintf(stderr, "Error! %s\n", except.what());
|
||||
SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
return 1;
|
||||
*appstate = new VulkanApp("Vulkan+SDL3 App", winInitWidth, winInitHeight);
|
||||
VulkanApp* app = static_cast<VulkanApp*>(*appstate);
|
||||
|
||||
return app->init();
|
||||
}
|
||||
|
||||
SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) {
|
||||
VulkanApp* app = static_cast<VulkanApp*>(appstate);
|
||||
|
||||
switch(event->type) {
|
||||
case SDL_EVENT_QUIT:
|
||||
app->mAppState = SDL_APP_SUCCESS;
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_RESIZED:
|
||||
app->resized(true);
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_MINIMIZED:
|
||||
app->minimized(true);
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_RESTORED:
|
||||
app->minimized(false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return app->mAppState;
|
||||
}
|
||||
|
||||
SDL_AppResult SDL_AppIterate(void *appstate) {
|
||||
VulkanApp* app = static_cast<VulkanApp*>(appstate);
|
||||
|
||||
return app->loop();
|
||||
}
|
||||
|
||||
void SDL_AppQuit(void *appstate, SDL_AppResult result) {
|
||||
VulkanApp* app = static_cast<VulkanApp*>(appstate);
|
||||
|
||||
#ifndef NDEBUG
|
||||
if(result == SDL_APP_FAILURE)
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Program failure occured, shutting down");
|
||||
else
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Program shutting down, no errors.");
|
||||
#endif
|
||||
|
||||
// Cleanup
|
||||
if(app) delete app;
|
||||
SDL_Quit();
|
||||
}
|
||||
@@ -1,13 +1,4 @@
|
||||
#include "vulkanapp.hh"
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_vulkan.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
#include <set>
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
#include "vk_app.hh"
|
||||
|
||||
// Validator stuff
|
||||
VkResult CreateDebugUtilsMessengerEXT(VkInstance instance,
|
||||
@@ -160,7 +151,7 @@ VkSurfaceFormatKHR VulkanApp::chooseSwapSurfaceFormat(const std::vector<VkSurfac
|
||||
|
||||
VkPresentModeKHR VulkanApp::chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes) {
|
||||
for (const VkPresentModeKHR& availablePresentMode : availablePresentModes) {
|
||||
if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) {
|
||||
if (availablePresentMode == VK_PRESENT_MODE_FIFO_KHR) {
|
||||
return availablePresentMode;
|
||||
}
|
||||
}
|
||||
@@ -304,13 +295,18 @@ void VulkanApp::drawFrame() {
|
||||
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
|
||||
}
|
||||
|
||||
void VulkanApp::init() {
|
||||
// Initialize SDL2
|
||||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
|
||||
//SDL_Vulkan_LoadLibrary(nullptr);
|
||||
SDL_AppResult VulkanApp::init() {
|
||||
// Initialize SDL3
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
|
||||
// if(!SDL_Vulkan_LoadLibrary(nullptr)) {
|
||||
// std::string err = "Could not load vulkan library! " + std::string(SDL_GetError()) + "\n";
|
||||
//
|
||||
// throw std::runtime_error(err);
|
||||
// }
|
||||
|
||||
// Create the window
|
||||
mWin = SDL_CreateWindow("Vulkan+SDL2 Application",
|
||||
mWin = SDL_CreateWindow(mTitle,
|
||||
mWidth,
|
||||
mHeight,
|
||||
SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE
|
||||
@@ -321,6 +317,9 @@ void VulkanApp::init() {
|
||||
throw std::runtime_error(err);
|
||||
}
|
||||
|
||||
SDL_SetWindowMaximumSize(mWin, mWidth, mHeight);
|
||||
SDL_SetWindowMinimumSize(mWin, mWidth / 2, mHeight / 2);
|
||||
|
||||
// Vulkan stuff from here
|
||||
createInstance();
|
||||
setupDebugMessenger();
|
||||
@@ -330,6 +329,7 @@ void VulkanApp::init() {
|
||||
throw std::runtime_error("Could not create Vulkan surface!");
|
||||
}
|
||||
|
||||
// TODO: Replace some of this crap with vulkan hpp code
|
||||
selectPhysicalDevice();
|
||||
createLogicalDevice();
|
||||
createSwapChain();
|
||||
@@ -340,29 +340,32 @@ void VulkanApp::init() {
|
||||
createCommandPool();
|
||||
createCommandBuffer();
|
||||
createSyncObjects();
|
||||
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
void VulkanApp::createInstance() {
|
||||
if (enableValidationLayers && !checkValidationLayerSupport()) {
|
||||
if (mEnableValidationLayers && !checkValidationLayerSupport()) {
|
||||
throw std::runtime_error("Validation layers requested, but not available!");
|
||||
}
|
||||
|
||||
// Get # of extensions then get extensions
|
||||
uint32_t extensionCount = 0;
|
||||
const char * const * extensionArr = SDL_Vulkan_GetInstanceExtensions(&extensionCount);
|
||||
const char * const *extensionArr = SDL_Vulkan_GetInstanceExtensions(&extensionCount);
|
||||
// Put extensions into vector
|
||||
std::vector<const char*> extensionNames(extensionArr, extensionArr + extensionCount);
|
||||
|
||||
if(enableValidationLayers)
|
||||
if(mEnableValidationLayers)
|
||||
extensionNames.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
|
||||
// App info
|
||||
VkApplicationInfo appInfo{};
|
||||
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
appInfo.pApplicationName = "Simple Triangle";
|
||||
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
|
||||
appInfo.pApplicationName = "Triangle";
|
||||
appInfo.applicationVersion = VK_MAKE_VERSION(1, 1, 0);
|
||||
appInfo.pEngineName = "RAPT2";
|
||||
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
|
||||
appInfo.apiVersion = VK_API_VERSION_1_0;
|
||||
appInfo.engineVersion = VK_MAKE_VERSION(1, 1, 0);
|
||||
appInfo.apiVersion = VK_API_VERSION_1_1;
|
||||
|
||||
// Extensions
|
||||
VkInstanceCreateInfo createInfo{};
|
||||
@@ -374,7 +377,7 @@ void VulkanApp::createInstance() {
|
||||
|
||||
// Debug handling
|
||||
VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo{};
|
||||
if(enableValidationLayers) {
|
||||
if(mEnableValidationLayers) {
|
||||
createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
|
||||
createInfo.ppEnabledLayerNames = validationLayers.data();
|
||||
|
||||
@@ -404,9 +407,8 @@ void VulkanApp::selectPhysicalDevice() {
|
||||
uint32_t deviceCount = 0;
|
||||
vkEnumeratePhysicalDevices(mInstance, &deviceCount, nullptr);
|
||||
|
||||
if(deviceCount == 0) {
|
||||
if(deviceCount == 0)
|
||||
throw std::runtime_error("Could not find a Vulkan compatible GPU!");
|
||||
}
|
||||
|
||||
std::vector<VkPhysicalDevice> devices(deviceCount);
|
||||
vkEnumeratePhysicalDevices(mInstance, &deviceCount, devices.data());
|
||||
@@ -419,9 +421,8 @@ void VulkanApp::selectPhysicalDevice() {
|
||||
}
|
||||
}
|
||||
|
||||
if(mPhysicalDevice == VK_NULL_HANDLE) {
|
||||
if(mPhysicalDevice == VK_NULL_HANDLE)
|
||||
throw std::runtime_error("Could not find any suitable GPU!");
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanApp::createLogicalDevice() {
|
||||
@@ -458,7 +459,7 @@ void VulkanApp::createLogicalDevice() {
|
||||
createInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
|
||||
createInfo.ppEnabledExtensionNames = deviceExtensions.data();
|
||||
|
||||
if (enableValidationLayers) {
|
||||
if (mEnableValidationLayers) {
|
||||
createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
|
||||
createInfo.ppEnabledLayerNames = validationLayers.data();
|
||||
} else {
|
||||
@@ -838,7 +839,7 @@ bool VulkanApp::checkValidationLayerSupport() {
|
||||
}
|
||||
|
||||
void VulkanApp::setupDebugMessenger() {
|
||||
if (!enableValidationLayers) return;
|
||||
if (!mEnableValidationLayers) return;
|
||||
|
||||
VkDebugUtilsMessengerCreateInfoEXT createInfo;
|
||||
createInfo = {};
|
||||
@@ -856,39 +857,17 @@ void VulkanApp::setupDebugMessenger() {
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanApp::loop() {
|
||||
SDL_AppResult VulkanApp::loop() {
|
||||
if(mWin == nullptr) {
|
||||
std::string err = "Could not find window " + std::string(SDL_GetError()) + "\n";
|
||||
throw std::runtime_error(err);
|
||||
}
|
||||
|
||||
mActive = true;
|
||||
|
||||
// Main loop
|
||||
while(mActive) {
|
||||
while(SDL_PollEvent(&mEvent)) {
|
||||
switch (mEvent.type) {
|
||||
case SDL_EVENT_QUIT:
|
||||
mActive = false;
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_RESIZED:
|
||||
mResized = true;
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_MINIMIZED:
|
||||
mMinimized = true;
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_RESTORED:
|
||||
mMinimized = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!mMinimized) drawFrame();
|
||||
}
|
||||
if(!mMinimized) drawFrame();
|
||||
|
||||
vkDeviceWaitIdle(mLogicalDevice);
|
||||
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
void VulkanApp::cleanup() {
|
||||
@@ -909,9 +888,8 @@ void VulkanApp::cleanup() {
|
||||
|
||||
vkDestroyDevice(mLogicalDevice, nullptr);
|
||||
|
||||
if (enableValidationLayers) {
|
||||
if (mEnableValidationLayers)
|
||||
DestroyDebugUtilsMessengerEXT(mInstance, mDebugMessenger, nullptr);
|
||||
}
|
||||
|
||||
vkDestroySurfaceKHR(mInstance, mSurface, nullptr);
|
||||
vkDestroyInstance(mInstance, nullptr);
|
||||
@@ -921,7 +899,4 @@ void VulkanApp::cleanup() {
|
||||
SDL_DestroyWindow(mWin);
|
||||
mWin = nullptr;
|
||||
}
|
||||
|
||||
//SDL_Vulkan_UnloadLibrary();
|
||||
SDL_Quit();
|
||||
}
|
||||
1
thirdparty/vk-bootstrap
vendored
1
thirdparty/vk-bootstrap
vendored
Submodule thirdparty/vk-bootstrap deleted from 0437431fd0
Reference in New Issue
Block a user