From 38e32025e9ca41377a3688c00dc8d8e5750c0fb6 Mon Sep 17 00:00:00 2001 From: SirLynix Date: Sun, 7 Aug 2022 20:19:04 +0200 Subject: [PATCH] Add a way to embed renderer backends code into NazaraRenderer --- examples/Std140Debug/xmake.lua | 7 +- include/Nazara/Graphics.hpp | 1 + include/Nazara/Widgets.hpp | 5 + src/Nazara/OpenGLRenderer/Export.cpp | 4 + src/Nazara/Renderer/Renderer.cpp | 46 ++++++- src/Nazara/VulkanRenderer/Export.cpp | 4 + xmake.lua | 186 ++++++++++++++++----------- xmake/rules/renderer_plugins.lua | 6 +- 8 files changed, 177 insertions(+), 82 deletions(-) diff --git a/examples/Std140Debug/xmake.lua b/examples/Std140Debug/xmake.lua index be6f486d7..ead0cd441 100644 --- a/examples/Std140Debug/xmake.lua +++ b/examples/Std140Debug/xmake.lua @@ -1,3 +1,8 @@ target("Std140Debug") - add_deps("NazaraOpenGLRenderer") add_files("main.cpp") + + if has_config("embed_rendererbackends") then + add_deps("NazaraRenderer") + else + add_deps("NazaraOpenGLRenderer") + end \ No newline at end of file diff --git a/include/Nazara/Graphics.hpp b/include/Nazara/Graphics.hpp index 578959766..038715937 100644 --- a/include/Nazara/Graphics.hpp +++ b/include/Nazara/Graphics.hpp @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include diff --git a/include/Nazara/Widgets.hpp b/include/Nazara/Widgets.hpp index e62fc2d89..e73711500 100644 --- a/include/Nazara/Widgets.hpp +++ b/include/Nazara/Widgets.hpp @@ -31,15 +31,20 @@ #include #include +#include #include #include #include #include #include #include +#include #include #include #include +#include +#include +#include #include #include #include diff --git a/src/Nazara/OpenGLRenderer/Export.cpp b/src/Nazara/OpenGLRenderer/Export.cpp index 58f0d5b7f..0806949e8 100644 --- a/src/Nazara/OpenGLRenderer/Export.cpp +++ b/src/Nazara/OpenGLRenderer/Export.cpp @@ -5,6 +5,8 @@ #include #include +#ifndef NAZARA_RENDERER_EMBEDDEDBACKENDS + extern "C" { NAZARA_EXPORT Nz::RendererImpl* NazaraRenderer_Instantiate() @@ -13,3 +15,5 @@ extern "C" return renderer.release(); } } + +#endif diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index 2b1c164bd..63567d77c 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -14,6 +14,12 @@ #include #include #include + +#ifdef NAZARA_RENDERER_EMBEDDEDBACKENDS +#include +#include +#endif + #include #ifdef NAZARA_COMPILER_MSVC @@ -81,11 +87,36 @@ namespace Nz struct RendererImplementations { +#ifdef NAZARA_RENDERER_EMBEDDEDBACKENDS + std::function()> factory; +#else std::filesystem::path fileName; +#endif int score; }; std::vector implementations; +#ifdef NAZARA_RENDERER_EMBEDDEDBACKENDS + auto RegisterImpl = [&](RenderAPI api, auto ComputeScore, std::function()> factory) + { + const char* rendererName = rendererPaths[UnderlyingCast(api)]; + assert(rendererName); + + std::filesystem::path fileName(rendererName); + fileName.replace_extension(NAZARA_DYNLIB_EXTENSION); + + int score = ComputeScore(); + if (score >= 0) + { + auto& impl = implementations.emplace_back(); + impl.factory = std::move(factory); + impl.score = (config.preferredAPI == api) ? std::numeric_limits::max() : score; + } + }; + + RegisterImpl(RenderAPI::OpenGL, [] { return 50; }, [] { return std::make_unique(); }); + RegisterImpl(RenderAPI::Vulkan, [] { return 100; }, [] { return std::make_unique(); }); +#else auto RegisterImpl = [&](RenderAPI api, auto ComputeScore) { const char* rendererName = rendererPaths[UnderlyingCast(api)]; @@ -105,16 +136,20 @@ namespace Nz RegisterImpl(RenderAPI::OpenGL, [] { return 50; }); RegisterImpl(RenderAPI::Vulkan, [] { return 100; }); +#endif std::sort(implementations.begin(), implementations.end(), [](const auto& lhs, const auto& rhs) { return lhs.score > rhs.score; }); + std::unique_ptr chosenImpl; +#ifndef NAZARA_RENDERER_EMBEDDEDBACKENDS NazaraDebug("Searching for renderer implementation"); DynLib chosenLib; - std::unique_ptr chosenImpl; +#endif for (auto&& rendererImpl : implementations) { +#ifndef NAZARA_RENDERER_EMBEDDEDBACKENDS std::string fileNameStr = rendererImpl.fileName.generic_u8string(); DynLib implLib; @@ -132,16 +167,21 @@ namespace Nz } std::unique_ptr impl(createRenderer()); +#else + std::unique_ptr impl = rendererImpl.factory(); +#endif if (!impl || !impl->Prepare({})) { NazaraError("Failed to create renderer implementation"); continue; } +#ifndef NAZARA_RENDERER_EMBEDDEDBACKENDS NazaraDebug("Loaded " + fileNameStr); + chosenLib = std::move(implLib); +#endif chosenImpl = std::move(impl); //< Move (and delete previous) implementation before unloading library - chosenLib = std::move(implLib); break; } @@ -149,7 +189,9 @@ namespace Nz throw std::runtime_error("no renderer found"); m_rendererImpl = std::move(chosenImpl); +#ifndef NAZARA_RENDERER_EMBEDDEDBACKENDS m_rendererLib = std::move(chosenLib); +#endif NazaraDebug("Using " + m_rendererImpl->QueryAPIString() + " as renderer"); } diff --git a/src/Nazara/VulkanRenderer/Export.cpp b/src/Nazara/VulkanRenderer/Export.cpp index 5e90fa92d..603f872f0 100644 --- a/src/Nazara/VulkanRenderer/Export.cpp +++ b/src/Nazara/VulkanRenderer/Export.cpp @@ -5,6 +5,8 @@ #include #include +#ifndef NAZARA_RENDERER_EMBEDDEDBACKENDS + extern "C" { NAZARA_EXPORT Nz::RendererImpl* NazaraRenderer_Instantiate() @@ -14,6 +16,8 @@ extern "C" } } +#endif + #if defined(NAZARA_PLATFORM_WINDOWS) #include #endif diff --git a/xmake.lua b/xmake.lua index e10845896..2e4c7dbea 100644 --- a/xmake.lua +++ b/xmake.lua @@ -1,3 +1,43 @@ +local rendererBackends = { + OpenGLRenderer = { + Deps = {"NazaraRenderer"}, + Custom = function() + if is_plat("windows", "mingw") then + add_syslinks("gdi32", "user32") + else + remove_files("src/Nazara/OpenGLRenderer/Wrapper/Win32/**.cpp") + remove_files("src/Nazara/OpenGLRenderer/Wrapper/WGL/**.cpp") + end + + if is_plat("linux") then + add_defines("EGL_NO_X11") + add_packages("wayland", { links = {} }) -- we only need wayland headers + else + remove_files("src/Nazara/OpenGLRenderer/Wrapper/Linux/**.cpp") + end + end + }, + VulkanRenderer = { + Deps = {"NazaraRenderer"}, + Custom = function() + add_defines("VK_NO_PROTOTYPES") + if is_plat("windows", "mingw") then + add_defines("VK_USE_PLATFORM_WIN32_KHR") + add_syslinks("user32") + elseif is_plat("linux") then + add_defines("VK_USE_PLATFORM_XLIB_KHR") + add_defines("VK_USE_PLATFORM_WAYLAND_KHR") + add_packages("wayland", { links = {} }) -- we only need wayland headers + elseif is_plat("macosx") then + add_defines("VK_USE_PLATFORM_METAL_EXT") + add_files("src/Nazara/VulkanRenderer/**.mm") + add_frameworks("quartzcore", "AppKit") + end + end + } +} +NazaraRendererBackends = rendererBackends + local modules = { Audio = { Deps = {"NazaraCore"}, @@ -39,24 +79,6 @@ local modules = { end end }, - OpenGLRenderer = { - Deps = {"NazaraRenderer"}, - Custom = function() - if is_plat("windows", "mingw") then - add_syslinks("gdi32", "user32") - else - remove_files("src/Nazara/OpenGLRenderer/Wrapper/Win32/**.cpp") - remove_files("src/Nazara/OpenGLRenderer/Wrapper/WGL/**.cpp") - end - - if is_plat("linux") then - add_defines("EGL_NO_X11") - add_packages("wayland", { links = {} }) -- we only need wayland headers - else - remove_files("src/Nazara/OpenGLRenderer/Wrapper/Linux/**.cpp") - end - end - }, Physics2D = { Deps = {"NazaraUtility"}, Packages = {"entt", "chipmunk2d"} @@ -82,36 +104,31 @@ local modules = { }, Renderer = { Deps = {"NazaraPlatform"}, - PublicPackages = { "nazarautils", "nzsl" } + PublicPackages = { "nazarautils", "nzsl" }, + Custom = function () + if has_config("embed_rendererbackends") then + -- Embed backends code inside our own modules + add_defines("NAZARA_RENDERER_EMBEDDEDBACKENDS") + for name, module in pairs(rendererBackends) do + ModuleTargetConfig(name, module) + end + else + -- Register backends as separate modules + for name, module in pairs(rendererBackends) do + ModuleTarget(name, module) + end + end + end }, Utility = { Deps = {"NazaraCore"}, Packages = {"entt", "freetype", "frozen", "ordered_map", "stb"} }, - VulkanRenderer = { - Deps = {"NazaraRenderer"}, - Custom = function() - add_defines("VK_NO_PROTOTYPES") - if is_plat("windows", "mingw") then - add_defines("VK_USE_PLATFORM_WIN32_KHR") - add_syslinks("user32") - elseif is_plat("linux") then - add_defines("VK_USE_PLATFORM_XLIB_KHR") - add_defines("VK_USE_PLATFORM_WAYLAND_KHR") - add_packages("wayland", { links = {} }) -- we only need wayland headers - elseif is_plat("macosx") then - add_defines("VK_USE_PLATFORM_METAL_EXT") - add_files("src/Nazara/VulkanRenderer/**.mm") - add_frameworks("quartzcore", "AppKit") - end - end - }, Widgets = { Deps = {"NazaraGraphics"}, Packages = {"entt", "kiwisolver"} } } - NazaraModules = modules includes("xmake/**.lua") @@ -122,6 +139,12 @@ option("compile_shaders") set_description("Compile nzsl shaders into an includable binary version") option_end() +option("embed_rendererbackends") + set_default(false) + set_showmenu(true) + set_description("Embed renderer backend code into NazaraRenderer instead of loading them dynamically") +option_end() + option("embed_resources") set_default(true) set_showmenu(true) @@ -224,45 +247,8 @@ elseif is_plat("mingw") then add_ldflags("-Wa,-mbig-obj") end -for name, module in pairs(modules) do - target("Nazara" .. name) - - set_kind("shared") - set_group("Modules") - - add_rpathdirs("$ORIGIN") - - if module.Deps then - add_deps(table.unpack(module.Deps)) - end - - if module.Packages then - add_packages(table.unpack(module.Packages)) - end - - if module.PublicPackages then - for _, pkg in ipairs(module.PublicPackages) do - add_packages(pkg, { public = true }) - end - end - - if module.Custom then - module.Custom() - end - - if has_config("usepch") then - set_pcxxheader("include/Nazara/" .. name .. ".hpp") - end - - if has_config("unitybuild") then - add_defines("NAZARA_UNITY_BUILD") - add_rules("c++.unity_build", {uniqueid = "NAZARA_UNITY_ID", batchsize = 12}) - end - - add_defines("NAZARA_BUILD") +function ModuleTargetConfig(name, module) add_defines("NAZARA_" .. name:upper() .. "_BUILD") - add_defines("NAZARA_UTILS_WINDOWS_NT6=1") - if is_mode("debug") then add_defines("NAZARA_" .. name:upper() .. "_DEBUG") end @@ -277,8 +263,6 @@ for name, module in pairs(modules) do remove_headerfiles("src/Nazara/" .. name .. "/Resources/**.h") add_files("src/Nazara/" .. name .. "/**.cpp") - add_includedirs("src") - if has_config("embed_resources") then local embedResourceRule = false for _, filepath in pairs(os.files("src/Nazara/" .. name .. "/Resources/**|**.h|**.nzsl|**.nzslb")) do @@ -325,6 +309,52 @@ for name, module in pairs(modules) do remove_files("src/Nazara/" .. name .. "/Linux/**.cpp") end + + if module.Custom then + module.Custom() + end +end + +function ModuleTarget(name, module) + target("Nazara" .. name) + set_kind("shared") + set_group("Modules") + + add_rpathdirs("$ORIGIN") + + if module.Deps then + add_deps(table.unpack(module.Deps)) + end + + if module.Packages then + add_packages(table.unpack(module.Packages)) + end + + if module.PublicPackages then + for _, pkg in ipairs(module.PublicPackages) do + add_packages(pkg, { public = true }) + end + end + + if has_config("usepch") then + set_pcxxheader("include/Nazara/" .. name .. ".hpp") + end + + if has_config("unitybuild") then + add_defines("NAZARA_UNITY_BUILD") + add_rules("c++.unity_build", {uniqueid = "NAZARA_UNITY_ID", batchsize = 12}) + end + + add_defines("NAZARA_BUILD") + add_defines("NAZARA_UTILS_WINDOWS_NT6=1") + + add_includedirs("src") + + ModuleTargetConfig(name, module) +end + +for name, module in pairs(modules) do + ModuleTarget(name, module) end includes("tools/*.lua") diff --git a/xmake/rules/renderer_plugins.lua b/xmake/rules/renderer_plugins.lua index d7634c01f..35d3377c2 100644 --- a/xmake/rules/renderer_plugins.lua +++ b/xmake/rules/renderer_plugins.lua @@ -1,8 +1,12 @@ -local modules = NazaraModules +local modules = NazaraRendererBackends -- Builds renderer plugins if linked to NazaraRenderer rule("build.rendererplugins") on_load(function (target) + if has_config("embed_rendererbackends") then + return + end + local deps = table.wrap(target:get("deps")) if target:kind() == "binary" and (table.contains(deps, "NazaraRenderer") or table.contains(deps, "NazaraGraphics")) then