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")
add_deps("NazaraOpenGLRenderer")
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/InstancedRenderable.hpp>
#include <Nazara/Graphics/Light.hpp>
#include <Nazara/Graphics/LinearSlicedSprite.hpp>
#include <Nazara/Graphics/Material.hpp>
#include <Nazara/Graphics/MaterialPass.hpp>
#include <Nazara/Graphics/MaterialPassRegistry.hpp>

View File

@ -31,15 +31,20 @@
#include <Nazara/Widgets/AbstractTextAreaWidget.hpp>
#include <Nazara/Widgets/BaseWidget.hpp>
#include <Nazara/Widgets/BoxLayout.hpp>
#include <Nazara/Widgets/ButtonWidget.hpp>
#include <Nazara/Widgets/Canvas.hpp>
#include <Nazara/Widgets/CheckboxWidget.hpp>
#include <Nazara/Widgets/Config.hpp>
#include <Nazara/Widgets/DefaultWidgetTheme.hpp>
#include <Nazara/Widgets/Enums.hpp>
#include <Nazara/Widgets/ImageButtonWidget.hpp>
#include <Nazara/Widgets/ImageWidget.hpp>
#include <Nazara/Widgets/LabelWidget.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/TextAreaWidget.hpp>
#include <Nazara/Widgets/Widgets.hpp>

View File

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

View File

@ -14,6 +14,12 @@
#include <Nazara/Utils/CallOnExit.hpp>
#include <filesystem>
#include <stdexcept>
#ifdef NAZARA_RENDERER_EMBEDDEDBACKENDS
#include <Nazara/OpenGLRenderer/OpenGLRenderer.hpp>
#include <Nazara/VulkanRenderer/VulkanRenderer.hpp>
#endif
#include <Nazara/Renderer/Debug.hpp>
#ifdef NAZARA_COMPILER_MSVC
@ -81,11 +87,36 @@ namespace Nz
struct RendererImplementations
{
#ifdef NAZARA_RENDERER_EMBEDDEDBACKENDS
std::function<std::unique_ptr<RendererImpl>()> factory;
#else
std::filesystem::path fileName;
#endif
int score;
};
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)
{
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<RendererImpl> chosenImpl;
#ifndef NAZARA_RENDERER_EMBEDDEDBACKENDS
NazaraDebug("Searching for renderer implementation");
DynLib chosenLib;
std::unique_ptr<RendererImpl> 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<RendererImpl> impl(createRenderer());
#else
std::unique_ptr<RendererImpl> 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");
}

View File

@ -5,6 +5,8 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/VulkanRenderer/VulkanRenderer.hpp>
#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 <Nazara/Core/AntiWindows.hpp>
#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 = {
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")

View File

@ -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