Renderer: Remake backend selection

This commit is contained in:
Lynix 2020-05-23 22:07:22 +02:00
parent 6ffbfd9941
commit 8fa456bdf5
6 changed files with 34 additions and 43 deletions

View File

@ -28,8 +28,6 @@ namespace Nz
std::shared_ptr<RenderDevice> InstanciateRenderDevice(std::size_t deviceIndex) override; std::shared_ptr<RenderDevice> InstanciateRenderDevice(std::size_t deviceIndex) override;
bool IsBetterThan(const RendererImpl* other) const override;
RenderAPI QueryAPI() const override; RenderAPI QueryAPI() const override;
std::string QueryAPIString() const override; std::string QueryAPIString() const override;
UInt32 QueryAPIVersion() const override; UInt32 QueryAPIVersion() const override;

View File

@ -38,8 +38,6 @@ namespace Nz
virtual std::shared_ptr<RenderDevice> InstanciateRenderDevice(std::size_t deviceIndex) = 0; virtual std::shared_ptr<RenderDevice> InstanciateRenderDevice(std::size_t deviceIndex) = 0;
virtual bool IsBetterThan(const RendererImpl* other) const = 0;
virtual RenderAPI QueryAPI() const = 0; virtual RenderAPI QueryAPI() const = 0;
virtual std::string QueryAPIString() const = 0; virtual std::string QueryAPIString() const = 0;
virtual UInt32 QueryAPIVersion() const = 0; virtual UInt32 QueryAPIVersion() const = 0;

View File

@ -30,8 +30,6 @@ namespace Nz
std::shared_ptr<RenderDevice> InstanciateRenderDevice(std::size_t deviceIndex) override; std::shared_ptr<RenderDevice> InstanciateRenderDevice(std::size_t deviceIndex) override;
bool IsBetterThan(const RendererImpl* other) const override;
RenderAPI QueryAPI() const override; RenderAPI QueryAPI() const override;
std::string QueryAPIString() const override; std::string QueryAPIString() const override;
UInt32 QueryAPIVersion() const override; UInt32 QueryAPIVersion() const override;

View File

@ -42,14 +42,6 @@ namespace Nz
return m_device; return m_device;
} }
bool OpenGLRenderer::IsBetterThan(const RendererImpl* other) const
{
if (other->QueryAPI() == RenderAPI::OpenGL && QueryAPIVersion() > other->QueryAPIVersion())
return true;
return false; //< OpenGL is mostly a fallback to other renderers
}
bool OpenGLRenderer::Prepare(const ParameterList& parameters) bool OpenGLRenderer::Prepare(const ParameterList& parameters)
{ {
if (!m_opengl32Lib.Load("opengl32" NAZARA_DYNLIB_EXTENSION)) if (!m_opengl32Lib.Load("opengl32" NAZARA_DYNLIB_EXTENSION))

View File

@ -16,9 +16,9 @@
#include <Nazara/Renderer/Debug.hpp> #include <Nazara/Renderer/Debug.hpp>
#ifdef NAZARA_DEBUG #ifdef NAZARA_DEBUG
#define NazaraRendererPattern "Nazara?*Renderer-d" NAZARA_DYNLIB_EXTENSION #define NazaraRendererDebugSuffix "-d"
#else #else
#define NazaraRendererPattern "Nazara?*Renderer" NAZARA_DYNLIB_EXTENSION #define NazaraRendererDebugSuffix ""
#endif #endif
namespace Nz namespace Nz
@ -48,26 +48,45 @@ namespace Nz
CallOnExit onExit(Renderer::Uninitialize); CallOnExit onExit(Renderer::Uninitialize);
struct RendererImplementations
{
std::filesystem::path fileName;
int score;
};
std::vector<RendererImplementations> implementations;
auto RegisterImpl = [&](std::filesystem::path fileName, auto ComputeScore)
{
fileName.replace_extension(NAZARA_DYNLIB_EXTENSION);
int score = ComputeScore();
if (score >= 0)
{
auto& impl = implementations.emplace_back();
impl.fileName = std::move(fileName);
impl.score = score;
}
};
RegisterImpl("NazaraOpenGLRenderer" NazaraRendererDebugSuffix, [] { return 50; });
RegisterImpl("NazaraVulkanRenderer" NazaraRendererDebugSuffix, [] { return 100; });
std::sort(implementations.begin(), implementations.end(), [](const auto& lhs, const auto& rhs) { return lhs.score > rhs.score; });
NazaraDebug("Searching for renderer implementation"); NazaraDebug("Searching for renderer implementation");
DynLib chosenLib; DynLib chosenLib;
std::unique_ptr<RendererImpl> chosenImpl; std::unique_ptr<RendererImpl> chosenImpl;
for (auto&& entry : std::filesystem::directory_iterator(".")) for (auto&& rendererImpl : implementations)
{ {
if (!entry.is_regular_file()) if (!std::filesystem::exists(rendererImpl.fileName))
continue; continue;
const std::filesystem::path& entryPath = entry.path(); std::string fileNameStr = rendererImpl.fileName.generic_u8string();
std::filesystem::path fileName = entryPath.filename();
std::string fileNameStr = fileName.generic_u8string();
if (!MatchPattern(fileNameStr, NazaraRendererPattern))
continue;
NazaraDebug("Trying to load " + fileNameStr);
DynLib implLib; DynLib implLib;
if (!implLib.Load(entryPath)) if (!implLib.Load(rendererImpl.fileName))
{ {
NazaraWarning("Failed to load " + fileNameStr + ": " + implLib.GetLastError()); NazaraWarning("Failed to load " + fileNameStr + ": " + implLib.GetLastError());
continue; continue;
@ -87,16 +106,10 @@ namespace Nz
continue; continue;
} }
NazaraDebug("Loaded " + impl->QueryAPIString()); NazaraDebug("Loaded " + fileNameStr);
if (!chosenImpl || impl->IsBetterThan(chosenImpl.get())) chosenImpl = std::move(impl); //< Move (and delete previous) implementation before unloading library
{ chosenLib = std::move(implLib);
if (chosenImpl)
NazaraDebug("Choose " + impl->QueryAPIString() + " over " + chosenImpl->QueryAPIString());
chosenImpl = std::move(impl); //< Move (and delete previous) implementation before unloading library
chosenLib = std::move(implLib);
}
} }
if (!chosenImpl) if (!chosenImpl)

View File

@ -36,14 +36,6 @@ namespace Nz
return Vulkan::SelectDevice(m_physDevices[deviceIndex]); return Vulkan::SelectDevice(m_physDevices[deviceIndex]);
} }
bool VulkanRenderer::IsBetterThan(const RendererImpl* other) const
{
if (other->QueryAPI() == RenderAPI::Vulkan && QueryAPIVersion() < other->QueryAPIVersion())
return false;
return true; //< Vulkan FTW
}
bool VulkanRenderer::Prepare(const ParameterList& parameters) bool VulkanRenderer::Prepare(const ParameterList& parameters)
{ {
return Vulkan::Initialize(APIVersion, parameters); return Vulkan::Initialize(APIVersion, parameters);