Settings: Add GPU adapter option and hook up to D3D11/Vulkan

This commit is contained in:
Connor McLaughlin 2020-06-20 03:33:57 +10:00
parent 1b5f8db2fc
commit 77291096db
23 changed files with 150 additions and 93 deletions

View file

@ -31,6 +31,7 @@ void Settings::Load(SettingsInterface& si)
gpu_renderer = ParseRendererName(si.GetStringValue("GPU", "Renderer", GetRendererName(DEFAULT_GPU_RENDERER)).c_str()) gpu_renderer = ParseRendererName(si.GetStringValue("GPU", "Renderer", GetRendererName(DEFAULT_GPU_RENDERER)).c_str())
.value_or(DEFAULT_GPU_RENDERER); .value_or(DEFAULT_GPU_RENDERER);
gpu_adapter = si.GetStringValue("GPU", "Adapter", "");
gpu_resolution_scale = static_cast<u32>(si.GetIntValue("GPU", "ResolutionScale", 1)); gpu_resolution_scale = static_cast<u32>(si.GetIntValue("GPU", "ResolutionScale", 1));
gpu_use_debug_device = si.GetBoolValue("GPU", "UseDebugDevice", false); gpu_use_debug_device = si.GetBoolValue("GPU", "UseDebugDevice", false);
gpu_true_color = si.GetBoolValue("GPU", "TrueColor", true); gpu_true_color = si.GetBoolValue("GPU", "TrueColor", true);
@ -128,6 +129,7 @@ void Settings::Save(SettingsInterface& si) const
si.SetStringValue("CPU", "ExecutionMode", GetCPUExecutionModeName(cpu_execution_mode)); si.SetStringValue("CPU", "ExecutionMode", GetCPUExecutionModeName(cpu_execution_mode));
si.SetStringValue("GPU", "Renderer", GetRendererName(gpu_renderer)); si.SetStringValue("GPU", "Renderer", GetRendererName(gpu_renderer));
si.SetStringValue("GPU", "Adapter", gpu_adapter.c_str());
si.SetIntValue("GPU", "ResolutionScale", static_cast<long>(gpu_resolution_scale)); si.SetIntValue("GPU", "ResolutionScale", static_cast<long>(gpu_resolution_scale));
si.SetBoolValue("GPU", "UseDebugDevice", gpu_use_debug_device); si.SetBoolValue("GPU", "UseDebugDevice", gpu_use_debug_device);
si.SetBoolValue("GPU", "TrueColor", gpu_true_color); si.SetBoolValue("GPU", "TrueColor", gpu_true_color);

View file

@ -48,6 +48,7 @@ struct Settings
bool load_memory_cards_from_save_states = false; bool load_memory_cards_from_save_states = false;
GPURenderer gpu_renderer = GPURenderer::Software; GPURenderer gpu_renderer = GPURenderer::Software;
std::string gpu_adapter;
u32 gpu_resolution_scale = 1; u32 gpu_resolution_scale = 1;
bool gpu_use_debug_device = false; bool gpu_use_debug_device = false;
bool gpu_true_color = true; bool gpu_true_color = true;

View file

@ -59,11 +59,14 @@ bool D3D11HostDisplay::hasDeviceContext() const
return m_interface.HasContext(); return m_interface.HasContext();
} }
bool D3D11HostDisplay::createDeviceContext(bool debug_device) bool D3D11HostDisplay::createDeviceContext(const QString& adapter_name, bool debug_device)
{ {
std::optional<WindowInfo> wi = getWindowInfo(); std::optional<WindowInfo> wi = getWindowInfo();
if (!wi || !m_interface.CreateContextAndSwapChain(wi.value(), shouldUseFlipModelSwapChain(), debug_device)) if (!wi || !m_interface.CreateContextAndSwapChain(wi.value(), adapter_name.toStdString(),
shouldUseFlipModelSwapChain(), debug_device))
{
return false; return false;
}
m_window_width = static_cast<s32>(m_interface.GetSwapChainWidth()); m_window_width = static_cast<s32>(m_interface.GetSwapChainWidth());
m_window_height = static_cast<s32>(m_interface.GetSwapChainHeight()); m_window_height = static_cast<s32>(m_interface.GetSwapChainHeight());

View file

@ -15,7 +15,7 @@ public:
~D3D11HostDisplay(); ~D3D11HostDisplay();
bool hasDeviceContext() const override; bool hasDeviceContext() const override;
bool createDeviceContext(bool debug_device) override; bool createDeviceContext(const QString& adapter_name, bool debug_device) override;
bool initializeDeviceContext(std::string_view shader_cache_directory, bool debug_device) override; bool initializeDeviceContext(std::string_view shader_cache_directory, bool debug_device) override;
bool activateDeviceContext() override; bool activateDeviceContext() override;
void deactivateDeviceContext() override; void deactivateDeviceContext() override;

View file

@ -1,9 +1,9 @@
#include "mainwindow.h" #include "mainwindow.h"
#include "aboutdialog.h"
#include "common/assert.h" #include "common/assert.h"
#include "core/game_list.h" #include "core/game_list.h"
#include "core/settings.h" #include "core/settings.h"
#include "core/system.h" #include "core/system.h"
#include "aboutdialog.h"
#include "gamelistsettingswidget.h" #include "gamelistsettingswidget.h"
#include "gamelistwidget.h" #include "gamelistwidget.h"
#include "gamepropertiesdialog.h" #include "gamepropertiesdialog.h"
@ -69,7 +69,8 @@ bool MainWindow::confirmMessage(const QString& message)
return (result == QMessageBox::Yes); return (result == QMessageBox::Yes);
} }
void MainWindow::createDisplay(QThread* worker_thread, bool use_debug_device, bool fullscreen, bool render_to_main) void MainWindow::createDisplay(QThread* worker_thread, const QString& adapter_name, bool use_debug_device,
bool fullscreen, bool render_to_main)
{ {
Assert(!m_host_display && !m_display_widget); Assert(!m_host_display && !m_display_widget);
Assert(!fullscreen || !render_to_main); Assert(!fullscreen || !render_to_main);
@ -97,7 +98,7 @@ void MainWindow::createDisplay(QThread* worker_thread, bool use_debug_device, bo
// we need the surface visible.. this might be able to be replaced with something else // we need the surface visible.. this might be able to be replaced with something else
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
if (!m_host_display->createDeviceContext(use_debug_device)) if (!m_host_display->createDeviceContext(adapter_name, use_debug_device))
{ {
reportError(tr("Failed to create host display device context.")); reportError(tr("Failed to create host display device context."));
return; return;

View file

@ -29,7 +29,8 @@ private Q_SLOTS:
void reportError(const QString& message); void reportError(const QString& message);
void reportMessage(const QString& message); void reportMessage(const QString& message);
bool confirmMessage(const QString& message); bool confirmMessage(const QString& message);
void createDisplay(QThread* worker_thread, bool use_debug_device, bool fullscreen, bool render_to_main); void createDisplay(QThread* worker_thread, const QString& adapter_name, bool use_debug_device, bool fullscreen,
bool render_to_main);
void updateDisplay(QThread* worker_thread, bool fullscreen, bool render_to_main); void updateDisplay(QThread* worker_thread, bool fullscreen, bool render_to_main);
void destroyDisplay(); void destroyDisplay();
void focusDisplayWidget(); void focusDisplayWidget();

View file

@ -188,7 +188,7 @@ bool OpenGLHostDisplay::hasDeviceContext() const
return static_cast<bool>(m_gl_context); return static_cast<bool>(m_gl_context);
} }
bool OpenGLHostDisplay::createDeviceContext(bool debug_device) bool OpenGLHostDisplay::createDeviceContext(const QString& adapter_name, bool debug_device)
{ {
m_window_width = m_widget->scaledWindowWidth(); m_window_width = m_widget->scaledWindowWidth();
m_window_height = m_widget->scaledWindowHeight(); m_window_height = m_widget->scaledWindowHeight();

View file

@ -26,7 +26,7 @@ public:
~OpenGLHostDisplay(); ~OpenGLHostDisplay();
bool hasDeviceContext() const override; bool hasDeviceContext() const override;
bool createDeviceContext(bool debug_device) override; bool createDeviceContext(const QString& adapter_name, bool debug_device) override;
bool initializeDeviceContext(std::string_view shader_cache_directory, bool debug_device) override; bool initializeDeviceContext(std::string_view shader_cache_directory, bool debug_device) override;
bool activateDeviceContext() override; bool activateDeviceContext() override;
void deactivateDeviceContext() override; void deactivateDeviceContext() override;

View file

@ -42,7 +42,7 @@ bool QtHostDisplay::hasDeviceContext() const
return false; return false;
} }
bool QtHostDisplay::createDeviceContext(bool debug_device) bool QtHostDisplay::createDeviceContext(const QString& adapter_name, bool debug_device)
{ {
return false; return false;
} }

View file

@ -5,6 +5,7 @@
#include <optional> #include <optional>
#include <string_view> #include <string_view>
class QString;
class QThread; class QThread;
class QWidget; class QWidget;
@ -24,7 +25,7 @@ public:
virtual void destroyWidget(); virtual void destroyWidget();
virtual bool hasDeviceContext() const; virtual bool hasDeviceContext() const;
virtual bool createDeviceContext(bool debug_device); virtual bool createDeviceContext(const QString& adapter_name, bool debug_device);
virtual bool initializeDeviceContext(std::string_view shader_cache_directory, bool debug_device); virtual bool initializeDeviceContext(std::string_view shader_cache_directory, bool debug_device);
virtual bool activateDeviceContext(); virtual bool activateDeviceContext();
virtual void deactivateDeviceContext(); virtual void deactivateDeviceContext();

View file

@ -316,8 +316,8 @@ bool QtHostInterface::AcquireHostDisplay()
Assert(!m_display); Assert(!m_display);
m_is_rendering_to_main = getSettingValue("Main/RenderToMainWindow", true).toBool(); m_is_rendering_to_main = getSettingValue("Main/RenderToMainWindow", true).toBool();
emit createDisplayRequested(m_worker_thread, m_settings.gpu_use_debug_device, m_is_fullscreen, emit createDisplayRequested(m_worker_thread, QString::fromStdString(m_settings.gpu_adapter),
m_is_rendering_to_main); m_settings.gpu_use_debug_device, m_is_fullscreen, m_is_rendering_to_main);
Assert(m_display); Assert(m_display);
if (!getHostDisplay()->hasDeviceContext()) if (!getHostDisplay()->hasDeviceContext())

View file

@ -96,7 +96,8 @@ Q_SIGNALS:
void emulationPaused(bool paused); void emulationPaused(bool paused);
void stateSaved(const QString& game_code, bool global, qint32 slot); void stateSaved(const QString& game_code, bool global, qint32 slot);
void gameListRefreshed(); void gameListRefreshed();
void createDisplayRequested(QThread* worker_thread, bool use_debug_device, bool fullscreen, bool render_to_main); void createDisplayRequested(QThread* worker_thread, const QString& adapter_name, bool use_debug_device,
bool fullscreen, bool render_to_main);
void updateDisplayRequested(QThread* worker_thread, bool fullscreen, bool render_to_main); void updateDisplayRequested(QThread* worker_thread, bool fullscreen, bool render_to_main);
void focusDisplayWidgetRequested(); void focusDisplayWidgetRequested();
void destroyDisplayRequested(); void destroyDisplayRequested();

View file

@ -52,10 +52,10 @@ bool VulkanHostDisplay::hasDeviceContext() const
return m_vulkan_display.HasContext(); return m_vulkan_display.HasContext();
} }
bool VulkanHostDisplay::createDeviceContext(bool debug_device) bool VulkanHostDisplay::createDeviceContext(const QString& adapter_name, bool debug_device)
{ {
std::optional<WindowInfo> wi = getWindowInfo(); std::optional<WindowInfo> wi = getWindowInfo();
if (!wi || !m_vulkan_display.CreateContextAndSwapChain(wi.value(), debug_device)) if (!wi || !m_vulkan_display.CreateContextAndSwapChain(wi.value(), adapter_name.toStdString(), debug_device))
return false; return false;
m_window_width = static_cast<s32>(m_vulkan_display.GetSwapChainWidth()); m_window_width = static_cast<s32>(m_vulkan_display.GetSwapChainWidth());

View file

@ -15,7 +15,7 @@ public:
~VulkanHostDisplay(); ~VulkanHostDisplay();
bool hasDeviceContext() const override; bool hasDeviceContext() const override;
bool createDeviceContext(bool debug_device) override; bool createDeviceContext(const QString& adapter_name, bool debug_device) override;
bool initializeDeviceContext(std::string_view shader_cache_directory, bool debug_device) override; bool initializeDeviceContext(std::string_view shader_cache_directory, bool debug_device) override;
bool activateDeviceContext() override; bool activateDeviceContext() override;
void deactivateDeviceContext() override; void deactivateDeviceContext() override;

View file

@ -18,10 +18,10 @@ SDLD3D11HostDisplay::~SDLD3D11HostDisplay()
SDL_DestroyWindow(m_window); SDL_DestroyWindow(m_window);
} }
std::unique_ptr<HostDisplay> SDLD3D11HostDisplay::Create(SDL_Window* window, bool debug_device) std::unique_ptr<HostDisplay> SDLD3D11HostDisplay::Create(SDL_Window* window, std::string_view adapter_name, bool debug_device)
{ {
std::unique_ptr<SDLD3D11HostDisplay> display = std::make_unique<SDLD3D11HostDisplay>(window); std::unique_ptr<SDLD3D11HostDisplay> display = std::make_unique<SDLD3D11HostDisplay>(window);
if (!display->Initialize(debug_device)) if (!display->Initialize(adapter_name, debug_device))
return {}; return {};
return display; return display;
@ -74,13 +74,13 @@ void SDLD3D11HostDisplay::SetVSync(bool enabled)
m_interface.SetVSync(enabled); m_interface.SetVSync(enabled);
} }
bool SDLD3D11HostDisplay::Initialize(bool debug_device) bool SDLD3D11HostDisplay::Initialize(std::string_view adapter_name, bool debug_device)
{ {
std::optional<WindowInfo> wi = SDLUtil::GetWindowInfoForSDLWindow(m_window); std::optional<WindowInfo> wi = SDLUtil::GetWindowInfoForSDLWindow(m_window);
if (!wi.has_value()) if (!wi.has_value())
return false; return false;
if (!m_interface.CreateContextAndSwapChain(wi.value(), true, debug_device)) if (!m_interface.CreateContextAndSwapChain(wi.value(), adapter_name, true, debug_device))
return false; return false;
if (!m_interface.CreateResources()) if (!m_interface.CreateResources())

View file

@ -12,7 +12,7 @@ public:
SDLD3D11HostDisplay(SDL_Window* window); SDLD3D11HostDisplay(SDL_Window* window);
~SDLD3D11HostDisplay(); ~SDLD3D11HostDisplay();
static std::unique_ptr<HostDisplay> Create(SDL_Window* window, bool debug_device); static std::unique_ptr<HostDisplay> Create(SDL_Window* window, std::string_view adapter_name, bool debug_device);
RenderAPI GetRenderAPI() const override; RenderAPI GetRenderAPI() const override;
void* GetRenderDevice() const override; void* GetRenderDevice() const override;
@ -35,5 +35,5 @@ private:
FrontendCommon::D3D11HostDisplay m_interface; FrontendCommon::D3D11HostDisplay m_interface;
bool Initialize(bool debug_device); bool Initialize(std::string_view adapter_name, bool debug_device);
}; };

View file

@ -129,27 +129,27 @@ void SDLHostInterface::DestroySDLWindow()
bool SDLHostInterface::CreateDisplay() bool SDLHostInterface::CreateDisplay()
{ {
const bool debug_device = m_settings.gpu_use_debug_device;
const std::string shader_cache_directory(GetShaderCacheDirectory()); const std::string shader_cache_directory(GetShaderCacheDirectory());
std::unique_ptr<HostDisplay> display; std::unique_ptr<HostDisplay> display;
switch (m_settings.gpu_renderer) switch (m_settings.gpu_renderer)
{ {
case GPURenderer::HardwareVulkan: case GPURenderer::HardwareVulkan:
display = SDLVulkanHostDisplay::Create(m_window, shader_cache_directory, debug_device); display = SDLVulkanHostDisplay::Create(m_window, m_settings.gpu_adapter, shader_cache_directory,
m_settings.gpu_use_debug_device);
break; break;
case GPURenderer::HardwareOpenGL: case GPURenderer::HardwareOpenGL:
#ifndef WIN32 #ifndef WIN32
default: default:
#endif #endif
display = OpenGLHostDisplay::Create(m_window, debug_device); display = OpenGLHostDisplay::Create(m_window, m_settings.gpu_use_debug_device);
break; break;
#ifdef WIN32 #ifdef WIN32
case GPURenderer::HardwareD3D11: case GPURenderer::HardwareD3D11:
default: default:
display = SDLD3D11HostDisplay::Create(m_window, debug_device); display = SDLD3D11HostDisplay::Create(m_window, m_settings.gpu_adapter, m_settings.gpu_use_debug_device);
break; break;
#endif #endif
} }

View file

@ -27,11 +27,11 @@ SDLVulkanHostDisplay::~SDLVulkanHostDisplay()
SDL_DestroyWindow(m_window); SDL_DestroyWindow(m_window);
} }
std::unique_ptr<HostDisplay> SDLVulkanHostDisplay::Create(SDL_Window* window, std::string_view shader_cache_directory, std::unique_ptr<HostDisplay> SDLVulkanHostDisplay::Create(SDL_Window* window, std::string_view adapter_name,
bool debug_device) std::string_view shader_cache_directory, bool debug_device)
{ {
std::unique_ptr<SDLVulkanHostDisplay> display = std::make_unique<SDLVulkanHostDisplay>(window); std::unique_ptr<SDLVulkanHostDisplay> display = std::make_unique<SDLVulkanHostDisplay>(window);
if (!display->Initialize(shader_cache_directory, debug_device)) if (!display->Initialize(adapter_name, shader_cache_directory, debug_device))
return nullptr; return nullptr;
return display; return display;
@ -84,7 +84,8 @@ void SDLVulkanHostDisplay::SetVSync(bool enabled)
m_display.SetVSync(enabled); m_display.SetVSync(enabled);
} }
bool SDLVulkanHostDisplay::Initialize(std::string_view shader_cache_directory, bool debug_device) bool SDLVulkanHostDisplay::Initialize(std::string_view adapter_name, std::string_view shader_cache_directory,
bool debug_device)
{ {
std::optional<WindowInfo> wi = SDLUtil::GetWindowInfoForSDLWindow(m_window); std::optional<WindowInfo> wi = SDLUtil::GetWindowInfoForSDLWindow(m_window);
if (!wi.has_value()) if (!wi.has_value())
@ -93,7 +94,7 @@ bool SDLVulkanHostDisplay::Initialize(std::string_view shader_cache_directory, b
return false; return false;
} }
if (!m_display.CreateContextAndSwapChain(wi.value(), debug_device)) if (!m_display.CreateContextAndSwapChain(wi.value(), adapter_name, debug_device))
return false; return false;
m_display.CreateShaderCache(shader_cache_directory, debug_device); m_display.CreateShaderCache(shader_cache_directory, debug_device);

View file

@ -10,8 +10,8 @@ public:
SDLVulkanHostDisplay(SDL_Window* window); SDLVulkanHostDisplay(SDL_Window* window);
~SDLVulkanHostDisplay(); ~SDLVulkanHostDisplay();
static std::unique_ptr<HostDisplay> Create(SDL_Window* window, std::string_view shader_cache_directory, static std::unique_ptr<HostDisplay> Create(SDL_Window* window, std::string_view adapter_name,
bool debug_device); std::string_view shader_cache_directory, bool debug_device);
RenderAPI GetRenderAPI() const override; RenderAPI GetRenderAPI() const override;
void* GetRenderDevice() const override; void* GetRenderDevice() const override;
@ -33,7 +33,7 @@ public:
void Render() override; void Render() override;
private: private:
bool Initialize(std::string_view shader_cache_directory, bool debug_device); bool Initialize(std::string_view adapter_name, std::string_view shader_cache_directory, bool debug_device);
SDL_Window* m_window = nullptr; SDL_Window* m_window = nullptr;
FrontendCommon::VulkanHostDisplay m_display; FrontendCommon::VulkanHostDisplay m_display;

View file

@ -140,14 +140,55 @@ bool D3D11HostDisplay::HasContext() const
return static_cast<bool>(m_device); return static_cast<bool>(m_device);
} }
bool D3D11HostDisplay::CreateContextAndSwapChain(const WindowInfo& wi, bool use_flip_model, bool debug_device) bool D3D11HostDisplay::CreateContextAndSwapChain(const WindowInfo& wi, std::string_view adapter_name,
bool use_flip_model, bool debug_device)
{ {
UINT create_flags = 0; UINT create_flags = 0;
if (debug_device) if (debug_device)
create_flags |= D3D11_CREATE_DEVICE_DEBUG; create_flags |= D3D11_CREATE_DEVICE_DEBUG;
HRESULT hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, create_flags, nullptr, 0, ComPtr<IDXGIFactory> temp_dxgi_factory;
D3D11_SDK_VERSION, m_device.GetAddressOf(), nullptr, m_context.GetAddressOf()); HRESULT hr = CreateDXGIFactory(IID_PPV_ARGS(temp_dxgi_factory.GetAddressOf()));
if (FAILED(hr))
{
Log_ErrorPrintf("Failed to create DXGI factory: 0x%08X", hr);
return false;
}
u32 adapter_index;
if (!adapter_name.empty())
{
std::vector<std::string> adapter_names = EnumerateAdapterNames(temp_dxgi_factory.Get());
for (adapter_index = 0; adapter_index < static_cast<u32>(adapter_names.size()); adapter_index++)
{
if (adapter_name == adapter_names[adapter_index])
break;
}
if (adapter_index == static_cast<u32>(adapter_names.size()))
{
Log_WarningPrintf("Could not find adapter '%s', using first (%s)", std::string(adapter_name).c_str(),
adapter_names[0].c_str());
adapter_index = 0;
}
}
else
{
Log_InfoPrintf("No adapter selected, using first.");
adapter_index = 0;
}
ComPtr<IDXGIAdapter> dxgi_adapter;
hr = temp_dxgi_factory->EnumAdapters(adapter_index, dxgi_adapter.GetAddressOf());
if (FAILED(hr))
Log_WarningPrintf("Failed to enumerate adapter %u, using default", adapter_index);
hr = D3D11CreateDevice(dxgi_adapter.Get(), dxgi_adapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE, nullptr,
create_flags, nullptr, 0, D3D11_SDK_VERSION, m_device.GetAddressOf(), nullptr,
m_context.GetAddressOf());
// we re-grab these later, see below
dxgi_adapter.Reset();
temp_dxgi_factory.Reset();
if (FAILED(hr)) if (FAILED(hr))
{ {
@ -168,7 +209,6 @@ bool D3D11HostDisplay::CreateContextAndSwapChain(const WindowInfo& wi, bool use_
// we need the specific factory for the device, otherwise MakeWindowAssociation() is flaky. // we need the specific factory for the device, otherwise MakeWindowAssociation() is flaky.
ComPtr<IDXGIDevice> dxgi_device; ComPtr<IDXGIDevice> dxgi_device;
ComPtr<IDXGIAdapter> dxgi_adapter;
if (FAILED(m_device.As(&dxgi_device)) || FAILED(dxgi_device->GetParent(IID_PPV_ARGS(dxgi_adapter.GetAddressOf()))) || if (FAILED(m_device.As(&dxgi_device)) || FAILED(dxgi_device->GetParent(IID_PPV_ARGS(dxgi_adapter.GetAddressOf()))) ||
FAILED(dxgi_adapter->GetParent(IID_PPV_ARGS(m_dxgi_factory.GetAddressOf())))) FAILED(dxgi_adapter->GetParent(IID_PPV_ARGS(m_dxgi_factory.GetAddressOf()))))
{ {
@ -482,8 +522,14 @@ std::vector<std::string> D3D11HostDisplay::EnumerateAdapterNames()
{ {
ComPtr<IDXGIFactory> dxgi_factory; ComPtr<IDXGIFactory> dxgi_factory;
HRESULT hr = CreateDXGIFactory(IID_PPV_ARGS(dxgi_factory.GetAddressOf())); HRESULT hr = CreateDXGIFactory(IID_PPV_ARGS(dxgi_factory.GetAddressOf()));
if (SUCCEEDED(hr)) if (FAILED(hr))
{ return {};
return EnumerateAdapterNames(dxgi_factory.Get());
}
std::vector<std::string> D3D11HostDisplay::EnumerateAdapterNames(IDXGIFactory* dxgi_factory)
{
std::vector<std::string> adapter_names; std::vector<std::string> adapter_names;
ComPtr<IDXGIAdapter> current_adapter; ComPtr<IDXGIAdapter> current_adapter;
while (SUCCEEDED( while (SUCCEEDED(
@ -525,11 +571,7 @@ std::vector<std::string> D3D11HostDisplay::EnumerateAdapterNames()
adapter_names.push_back(std::move(adapter_name)); adapter_names.push_back(std::move(adapter_name));
} }
if (!adapter_names.empty())
return adapter_names; return adapter_names;
}
return {"(Default)"};
} }
} // namespace FrontendCommon } // namespace FrontendCommon

View file

@ -8,9 +8,10 @@
#include <d3d11.h> #include <d3d11.h>
#include <dxgi.h> #include <dxgi.h>
#include <memory> #include <memory>
#include <wrl/client.h>
#include <vector>
#include <string> #include <string>
#include <string_view>
#include <vector>
#include <wrl/client.h>
namespace FrontendCommon { namespace FrontendCommon {
@ -27,7 +28,8 @@ public:
ALWAYS_INLINE void* GetRenderDevice() const { return m_device.Get(); } ALWAYS_INLINE void* GetRenderDevice() const { return m_device.Get(); }
ALWAYS_INLINE void* GetRenderContext() const { return m_context.Get(); } ALWAYS_INLINE void* GetRenderContext() const { return m_context.Get(); }
bool CreateContextAndSwapChain(const WindowInfo& wi, bool use_flip_model, bool debug_device); bool CreateContextAndSwapChain(const WindowInfo& wi, std::string_view adapter_name, bool use_flip_model,
bool debug_device);
bool HasContext() const; bool HasContext() const;
void DestroyContext(); void DestroyContext();
@ -67,6 +69,8 @@ public:
private: private:
static constexpr u32 DISPLAY_UNIFORM_BUFFER_SIZE = 16; static constexpr u32 DISPLAY_UNIFORM_BUFFER_SIZE = 16;
static std::vector<std::string> EnumerateAdapterNames(IDXGIFactory* dxgi_factory);
bool CreateSwapChain(const WindowInfo& new_wi, bool use_flip_model); bool CreateSwapChain(const WindowInfo& new_wi, bool use_flip_model);
bool CreateSwapChainRTV(); bool CreateSwapChainRTV();

View file

@ -192,9 +192,9 @@ void VulkanHostDisplay::SetVSync(bool enabled)
m_swap_chain->SetVSync(enabled); m_swap_chain->SetVSync(enabled);
} }
bool VulkanHostDisplay::CreateContextAndSwapChain(const WindowInfo& wi, bool debug_device) bool VulkanHostDisplay::CreateContextAndSwapChain(const WindowInfo& wi, std::string_view gpu_name, bool debug_device)
{ {
if (!Vulkan::Context::Create({}, &wi, &m_swap_chain, debug_device, false)) if (!Vulkan::Context::Create(gpu_name, &wi, &m_swap_chain, debug_device, false))
{ {
Log_ErrorPrintf("Failed to create Vulkan context"); Log_ErrorPrintf("Failed to create Vulkan context");
return false; return false;

View file

@ -41,7 +41,7 @@ public:
void RenderSoftwareCursor(s32 left, s32 top, s32 width, s32 height, HostDisplayTexture* texture_handle); void RenderSoftwareCursor(s32 left, s32 top, s32 width, s32 height, HostDisplayTexture* texture_handle);
void EndRenderAndPresent(); void EndRenderAndPresent();
bool CreateContextAndSwapChain(const WindowInfo& wi, bool debug_device); bool CreateContextAndSwapChain(const WindowInfo& wi, std::string_view gpu_name, bool debug_device);
bool HasContext() const; bool HasContext() const;
void DestroyContext(); void DestroyContext();