mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
Do vulkan work
This commit is contained in:
parent
07c17687ef
commit
021869a3a1
@ -98,10 +98,20 @@ if (MINGW)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC mingw32)
|
||||
endif()
|
||||
|
||||
# Vulkan
|
||||
find_package(Vulkan REQUIRED)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${Vulkan_INCLUDE_DIRS})
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Vulkan::Vulkan)
|
||||
# GLAD:
|
||||
set(GLAD_PROFILE "core" CACHE INTERNAL "" FORCE)
|
||||
set(GLAD_API "gl=3.3" CACHE INTERNAL "" FORCE)
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(GLAD_GENERATOR "c-debug" CACHE INTERNAL "" FORCE)
|
||||
else()
|
||||
set(GLAD_GENERATOR "c" CACHE INTERNAL "" FORCE)
|
||||
endif()
|
||||
set(GLAD_SPEC "gl" CACHE INTERNAL "" FORCE)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
add_subdirectory(dependencies/glad)
|
||||
set_property(TARGET glad PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC glad)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC dependencies/glad/include)
|
||||
|
||||
# SDL2:
|
||||
find_package(SDL2)
|
||||
@ -124,21 +134,6 @@ set(BUILD_SHARED_LIBS OFF)
|
||||
add_subdirectory(dependencies/glm)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC dependencies/glm)
|
||||
|
||||
# GLAD:
|
||||
set(GLAD_PROFILE "core" CACHE INTERNAL "" FORCE)
|
||||
set(GLAD_API "gl=3.3" CACHE INTERNAL "" FORCE)
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(GLAD_GENERATOR "c-debug" CACHE INTERNAL "" FORCE)
|
||||
else()
|
||||
set(GLAD_GENERATOR "c" CACHE INTERNAL "" FORCE)
|
||||
endif()
|
||||
set(GLAD_SPEC "gl" CACHE INTERNAL "" FORCE)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
add_subdirectory(dependencies/glad)
|
||||
set_property(TARGET glad PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC glad)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC dependencies/glad/include)
|
||||
|
||||
# spdlog
|
||||
set(SPDLOG_BUILD_SHARED ON CACHE INTERNAL "" FORCE)
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
|
@ -15,7 +15,7 @@ namespace engine::gfx {
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> pimpl{};
|
||||
std::unique_ptr<Impl> pimpl;
|
||||
|
||||
};
|
||||
|
||||
|
@ -28,25 +28,10 @@ public:
|
||||
// Return the title name
|
||||
std::string getTitle() const;
|
||||
|
||||
// Make this window the current OpenGL context.
|
||||
// This is already done in window initialisation.
|
||||
void makeContextCurrent();
|
||||
|
||||
// Tell the GPU to render the back buffer to the screen.
|
||||
// Run this on every frame.
|
||||
void swapBuffers();
|
||||
// Update the window state to capture any events that have occurred.
|
||||
// Run this on every frame.
|
||||
void getInputAndEvents();
|
||||
|
||||
// if 'true', swapBuffers() will wait in order to synchronise with the
|
||||
// monitor's refresh rate.
|
||||
void setVSync(bool enable);
|
||||
// Returns true if VSync is enabled.
|
||||
bool getVSync() const;
|
||||
|
||||
glm::ivec2 getViewportSize();
|
||||
|
||||
void setTitle(std::string title);
|
||||
|
||||
// Hides the window (it will appear closed to the user).
|
||||
@ -146,7 +131,6 @@ public:
|
||||
|
||||
private:
|
||||
SDL_Window* m_handle;
|
||||
SDL_GLContext m_glContext;
|
||||
|
||||
bool m_shouldClose = false;
|
||||
|
||||
@ -158,8 +142,6 @@ public:
|
||||
|
||||
// size in screen coordinates
|
||||
glm::ivec2 m_winSize = glm::vec2(640, 480);
|
||||
// actual framebuffer size
|
||||
glm::ivec2 m_fbSize;
|
||||
|
||||
// performance counter frequency
|
||||
uint64_t m_counterFreq;
|
||||
|
@ -54,7 +54,7 @@ void Camera::updateCam(glm::mat4 transform)
|
||||
auto shader = dynamic_cast<Shader*>(lockedPtr.get());
|
||||
shader->setUniform_m4(VIEW_MAT_UNIFORM, viewMatrix);
|
||||
shader->setUniform_m4(PROJ_MAT_UNIFORM, m_projMatrix);
|
||||
shader->setUniform_v2(WINDOW_SIZE_UNIFORM, win.getViewportSize());
|
||||
// shader->setUniform_v2(WINDOW_SIZE_UNIFORM, win.getViewportSize());
|
||||
shader->setUniform_v3("lightPos", m_lightPos);
|
||||
}
|
||||
|
||||
|
@ -6,10 +6,14 @@
|
||||
|
||||
#include "window.hpp"
|
||||
|
||||
#include "log.hpp"
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
|
||||
namespace engine::gfx {
|
||||
|
||||
@ -17,10 +21,43 @@ namespace engine::gfx {
|
||||
friend Device;
|
||||
|
||||
VkInstance m_instance;
|
||||
#ifndef NDEBUG
|
||||
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;
|
||||
|
||||
Device::Device(AppInfo appInfo, const Window& window)
|
||||
std::vector<VkLayerProperties> m_layersAvailable{};
|
||||
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
|
||||
for (auto it = m_layersAvailable.begin(); it != m_layersAvailable.end(); it++) {
|
||||
TRACE("Found Vulkan layer: {}, {}", it->layerName, it->description);
|
||||
if (strncmp(it->layerName, VALIDATION_LAYER_NAME, 256) == 0) {
|
||||
m_validationLayer = it;
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
VkResult res;
|
||||
|
||||
@ -29,36 +66,147 @@ namespace engine::gfx {
|
||||
int engineVersionMajor, engineVersionMinor, engineVersionPatch;
|
||||
assert(versionFromCharArray(ENGINE_VERSION, &engineVersionMajor, &engineVersionMinor, &engineVersionPatch));
|
||||
|
||||
VkApplicationInfo applicationInfo{
|
||||
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_VERSION_1_0,
|
||||
.apiVersion = VK_API_VERSION_1_0,
|
||||
};
|
||||
|
||||
VkInstanceCreateInfo instanceInfo{
|
||||
// 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
|
||||
if (m_validationLayer.has_value())
|
||||
layers.push_back(m_validationLayer.value()->layerName);
|
||||
#endif
|
||||
|
||||
VkInstanceCreateInfo instanceInfo {
|
||||
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.pApplicationInfo = nullptr,
|
||||
.enabledLayerCount = 0,
|
||||
.ppEnabledLayerNames = nullptr,
|
||||
.enabledExtensionCount = 0,
|
||||
.ppEnabledExtensionNames = nullptr,
|
||||
.pApplicationInfo = &applicationInfo,
|
||||
.enabledLayerCount = (uint32_t)layers.size(),
|
||||
.ppEnabledLayerNames = layers.data(),
|
||||
.enabledExtensionCount = (uint32_t)extensions.size(),
|
||||
.ppEnabledExtensionNames = extensions.data(),
|
||||
};
|
||||
|
||||
res = vkCreateInstance(&instanceInfo, nullptr, &pimpl->m_instance);
|
||||
std::cout << "ERROR CODE: " << res << std::endl;
|
||||
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);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
void createDebugMessenger()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
VkResult res;
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
Device::Device(AppInfo appInfo, const Window& window) : pimpl(std::make_unique<Impl>())
|
||||
{
|
||||
pimpl->findAvailableLayers();
|
||||
pimpl->createInstance(appInfo, window.getRequiredVulkanExtensions());
|
||||
pimpl->createDebugMessenger();
|
||||
}
|
||||
|
||||
Device::~Device()
|
||||
{
|
||||
vkDestroyInstance(pimpl->m_instance, nullptr);
|
||||
#ifndef NDEBUG
|
||||
vkDestroyDebugUtilsMessengerEXT(pimpl->m_instance, pimpl->m_debugMessenger, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
#include "window.hpp"
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
@ -28,17 +26,13 @@ Window::Window(const std::string& title) : m_title(title)
|
||||
m_lastFrameStamp = m_startTime - 1;
|
||||
m_avgFpsStart = m_startTime;
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
|
||||
// create the window
|
||||
m_handle = SDL_CreateWindow(
|
||||
m_title.c_str(),
|
||||
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||
static_cast<int>(m_winSize.x),
|
||||
static_cast<int>(m_winSize.y),
|
||||
SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||
0);
|
||||
if (m_handle == NULL) {
|
||||
SDL_Quit();
|
||||
throw std::runtime_error("Unable to create window: " + std::string(SDL_GetError()));
|
||||
@ -54,6 +48,7 @@ Window::Window(const std::string& title) : m_title(title)
|
||||
const int WINDOWED_MIN_HEIGHT = 480;
|
||||
SDL_SetWindowMinimumSize(m_handle, WINDOWED_MIN_WIDTH, WINDOWED_MIN_HEIGHT);
|
||||
|
||||
/*
|
||||
m_glContext = SDL_GL_CreateContext(m_handle);
|
||||
if (m_glContext == NULL) {
|
||||
SDL_DestroyWindow(m_handle);
|
||||
@ -66,14 +61,14 @@ Window::Window(const std::string& title) : m_title(title)
|
||||
SDL_Quit();
|
||||
throw std::runtime_error("Unable to initialise GLAD");
|
||||
}
|
||||
*/
|
||||
|
||||
onResize(m_winSize.x, m_winSize.y);
|
||||
// onResize(m_winSize.x, m_winSize.y);
|
||||
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
SDL_GL_DeleteContext(m_glContext);
|
||||
SDL_DestroyWindow(m_handle);
|
||||
SDL_Quit();
|
||||
}
|
||||
@ -86,13 +81,6 @@ void Window::onResize(Sint32 width, Sint32 height)
|
||||
m_winSize.x = static_cast<int>(width);
|
||||
m_winSize.y = static_cast<int>(height);
|
||||
|
||||
// get framebuffer size
|
||||
int fbWidth, fbHeight;
|
||||
SDL_GL_GetDrawableSize(m_handle, &fbWidth, &fbHeight);
|
||||
m_fbSize.x = static_cast<int>(fbWidth);
|
||||
m_fbSize.y = static_cast<int>(fbHeight);
|
||||
glViewport(0, 0, fbWidth, fbHeight);
|
||||
|
||||
m_justResized = true;
|
||||
}
|
||||
|
||||
@ -195,26 +183,13 @@ std::string Window::getTitle() const
|
||||
return m_title;
|
||||
}
|
||||
|
||||
void Window::makeContextCurrent()
|
||||
void Window::getInputAndEvents()
|
||||
{
|
||||
if (SDL_GL_MakeCurrent(m_handle, m_glContext) != 0) {
|
||||
throw std::runtime_error("Failed to make GL context current");
|
||||
}
|
||||
}
|
||||
|
||||
void Window::swapBuffers()
|
||||
{
|
||||
#ifndef SDLTEST_NOGFX
|
||||
SDL_GL_SwapWindow(m_handle);
|
||||
#endif
|
||||
m_frames++;
|
||||
uint64_t currentFrameStamp = getNanos();
|
||||
m_lastFrameTime = currentFrameStamp - m_lastFrameStamp;
|
||||
m_lastFrameStamp = currentFrameStamp;
|
||||
}
|
||||
|
||||
void Window::getInputAndEvents()
|
||||
{
|
||||
|
||||
resetInputDeltas();
|
||||
|
||||
@ -254,23 +229,6 @@ void Window::getInputAndEvents()
|
||||
|
||||
}
|
||||
|
||||
void Window::setVSync(bool enable)
|
||||
{
|
||||
if (SDL_GL_SetSwapInterval(enable ? 1 : 0) != 0) {
|
||||
throw std::runtime_error("Failed to set swap interval");
|
||||
}
|
||||
}
|
||||
|
||||
bool Window::getVSync() const
|
||||
{
|
||||
return SDL_GL_GetSwapInterval() == 0 ? false : true;
|
||||
}
|
||||
|
||||
glm::ivec2 Window::getViewportSize()
|
||||
{
|
||||
return m_fbSize;
|
||||
}
|
||||
|
||||
void Window::setTitle(std::string title)
|
||||
{
|
||||
SDL_SetWindowTitle(m_handle, title.c_str());
|
||||
|
Loading…
Reference in New Issue
Block a user