Add a way to embed renderer backends code into NazaraRenderer

This commit is contained in:
SirLynix 2022-08-07 20:19:04 +02:00
parent 09d21b4a45
commit 38e32025e9
8 changed files with 177 additions and 82 deletions

View File

@ -1,3 +1,8 @@
target("Std140Debug") target("Std140Debug")
add_deps("NazaraOpenGLRenderer")
add_files("main.cpp") add_files("main.cpp")
if has_config("embed_rendererbackends") then
add_deps("NazaraRenderer")
else
add_deps("NazaraOpenGLRenderer")
end

View File

@ -52,6 +52,7 @@
#include <Nazara/Graphics/GuillotineTextureAtlas.hpp> #include <Nazara/Graphics/GuillotineTextureAtlas.hpp>
#include <Nazara/Graphics/InstancedRenderable.hpp> #include <Nazara/Graphics/InstancedRenderable.hpp>
#include <Nazara/Graphics/Light.hpp> #include <Nazara/Graphics/Light.hpp>
#include <Nazara/Graphics/LinearSlicedSprite.hpp>
#include <Nazara/Graphics/Material.hpp> #include <Nazara/Graphics/Material.hpp>
#include <Nazara/Graphics/MaterialPass.hpp> #include <Nazara/Graphics/MaterialPass.hpp>
#include <Nazara/Graphics/MaterialPassRegistry.hpp> #include <Nazara/Graphics/MaterialPassRegistry.hpp>

View File

@ -31,15 +31,20 @@
#include <Nazara/Widgets/AbstractTextAreaWidget.hpp> #include <Nazara/Widgets/AbstractTextAreaWidget.hpp>
#include <Nazara/Widgets/BaseWidget.hpp> #include <Nazara/Widgets/BaseWidget.hpp>
#include <Nazara/Widgets/BoxLayout.hpp>
#include <Nazara/Widgets/ButtonWidget.hpp> #include <Nazara/Widgets/ButtonWidget.hpp>
#include <Nazara/Widgets/Canvas.hpp> #include <Nazara/Widgets/Canvas.hpp>
#include <Nazara/Widgets/CheckboxWidget.hpp> #include <Nazara/Widgets/CheckboxWidget.hpp>
#include <Nazara/Widgets/Config.hpp> #include <Nazara/Widgets/Config.hpp>
#include <Nazara/Widgets/DefaultWidgetTheme.hpp> #include <Nazara/Widgets/DefaultWidgetTheme.hpp>
#include <Nazara/Widgets/Enums.hpp> #include <Nazara/Widgets/Enums.hpp>
#include <Nazara/Widgets/ImageButtonWidget.hpp>
#include <Nazara/Widgets/ImageWidget.hpp> #include <Nazara/Widgets/ImageWidget.hpp>
#include <Nazara/Widgets/LabelWidget.hpp> #include <Nazara/Widgets/LabelWidget.hpp>
#include <Nazara/Widgets/RichTextAreaWidget.hpp> #include <Nazara/Widgets/RichTextAreaWidget.hpp>
#include <Nazara/Widgets/ScrollAreaWidget.hpp>
#include <Nazara/Widgets/ScrollbarButtonWidget.hpp>
#include <Nazara/Widgets/ScrollbarWidget.hpp>
#include <Nazara/Widgets/SimpleWidgetStyles.hpp> #include <Nazara/Widgets/SimpleWidgetStyles.hpp>
#include <Nazara/Widgets/TextAreaWidget.hpp> #include <Nazara/Widgets/TextAreaWidget.hpp>
#include <Nazara/Widgets/Widgets.hpp> #include <Nazara/Widgets/Widgets.hpp>

View File

@ -5,6 +5,8 @@
#include <Nazara/Prerequisites.hpp> #include <Nazara/Prerequisites.hpp>
#include <Nazara/OpenGLRenderer/OpenGLRenderer.hpp> #include <Nazara/OpenGLRenderer/OpenGLRenderer.hpp>
#ifndef NAZARA_RENDERER_EMBEDDEDBACKENDS
extern "C" extern "C"
{ {
NAZARA_EXPORT Nz::RendererImpl* NazaraRenderer_Instantiate() NAZARA_EXPORT Nz::RendererImpl* NazaraRenderer_Instantiate()
@ -13,3 +15,5 @@ extern "C"
return renderer.release(); return renderer.release();
} }
} }
#endif

View File

@ -14,6 +14,12 @@
#include <Nazara/Utils/CallOnExit.hpp> #include <Nazara/Utils/CallOnExit.hpp>
#include <filesystem> #include <filesystem>
#include <stdexcept> #include <stdexcept>
#ifdef NAZARA_RENDERER_EMBEDDEDBACKENDS
#include <Nazara/OpenGLRenderer/OpenGLRenderer.hpp>
#include <Nazara/VulkanRenderer/VulkanRenderer.hpp>
#endif
#include <Nazara/Renderer/Debug.hpp> #include <Nazara/Renderer/Debug.hpp>
#ifdef NAZARA_COMPILER_MSVC #ifdef NAZARA_COMPILER_MSVC
@ -81,11 +87,36 @@ namespace Nz
struct RendererImplementations struct RendererImplementations
{ {
#ifdef NAZARA_RENDERER_EMBEDDEDBACKENDS
std::function<std::unique_ptr<RendererImpl>()> factory;
#else
std::filesystem::path fileName; std::filesystem::path fileName;
#endif
int score; int score;
}; };
std::vector<RendererImplementations> implementations; std::vector<RendererImplementations> implementations;
#ifdef NAZARA_RENDERER_EMBEDDEDBACKENDS
auto RegisterImpl = [&](RenderAPI api, auto ComputeScore, std::function<std::unique_ptr<RendererImpl>()> 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<int>::max() : score;
}
};
RegisterImpl(RenderAPI::OpenGL, [] { return 50; }, [] { return std::make_unique<OpenGLRenderer>(); });
RegisterImpl(RenderAPI::Vulkan, [] { return 100; }, [] { return std::make_unique<VulkanRenderer>(); });
#else
auto RegisterImpl = [&](RenderAPI api, auto ComputeScore) auto RegisterImpl = [&](RenderAPI api, auto ComputeScore)
{ {
const char* rendererName = rendererPaths[UnderlyingCast(api)]; const char* rendererName = rendererPaths[UnderlyingCast(api)];
@ -105,16 +136,20 @@ namespace Nz
RegisterImpl(RenderAPI::OpenGL, [] { return 50; }); RegisterImpl(RenderAPI::OpenGL, [] { return 50; });
RegisterImpl(RenderAPI::Vulkan, [] { return 100; }); RegisterImpl(RenderAPI::Vulkan, [] { return 100; });
#endif
std::sort(implementations.begin(), implementations.end(), [](const auto& lhs, const auto& rhs) { return lhs.score > rhs.score; }); std::sort(implementations.begin(), implementations.end(), [](const auto& lhs, const auto& rhs) { return lhs.score > rhs.score; });
std::unique_ptr<RendererImpl> chosenImpl;
#ifndef NAZARA_RENDERER_EMBEDDEDBACKENDS
NazaraDebug("Searching for renderer implementation"); NazaraDebug("Searching for renderer implementation");
DynLib chosenLib; DynLib chosenLib;
std::unique_ptr<RendererImpl> chosenImpl; #endif
for (auto&& rendererImpl : implementations) for (auto&& rendererImpl : implementations)
{ {
#ifndef NAZARA_RENDERER_EMBEDDEDBACKENDS
std::string fileNameStr = rendererImpl.fileName.generic_u8string(); std::string fileNameStr = rendererImpl.fileName.generic_u8string();
DynLib implLib; DynLib implLib;
@ -132,16 +167,21 @@ namespace Nz
} }
std::unique_ptr<RendererImpl> impl(createRenderer()); std::unique_ptr<RendererImpl> impl(createRenderer());
#else
std::unique_ptr<RendererImpl> impl = rendererImpl.factory();
#endif
if (!impl || !impl->Prepare({})) if (!impl || !impl->Prepare({}))
{ {
NazaraError("Failed to create renderer implementation"); NazaraError("Failed to create renderer implementation");
continue; continue;
} }
#ifndef NAZARA_RENDERER_EMBEDDEDBACKENDS
NazaraDebug("Loaded " + fileNameStr); NazaraDebug("Loaded " + fileNameStr);
chosenLib = std::move(implLib);
#endif
chosenImpl = std::move(impl); //< Move (and delete previous) implementation before unloading library chosenImpl = std::move(impl); //< Move (and delete previous) implementation before unloading library
chosenLib = std::move(implLib);
break; break;
} }
@ -149,7 +189,9 @@ namespace Nz
throw std::runtime_error("no renderer found"); throw std::runtime_error("no renderer found");
m_rendererImpl = std::move(chosenImpl); m_rendererImpl = std::move(chosenImpl);
#ifndef NAZARA_RENDERER_EMBEDDEDBACKENDS
m_rendererLib = std::move(chosenLib); m_rendererLib = std::move(chosenLib);
#endif
NazaraDebug("Using " + m_rendererImpl->QueryAPIString() + " as renderer"); NazaraDebug("Using " + m_rendererImpl->QueryAPIString() + " as renderer");
} }

View File

@ -5,6 +5,8 @@
#include <Nazara/Prerequisites.hpp> #include <Nazara/Prerequisites.hpp>
#include <Nazara/VulkanRenderer/VulkanRenderer.hpp> #include <Nazara/VulkanRenderer/VulkanRenderer.hpp>
#ifndef NAZARA_RENDERER_EMBEDDEDBACKENDS
extern "C" extern "C"
{ {
NAZARA_EXPORT Nz::RendererImpl* NazaraRenderer_Instantiate() NAZARA_EXPORT Nz::RendererImpl* NazaraRenderer_Instantiate()
@ -14,6 +16,8 @@ extern "C"
} }
} }
#endif
#if defined(NAZARA_PLATFORM_WINDOWS) #if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Core/AntiWindows.hpp> #include <Nazara/Core/AntiWindows.hpp>
#endif #endif

186
xmake.lua
View File

@ -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 = { local modules = {
Audio = { Audio = {
Deps = {"NazaraCore"}, Deps = {"NazaraCore"},
@ -39,24 +79,6 @@ local modules = {
end end
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 = { Physics2D = {
Deps = {"NazaraUtility"}, Deps = {"NazaraUtility"},
Packages = {"entt", "chipmunk2d"} Packages = {"entt", "chipmunk2d"}
@ -82,36 +104,31 @@ local modules = {
}, },
Renderer = { Renderer = {
Deps = {"NazaraPlatform"}, 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 = { Utility = {
Deps = {"NazaraCore"}, Deps = {"NazaraCore"},
Packages = {"entt", "freetype", "frozen", "ordered_map", "stb"} 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 = { Widgets = {
Deps = {"NazaraGraphics"}, Deps = {"NazaraGraphics"},
Packages = {"entt", "kiwisolver"} Packages = {"entt", "kiwisolver"}
} }
} }
NazaraModules = modules NazaraModules = modules
includes("xmake/**.lua") includes("xmake/**.lua")
@ -122,6 +139,12 @@ option("compile_shaders")
set_description("Compile nzsl shaders into an includable binary version") set_description("Compile nzsl shaders into an includable binary version")
option_end() 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") option("embed_resources")
set_default(true) set_default(true)
set_showmenu(true) set_showmenu(true)
@ -224,45 +247,8 @@ elseif is_plat("mingw") then
add_ldflags("-Wa,-mbig-obj") add_ldflags("-Wa,-mbig-obj")
end end
for name, module in pairs(modules) do function ModuleTargetConfig(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 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")
add_defines("NAZARA_" .. name:upper() .. "_BUILD") add_defines("NAZARA_" .. name:upper() .. "_BUILD")
add_defines("NAZARA_UTILS_WINDOWS_NT6=1")
if is_mode("debug") then if is_mode("debug") then
add_defines("NAZARA_" .. name:upper() .. "_DEBUG") add_defines("NAZARA_" .. name:upper() .. "_DEBUG")
end end
@ -277,8 +263,6 @@ for name, module in pairs(modules) do
remove_headerfiles("src/Nazara/" .. name .. "/Resources/**.h") remove_headerfiles("src/Nazara/" .. name .. "/Resources/**.h")
add_files("src/Nazara/" .. name .. "/**.cpp") add_files("src/Nazara/" .. name .. "/**.cpp")
add_includedirs("src")
if has_config("embed_resources") then if has_config("embed_resources") then
local embedResourceRule = false local embedResourceRule = false
for _, filepath in pairs(os.files("src/Nazara/" .. name .. "/Resources/**|**.h|**.nzsl|**.nzslb")) do 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") remove_files("src/Nazara/" .. name .. "/Linux/**.cpp")
end 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 end
includes("tools/*.lua") includes("tools/*.lua")

View File

@ -1,8 +1,12 @@
local modules = NazaraModules local modules = NazaraRendererBackends
-- Builds renderer plugins if linked to NazaraRenderer -- Builds renderer plugins if linked to NazaraRenderer
rule("build.rendererplugins") rule("build.rendererplugins")
on_load(function (target) on_load(function (target)
if has_config("embed_rendererbackends") then
return
end
local deps = table.wrap(target:get("deps")) local deps = table.wrap(target:get("deps"))
if target:kind() == "binary" and (table.contains(deps, "NazaraRenderer") or table.contains(deps, "NazaraGraphics")) then if target:kind() == "binary" and (table.contains(deps, "NazaraRenderer") or table.contains(deps, "NazaraGraphics")) then