Renderer: Remake backend selection
This commit is contained in:
parent
6ffbfd9941
commit
8fa456bdf5
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue