mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
gfx work
This commit is contained in:
parent
2c4a47541d
commit
40c0c024a1
@ -1,11 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
#include "log.hpp"
|
|
||||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
|
||||||
#include <spdlog/sinks/basic_file_sink.h>
|
|
||||||
|
|
||||||
namespace engine {
|
namespace engine {
|
||||||
|
|
||||||
struct AppInfo {
|
struct AppInfo {
|
||||||
|
@ -4,13 +4,16 @@
|
|||||||
|
|
||||||
#include "engine.hpp"
|
#include "engine.hpp"
|
||||||
|
|
||||||
class Window;
|
#include <SDL_video.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
|
||||||
namespace engine::gfx {
|
namespace engine::gfx {
|
||||||
|
|
||||||
struct ENGINE_API Device {
|
struct ENGINE_API Device {
|
||||||
|
|
||||||
Device(AppInfo appInfo, const Window& window);
|
Device(AppInfo appInfo, SDL_Window* window);
|
||||||
~Device();
|
~Device();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -124,77 +124,76 @@ public:
|
|||||||
|
|
||||||
bool infoBox(const std::string& title, const std::string& msg);
|
bool infoBox(const std::string& title, const std::string& msg);
|
||||||
|
|
||||||
std::vector<const char*> getRequiredVulkanExtensions() const;
|
|
||||||
|
|
||||||
/* STATIC METHODS */
|
/* STATIC METHODS */
|
||||||
static void errorBox(const std::string& message);
|
static void errorBox(const std::string& message);
|
||||||
|
|
||||||
private:
|
public:
|
||||||
SDL_Window* m_handle;
|
SDL_Window* m_handle;
|
||||||
|
|
||||||
bool m_shouldClose = false;
|
private:
|
||||||
|
|
||||||
std::string m_title;
|
bool m_shouldClose = false;
|
||||||
|
|
||||||
bool m_fullscreen = false;
|
std::string m_title;
|
||||||
bool m_justResized = false;
|
|
||||||
bool m_keyboardFocus = true;
|
|
||||||
|
|
||||||
// size in screen coordinates
|
bool m_fullscreen = false;
|
||||||
glm::ivec2 m_winSize = glm::vec2(640, 480);
|
bool m_justResized = false;
|
||||||
|
bool m_keyboardFocus = true;
|
||||||
|
|
||||||
// performance counter frequency
|
// size in screen coordinates
|
||||||
uint64_t m_counterFreq;
|
glm::ivec2 m_winSize = glm::vec2(640, 480);
|
||||||
|
|
||||||
// number of frames swapped
|
// performance counter frequency
|
||||||
uint64_t m_frames = 0;
|
uint64_t m_counterFreq;
|
||||||
// frame count offset for fpsAvg
|
|
||||||
uint64_t m_avgFpsStartCount = 0;
|
|
||||||
// in nanoseconds
|
|
||||||
uint64_t m_startTime;
|
|
||||||
// in nanoseconds
|
|
||||||
uint64_t m_lastFrameStamp;
|
|
||||||
// in nanoseconds; elapsed time between frames
|
|
||||||
uint64_t m_lastFrameTime = 1; // not 0 to avoid division by zero
|
|
||||||
// in nanoseconds
|
|
||||||
uint64_t m_avgFpsStart;
|
|
||||||
|
|
||||||
// input stuff
|
// number of frames swapped
|
||||||
|
uint64_t m_frames = 0;
|
||||||
|
// frame count offset for fpsAvg
|
||||||
|
uint64_t m_avgFpsStartCount = 0;
|
||||||
|
// in nanoseconds
|
||||||
|
uint64_t m_startTime;
|
||||||
|
// in nanoseconds
|
||||||
|
uint64_t m_lastFrameStamp;
|
||||||
|
// in nanoseconds; elapsed time between frames
|
||||||
|
uint64_t m_lastFrameTime = 1; // not 0 to avoid division by zero
|
||||||
|
// in nanoseconds
|
||||||
|
uint64_t m_avgFpsStart;
|
||||||
|
|
||||||
enum class ButtonDelta {
|
// input stuff
|
||||||
SAME = 0,
|
|
||||||
PRESSED,
|
|
||||||
RELEASED
|
|
||||||
};
|
|
||||||
|
|
||||||
struct {
|
enum class ButtonDelta {
|
||||||
std::array<bool, SDL_NUM_SCANCODES> keys;
|
SAME = 0,
|
||||||
std::array<enum ButtonDelta, SDL_NUM_SCANCODES> deltas;
|
PRESSED,
|
||||||
} m_keyboard{ };
|
RELEASED
|
||||||
|
};
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
std::array<bool, static_cast<int>(inputs::MouseButton::M_SIZE)> buttons;
|
std::array<bool, SDL_NUM_SCANCODES> keys;
|
||||||
std::array<enum ButtonDelta, 8> deltas;
|
std::array<enum ButtonDelta, SDL_NUM_SCANCODES> deltas;
|
||||||
Sint32 x;
|
} m_keyboard{ };
|
||||||
Sint32 y;
|
|
||||||
Sint32 dx;
|
|
||||||
Sint32 dy;
|
|
||||||
float xscroll;
|
|
||||||
float yscroll;
|
|
||||||
bool captured = false;
|
|
||||||
} m_mouse{ };
|
|
||||||
|
|
||||||
// private methods
|
struct {
|
||||||
|
std::array<bool, static_cast<int>(inputs::MouseButton::M_SIZE)> buttons;
|
||||||
|
std::array<enum ButtonDelta, 8> deltas;
|
||||||
|
Sint32 x;
|
||||||
|
Sint32 y;
|
||||||
|
Sint32 dx;
|
||||||
|
Sint32 dy;
|
||||||
|
float xscroll;
|
||||||
|
float yscroll;
|
||||||
|
bool captured = false;
|
||||||
|
} m_mouse{ };
|
||||||
|
|
||||||
void onResize(Sint32 width, Sint32 height);
|
// private methods
|
||||||
void resetInputDeltas();
|
|
||||||
|
|
||||||
// event methods (like callbacks)
|
void onResize(Sint32 width, Sint32 height);
|
||||||
|
void resetInputDeltas();
|
||||||
|
|
||||||
void onWindowEvent(SDL_WindowEvent& e);
|
// event methods (like callbacks)
|
||||||
void onKeyEvent(SDL_KeyboardEvent& e);
|
|
||||||
void onMouseButtonEvent(SDL_MouseButtonEvent& e);
|
|
||||||
void onMouseMotionEvent(SDL_MouseMotionEvent& e);
|
|
||||||
void onMouseWheelEvent(SDL_MouseWheelEvent& e);
|
|
||||||
|
|
||||||
|
void onWindowEvent(SDL_WindowEvent& e);
|
||||||
|
void onKeyEvent(SDL_KeyboardEvent& e);
|
||||||
|
void onMouseButtonEvent(SDL_MouseButtonEvent& e);
|
||||||
|
void onMouseMotionEvent(SDL_MouseMotionEvent& e);
|
||||||
|
void onMouseWheelEvent(SDL_MouseWheelEvent& e);
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "engine.hpp"
|
#include "engine.hpp"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
namespace engine {
|
namespace engine {
|
||||||
|
|
||||||
bool versionFromCharArray(const char* version, int* major, int* minor, int* patch)
|
bool versionFromCharArray(const char* version, int* major, int* minor, int* patch)
|
||||||
|
@ -3,14 +3,13 @@
|
|||||||
#include "gfx_device.hpp"
|
#include "gfx_device.hpp"
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "window.hpp"
|
|
||||||
|
|
||||||
#include "log.hpp"
|
#include "log.hpp"
|
||||||
|
|
||||||
#define VOLK_IMPLEMENTATION
|
#define VOLK_IMPLEMENTATION
|
||||||
#include "volk.h"
|
#include "volk.h"
|
||||||
|
|
||||||
|
#include <SDL_vulkan.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -18,194 +17,286 @@
|
|||||||
|
|
||||||
namespace engine::gfx {
|
namespace engine::gfx {
|
||||||
|
|
||||||
|
static std::vector<const char*> getRequiredVulkanExtensions(SDL_Window* window)
|
||||||
|
{
|
||||||
|
#ifdef ENGINE_BUILD_VULKAN
|
||||||
|
SDL_bool res;
|
||||||
|
|
||||||
|
unsigned int sdlExtensionCount = 0;
|
||||||
|
res = SDL_Vulkan_GetInstanceExtensions(window, &sdlExtensionCount, nullptr);
|
||||||
|
assert(res == SDL_TRUE);
|
||||||
|
std::vector<const char*> requiredExtensions(sdlExtensionCount);
|
||||||
|
res = SDL_Vulkan_GetInstanceExtensions(window, &sdlExtensionCount, requiredExtensions.data());
|
||||||
|
assert(res == SDL_TRUE);
|
||||||
|
|
||||||
|
return requiredExtensions;
|
||||||
|
#else
|
||||||
|
return std::vector<const char*>{};
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static VkBool32 debugMessenger(
|
||||||
|
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||||
|
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
|
||||||
|
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||||
|
void* pUserData)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string msgType{};
|
||||||
|
|
||||||
|
if (messageTypes & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT)
|
||||||
|
msgType += " (GENERAL)";
|
||||||
|
if (messageTypes & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT)
|
||||||
|
msgType += " (PERF.)";
|
||||||
|
if (messageTypes & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT)
|
||||||
|
msgType += " (VALID.)";
|
||||||
|
|
||||||
|
switch (messageSeverity) {
|
||||||
|
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
|
||||||
|
TRACE("VULKAN MESSAGE{}: ID: {} MSG: {}", msgType, pCallbackData->pMessageIdName, pCallbackData->pMessage);
|
||||||
|
break;
|
||||||
|
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
|
||||||
|
INFO("VULKAN MESSAGE{}: ID: {} MSG: {}", msgType, pCallbackData->pMessageIdName, pCallbackData->pMessage);
|
||||||
|
break;
|
||||||
|
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
|
||||||
|
WARN("VULKAN MESSAGE{}: ID: {} MSG: {}", msgType, pCallbackData->pMessageIdName, pCallbackData->pMessage);
|
||||||
|
break;
|
||||||
|
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
|
||||||
|
ERROR("VULKAN MESSAGE{}: ID: {} MSG: {}", msgType, pCallbackData->pMessageIdName, pCallbackData->pMessage);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return VK_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
class Device::Impl {
|
class Device::Impl {
|
||||||
friend Device;
|
friend Device;
|
||||||
|
|
||||||
VkInstance m_instance;
|
public:
|
||||||
#ifndef NDEBUG
|
Impl(AppInfo appInfo, SDL_Window* window)
|
||||||
VkDebugUtilsMessengerEXT m_debugMessenger;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static constexpr const char * VALIDATION_LAYER_NAME = "VK_LAYER_KHRONOS_validation";
|
|
||||||
static constexpr VkDebugUtilsMessageSeverityFlagBitsEXT MESSAGE_LEVEL = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
|
|
||||||
|
|
||||||
std::vector<VkLayerProperties> m_layersAvailable{};
|
|
||||||
std::optional<std::vector<VkLayerProperties>::iterator> m_validationLayer;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void findAvailableLayers()
|
|
||||||
{
|
{
|
||||||
VkResult res;
|
m_instance = std::make_unique<Instance>(appInfo, getRequiredVulkanExtensions(window));
|
||||||
|
|
||||||
uint32_t layerCount;
|
|
||||||
res = vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
|
|
||||||
assert(res == VK_SUCCESS);
|
|
||||||
m_layersAvailable.resize(layerCount);
|
|
||||||
res = vkEnumerateInstanceLayerProperties(&layerCount, m_layersAvailable.data());
|
|
||||||
assert(res == VK_SUCCESS);
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
for (auto it = m_layersAvailable.begin(); it != m_layersAvailable.end(); it++) {
|
m_debugMessenger = std::make_unique<DebugMessenger>(m_instance->getHandle());
|
||||||
TRACE("Found Vulkan layer: {}, {}", it->layerName, it->description);
|
#endif
|
||||||
if (strncmp(it->layerName, VALIDATION_LAYER_NAME, 256) == 0) {
|
}
|
||||||
m_validationLayer = it;
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// VkSurfaceKHR m_surface;
|
||||||
|
|
||||||
|
static constexpr VkDebugUtilsMessageSeverityFlagBitsEXT MESSAGE_LEVEL = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
|
||||||
|
|
||||||
|
class Instance {
|
||||||
|
|
||||||
|
public:
|
||||||
|
Instance(AppInfo appInfo, const std::vector<const char*>& windowExtensions)
|
||||||
|
{
|
||||||
|
VkResult res;
|
||||||
|
|
||||||
|
findAvailableLayers();
|
||||||
|
|
||||||
|
int appVersionMajor, appVersionMinor, appVersionPatch;
|
||||||
|
assert(versionFromCharArray(appInfo.version, &appVersionMajor, &appVersionMinor, &appVersionPatch));
|
||||||
|
int engineVersionMajor, engineVersionMinor, engineVersionPatch;
|
||||||
|
assert(versionFromCharArray(ENGINE_VERSION, &engineVersionMajor, &engineVersionMinor, &engineVersionPatch));
|
||||||
|
|
||||||
|
VkApplicationInfo applicationInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.pApplicationName = appInfo.name,
|
||||||
|
.applicationVersion = VK_MAKE_VERSION(appVersionMajor, appVersionMinor, appVersionPatch),
|
||||||
|
.pEngineName = "engine",
|
||||||
|
.engineVersion = VK_MAKE_VERSION(engineVersionMajor, engineVersionMinor, engineVersionPatch),
|
||||||
|
.apiVersion = VK_API_VERSION_1_0,
|
||||||
|
};
|
||||||
|
|
||||||
|
// make a list of all extensions to use
|
||||||
|
std::vector<const char*> extensions{};
|
||||||
|
extensions.insert(extensions.end(), windowExtensions.begin(), windowExtensions.end());
|
||||||
|
|
||||||
|
std::vector<const char*> layers{};
|
||||||
|
|
||||||
|
if (m_validationLayer.has_value()) {
|
||||||
|
layers.push_back(m_validationLayer.value()->layerName);
|
||||||
|
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (m_validationLayer.has_value() == false) {
|
|
||||||
WARN("The validation layer was not found. Continuing.");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void createInstance(AppInfo appInfo, const std::vector<const char*>& windowExtensions)
|
VkInstanceCreateInfo instanceInfo{
|
||||||
{
|
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
||||||
VkResult res;
|
.pNext = nullptr,
|
||||||
|
.flags = 0,
|
||||||
|
.pApplicationInfo = &applicationInfo,
|
||||||
|
.enabledLayerCount = (uint32_t)layers.size(),
|
||||||
|
.ppEnabledLayerNames = layers.data(),
|
||||||
|
.enabledExtensionCount = (uint32_t)extensions.size(),
|
||||||
|
.ppEnabledExtensionNames = extensions.data(),
|
||||||
|
};
|
||||||
|
|
||||||
int appVersionMajor, appVersionMinor, appVersionPatch;
|
if (m_validationLayer.has_value()) {
|
||||||
assert(versionFromCharArray(appInfo.version, &appVersionMajor, &appVersionMinor, &appVersionPatch));
|
VkDebugUtilsMessengerCreateInfoEXT debugMessengerCreateInfo = DebugMessenger::getCreateInfo();
|
||||||
int engineVersionMajor, engineVersionMinor, engineVersionPatch;
|
instanceInfo.pNext = &debugMessengerCreateInfo;
|
||||||
assert(versionFromCharArray(ENGINE_VERSION, &engineVersionMajor, &engineVersionMinor, &engineVersionPatch));
|
}
|
||||||
|
|
||||||
VkApplicationInfo applicationInfo {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
|
||||||
.pNext = nullptr,
|
|
||||||
.pApplicationName = appInfo.name,
|
|
||||||
.applicationVersion = VK_MAKE_VERSION(appVersionMajor, appVersionMinor, appVersionPatch),
|
|
||||||
.pEngineName = "engine",
|
|
||||||
.engineVersion = VK_MAKE_VERSION(engineVersionMajor, engineVersionMinor, engineVersionPatch),
|
|
||||||
.apiVersion = VK_API_VERSION_1_0,
|
|
||||||
};
|
|
||||||
|
|
||||||
// make a list of all extensions to use
|
|
||||||
std::vector<const char*> extensions{};
|
|
||||||
extensions.insert(extensions.end(), windowExtensions.begin(), windowExtensions.end());
|
|
||||||
#ifndef NDEBUG
|
|
||||||
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::vector<const char*> layers{};
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (m_validationLayer.has_value())
|
for (const char* ext : extensions) {
|
||||||
layers.push_back(m_validationLayer.value()->layerName);
|
TRACE("Using Vulkan instance extension: {}", ext);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VkInstanceCreateInfo instanceInfo {
|
res = vkCreateInstance(&instanceInfo, nullptr, &m_handle);
|
||||||
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
if (res == VK_ERROR_INCOMPATIBLE_DRIVER) {
|
||||||
.pNext = nullptr,
|
CRITICAL("The graphics driver is incompatible with vulkan");
|
||||||
.flags = 0,
|
throw std::runtime_error("Graphics driver is incompatible with Vulkan");
|
||||||
.pApplicationInfo = &applicationInfo,
|
}
|
||||||
.enabledLayerCount = (uint32_t)layers.size(),
|
assert(res == VK_SUCCESS);
|
||||||
.ppEnabledLayerNames = layers.data(),
|
|
||||||
.enabledExtensionCount = (uint32_t)extensions.size(),
|
volkLoadInstance(m_handle);
|
||||||
.ppEnabledExtensionNames = extensions.data(),
|
|
||||||
};
|
|
||||||
|
|
||||||
res = vkCreateInstance(&instanceInfo, nullptr, &m_instance);
|
|
||||||
if (res == VK_ERROR_INCOMPATIBLE_DRIVER) {
|
|
||||||
CRITICAL("The graphics driver is incompatible with vulkan");
|
|
||||||
throw std::runtime_error("Graphics driver is incompatible with Vulkan");
|
|
||||||
}
|
}
|
||||||
assert(res == VK_SUCCESS);
|
|
||||||
}
|
~Instance()
|
||||||
|
{
|
||||||
|
vkDestroyInstance(m_handle, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkInstance getHandle()
|
||||||
|
{
|
||||||
|
return m_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
VkInstance m_handle;
|
||||||
|
|
||||||
|
std::vector<VkLayerProperties> m_layersAvailable{};
|
||||||
|
static constexpr const char* VALIDATION_LAYER_NAME = "VK_LAYER_KHRONOS_validation";
|
||||||
|
std::optional<std::vector<VkLayerProperties>::iterator> m_validationLayer;
|
||||||
|
|
||||||
|
void findAvailableLayers()
|
||||||
|
{
|
||||||
|
VkResult res;
|
||||||
|
|
||||||
|
uint32_t layerCount;
|
||||||
|
res = vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
|
||||||
|
assert(res == VK_SUCCESS);
|
||||||
|
m_layersAvailable.resize(layerCount);
|
||||||
|
res = vkEnumerateInstanceLayerProperties(&layerCount, m_layersAvailable.data());
|
||||||
|
assert(res == VK_SUCCESS);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
static VkBool32 debugMessenger(
|
// find validation layer and print all layers to log
|
||||||
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
for (auto it = m_layersAvailable.begin(); it != m_layersAvailable.end(); it++) {
|
||||||
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
|
// TRACE("Found Vulkan layer: {}, {}", it->layerName, it->description);
|
||||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
if (strncmp(it->layerName, VALIDATION_LAYER_NAME, 256) == 0) {
|
||||||
void* pUserData)
|
m_validationLayer = it;
|
||||||
{
|
}
|
||||||
|
}
|
||||||
|
if (m_validationLayer.has_value() == false) {
|
||||||
|
CRITICAL("The validation layer was not found. Quitting.");
|
||||||
|
throw std::runtime_error("Validation layer not found");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
std::string msgType{};
|
};
|
||||||
|
|
||||||
if (messageTypes & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT)
|
#ifndef NDEBUG
|
||||||
msgType += " (GENERAL)";
|
class DebugMessenger {
|
||||||
if (messageTypes & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT)
|
|
||||||
msgType += " (PERF.)";
|
|
||||||
if (messageTypes & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT)
|
|
||||||
msgType += " (VALID.)";
|
|
||||||
|
|
||||||
switch (messageSeverity) {
|
public:
|
||||||
|
DebugMessenger(const VkInstance& instance) : m_instance(instance)
|
||||||
|
{
|
||||||
|
VkDebugUtilsMessengerCreateInfoEXT createInfo = getCreateInfo();
|
||||||
|
|
||||||
|
VkResult res = vkCreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &m_debugMessenger);
|
||||||
|
assert(res == VK_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
~DebugMessenger()
|
||||||
|
{
|
||||||
|
vkDestroyDebugUtilsMessengerEXT(m_instance, m_debugMessenger, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VkDebugUtilsMessengerCreateInfoEXT getCreateInfo()
|
||||||
|
{
|
||||||
|
VkDebugUtilsMessengerCreateInfoEXT createInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.flags = 0,
|
||||||
|
.messageSeverity = 0,
|
||||||
|
.messageType =
|
||||||
|
VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
|
||||||
|
VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
|
||||||
|
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
|
||||||
|
.pfnUserCallback = debugMessenger,
|
||||||
|
.pUserData = nullptr,
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (MESSAGE_LEVEL) {
|
||||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
|
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
|
||||||
TRACE("VULKAN MESSAGE{}: ID: {} MSG: {}", msgType, pCallbackData->pMessageIdName, pCallbackData->pMessage);
|
createInfo.messageSeverity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
|
||||||
break;
|
// fall-through
|
||||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
|
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
|
||||||
INFO("VULKAN MESSAGE{}: ID: {} MSG: {}", msgType, pCallbackData->pMessageIdName, pCallbackData->pMessage);
|
createInfo.messageSeverity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
|
||||||
break;
|
// fall-through
|
||||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
|
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
|
||||||
WARN("VULKAN MESSAGE{}: ID: {} MSG: {}", msgType, pCallbackData->pMessageIdName, pCallbackData->pMessage);
|
createInfo.messageSeverity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
|
||||||
break;
|
// fall-through
|
||||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
|
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
|
||||||
ERROR("VULKAN MESSAGE{}: ID: {} MSG: {}", msgType, pCallbackData->pMessageIdName, pCallbackData->pMessage);
|
createInfo.messageSeverity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
|
||||||
break;
|
// fall-through
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return createInfo;
|
||||||
}
|
}
|
||||||
return VK_FALSE;
|
|
||||||
}
|
private:
|
||||||
|
VkDebugUtilsMessengerEXT m_debugMessenger;
|
||||||
|
const VkInstance& m_instance;
|
||||||
|
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void createDebugMessenger()
|
std::unique_ptr<Instance> m_instance;
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
VkResult res;
|
std::unique_ptr<DebugMessenger> m_debugMessenger;
|
||||||
|
|
||||||
if (m_validationLayer.has_value() == false) return;
|
|
||||||
|
|
||||||
VkDebugUtilsMessengerCreateInfoEXT createInfo {
|
|
||||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
|
|
||||||
.pNext = nullptr,
|
|
||||||
.flags = 0,
|
|
||||||
.messageSeverity = 0,
|
|
||||||
.messageType =
|
|
||||||
VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
|
|
||||||
VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
|
|
||||||
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
|
|
||||||
.pfnUserCallback = debugMessenger,
|
|
||||||
.pUserData = nullptr,
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (MESSAGE_LEVEL) {
|
|
||||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
|
|
||||||
createInfo.messageSeverity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
|
|
||||||
// fall-through
|
|
||||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
|
|
||||||
createInfo.messageSeverity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
|
|
||||||
// fall-through
|
|
||||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
|
|
||||||
createInfo.messageSeverity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
|
|
||||||
// fall-through
|
|
||||||
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
|
|
||||||
createInfo.messageSeverity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
|
|
||||||
// fall-through
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = vkCreateDebugUtilsMessengerEXT(m_instance, &createInfo, nullptr, &m_debugMessenger);
|
|
||||||
assert(res == VK_SUCCESS);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
void createSurface(SDL_Window* window)
|
||||||
|
{
|
||||||
|
if (SDL_Vulkan_CreateSurface(window, m_instance, &m_surface) == false) {
|
||||||
|
CRITICAL("Unable to create window surface");
|
||||||
|
throw std::runtime_error("Unable to create window surface");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Device::Device(AppInfo appInfo, SDL_Window* window)
|
||||||
|
|
||||||
Device::Device(AppInfo appInfo, const Window& window) : pimpl(std::make_unique<Impl>())
|
|
||||||
{
|
{
|
||||||
pimpl->findAvailableLayers();
|
VkResult res;
|
||||||
pimpl->createInstance(appInfo, window.getRequiredVulkanExtensions());
|
res = volkInitialize();
|
||||||
pimpl->createDebugMessenger();
|
if (res == VK_ERROR_INITIALIZATION_FAILED) {
|
||||||
|
CRITICAL("Unable to load vulkan, is it installed?");
|
||||||
|
throw std::runtime_error("Unable to load vulkan, is it installed?");
|
||||||
|
}
|
||||||
|
assert(res == VK_SUCCESS);
|
||||||
|
|
||||||
|
pimpl = std::make_unique<Impl>(appInfo, window);
|
||||||
|
|
||||||
|
//pimpl->createDebugMessenger();
|
||||||
}
|
}
|
||||||
|
|
||||||
Device::~Device()
|
Device::~Device()
|
||||||
{
|
{
|
||||||
vkDestroyInstance(pimpl->m_instance, nullptr);
|
//pimpl->cleanup();
|
||||||
#ifndef NDEBUG
|
|
||||||
vkDestroyDebugUtilsMessengerEXT(pimpl->m_instance, pimpl->m_debugMessenger, nullptr);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
#include "window.hpp"
|
#include "window.hpp"
|
||||||
|
|
||||||
|
#include "log.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#ifdef ENGINE_BUILD_VULKAN
|
|
||||||
#include <SDL2/SDL_vulkan.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const uint64_t BILLION = 1000000000;
|
const uint64_t BILLION = 1000000000;
|
||||||
|
|
||||||
Window::Window(const std::string& title) : m_title(title)
|
Window::Window(const std::string& title) : m_title(title)
|
||||||
@ -32,7 +30,7 @@ Window::Window(const std::string& title) : m_title(title)
|
|||||||
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||||
static_cast<int>(m_winSize.x),
|
static_cast<int>(m_winSize.x),
|
||||||
static_cast<int>(m_winSize.y),
|
static_cast<int>(m_winSize.y),
|
||||||
0);
|
SDL_WINDOW_VULKAN | SDL_WINDOW_SHOWN);
|
||||||
if (m_handle == NULL) {
|
if (m_handle == NULL) {
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
throw std::runtime_error("Unable to create window: " + std::string(SDL_GetError()));
|
throw std::runtime_error("Unable to create window: " + std::string(SDL_GetError()));
|
||||||
@ -447,20 +445,6 @@ bool Window::infoBox(const std::string& title, const std::string& msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<const char*> Window::getRequiredVulkanExtensions() const
|
|
||||||
{
|
|
||||||
#ifdef ENGINE_BUILD_VULKAN
|
|
||||||
unsigned int sdlExtensionCount = 0;
|
|
||||||
SDL_Vulkan_GetInstanceExtensions(m_handle, &sdlExtensionCount, nullptr);
|
|
||||||
std::vector<const char*> requiredExtensions(sdlExtensionCount);
|
|
||||||
SDL_Vulkan_GetInstanceExtensions(m_handle, &sdlExtensionCount, requiredExtensions.data());
|
|
||||||
|
|
||||||
return requiredExtensions;
|
|
||||||
#else
|
|
||||||
return std::vector<const char*>{};
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* STATIC METHODS */
|
/* STATIC METHODS */
|
||||||
|
|
||||||
// Display an error message box
|
// Display an error message box
|
||||||
|
Loading…
Reference in New Issue
Block a user