From feb438a3e6bb52035408da3410739cebde5de21e Mon Sep 17 00:00:00 2001 From: Jayden Grubb Date: Sun, 23 Nov 2025 17:52:47 +1000 Subject: [PATCH] Add IContext and IDevice classes with Vulkan backend --- CMakeLists.txt | 5 +++ engine/CMakeLists.txt | 17 +++++++ engine/include/nova/graphics/context.hpp | 38 ++++++++++++++++ engine/include/nova/graphics/device.hpp | 16 +++++++ .../graphics => src/backends/dx12}/.gitkeep | 0 engine/src/backends/metal/.gitkeep | 0 engine/src/backends/vulkan/context.cpp | 45 +++++++++++++++++++ engine/src/backends/vulkan/context.hpp | 24 ++++++++++ engine/src/backends/vulkan/device.cpp | 15 +++++++ engine/src/backends/vulkan/device.hpp | 18 ++++++++ engine/src/backends/webgpu/.gitkeep | 0 engine/src/graphics/context.cpp | 26 +++++++++++ 12 files changed, 204 insertions(+) create mode 100644 engine/include/nova/graphics/context.hpp create mode 100644 engine/include/nova/graphics/device.hpp rename engine/{include/nova/graphics => src/backends/dx12}/.gitkeep (100%) create mode 100644 engine/src/backends/metal/.gitkeep create mode 100644 engine/src/backends/vulkan/context.cpp create mode 100644 engine/src/backends/vulkan/context.hpp create mode 100644 engine/src/backends/vulkan/device.cpp create mode 100644 engine/src/backends/vulkan/device.hpp create mode 100644 engine/src/backends/webgpu/.gitkeep create mode 100644 engine/src/graphics/context.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ceaf0e5..f3cf7cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,11 @@ set(NOVA_SANITIZERS "" CACHE STRING "Sanitizers to enable (address, undefined, l set(NOVA_WERROR OFF CACHE BOOL "Treat compiler warnings as errors") set(NOVA_LIBRARY_INSTALL OFF CACHE BOOL "Enable library installation targets") +# set(NOVA_BACKEND_DX12 ON CACHE BOOL "Enable DX12 backend") +# set(NOVA_BACKEND_METAL ON CACHE BOOL "Enable Metal backend") +set(NOVA_BACKEND_VULKAN ON CACHE BOOL "Enable Vulkan backend") +# set(NOVA_BACKEND_WEBGPU ON CACHE BOOL "Enable WebGPU backend") + add_compile_definitions( NOVA_VERSION_MAJOR=${PROJECT_VERSION_MAJOR} NOVA_VERSION_MINOR=${PROJECT_VERSION_MINOR} diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index c9703c6..832bb1c 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -3,6 +3,7 @@ set(NOVA_ENGINE_SRC core/debug.cpp + graphics/context.cpp ) list(TRANSFORM NOVA_ENGINE_SRC PREPEND ${CMAKE_CURRENT_SOURCE_DIR}/src/) @@ -17,6 +18,22 @@ target_include_directories(nova ${CMAKE_CURRENT_SOURCE_DIR}/src ) +if (NOVA_BACKEND_VULKAN) + find_package(Vulkan REQUIRED) + + set(NOVA_VULKAN_SRC + backends/vulkan/context.cpp + backends/vulkan/device.cpp + ) + + list(TRANSFORM NOVA_VULKAN_SRC PREPEND ${CMAKE_CURRENT_SOURCE_DIR}/src/) + + target_sources(nova PRIVATE ${NOVA_VULKAN_SRC}) + target_compile_definitions(nova PRIVATE NOVA_BACKEND_VULKAN) + target_include_directories(nova PRIVATE ${Vulkan_INCLUDE_DIRS}) + target_link_libraries(nova PRIVATE Vulkan::Vulkan) +endif() + set_target_properties(nova PROPERTIES DEFINE_SYMBOL NOVA_EXPORT_SYMBOLS VERSION ${PROJECT_VERSION} diff --git a/engine/include/nova/graphics/context.hpp b/engine/include/nova/graphics/context.hpp new file mode 100644 index 0000000..111fd4f --- /dev/null +++ b/engine/include/nova/graphics/context.hpp @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2025, Jayden Grubb + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#pragma once + +#include +#include + +#include +#include + +namespace nova::gfx { + +class IDevice; + +enum class API { + UNDEFINED, + VULKAN, +}; + +class NOVA_API IContext { + public: + static std::unique_ptr create(API api); + virtual ~IContext() = default; + + virtual API get_api() const = 0; + virtual std::string get_api_name() const = 0; + + virtual u32 get_api_version() const = 0; + virtual std::string get_api_version_string() const = 0; + + virtual std::unique_ptr create_device() = 0; +}; + +} // namespace nova::gfx diff --git a/engine/include/nova/graphics/device.hpp b/engine/include/nova/graphics/device.hpp new file mode 100644 index 0000000..fd02694 --- /dev/null +++ b/engine/include/nova/graphics/device.hpp @@ -0,0 +1,16 @@ +/** + * Copyright (c) 2025, Jayden Grubb + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#pragma once + +#include +#include + +namespace nova::gfx { + +class NOVA_API IDevice {}; + +} // namespace nova::gfx diff --git a/engine/include/nova/graphics/.gitkeep b/engine/src/backends/dx12/.gitkeep similarity index 100% rename from engine/include/nova/graphics/.gitkeep rename to engine/src/backends/dx12/.gitkeep diff --git a/engine/src/backends/metal/.gitkeep b/engine/src/backends/metal/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/engine/src/backends/vulkan/context.cpp b/engine/src/backends/vulkan/context.cpp new file mode 100644 index 0000000..fc242ba --- /dev/null +++ b/engine/src/backends/vulkan/context.cpp @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2025, Jayden Grubb + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include "backends/vulkan/context.hpp" +#include "backends/vulkan/device.hpp" + +namespace nova::gfx { + +API VulkanContext::get_api() const { + return API::VULKAN; +} + +std::string VulkanContext::get_api_name() const { + return "Vulkan"; +} + +u32 VulkanContext::get_api_version() const { + u32 version; + vkEnumerateInstanceVersion(&version); + return version; +} + +std::string VulkanContext::get_api_version_string() const { + const u32 version = get_api_version(); + return std::format( + "{}.{}.{}-{}", + VK_API_VERSION_MAJOR(version), + VK_API_VERSION_MINOR(version), + VK_API_VERSION_PATCH(version), + VK_API_VERSION_VARIANT(version) + ); +} + +std::unique_ptr VulkanContext::create_device() { + return std::make_unique(); +} + +} // namespace nova::gfx diff --git a/engine/src/backends/vulkan/context.hpp b/engine/src/backends/vulkan/context.hpp new file mode 100644 index 0000000..27afc7b --- /dev/null +++ b/engine/src/backends/vulkan/context.hpp @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2025, Jayden Grubb + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#pragma once + +#include + +namespace nova::gfx { + +class VulkanContext final : public IContext { + public: + API get_api() const override; + std::string get_api_name() const override; + + u32 get_api_version() const override; + std::string get_api_version_string() const override; + + std::unique_ptr create_device() override; +}; + +} // namespace nova::gfx diff --git a/engine/src/backends/vulkan/device.cpp b/engine/src/backends/vulkan/device.cpp new file mode 100644 index 0000000..27a847d --- /dev/null +++ b/engine/src/backends/vulkan/device.cpp @@ -0,0 +1,15 @@ +/** + * Copyright (c) 2025, Jayden Grubb + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include "backends/vulkan/device.hpp" + +namespace nova::gfx { + +// TODO + +} diff --git a/engine/src/backends/vulkan/device.hpp b/engine/src/backends/vulkan/device.hpp new file mode 100644 index 0000000..b008326 --- /dev/null +++ b/engine/src/backends/vulkan/device.hpp @@ -0,0 +1,18 @@ +/** + * Copyright (c) 2025, Jayden Grubb + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#pragma once + +#include + +namespace nova::gfx { + +class VulkanDevice final : public IDevice { + public: + // TODO +}; + +} // namespace nova::gfx diff --git a/engine/src/backends/webgpu/.gitkeep b/engine/src/backends/webgpu/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/engine/src/graphics/context.cpp b/engine/src/graphics/context.cpp new file mode 100644 index 0000000..0e10cea --- /dev/null +++ b/engine/src/graphics/context.cpp @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2025, Jayden Grubb + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include "backends/vulkan/context.hpp" + +namespace nova::gfx { + +std::unique_ptr IContext::create(API p_api) { + switch (p_api) { +#if defined(NOVA_BACKEND_VULKAN) + case API::VULKAN: + return std::make_unique(); +#endif + default: + throw std::runtime_error("Unsupported graphics API"); + } +} + +} // namespace nova::gfx