diff --git a/3rdParty/CMakeLists.txt b/3rdParty/CMakeLists.txt index d327508..59f0d8e 100644 --- a/3rdParty/CMakeLists.txt +++ b/3rdParty/CMakeLists.txt @@ -33,6 +33,7 @@ add_subdirectory(units) add_subdirectory(libjpeg-turbo) add_subdirectory(msdf) add_subdirectory(eastl) +add_subdirectory(moodycamel_concurrentqueue) if (NOT IOS AND ENABLE_CURL) add_subdirectory(curl) endif() diff --git a/3rdParty/assimp/CMakeLists.txt b/3rdParty/assimp/CMakeLists.txt index bad2bad..782c75b 100644 --- a/3rdParty/assimp/CMakeLists.txt +++ b/3rdParty/assimp/CMakeLists.txt @@ -7,7 +7,7 @@ if (NOT IOS) endif () if (assimp_FOUND OR ASSIMP_FOUND) message("Using system assimp") -elseif (ENABLE_ASSIMP AND NOT assimp_BUILT) +elseif (ENABLE_ASSIMP) message("Building assimp from sources") if(NOT DEFINED ASSIMP_REPO) set(ASSIMP_REPO https://github.com/assimp/assimp.git) diff --git a/3rdParty/ftxui/CMakeLists.txt b/3rdParty/ftxui/CMakeLists.txt index 8fc318f..d485171 100644 --- a/3rdParty/ftxui/CMakeLists.txt +++ b/3rdParty/ftxui/CMakeLists.txt @@ -8,7 +8,7 @@ FetchContent_Declare( ftxui EXCLUDE_FROM_ALL GIT_REPOSITORY ${FTXUI_REPO} - GIT_TAG v5.0.0 + GIT_TAG daa421fa6ad97c8a6c9bd43f77c81862bfa52c77 GIT_SHALLOW TRUE ) FetchContent_MakeAvailable(ftxui) \ No newline at end of file diff --git a/3rdParty/libstud-uuid/CMakeLists.txt b/3rdParty/libstud-uuid/CMakeLists.txt index 1e9aae3..c0569a5 100644 --- a/3rdParty/libstud-uuid/CMakeLists.txt +++ b/3rdParty/libstud-uuid/CMakeLists.txt @@ -1,7 +1,7 @@ include(FetchContent) if(NOT DEFINED LIBSTUD_REPO) - set(LIBSTUD_REPO https://github.com/GeorgH93/libstud-uuid.git) + set(LIBSTUD_REPO https://git.madvoxel.net/Mirrors/libstud-uuid.git) endif () FetchContent_Declare( diff --git a/3rdParty/moodycamel_concurrentqueue/CMakeLists.txt b/3rdParty/moodycamel_concurrentqueue/CMakeLists.txt new file mode 100644 index 0000000..d4f7d3b --- /dev/null +++ b/3rdParty/moodycamel_concurrentqueue/CMakeLists.txt @@ -0,0 +1,15 @@ +include(FetchContent) + +if(NOT DEFINED MOODY_CONCURRENTQUEUE_REPO) + set(MOODY_CONCURRENTQUEUE_REPO https://github.com/cameron314/concurrentqueue.git) +endif () + +FetchContent_Declare( + moodycamel_concurrentqueue + EXCLUDE_FROM_ALL + GIT_REPOSITORY ${MOODY_CONCURRENTQUEUE_REPO} + GIT_TAG v1.0.4 + GIT_SHALLOW TRUE +) +FetchContent_MakeAvailable(moodycamel_concurrentqueue) + diff --git a/3rdParty/pugixml/CMakeLists.txt b/3rdParty/pugixml/CMakeLists.txt index 9541e97..c9e670c 100644 --- a/3rdParty/pugixml/CMakeLists.txt +++ b/3rdParty/pugixml/CMakeLists.txt @@ -8,7 +8,7 @@ FetchContent_Declare( pugixml EXCLUDE_FROM_ALL GIT_REPOSITORY ${PUGIXML_REPO} - GIT_TAG v1.14 + GIT_TAG 4bc14418d12d289dd9978fdce9490a45deeb653e GIT_SHALLOW TRUE ) set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) diff --git a/3rdParty/rapidyaml/CMakeLists.txt b/3rdParty/rapidyaml/CMakeLists.txt index aca7338..18cc3f0 100644 --- a/3rdParty/rapidyaml/CMakeLists.txt +++ b/3rdParty/rapidyaml/CMakeLists.txt @@ -8,7 +8,7 @@ FetchContent_Declare( ryml EXCLUDE_FROM_ALL GIT_REPOSITORY ${RAPIDYAML_REPO} - GIT_TAG v0.6.0 + GIT_TAG v0.7.2 GIT_SHALLOW FALSE # ensure submodules are checked out ) FetchContent_MakeAvailable(ryml) \ No newline at end of file diff --git a/3rdParty/yaml-cpp/CMakeLists.txt b/3rdParty/yaml-cpp/CMakeLists.txt index 076fc3d..8f14e90 100644 --- a/3rdParty/yaml-cpp/CMakeLists.txt +++ b/3rdParty/yaml-cpp/CMakeLists.txt @@ -8,7 +8,7 @@ FetchContent_Declare( yaml-cpp EXCLUDE_FROM_ALL GIT_REPOSITORY ${YAMLCPP_REPO} - GIT_TAG 0.8.0 + GIT_TAG d45c4fba3eccb318441ceeccca67345b0dd21a80 GIT_SHALLOW TRUE ) set(YAML_CPP_BUILD_TOOLS OFF CACHE BOOL "" FORCE) diff --git a/cmake/toolchain/ios.toolchain.cmake b/cmake/toolchain/ios.toolchain.cmake index a235cd0..74b0315 100644 --- a/cmake/toolchain/ios.toolchain.cmake +++ b/cmake/toolchain/ios.toolchain.cmake @@ -1143,3 +1143,8 @@ macro(find_host_package) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH) endmacro(find_host_package) + + + +set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "-Xlinker -force_load -Xlinker ") +set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED True) \ No newline at end of file diff --git a/examples/ExampleApps/BillboardExampleApp.cpp b/examples/ExampleApps/BillboardExampleApp.cpp index 2b69d6a..068f812 100644 --- a/examples/ExampleApps/BillboardExampleApp.cpp +++ b/examples/ExampleApps/BillboardExampleApp.cpp @@ -35,7 +35,6 @@ namespace OpenVulkano void Init() override { auto engineConfig = OpenVulkano::EngineConfiguration::GetEngineConfiguration(); - engineConfig->SetNumThreads(4); engineConfig->SetPreferFramebufferFormatSRGB(false); engineConfig->SetFpsCap(0); // monitor's refresh rate engineConfig->SetVSync(true); diff --git a/examples/ExampleApps/CubesExampleApp.cpp b/examples/ExampleApps/CubesExampleApp.cpp index 8b3909b..391f548 100644 --- a/examples/ExampleApps/CubesExampleApp.cpp +++ b/examples/ExampleApps/CubesExampleApp.cpp @@ -51,7 +51,7 @@ namespace OpenVulkano void Init() override { auto engineConfig = OpenVulkano::EngineConfiguration::GetEngineConfiguration(); - engineConfig->SetNumThreads(4); + //engineConfig->SetNumThreads(4); engineConfig->SetPreferFramebufferFormatSRGB(false); std::srand(1); // Fix seed for random numbers diff --git a/examples/ExampleApps/TextExampleApp.cpp b/examples/ExampleApps/TextExampleApp.cpp index 4a97377..3436a83 100644 --- a/examples/ExampleApps/TextExampleApp.cpp +++ b/examples/ExampleApps/TextExampleApp.cpp @@ -47,7 +47,6 @@ namespace OpenVulkano void Init() override { auto engineConfig = OpenVulkano::EngineConfiguration::GetEngineConfiguration(); - engineConfig->SetNumThreads(4); engineConfig->SetPreferFramebufferFormatSRGB(false); std::srand(1); // Fix seed for random numbers diff --git a/examples/main.cpp b/examples/main.cpp index 002e431..f10b998 100644 --- a/examples/main.cpp +++ b/examples/main.cpp @@ -11,6 +11,7 @@ #include #include #include +#include // for Event, Event::Custom #include #include @@ -28,14 +29,34 @@ int main(int argc, char** argv) int selectedExample = 0; ftxui::MenuOption option; auto screen = ftxui::ScreenInteractive::TerminalOutput(); + screen.ForceHandleCtrlC(true); + //screen.ForceHandleCtrlZ(true); option.on_enter = screen.ExitLoopClosure(); auto menu = ftxui::Menu(&examples, &selectedExample, option); - + bool shouldExit = false; + menu |= ftxui::CatchEvent( + [&](ftxui::Event event) + { + if (event == ftxui::Event::CtrlC || event == ftxui::Event::CtrlZ) + { + screen.ExitLoopClosure()(); + shouldExit = true; + } + return false; + }); screen.Loop(menu); - if (selectedExample >= examples.size()) throw std::runtime_error("Invalid menu selection!"); + if (shouldExit) + { + return 0; + } - std::unique_ptr app( EXAMPLE_APPS[selectedExample].second() ); + if (selectedExample >= examples.size()) + { + throw std::runtime_error("Invalid menu selection!"); + } + + std::unique_ptr app(EXAMPLE_APPS[selectedExample].second()); GraphicsAppManager manager(app.get()); manager.Run(); diff --git a/openVulkanoCpp/Base/PauseCV.hpp b/openVulkanoCpp/Base/PauseCV.hpp index 1d23247..2df1791 100644 --- a/openVulkanoCpp/Base/PauseCV.hpp +++ b/openVulkanoCpp/Base/PauseCV.hpp @@ -6,6 +6,7 @@ #pragma once +#include #include #include @@ -15,7 +16,8 @@ namespace OpenVulkano { std::mutex m_mutex; std::condition_variable m_condVar; - bool m_paused = false; + std::atomic_bool m_paused = false; + std::atomic_bool m_isSleeping = false; public: void Pause() { m_paused = true; } @@ -33,9 +35,13 @@ namespace OpenVulkano { while (m_paused) { + m_isSleeping = true; std::unique_lock l(m_mutex); m_condVar.wait(l, [this]{ return !m_paused; }); } + m_isSleeping = false; } + + bool IsSleeping() const { return m_isSleeping; } }; } diff --git a/openVulkanoCpp/Base/UI/IWindow.hpp b/openVulkanoCpp/Base/UI/IWindow.hpp index aee6a6e..876cd19 100644 --- a/openVulkanoCpp/Base/UI/IWindow.hpp +++ b/openVulkanoCpp/Base/UI/IWindow.hpp @@ -32,12 +32,14 @@ namespace OpenVulkano Math::Vector2i position{0, 0}; std::string title = "Window Title"; WindowMode windowMode = WINDOWED; + bool transparentFrameBuffer = false; + bool resizeable = true; }; class IWindow : public ICloseable { public: - virtual ~IWindow() = default; + ~IWindow() override = default; virtual void Init(RenderAPI::RenderApi renderApi) = 0; @@ -48,22 +50,22 @@ namespace OpenVulkano virtual const std::string& GetTitle() = 0; virtual void SetTitle(const std::string& title) = 0; - virtual WindowMode GetWindowMode() = 0; + [[nodiscard]] virtual WindowMode GetWindowMode() = 0; virtual void SetWindowMode(WindowMode) = 0; - inline void SetFullscreen() { SetWindowMode(FULLSCREEN); } - inline void SetWindowed() { SetWindowMode(WINDOWED); } + void SetFullscreen() { SetWindowMode(FULLSCREEN); } + void SetWindowed() { SetWindowMode(WINDOWED); } - virtual const WindowConfiguration& GetWindowConfiguration() = 0; - inline uint32_t GetWidth() { return GetSize().x; } - inline uint32_t GetHeight() { return GetSize().y; } - virtual Math::Vector2ui GetSize() = 0; + [[nodiscard]] virtual const WindowConfiguration& GetWindowConfiguration() = 0; + [[nodiscard]] uint32_t GetWidth() { return GetSize().x; } + [[nodiscard]] uint32_t GetHeight() { return GetSize().y; } + [[nodiscard]] virtual Math::Vector2ui GetSize() = 0; virtual void SetSize(uint32_t width, uint32_t height) = 0; - inline void SetSize(Math::Vector2ui size) { SetSize(size.x, size.y); } + void SetSize(const Math::Vector2ui& size) { SetSize(size.x, size.y); } virtual void SetSizeLimits(int minWidth, int minHeight, int maxWidth, int maxHeight) = 0; - virtual Math::Vector2i GetPosition() = 0; + [[nodiscard]] virtual Math::Vector2i GetPosition() = 0; virtual void SetPosition(int posX, int posY) = 0; - inline void SetPosition(Math::Vector2i pos) { SetPosition(pos.x, pos.y); }; + void SetPosition(Math::Vector2i pos) { SetPosition(pos.x, pos.y); }; virtual void SetMouseVisibility(bool hideMouse) {}; @@ -71,15 +73,15 @@ namespace OpenVulkano virtual void Hide() = 0; virtual void Show(bool show) = 0; - virtual IWindowHandler* GetWindowHandler() = 0; + [[nodiscard]] virtual IWindowHandler* GetWindowHandler() = 0; virtual void SetWindowHandler(IWindowHandler* handler) = 0; /** * \brief Gets the vulkan window implementation of the window. * \return The IVulkanWindow reference of the window. nullptr if the current Window dose not implement IVulkanWindow */ - virtual IVulkanWindow* GetVulkanWindow() = 0; - virtual IOpenGlWindow* GetOpenGlWindow() = 0; + [[nodiscard]] virtual IVulkanWindow* GetVulkanWindow() = 0; + [[nodiscard]] virtual IOpenGlWindow* GetOpenGlWindow() = 0; [[nodiscard]] virtual uint32_t GetWindowId() const = 0; diff --git a/openVulkanoCpp/Base/UUID.cpp b/openVulkanoCpp/Base/UUID.cpp new file mode 100644 index 0000000..ca70295 --- /dev/null +++ b/openVulkanoCpp/Base/UUID.cpp @@ -0,0 +1,49 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "UUID.hpp" +#include + +namespace OpenVulkano +{ + UUID GenerateTimePrefixedCustomUUID() + { + UUID uuid = UUID::generate(); + + uuid.time_low = 0; + uuid.time_mid = 0; + time_t now = time(nullptr); + struct tm* timeinfo = localtime(&now); + + // Extract time components + uint32_t year = timeinfo->tm_year % 100; // Get last two digits of year + uint32_t month = timeinfo->tm_mon + 1; // Month is 0-based + uint32_t day = timeinfo->tm_mday; + uint32_t hour = timeinfo->tm_hour; + uint16_t minute = timeinfo->tm_min; + uint16_t second = timeinfo->tm_sec; + + // Each decimal digit takes 4 bits in the final hex number + uuid.time_low |= (year / 10) << 28; + uuid.time_low |= (year % 10) << 24; + uuid.time_low |= (month / 10) << 20; + uuid.time_low |= (month % 10) << 16; + uuid.time_low |= (day / 10) << 12; + uuid.time_low |= (day % 10) << 8; + uuid.time_low |= (hour / 10) << 4; + uuid.time_low |= (hour % 10) << 0; + uuid.time_mid |= (minute / 10) << 12; + uuid.time_mid |= (minute % 10) << 8; + uuid.time_mid |= (second / 10) << 4; + uuid.time_mid |= (second % 10) << 0; + + // Set version to custom + uuid.time_hiv &= ~(static_cast(uuid.version()) << 12); + uuid.time_hiv |= 8 << 12; + + return uuid; + } +} \ No newline at end of file diff --git a/openVulkanoCpp/Base/UUID.hpp b/openVulkanoCpp/Base/UUID.hpp index 0fa9288..3e02aed 100644 --- a/openVulkanoCpp/Base/UUID.hpp +++ b/openVulkanoCpp/Base/UUID.hpp @@ -11,4 +11,6 @@ namespace OpenVulkano { typedef stud::uuid UUID; + + UUID GenerateTimePrefixedCustomUUID(); } diff --git a/openVulkanoCpp/Base/Utils.cpp b/openVulkanoCpp/Base/Utils.cpp index f9bb154..98c80c7 100644 --- a/openVulkanoCpp/Base/Utils.cpp +++ b/openVulkanoCpp/Base/Utils.cpp @@ -10,6 +10,7 @@ #include #else #include + #include #endif #include #include @@ -90,5 +91,15 @@ namespace OpenVulkano template Array Utils::ReadFile(const std::string& filePath, bool emptyOnMissing, bool nullTerminateString); template Array Utils::ReadFile(const std::filesystem::path& filePath, bool emptyOnMissing, bool nullTerminateString); - + + std::string Utils::DemangleTypeName(const char* name) + { + #ifdef _MSC_VER + return name; + #else + int status = 0; + std::unique_ptr res(abi::__cxa_demangle(name, NULL, NULL, &status), std::free); + return (status==0) ? res.get() : name ; + #endif + } } diff --git a/openVulkanoCpp/Base/Utils.hpp b/openVulkanoCpp/Base/Utils.hpp index 0999241..8782429 100644 --- a/openVulkanoCpp/Base/Utils.hpp +++ b/openVulkanoCpp/Base/Utils.hpp @@ -196,5 +196,7 @@ namespace OpenVulkano static const int id = uniqueTypeID++; return id; } + + static std::string DemangleTypeName(const char* name); }; } diff --git a/openVulkanoCpp/CMakeLists.txt b/openVulkanoCpp/CMakeLists.txt index 6a86577..97462fa 100644 --- a/openVulkanoCpp/CMakeLists.txt +++ b/openVulkanoCpp/CMakeLists.txt @@ -67,7 +67,7 @@ if (NOT ANDROID AND NOT IOS) endif() endif() -target_link_libraries(openVulkanoCpp PUBLIC magic_enum yaml-cpp fmt spdlog glm pugixml stb eigen utf8cpp imgui_internal TracyClient stud-uuid ryml unordered_dense units ktx dds_image) +target_link_libraries(openVulkanoCpp PUBLIC magic_enum yaml-cpp fmt spdlog glm pugixml stb eigen utf8cpp imgui_internal TracyClient stud-uuid ryml unordered_dense concurrentqueue units ktx dds_image) LinkAssimp(openVulkanoCpp) LinkLibArchive(openVulkanoCpp) LinkLibJpegTurbo(openVulkanoCpp) diff --git a/openVulkanoCpp/Data/ReadOnlyAtomicArrayQueue.hpp b/openVulkanoCpp/Data/Concurent/Containers/ReadOnlyAtomicArrayQueue.hpp similarity index 100% rename from openVulkanoCpp/Data/ReadOnlyAtomicArrayQueue.hpp rename to openVulkanoCpp/Data/Concurent/Containers/ReadOnlyAtomicArrayQueue.hpp diff --git a/openVulkanoCpp/Host/GLFW/WindowGLFW.cpp b/openVulkanoCpp/Host/GLFW/WindowGLFW.cpp index a4e3cd9..b669695 100644 --- a/openVulkanoCpp/Host/GLFW/WindowGLFW.cpp +++ b/openVulkanoCpp/Host/GLFW/WindowGLFW.cpp @@ -52,10 +52,15 @@ namespace OpenVulkano::GLFW void WindowGLFW::Create() { + glfwWindowHint(GLFW_RESIZABLE, windowConfig.resizeable); glfwWindowHint(GLFW_DECORATED, (~windowConfig.windowMode) & 1); + glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, windowConfig.transparentFrameBuffer); //TODO handle full screen resolutions window = glfwCreateWindow(windowConfig.size.x, windowConfig.size.y, windowConfig.title.c_str(), GetTargetMonitor(), nullptr); if (!window) return; + float scaleX, scaleY; + glfwGetWindowContentScale(window, &scaleX, &scaleY); + contentScale = std::max(scaleX, scaleY); glfwSetWindowUserPointer(window, this); RegisterCallbacks(); } @@ -114,7 +119,7 @@ namespace OpenVulkano::GLFW throw WindowInitFailedException("Failed to initialize window"); } if (renderApi != RenderAPI::Vulkan) MakeCurrentThread(); - Logger::WINDOW->info("GLFW Window created (id: {0})", GetWindowId()); + Logger::WINDOW->info("GLFW Window created (id: {0}) with scale {1}", GetWindowId(), contentScale); } void WindowGLFW::Close() diff --git a/openVulkanoCpp/Host/GLFW/WindowGLFW.hpp b/openVulkanoCpp/Host/GLFW/WindowGLFW.hpp index fc6844f..f7876ed 100644 --- a/openVulkanoCpp/Host/GLFW/WindowGLFW.hpp +++ b/openVulkanoCpp/Host/GLFW/WindowGLFW.hpp @@ -19,11 +19,11 @@ namespace OpenVulkano::GLFW { class WindowGLFW final : virtual public BaseWindow, virtual public IVulkanWindow, virtual public IOpenGlWindow { - private: InputProviderGLFW& inputProvider; GLFWwindow* window = nullptr; IWindowHandler* handler = nullptr; Math::Vector2ui currentSize = {}; + float contentScale = 1.0f; public: WindowGLFW(InputProviderGLFW& inputProvider); @@ -39,9 +39,9 @@ namespace OpenVulkano::GLFW void RegisterCallbacks() const; - static GLFWmonitor* GetPrimaryMonitor(); + [[nodiscard]] static GLFWmonitor* GetPrimaryMonitor(); - static std::vector GetMonitors(); + [[nodiscard]] static std::vector GetMonitors(); public: // IWindow implementation void Init(RenderAPI::RenderApi renderApi) override; @@ -64,27 +64,29 @@ namespace OpenVulkano::GLFW void SetSizeLimits(int minWidth, int minHeight, int maxWidth, int maxHeight) override; + [[nodiscard]] float GetContentScale() const override { return contentScale; } + void MakeCurrentThread() override; void SetWindowMode(WindowMode windowMode) override; void SetWindowHandler(IWindowHandler* handler) override; - IVulkanWindow* GetVulkanWindow() override { return this; }; + [[nodiscard]] IVulkanWindow* GetVulkanWindow() override { return this; }; - IOpenGlWindow* GetOpenGlWindow() override { return this; }; + [[nodiscard]] IOpenGlWindow* GetOpenGlWindow() override { return this; }; // Status getter - Math::Vector2ui GetSize() override; + [[nodiscard]] Math::Vector2ui GetSize() override; - Math::Vector2i GetPosition() override; + [[nodiscard]] Math::Vector2i GetPosition() override; - IWindowHandler* GetWindowHandler() override { return handler; } + [[nodiscard]] IWindowHandler* GetWindowHandler() override { return handler; } //IVulkanWindow stuff - vk::SurfaceKHR CreateSurface(const vk::Instance& instance, const vk::AllocationCallbacks* pAllocator) override; + [[nodiscard]] vk::SurfaceKHR CreateSurface(const vk::Instance& instance, const vk::AllocationCallbacks* pAllocator) override; - std::vector GetRequiredInstanceExtensions() override; + [[nodiscard]] std::vector GetRequiredInstanceExtensions() override; void* GetNativeWindowHandle() override { return window; } @@ -104,7 +106,7 @@ namespace OpenVulkano::GLFW void OnClose(); protected: - virtual void OnKeyEvent(int key, int scanCode, int action, int mods); + void OnKeyEvent(int key, int scanCode, int action, int mods); private: // Callbacks static WindowGLFW* GetWindow(GLFWwindow* window); @@ -134,6 +136,6 @@ namespace OpenVulkano::GLFW static void DropCallback(GLFWwindow* window, int count, const char** paths); public: - static std::vector GetVulkanRequiredInstanceExtensions(); + [[nodiscard]] static std::vector GetVulkanRequiredInstanceExtensions(); }; } diff --git a/openVulkanoCpp/Host/GraphicsAppManager.cpp b/openVulkanoCpp/Host/GraphicsAppManager.cpp index 8457e07..9044561 100644 --- a/openVulkanoCpp/Host/GraphicsAppManager.cpp +++ b/openVulkanoCpp/Host/GraphicsAppManager.cpp @@ -194,6 +194,7 @@ namespace OpenVulkano { auto start = clock::now(); inputManager->Tick(); + mainThreadTaskPool.Tick(); app->Tick(); if (CURRENT_FRAME.needsRedraw) { diff --git a/openVulkanoCpp/Host/GraphicsAppManager.hpp b/openVulkanoCpp/Host/GraphicsAppManager.hpp index d48704a..2e7b77f 100644 --- a/openVulkanoCpp/Host/GraphicsAppManager.hpp +++ b/openVulkanoCpp/Host/GraphicsAppManager.hpp @@ -12,6 +12,7 @@ #include "Base/UI/IWindow.hpp" #include "Base/PlatformEnums.hpp" #include "Base/Timer.hpp" +#include "Threading/TaskPool.hpp" #include #include @@ -43,6 +44,7 @@ namespace OpenVulkano std::string windowTitleFormat; Input::InputManager* inputManager; EngineConfiguration* engineConfig; + MainThreadTaskPool mainThreadTaskPool; private: void OnCappedFPS(const auto& frameStartTime); diff --git a/openVulkanoCpp/Host/Linux/SystemInfo.cpp b/openVulkanoCpp/Host/Linux/SystemInfo.cpp index 519462c..708bf4c 100644 --- a/openVulkanoCpp/Host/Linux/SystemInfo.cpp +++ b/openVulkanoCpp/Host/Linux/SystemInfo.cpp @@ -329,9 +329,9 @@ namespace OpenVulkano { float value; powerSupplyFile >> value; - return value; + return value / 100.0f; } - return 0; + return -1; } void SystemInfo::EnableEnergyEvents() diff --git a/openVulkanoCpp/Host/SystemInfo.hpp b/openVulkanoCpp/Host/SystemInfo.hpp index 2825457..b42ed10 100644 --- a/openVulkanoCpp/Host/SystemInfo.hpp +++ b/openVulkanoCpp/Host/SystemInfo.hpp @@ -56,6 +56,7 @@ namespace OpenVulkano static bool IsDeviceInLowPowerMode(); static bool GetDeviceHasBattery() { return GetDeviceBatteryState() != BatteryState::Unavailable; } static BatteryState GetDeviceBatteryState(); + // 0 to 1; -1 not available static float GetDeviceBatteryLevel(); static void EnableEnergyEvents(); diff --git a/openVulkanoCpp/Host/Windows/SystemInfo.cpp b/openVulkanoCpp/Host/Windows/SystemInfo.cpp index 6457544..4d61fef 100644 --- a/openVulkanoCpp/Host/Windows/SystemInfo.cpp +++ b/openVulkanoCpp/Host/Windows/SystemInfo.cpp @@ -4,24 +4,46 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +#define _WIN32_DCOM + #include "Host/SystemInfo.hpp" #include "Base/Logger.hpp" #include +#include #include #include #include #include #include +#include +#include +#include +#include // NOTE(vb): Windows defines macros like GetUserName that are used to automatically select the appropriate function version (GetUserNameA for ANSI and GetUserNameW for Unicode) // based on whether the _UNICODE macro is defined, so we manually undefine these macros to avoid naming collisions. #undef GetUserName +// link this for power settings +#pragma comment(lib, "PowrProf.lib") +#pragma comment(lib, "wbemuuid.lib") + namespace OpenVulkano { namespace { enum class SYS_MEM_TYPE { TOTAL_PHYS, AVAIL_PHYS }; + + enum BatteryChargeStatus + { + MEDIUM = 0, // [low, high] + HIGH = 1, // > 66% + LOW = 2, // < 33% + CRITICAL = 4, // <5% + CHARGING = 8, + NO_SYSTEM_BATTERY = 128, + UNKNOWN = 255 + }; size_t ReadSystemMemInfo(SYS_MEM_TYPE type) { @@ -67,6 +89,170 @@ namespace OpenVulkano Logger::PERF->error("Failed to get system commit limit"); return 0; } + + std::optional GetWMIProperty(const std::string& propName) + { + std::optional res; + + // https://learn.microsoft.com/en-us/windows/win32/wmisdk/example-creating-a-wmi-application?redirectedfrom=MSDN + HRESULT hres; + + // Initialize COM. + hres = CoInitializeEx(0, COINIT_MULTITHREADED); + if (FAILED(hres)) + { + Logger::APP->error("Failed to initialize COM library. Error code = 0x{}", hres); + return {}; + } + + // Initialize + hres = CoInitializeSecurity(NULL, + -1, // COM negotiates service + NULL, // Authentication services + NULL, // Reserved + RPC_C_AUTHN_LEVEL_DEFAULT, // authentication + RPC_C_IMP_LEVEL_IMPERSONATE, // Impersonation + NULL, // Authentication info + EOAC_NONE, // Additional capabilities + NULL // Reserved + ); + + + if (FAILED(hres)) + { + Logger::APP->error("Failed to initialize security. Error code = 0x{}", hres); + CoUninitialize(); + return {}; + } + + // Obtain the initial locator to Windows Management + // on a particular host computer. + IWbemLocator* pLoc = 0; + + hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*) &pLoc); + + if (FAILED(hres)) + { + Logger::APP->error("Failed to create IWbemLocator object. Error code = 0x{}", hres); + CoUninitialize(); + return {}; + } + + IWbemServices* pSvc = 0; + + // Connect to the root\cimv2 namespace with the + // current user and obtain pointer pSvc + // to make IWbemServices calls. + + hres = pLoc->ConnectServer( + _bstr_t(L"ROOT\\CIMV2"), // WMI namespace + NULL, // User name + NULL, // User password + 0, // Locale + NULL, // Security flags + 0, // Authority + 0, // Context object + &pSvc // IWbemServices proxy + ); + + if (FAILED(hres)) + { + Logger::APP->error("Could not connect. Error code = 0x{}", hres); + pLoc->Release(); + CoUninitialize(); + return {}; + } + + // Set the IWbemServices proxy so that impersonation + // of the user (client) occurs. + hres = CoSetProxyBlanket( + pSvc, // the proxy to set + RPC_C_AUTHN_WINNT, // authentication service + RPC_C_AUTHZ_NONE, // authorization service + NULL, // Server principal name + RPC_C_AUTHN_LEVEL_CALL, // authentication level + RPC_C_IMP_LEVEL_IMPERSONATE, // impersonation level + NULL, // client identity + EOAC_NONE // proxy capabilities + ); + + if (FAILED(hres)) + { + Logger::APP->error("Could not set proxy blanket. Error code = 0x{}", hres); + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + return {}; + } + + // Use the IWbemServices pointer to make requests of WMI. + // Make requests here: + + // For example, query for all the running processes + IEnumWbemClassObject* pEnumerator = NULL; + hres = pSvc->ExecQuery(bstr_t("WQL"), bstr_t("SELECT * FROM Win32_ComputerSystem"), + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); + + if (FAILED(hres)) + { + Logger::APP->error("Query for processes failed. Error code = 0x{}", hres); + pSvc->Release(); + pLoc->Release(); + CoUninitialize(); + return {}; + } + else + { + IWbemClassObject* pclsObj; + ULONG uReturn = 0; + + while (pEnumerator) + { + hres = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); + + if (0 == uReturn) + { + break; + } + + VARIANT vtProp; + ZeroMemory(&vtProp, sizeof(vtProp)); + + std::wstring propNameUtf16; + utf8::utf8to16(propName.begin(), propName.end(), std::back_inserter(propNameUtf16)); + + // Get the value of the specified property + hres = pclsObj->Get(propNameUtf16.data(), 0, &vtProp, 0, 0); + + if (FAILED(hres)) + { + Logger::APP->error("Failed to get property {}. Error code = 0x{}", propName, hres); + } + else + { + // init optional + res = ""; + std::wstring propValue = vtProp.bstrVal; + utf8::utf16to8(propValue.begin(), propValue.end(), std::back_inserter(*res)); + } + VariantClear(&vtProp); + pclsObj->Release(); + pclsObj = NULL; + } + } + + // Cleanup + // ======== + + pSvc->Release(); + pLoc->Release(); + pEnumerator->Release(); + + CoUninitialize(); + + return res; + } + } size_t SystemInfo::GetSystemRam() @@ -124,12 +310,14 @@ namespace OpenVulkano std::string SystemInfo::GetDeviceVendorName() { - return "Microsoft"; //TODO + std::optional res = GetWMIProperty("Manufacturer"); + return res ? *res : "Unknown"; } std::string SystemInfo::GetDeviceModelName() - { - return "Unknown"; //TODO + { + std::optional res = GetWMIProperty("Model"); + return res ? *res : "Unknown"; } std::string SystemInfo::GetOsName() @@ -137,25 +325,31 @@ namespace OpenVulkano return "Windows"; } - OsVersion SystemInfo::GetOsVersion() + OsVersion SystemInfo::GetOsVersion() { - OSVERSIONINFOA info; - ZeroMemory(&info, sizeof(OSVERSIONINFOA)); - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); - GetVersionExA(&info); + NTSTATUS(WINAPI * RtlGetVersion)(LPOSVERSIONINFOEXW); + OSVERSIONINFOEXW info; + *(FARPROC*) &RtlGetVersion = GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion"); + info.dwOSVersionInfoSize = sizeof(info); + RtlGetVersion(&info); return { (int)info.dwMajorVersion, (int)info.dwMinorVersion, 0, (int)info.dwBuildNumber }; } std::string SystemInfo::GetOsNameHumanReadable() { - OSVERSIONINFOEXA info; - ZeroMemory(&info, sizeof(OSVERSIONINFOEXA)); - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA); - GetVersionEx((OSVERSIONINFOA *)&info); + NTSTATUS(WINAPI *RtlGetVersion)(LPOSVERSIONINFOEXW); + OSVERSIONINFOEXW info; + *(FARPROC*)&RtlGetVersion = GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion"); + info.dwOSVersionInfoSize = sizeof(info); + RtlGetVersion(&info); if (info.wProductType == VER_NT_WORKSTATION) { if (info.dwMajorVersion == 10) + { + if (info.dwBuildNumber >= 22000) + return "Windows 11"; return "Windows 10"; + } else if (info.dwMajorVersion == 6) { switch (info.dwMinorVersion) @@ -172,7 +366,35 @@ namespace OpenVulkano else { if (info.dwMajorVersion == 10) - return "Windows Server 2016"; + { + switch (info.dwBuildNumber) + { + case 14393: + return "Windows Server 2016"; + case 16299: + return "Windows Server 1709"; + case 17134: + return "Windows Server 1803"; + case 17763: + return "Windows Server 2019"; + case 18362: + return "Windows Server 1903"; + case 18363: + return "Windows Server 1909"; + case 19041: + return "Windows Server 2004"; + case 19042: + return "Windows Server 20H2"; + case 20348: + return "Windows Server 2022"; + case 25398: + return "Windows Server 23H2"; + case 26100: + return "Windows Server 2025"; + default: + return "Windows Server"; + } + } else if (info.dwMajorVersion == 6) { switch (info.dwMinorVersion) @@ -188,17 +410,33 @@ namespace OpenVulkano } } - DeviceType SystemInfo::GetDeviceType() + DeviceType SystemInfo::GetDeviceType() { return DeviceType::PC; } - size_t SystemInfo::GetCpuCoreCount() + size_t SystemInfo::GetCpuCoreCount() { - return 0; //TODO + DWORD bufferSize = 0; + GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP::RelationProcessorCore, nullptr, &bufferSize); + + std::vector buf(bufferSize); + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* info = reinterpret_cast(buf.data()); + GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP::RelationProcessorCore, info, &bufferSize); + + size_t physProcessorCount = 0; + BYTE* start = buf.data(); + BYTE* end = buf.data() + bufferSize; + while (start < end) + { + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* current = reinterpret_cast(start); + physProcessorCount++; + start += current->Size; + } + return physProcessorCount; } - size_t SystemInfo::GetCpuThreadCount() + size_t SystemInfo::GetCpuThreadCount() { return std::thread::hardware_concurrency(); } @@ -210,22 +448,46 @@ namespace OpenVulkano CpuThermalState SystemInfo::GetCpuThermalState() { - return CpuThermalState::Normal; + return CpuThermalState::Normal; // TODO } bool SystemInfo::IsDeviceInLowPowerMode() { - return false; //TODO + GUID* activePowerMode; + bool res = false; + if(PowerGetActiveScheme(0, &activePowerMode) == 0) + { + res = IsEqualGUID(*activePowerMode, GUID_MAX_POWER_SAVINGS); + } + LocalFree(activePowerMode); + return res; } BatteryState SystemInfo::GetDeviceBatteryState() { - return BatteryState::Unavailable; //TODO + SYSTEM_POWER_STATUS info; + GetSystemPowerStatus(&info); + BYTE batteryFlag = info.BatteryFlag; + if (batteryFlag & BatteryChargeStatus::CHARGING) + { + if (info.BatteryLifePercent == 100) + return BatteryState::ChargingFull; + return BatteryState::Charging; + } + else if (batteryFlag < BatteryChargeStatus::CHARGING) + { + return BatteryState::Unplugged; + } + // BatteryState::NotCharging is impossible to distinguish + // NO_SYSTEM_BATTERY or UNKNOWN + return BatteryState::Unavailable; } float SystemInfo::GetDeviceBatteryLevel() { - return 0; //TODO + SYSTEM_POWER_STATUS info; + GetSystemPowerStatus(&info); + return info.BatteryLifePercent != 255 ? (static_cast(info.BatteryLifePercent / 100.f)) : -1.f; } void SystemInfo::EnableEnergyEvents() @@ -240,7 +502,24 @@ namespace OpenVulkano DeviceOrientation SystemInfo::GetDeviceOrientation() { - return DeviceOrientation::LandscapeRight; //TODO + DEVMODEA devmode; + ZeroMemory(&devmode, sizeof(devmode)); + devmode.dmSize = sizeof(DEVMODE); + if (EnumDisplaySettingsA(0, ENUM_CURRENT_SETTINGS, &devmode)) + { + DWORD width = devmode.dmPelsWidth; + DWORD height = devmode.dmPelsHeight; + if (width > height) + { + // landscape + return devmode.dmDisplayOrientation == DMDO_180 ? DeviceOrientation::LandscapeLeft : + DeviceOrientation::LandscapeRight; + } + // portrait + return devmode.dmDisplayOrientation == DMDO_180 ? DeviceOrientation::PortraitUpsideDown : + DeviceOrientation::Portrait; + } + return DeviceOrientation::Unknown; } void SystemInfo::EnableDeviceOrientationEvents() @@ -250,6 +529,19 @@ namespace OpenVulkano InterfaceOrientation SystemInfo::GetInterfaceOrientation() { - return InterfaceOrientation::Landscape; //TODO + DeviceOrientation devOrient = GetDeviceOrientation(); + switch (devOrient) + { + case OpenVulkano::DeviceOrientation::Portrait: + return InterfaceOrientation::Portrait; + case OpenVulkano::DeviceOrientation::PortraitUpsideDown: + return InterfaceOrientation::PortraitUpsideDown; + case OpenVulkano::DeviceOrientation::LandscapeLeft: + return InterfaceOrientation::LandscapeRight; + case OpenVulkano::DeviceOrientation::LandscapeRight: + return InterfaceOrientation::LandscapeLeft; + default: + return InterfaceOrientation::Landscape; + } } } \ No newline at end of file diff --git a/openVulkanoCpp/Math/Math.hpp b/openVulkanoCpp/Math/Math.hpp index 4205600..a6f0f03 100644 --- a/openVulkanoCpp/Math/Math.hpp +++ b/openVulkanoCpp/Math/Math.hpp @@ -171,3 +171,9 @@ namespace OpenVulkano::Math typedef Quaternion QuaternionD; typedef Quaternion QuaternionI; } + +template>> +glm::vec operator / (const float lhs, const glm::vec& rhs) +{ + return lhs / glm::vec(rhs); +} diff --git a/openVulkanoCpp/Math/RGB10A2.hpp b/openVulkanoCpp/Math/RGB10A2.hpp index b22aab0..4b79ce3 100644 --- a/openVulkanoCpp/Math/RGB10A2.hpp +++ b/openVulkanoCpp/Math/RGB10A2.hpp @@ -102,7 +102,7 @@ namespace OpenVulkano::Math template>> void SetNormalized(Vector4 vec4) { - Set(Vector4(vec4 * static_cast(MAX_VALUE))); + Set(Vector4(Vector3(vec4 * static_cast(MAX_VALUE)), vec4.a * static_cast(MAX_ALPHA_VALUE))); } void SetNormalized(const Vector3uc& vec3) @@ -125,14 +125,14 @@ namespace OpenVulkano::Math value.x *= 4; value.y *= 4; value.z *= 4; - value.w /= 255; + value.w /= 85; } else { value.x *= 2; value.y *= 2; value.z *= 2; - value.w /= 85; + value.w /= 255; } SetUnchecked(value); } diff --git a/openVulkanoCpp/Scene/Texture.hpp b/openVulkanoCpp/Scene/Texture.hpp index 3565105..c95cb37 100644 --- a/openVulkanoCpp/Scene/Texture.hpp +++ b/openVulkanoCpp/Scene/Texture.hpp @@ -28,12 +28,19 @@ namespace OpenVulkano::Scene UpdateFrequency updateFrequency = UpdateFrequency::Never; const SamplerConfig* m_samplerConfig; bool updated = true; + bool ownsData = false; Texture(const SamplerConfig* samplerConfig = &SamplerConfig::DEFAULT, bool placeholder = false) : m_samplerConfig(samplerConfig) { if (placeholder) MakePlaceholder(); } - ~Texture() = default; + Texture(Math::Vector2ui resolution, DataFormat format) : resolution(resolution, 1), format(format), ownsData(true) + { + size = format.CalculatedSize(resolution.x, resolution.y); + textureBuffer = malloc(size); + } + + ~Texture() { if (ownsData) free(textureBuffer); } void MakePlaceholder(uint32_t width = 32, uint32_t height = 32, Math::Vector4uc color1 = {248, 123, 255, 255}, Math::Vector4uc color2 = {250, 19, 255, 255}); diff --git a/openVulkanoCpp/Threading/Task.hpp b/openVulkanoCpp/Threading/Task.hpp new file mode 100644 index 0000000..e0effe4 --- /dev/null +++ b/openVulkanoCpp/Threading/Task.hpp @@ -0,0 +1,30 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include + +namespace OpenVulkano +{ + class Task + { + public: + virtual ~Task() = default; + virtual void Execute() {} + }; + + class FunctionalTask final : public Task + { + std::function function; + + public: + FunctionalTask(const std::function& function) : function(function) {} + FunctionalTask(std::function&& function) : function(std::move(function)) {} + ~FunctionalTask() override = default; + void Execute() override { function(); } + }; +} diff --git a/openVulkanoCpp/Threading/TaskPool.cpp b/openVulkanoCpp/Threading/TaskPool.cpp new file mode 100644 index 0000000..4ead90c --- /dev/null +++ b/openVulkanoCpp/Threading/TaskPool.cpp @@ -0,0 +1,12 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "TaskPool.hpp" + +namespace OpenVulkano +{ + MainThreadTaskPool* MainThreadTaskPool::INSTANCE; +} \ No newline at end of file diff --git a/openVulkanoCpp/Threading/TaskPool.hpp b/openVulkanoCpp/Threading/TaskPool.hpp new file mode 100644 index 0000000..20ceec9 --- /dev/null +++ b/openVulkanoCpp/Threading/TaskPool.hpp @@ -0,0 +1,87 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "Task.hpp" +#include "Base/Logger.hpp" +#include "Base/Wrapper.hpp" +#include + +namespace OpenVulkano +{ + class ITaskPool + { + protected: + void ExecuteTask(const Ptr& task) + { + try + { + task->Execute(); + } + catch(const std::exception& e) + { + Logger::MANAGER->error("Failed to execute task! With exception: {}", e.what()); + } + catch(...) + { + Logger::MANAGER->error("Failed to execute task! With unknown throwable"); + } + } + + public: + /*template + void EmplaceTask(Args&&... args) + { + m_tasks.enqueue(std::make_shared((std::forward(args)...))); + }*/ + + virtual void Enqueue(const Ptr& task) = 0; + + void Enqueue(const std::function& taskFunction) + { + Enqueue(std::make_shared(taskFunction)); + } + + void operator +=(const std::function& taskFunction) + { + Enqueue(taskFunction); + } + }; + + class MainThreadTaskPool final : public ITaskPool + { + static MainThreadTaskPool* INSTANCE; + moodycamel::ConcurrentQueue> m_tasks; + + public: + MainThreadTaskPool() + { + if (!INSTANCE) INSTANCE = this; + } + + ~MainThreadTaskPool() + { + if (INSTANCE == this) INSTANCE = nullptr; + } + + static MainThreadTaskPool& GetInstance() { return *INSTANCE; } + + void Tick() + { + Ptr task; + while (m_tasks.try_dequeue(task)) + { + ExecuteTask(task); + } + } + + void Enqueue(const Ptr& task) override + { + m_tasks.enqueue(task); + } + }; +} diff --git a/openVulkanoCpp/Vulkan/Context.cpp b/openVulkanoCpp/Vulkan/Context.cpp index b34f8b7..10c0cf1 100644 --- a/openVulkanoCpp/Vulkan/Context.cpp +++ b/openVulkanoCpp/Vulkan/Context.cpp @@ -50,7 +50,7 @@ namespace OpenVulkano::Vulkan vkDestroySurfaceKHR(static_cast(instance), surface, nullptr); //TODO - if (enableValidationLayer) Debug::CloseValidationLayers(instance); + if (enableValidationLayer) Debug::CloseValidationLayers(instance, dynamicDispatch); instance.destroy(); initialized = false; @@ -77,9 +77,9 @@ namespace OpenVulkano::Vulkan #endif instance = vk::createInstance(createInfo); - - if (enableValidationLayer) Debug::SetupValidationLayers(instance, vk::DebugReportFlagBitsEXT::eError | vk::DebugReportFlagBitsEXT::eWarning | vk::DebugReportFlagBitsEXT::ePerformanceWarning /*| vk::DebugReportFlagBitsEXT::eInformation | vk::DebugReportFlagBitsEXT::eDebug*/); dynamicDispatch.init(instance, &vkGetInstanceProcAddr); + + if (enableValidationLayer) Debug::SetupValidationLayers(instance, vk::DebugReportFlagBitsEXT::eError | vk::DebugReportFlagBitsEXT::eWarning | vk::DebugReportFlagBitsEXT::ePerformanceWarning /*| vk::DebugReportFlagBitsEXT::eInformation | vk::DebugReportFlagBitsEXT::eDebug*/, dynamicDispatch); } void Context::CreateDevice() diff --git a/openVulkanoCpp/Vulkan/Context.hpp b/openVulkanoCpp/Vulkan/Context.hpp index d474963..18d4765 100644 --- a/openVulkanoCpp/Vulkan/Context.hpp +++ b/openVulkanoCpp/Vulkan/Context.hpp @@ -7,6 +7,7 @@ #pragma once #include +#include "Debuging/ValidationLayer.hpp" #include "DeviceManager.hpp" #include "SwapChain.hpp" #include "RenderPass.hpp" diff --git a/openVulkanoCpp/Vulkan/Debuging/ValidationLayer.cpp b/openVulkanoCpp/Vulkan/Debuging/ValidationLayer.cpp index bcedf26..5bcf423 100644 --- a/openVulkanoCpp/Vulkan/Debuging/ValidationLayer.cpp +++ b/openVulkanoCpp/Vulkan/Debuging/ValidationLayer.cpp @@ -72,24 +72,23 @@ namespace OpenVulkano::Vulkan return false; } - static std::once_flag dispatcherInitFlag; - vk::DispatchLoaderDynamic dispatcher; - vk::DebugReportCallbackEXT msgCallback; + namespace + { + vk::DebugReportCallbackEXT msgCallback; + } - void Debug::SetupValidationLayers(const vk::Instance& instance, const vk::DebugReportFlagsEXT& flags) + void Debug::SetupValidationLayers(const vk::Instance& instance, const vk::DebugReportFlagsEXT& flags, vk::DispatchLoaderDynamic& dispatchLoaderDynamic) { Logger::RENDER->info("Setting up Vulkan Validation Layer"); - std::call_once(dispatcherInitFlag, [&] { dispatcher.init(instance, &vkGetInstanceProcAddr); }); vk::DebugReportCallbackCreateInfoEXT dbgCreateInfo = {}; dbgCreateInfo.pfnCallback = (PFN_vkDebugReportCallbackEXT)ValidationLayerCallback; dbgCreateInfo.flags = flags; - msgCallback = instance.createDebugReportCallbackEXT(dbgCreateInfo, nullptr, dispatcher); + msgCallback = instance.createDebugReportCallbackEXT(dbgCreateInfo, nullptr, dispatchLoaderDynamic); Logger::RENDER->info("Vulkan Validation Layer setup"); } - void Debug::CloseValidationLayers(const vk::Instance& instance) + void Debug::CloseValidationLayers(const vk::Instance& instance, vk::DispatchLoaderDynamic& dispatchLoaderDynamic) { - std::call_once(dispatcherInitFlag, [&] { dispatcher.init(instance, &vkGetInstanceProcAddr); }); - instance.destroyDebugReportCallbackEXT(msgCallback, nullptr, dispatcher); + instance.destroyDebugReportCallbackEXT(msgCallback, nullptr, dispatchLoaderDynamic); } } \ No newline at end of file diff --git a/openVulkanoCpp/Vulkan/Debuging/ValidationLayer.hpp b/openVulkanoCpp/Vulkan/Debuging/ValidationLayer.hpp index f195ee5..536efbd 100644 --- a/openVulkanoCpp/Vulkan/Debuging/ValidationLayer.hpp +++ b/openVulkanoCpp/Vulkan/Debuging/ValidationLayer.hpp @@ -11,6 +11,15 @@ #include #include +#if VK_HEADER_VERSION > 302 +// Vulkan 1.4.303 moved the dynamic dispatch loader definition, +// this is a workaround to allow building for both the old and the new verisons +namespace vk +{ + using DispatchLoaderDynamic = detail::DispatchLoaderDynamic; +} +#endif + namespace OpenVulkano::Vulkan { class Debug @@ -20,8 +29,8 @@ namespace OpenVulkano::Vulkan static std::vector GetValidationLayers(); - static void SetupValidationLayers(const vk::Instance& instance, const vk::DebugReportFlagsEXT& flags); + static void SetupValidationLayers(const vk::Instance& instance, const vk::DebugReportFlagsEXT& flags, vk::DispatchLoaderDynamic& dispatchLoaderDynamic); - static void CloseValidationLayers(const vk::Instance& instance); + static void CloseValidationLayers(const vk::Instance& instance, vk::DispatchLoaderDynamic& dispatchLoaderDynamic); }; } diff --git a/openVulkanoCpp/Vulkan/Renderer.hpp b/openVulkanoCpp/Vulkan/Renderer.hpp index 718356d..567e3ea 100644 --- a/openVulkanoCpp/Vulkan/Renderer.hpp +++ b/openVulkanoCpp/Vulkan/Renderer.hpp @@ -12,7 +12,7 @@ #include "Context.hpp" #include "UiRenderer.hpp" #include "Resources/ResourceManager.hpp" -#include "Data/ReadOnlyAtomicArrayQueue.hpp" +#include "Data/Concurent/Containers/ReadOnlyAtomicArrayQueue.hpp" #include "CommandHelper.hpp" #include "Base/EngineConfiguration.hpp" #include "Resources/ResourceManager.hpp"