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

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