Begin vulkan impl

This commit is contained in:
Bailey Harrison 2022-09-13 19:25:18 +01:00
parent 7ae447b392
commit 07c17687ef
14 changed files with 189 additions and 117 deletions

View File

@ -8,8 +8,8 @@ project(engine LANGUAGES CXX
add_library(${PROJECT_NAME} SHARED
"src/engine.cpp"
"src/window.cpp"
"src/input.cpp" #TODO make input_manager
"src/object.cpp"
@ -30,6 +30,8 @@ add_library(${PROJECT_NAME} SHARED
"src/resource_manager.cpp"
"src/gfx_device_vulkan.cpp"
# PUBLIC API
"include/engine_api.h"
@ -63,6 +65,9 @@ add_library(${PROJECT_NAME} SHARED
"include/resource_manager.hpp"
"include/gfx.hpp"
"include/gfx_device.hpp"
)
# compiling options:
@ -84,13 +89,7 @@ target_include_directories(${PROJECT_NAME} PRIVATE src)
configure_file(config.h.in config.h)
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
# project submodules:
add_subdirectory(graphics)
target_include_directories(${PROJECT_NAME} PUBLIC graphics/include)
target_link_libraries(${PROJECT_NAME} PUBLIC graphics)
target_compile_definitions(${PROJECT_NAME} PRIVATE "ENGINE_BUILD_VULKAN")
# external libraries:
@ -99,6 +98,11 @@ 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)
# SDL2:
find_package(SDL2)
if (SDL2_FOUND)

View File

@ -1,3 +1,3 @@
#pragma once
#define ENGINE_VERSION @PROJECT_VERSION@
#define ENGINE_VERSION "@PROJECT_VERSION@"

View File

@ -1,26 +0,0 @@
cmake_minimum_required(VERSION 3.4)
# options
project(graphics LANGUAGES CXX)
add_library(${PROJECT_NAME} STATIC
"src/gfx_device.cpp"
# PUBLIC API
"include/gfx_api.h"
"include/gfx.hpp"
"include/gfx_device.hpp"
)
# compiling options:
target_compile_definitions(${PROJECT_NAME} PRIVATE DEFINITIONS "GFX_EXPORTS")
target_include_directories(${PROJECT_NAME} PUBLIC include)
target_include_directories(${PROJECT_NAME} PRIVATE src)
# libraries:

View File

@ -1,13 +0,0 @@
#pragma once
#ifndef GFX_API
# ifdef _MSC_VER
# ifdef GFX_EXPORTS
# define GFX_API __declspec(dllexport)
# else
# define GFX_API __declspec(dllimport)
# endif
# else
# define GFX_API
# endif
#endif

View File

@ -1,30 +0,0 @@
#pragma once
#include "gfx_api.h"
#include "gfx.hpp"
namespace gfx {
// Do not use a pointer to this class, always cast to the proper implementation to avoid V-Table overhead
struct GFX_API IDevice {
virtual void setViewport(uint32_t top_left_x, uint32_t top_left_y, uint32_t width, uint32_t height) = 0;
virtual bool createShader(ShaderType type, const char* source, Shader& out) = 0;
virtual bool createProgram(int count, const Shader* shaders, Program& out) = 0;
virtual bool createBuffer(BufferType type, const void* data, Buffer& out) = 0;
virtual void bufferData(const void* data, Buffer buffer) = 0;
virtual void bufferSubData(uint32_t offset, uint32_t size, const void* data, Buffer buffer) = 0;
virtual void drawElements(Primitive primitive, IndexBufferFormat format, uint32_t count, uint32_t offset) = 0;
virtual void drawArrays() = 0;
};
}

View File

@ -1,7 +0,0 @@
#include "gfx_device.hpp"
#include <stdio.h>
namespace gfx {
}

View File

@ -8,38 +8,12 @@
namespace engine {
// To be executed in the target application, NOT engine.dll
void setupLog(const char* appName)
{
struct AppInfo {
const char* name;
const char* version;
};
const std::string LOG_FILENAME{ std::string(appName) + ".log"};
#ifdef NDEBUG
// RELEASE
const std::filesystem::path log_path{ std::filesystem::temp_directory_path() / LOG_FILENAME };
#else
// DEBUG
const std::filesystem::path log_path{ LOG_FILENAME };
#endif
bool versionFromCharArray(const char* version, int* major, int* minor, int* patch);
std::vector<spdlog::sink_ptr> sinks;
sinks.emplace_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>(log_path.string(), true));
#ifndef NDEBUG
// DEBUG
sinks.emplace_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
#endif
auto logger = std::make_shared<spdlog::logger>("sdltest", sinks.begin(), sinks.end());
logger->set_level(spdlog::level::trace);
spdlog::register_logger(logger);
spdlog::set_default_logger(logger);
INFO("Created log with path: {}", log_path.string());
}
}
}

22
include/gfx_device.hpp Normal file
View File

@ -0,0 +1,22 @@
#pragma once
#include "engine_api.h"
#include "engine.hpp"
class Window;
namespace engine::gfx {
struct ENGINE_API Device {
Device(AppInfo appInfo, const Window& window);
~Device();
private:
class Impl;
std::unique_ptr<Impl> pimpl{};
};
}

45
include/logger.hpp Normal file
View File

@ -0,0 +1,45 @@
#pragma once
#include <filesystem>
#include "log.hpp"
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/basic_file_sink.h>
namespace engine {
// To be executed in the target application, NOT engine.dll
void setupLog(const char* appName)
{
const std::string LOG_FILENAME{ std::string(appName) + ".log"};
#ifdef NDEBUG
// RELEASE
const std::filesystem::path log_path{ std::filesystem::temp_directory_path() / LOG_FILENAME };
#else
// DEBUG
const std::filesystem::path log_path{ LOG_FILENAME };
#endif
std::vector<spdlog::sink_ptr> sinks;
sinks.emplace_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>(log_path.string(), true));
#ifndef NDEBUG
// DEBUG
sinks.emplace_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
#endif
auto logger = std::make_shared<spdlog::logger>("sdltest", sinks.begin(), sinks.end());
logger->set_level(spdlog::level::trace);
spdlog::register_logger(logger);
spdlog::set_default_logger(logger);
INFO("Created log with path: {}", log_path.string());
}
}

View File

@ -13,6 +13,7 @@
#include <array>
#include <string>
#include <vector>
ENGINE_API extern const uint64_t BILLION;
@ -138,6 +139,8 @@ public:
bool infoBox(const std::string& title, const std::string& msg);
std::vector<const char*> getRequiredVulkanExtensions() const;
/* STATIC METHODS */
static void errorBox(const std::string& message);

16
src/engine.cpp Normal file
View File

@ -0,0 +1,16 @@
#include "engine.hpp"
namespace engine {
bool versionFromCharArray(const char* version, int* major, int* minor, int* patch)
{
if (sscanf(version, "%d.%d.%d", major, minor, patch) != 3) {
*major = 0;
*minor = 0;
*patch = 0;
return false;
}
return true;
}
}

66
src/gfx_device_vulkan.cpp Normal file
View File

@ -0,0 +1,66 @@
#ifdef ENGINE_BUILD_VULKAN
#include "gfx_device.hpp"
#include "config.h"
#include "window.hpp"
#include <vulkan/vulkan.h>
#include <assert.h>
#include <iostream>
namespace engine::gfx {
class Device::Impl {
friend Device;
VkInstance m_instance;
};
Device::Device(AppInfo appInfo, const Window& window)
{
VkResult res;
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_VERSION_1_0,
};
VkInstanceCreateInfo instanceInfo{
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.pApplicationInfo = nullptr,
.enabledLayerCount = 0,
.ppEnabledLayerNames = nullptr,
.enabledExtensionCount = 0,
.ppEnabledExtensionNames = nullptr,
};
res = vkCreateInstance(&instanceInfo, nullptr, &pimpl->m_instance);
std::cout << "ERROR CODE: " << res << std::endl;
assert(res == VK_SUCCESS);
}
Device::~Device()
{
vkDestroyInstance(pimpl->m_instance, nullptr);
}
}
#endif

View File

@ -5,6 +5,10 @@
#include <iostream>
#include <stdexcept>
#ifdef ENGINE_BUILD_VULKAN
#include <SDL2/SDL_vulkan.h>
#endif
const uint64_t BILLION = 1000000000;
Window::Window(const std::string& title) : m_title(title)
@ -485,6 +489,20 @@ 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 */
// Display an error message box