[App] Rework graphics system creation.

This commit is contained in:
gibbed 2019-08-03 16:42:38 -05:00
parent 890a32bd98
commit 848e2a4088
5 changed files with 53 additions and 33 deletions

View File

@ -65,6 +65,43 @@ DEFINE_bool(discord, true, "Enable Discord rich presence", "General");
namespace xe { namespace xe {
namespace app { namespace app {
template <class T>
struct Factory {
std::string name;
std::function<bool()> is_available;
std::function<std::unique_ptr<T>()> instantiate;
template <class DT>
static Factory Define(const std::string& name) {
return {name, DT::IsAvailable,
[]() { return std::unique_ptr<DT>(new DT); }};
}
static std::unique_ptr<T> Create(const std::string& name,
const std::vector<Factory>& factories) {
if (!name.empty() && name != "any") {
auto it = std::find_if(
factories.begin(), factories.end(),
[&name](const auto& f) { return name.compare(f.name) == 0; });
if (it != factories.end() && (*it).is_available()) {
return (*it).instantiate();
}
return nullptr;
} else {
// Create best available.
std::unique_ptr<T> best;
for (const auto& factory : factories) {
if (!factory.is_available()) continue;
best = factory.instantiate();
if (!best) continue;
return best;
}
// Nothing!
return nullptr;
}
}
};
std::unique_ptr<apu::AudioSystem> CreateAudioSystem(cpu::Processor* processor) { std::unique_ptr<apu::AudioSystem> CreateAudioSystem(cpu::Processor* processor) {
if (cvars::apu.compare("nop") == 0) { if (cvars::apu.compare("nop") == 0) {
return apu::nop::NopAudioSystem::Create(processor); return apu::nop::NopAudioSystem::Create(processor);
@ -89,39 +126,18 @@ std::unique_ptr<apu::AudioSystem> CreateAudioSystem(cpu::Processor* processor) {
} }
std::unique_ptr<gpu::GraphicsSystem> CreateGraphicsSystem() { std::unique_ptr<gpu::GraphicsSystem> CreateGraphicsSystem() {
if (cvars::gpu.compare("vulkan") == 0) { using NullGS = gpu::null::NullGraphicsSystem;
return std::unique_ptr<gpu::GraphicsSystem>( using D3D12GS = gpu::d3d12::D3D12GraphicsSystem;
new xe::gpu::vulkan::VulkanGraphicsSystem()); using VulkanGS = gpu::vulkan::VulkanGraphicsSystem;
using Factory = Factory<gpu::GraphicsSystem>;
std::vector<Factory> factories = {
#if XE_PLATFORM_WIN32 #if XE_PLATFORM_WIN32
} else if (cvars::gpu.compare("d3d12") == 0) { Factory::Define<D3D12GS>("d3d12"),
return std::unique_ptr<gpu::GraphicsSystem>(
new xe::gpu::d3d12::D3D12GraphicsSystem());
#endif // XE_PLATFORM_WIN32 #endif // XE_PLATFORM_WIN32
} else if (cvars::gpu.compare("null") == 0) { Factory::Define<VulkanGS>("vulkan"),
return std::unique_ptr<gpu::GraphicsSystem>( Factory::Define<NullGS>("null"),
new xe::gpu::null::NullGraphicsSystem()); };
} else { return Factory::Create(cvars::gpu, factories);
// Create best available.
std::unique_ptr<gpu::GraphicsSystem> best;
#if XE_PLATFORM_WIN32
if (xe::gpu::d3d12::D3D12GraphicsSystem::IsD3D12APIAvailable()) {
best = std::unique_ptr<gpu::GraphicsSystem>(
new xe::gpu::d3d12::D3D12GraphicsSystem());
if (best) {
return best;
}
}
#endif // XE_PLATFORM_WIN32
best = std::unique_ptr<gpu::GraphicsSystem>(
new xe::gpu::vulkan::VulkanGraphicsSystem());
if (best) {
return best;
}
// Nothing!
return nullptr;
}
} }
std::vector<std::unique_ptr<hid::InputDriver>> CreateInputDrivers( std::vector<std::unique_ptr<hid::InputDriver>> CreateInputDrivers(

View File

@ -27,7 +27,7 @@ D3D12GraphicsSystem::D3D12GraphicsSystem() {}
D3D12GraphicsSystem::~D3D12GraphicsSystem() {} D3D12GraphicsSystem::~D3D12GraphicsSystem() {}
bool D3D12GraphicsSystem::IsD3D12APIAvailable() { bool D3D12GraphicsSystem::IsAvailable() {
return xe::ui::d3d12::D3D12Provider::IsD3D12APIAvailable(); return xe::ui::d3d12::D3D12Provider::IsD3D12APIAvailable();
} }

View File

@ -26,7 +26,7 @@ class D3D12GraphicsSystem : public GraphicsSystem {
D3D12GraphicsSystem(); D3D12GraphicsSystem();
~D3D12GraphicsSystem() override; ~D3D12GraphicsSystem() override;
static bool IsD3D12APIAvailable(); static bool IsAvailable();
std::wstring name() const override; std::wstring name() const override;

View File

@ -24,6 +24,8 @@ class NullGraphicsSystem : public GraphicsSystem {
NullGraphicsSystem(); NullGraphicsSystem();
~NullGraphicsSystem() override; ~NullGraphicsSystem() override;
static bool IsAvailable() { return true; }
std::wstring name() const override { return L"null"; } std::wstring name() const override { return L"null"; }
X_STATUS Setup(cpu::Processor* processor, kernel::KernelState* kernel_state, X_STATUS Setup(cpu::Processor* processor, kernel::KernelState* kernel_state,

View File

@ -24,6 +24,8 @@ class VulkanGraphicsSystem : public GraphicsSystem {
VulkanGraphicsSystem(); VulkanGraphicsSystem();
~VulkanGraphicsSystem() override; ~VulkanGraphicsSystem() override;
static bool IsAvailable() { return true; }
std::wstring name() const override { return L"Vulkan"; } std::wstring name() const override { return L"Vulkan"; }
X_STATUS Setup(cpu::Processor* processor, kernel::KernelState* kernel_state, X_STATUS Setup(cpu::Processor* processor, kernel::KernelState* kernel_state,