From aef3ea22a85599b775f8bd0b95c2f2f53fef1c9d Mon Sep 17 00:00:00 2001 From: Piotr Doan Date: Thu, 30 Jan 2025 05:23:52 +0100 Subject: [PATCH] Create graphics system via factory function --- Engine/CMakeLists.txt | 1 + Engine/Graphics/Defines.hpp | 3 ++ Engine/Graphics/GraphicsSystem.cpp | 60 ++++++----------------- Engine/Graphics/GraphicsSystem.hpp | 27 ++++++---- Engine/Graphics/Includes.hpp | 8 +-- Engine/Graphics/Vulkan/GraphicsSystem.cpp | 57 +++++++++++++++++++++ Engine/Graphics/Vulkan/GraphicsSystem.hpp | 9 ++++ Engine/Graphics/Vulkan/Includes.hpp | 5 ++ Engine/Platform/Includes.hpp | 2 +- Engine/Platform/Window.hpp | 2 +- Example/Main.cpp | 8 +-- 11 files changed, 117 insertions(+), 65 deletions(-) create mode 100644 Engine/Graphics/Vulkan/GraphicsSystem.cpp create mode 100644 Engine/Graphics/Vulkan/GraphicsSystem.hpp create mode 100644 Engine/Graphics/Vulkan/Includes.hpp diff --git a/Engine/CMakeLists.txt b/Engine/CMakeLists.txt index 24aad0e..aa781d7 100644 --- a/Engine/CMakeLists.txt +++ b/Engine/CMakeLists.txt @@ -18,6 +18,7 @@ add_library(Engine STATIC "Graphics/GraphicsSystem.cpp" "Graphics/GraphicsStats.cpp" "Graphics/Vulkan/VulkanAllocator.cpp" + "Graphics/Vulkan/GraphicsSystem.cpp" "Engine.cpp" ) diff --git a/Engine/Graphics/Defines.hpp b/Engine/Graphics/Defines.hpp index 83b1ac4..9592bab 100644 --- a/Engine/Graphics/Defines.hpp +++ b/Engine/Graphics/Defines.hpp @@ -1,5 +1,8 @@ #pragma once +// #todo: Graphics API should be defined from CMake. +#define GRAPHICS_VULKAN + #ifdef CONFIG_DEBUG #define ENABLE_GRAPHICS_DEBUG // Enable graphics debugging #endif diff --git a/Engine/Graphics/GraphicsSystem.cpp b/Engine/Graphics/GraphicsSystem.cpp index 9e6c48b..f7b9136 100644 --- a/Engine/Graphics/GraphicsSystem.cpp +++ b/Engine/Graphics/GraphicsSystem.cpp @@ -4,64 +4,32 @@ #include "Platform/Window.hpp" #include "Engine.hpp" -Graphics::System::~System() -{ - LOG("Destroying graphics system..."); - - if(m_instance) - { - vkDestroyInstance(m_instance, &g_vkAllocationCallbacks); - } -} - -bool Graphics::System::Setup(Platform::Window* window) +UniquePtr Graphics::System::Create(Platform::Window* window) { - LOG("Creating graphics system..."); + UniquePtr instance = Memory::New(PrivateConstructorTag{}); ASSERT(window); - m_window = window; + instance->m_window = window; - if(!CreateInstance()) + if(!instance->OnCreate()) { - LOG_ERROR("Failed to setup graphics system"); - return false; + LOG_ERROR("Failed to create graphics system"); + return nullptr; } LOG_SUCCESS("Created graphics system"); - return true; + return instance; } -bool Graphics::System::CreateInstance() +Graphics::System::System(PrivateConstructorTag) { - InlineArray extensions; - extensions.Add(VK_KHR_SURFACE_EXTENSION_NAME); - extensions.Add(Platform::Window::GetVulkanSurfaceExtension()); - - VkApplicationInfo applicationInfo{}; - applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - applicationInfo.apiVersion = VK_API_VERSION_1_3; - applicationInfo.pEngineName = "Bourne Engine"; - applicationInfo.pApplicationName = Engine::GetApplicationName(); - applicationInfo.engineVersion = VK_MAKE_VERSION(EngineVersion::Major, EngineVersion::Minor, EngineVersion::Patch); - applicationInfo.applicationVersion = VK_MAKE_VERSION(ApplicationVersion::Major, ApplicationVersion::Minor, ApplicationVersion::Patch); - - VkInstanceCreateInfo createInfo{}; - createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - createInfo.pApplicationInfo = &applicationInfo; - createInfo.enabledLayerCount = 0; - createInfo.ppEnabledLayerNames = nullptr; - createInfo.enabledExtensionCount = extensions.GetSize(); - createInfo.ppEnabledExtensionNames = extensions.GetData(); - - const VkResult result = vkCreateInstance(&createInfo, &g_vkAllocationCallbacks, &m_instance); - if(result != VK_SUCCESS) - { - LOG_ERROR("Failed to create Vulkan instance (error: %s)", string_VkResult(result)); - return false; - } + LOG_INFO("Creating graphics system..."); +} - LOG_SUCCESS("Created Vulkan instance"); - return true; +Graphics::System::~System() +{ + LOG_INFO("Destroying graphics system..."); + OnDestroy(); } void Graphics::System::BeginFrame() diff --git a/Engine/Graphics/GraphicsSystem.hpp b/Engine/Graphics/GraphicsSystem.hpp index abf9d43..65324c8 100644 --- a/Engine/Graphics/GraphicsSystem.hpp +++ b/Engine/Graphics/GraphicsSystem.hpp @@ -1,6 +1,10 @@ #pragma once -#include "GraphicsStats.hpp" +#if defined(GRAPHICS_VULKAN) + #include "Vulkan/GraphicsSystem.hpp" +#else + #error "Unknown graphics define!" +#endif namespace Platform { @@ -9,24 +13,27 @@ namespace Platform namespace Graphics { - class System final + class System final : NonCopyable { + SystemPrivate m_private; Platform::Window* m_window = nullptr; - VkInstance m_instance; + + struct PrivateConstructorTag + { + explicit PrivateConstructorTag() = default; + }; public: - System() = default; - ~System(); + static UniquePtr Create(Platform::Window* window); - System(const System&) = delete; - System& operator=(const System&) = delete; + System(PrivateConstructorTag); + ~System(); - bool Setup(Platform::Window* window); void BeginFrame(); void EndFrame(); private: - bool CreateInstance(); - void DestroyInstance(); + bool OnCreate(); + void OnDestroy(); }; } diff --git a/Engine/Graphics/Includes.hpp b/Engine/Graphics/Includes.hpp index d2afb6f..1900225 100644 --- a/Engine/Graphics/Includes.hpp +++ b/Engine/Graphics/Includes.hpp @@ -1,5 +1,7 @@ #pragma once -#include -#include -#include "Vulkan/VulkanAllocator.hpp" +#if defined(GRAPHICS_VULKAN) + #include "Vulkan/Includes.hpp" +#else + #error "Unknown graphics define!" +#endif \ No newline at end of file diff --git a/Engine/Graphics/Vulkan/GraphicsSystem.cpp b/Engine/Graphics/Vulkan/GraphicsSystem.cpp new file mode 100644 index 0000000..6cd3326 --- /dev/null +++ b/Engine/Graphics/Vulkan/GraphicsSystem.cpp @@ -0,0 +1,57 @@ +#include "Shared.hpp" +#include "GraphicsSystem.hpp" + +static bool CreateVulkanInstance(Graphics::SystemPrivate& vulkanPrivate) +{ + InlineArray extensions; + extensions.Add(VK_KHR_SURFACE_EXTENSION_NAME); + extensions.Add(Platform::Window::GetVulkanSurfaceExtension()); + + VkApplicationInfo applicationInfo{}; + applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + applicationInfo.apiVersion = VK_API_VERSION_1_3; + applicationInfo.pEngineName = "Bourne Engine"; + applicationInfo.pApplicationName = Engine::GetApplicationName(); + applicationInfo.engineVersion = VK_MAKE_VERSION(EngineVersion::Major, EngineVersion::Minor, EngineVersion::Patch); + applicationInfo.applicationVersion = VK_MAKE_VERSION(ApplicationVersion::Major, ApplicationVersion::Minor, ApplicationVersion::Patch); + + VkInstanceCreateInfo createInfo{}; + createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + createInfo.pApplicationInfo = &applicationInfo; + createInfo.enabledLayerCount = 0; + createInfo.ppEnabledLayerNames = nullptr; + createInfo.enabledExtensionCount = extensions.GetSize(); + createInfo.ppEnabledExtensionNames = extensions.GetData(); + + ASSERT_SLOW(vulkanPrivate.instance == nullptr); + const VkResult result = vkCreateInstance(&createInfo, &g_vkAllocationCallbacks, &vulkanPrivate.instance); + if(result != VK_SUCCESS) + { + LOG_ERROR("Failed to create Vulkan instance (error: %s)", string_VkResult(result)); + return false; + } + + LOG_SUCCESS("Created Vulkan instance"); + return true; +} + +static void DestroyVulkanInstance(Graphics::SystemPrivate& vulkanPrivate) +{ + if(vulkanPrivate.instance) + { + vkDestroyInstance(vulkanPrivate.instance, &g_vkAllocationCallbacks); + } +} + +bool Graphics::System::OnCreate() +{ + if(!CreateVulkanInstance(m_private)) + return false; + + return true; +} + +void Graphics::System::OnDestroy() +{ + DestroyVulkanInstance(m_private); +} \ No newline at end of file diff --git a/Engine/Graphics/Vulkan/GraphicsSystem.hpp b/Engine/Graphics/Vulkan/GraphicsSystem.hpp new file mode 100644 index 0000000..5e335b6 --- /dev/null +++ b/Engine/Graphics/Vulkan/GraphicsSystem.hpp @@ -0,0 +1,9 @@ +#pragma once + +namespace Graphics +{ + struct SystemPrivate + { + VkInstance instance = nullptr; + }; +} diff --git a/Engine/Graphics/Vulkan/Includes.hpp b/Engine/Graphics/Vulkan/Includes.hpp new file mode 100644 index 0000000..d8649b3 --- /dev/null +++ b/Engine/Graphics/Vulkan/Includes.hpp @@ -0,0 +1,5 @@ +#pragma once + +#include +#include +#include "VulkanAllocator.hpp" diff --git a/Engine/Platform/Includes.hpp b/Engine/Platform/Includes.hpp index a5fddee..aa101ad 100644 --- a/Engine/Platform/Includes.hpp +++ b/Engine/Platform/Includes.hpp @@ -5,5 +5,5 @@ #elif defined(PLATFORM_LINUX) #include "Linux/Includes.hpp" #else - #error Unsupported platform! + #error "Unknown platform define!" #endif diff --git a/Engine/Platform/Window.hpp b/Engine/Platform/Window.hpp index f3bc5f6..6b19dc4 100644 --- a/Engine/Platform/Window.hpp +++ b/Engine/Platform/Window.hpp @@ -5,7 +5,7 @@ #elif defined(PLATFORM_LINUX) #include "Linux/Window.hpp" #else - #error "Unknown platform!" + #error "Unknown platform define!" #endif namespace Platform diff --git a/Example/Main.cpp b/Example/Main.cpp index 105151f..f3802e6 100644 --- a/Example/Main.cpp +++ b/Example/Main.cpp @@ -19,8 +19,8 @@ int main(const int argc, const char* const* argv) return -1; } - Graphics::System graphics; - if(!graphics.Setup(window.Get())) + UniquePtr graphics = Graphics::System::Create(window.Get()); + if(graphics == nullptr) { LOG_FATAL("Failed to setup graphics system"); return -1; @@ -38,10 +38,10 @@ int main(const int argc, const char* const* argv) if(window->IsClosing()) break; - graphics.BeginFrame(); + graphics->BeginFrame(); { } - graphics.EndFrame(); + graphics->EndFrame(); } LOG_INFO("Exiting application...");