System: Get rid of double popup on renderer create error

This commit is contained in:
Stenzek 2024-05-12 23:37:00 +10:00
parent 5808e14b7e
commit be920acf38
No known key found for this signature in database
4 changed files with 34 additions and 27 deletions

View file

@ -268,7 +268,7 @@ void Host::ReportFormattedDebuggerMessage(const char* format, ...)
ReportDebuggerMessage(message); ReportDebuggerMessage(message);
} }
bool Host::CreateGPUDevice(RenderAPI api) bool Host::CreateGPUDevice(RenderAPI api, Error* error)
{ {
DebugAssert(!g_gpu_device); DebugAssert(!g_gpu_device);
@ -292,29 +292,32 @@ bool Host::CreateGPUDevice(RenderAPI api)
if (g_settings.gpu_disable_texture_copy_to_self) if (g_settings.gpu_disable_texture_copy_to_self)
disabled_features |= GPUDevice::FEATURE_MASK_TEXTURE_COPY_TO_SELF; disabled_features |= GPUDevice::FEATURE_MASK_TEXTURE_COPY_TO_SELF;
Error error; Error create_error;
if (!g_gpu_device || !g_gpu_device->Create( if (!g_gpu_device || !g_gpu_device->Create(
g_settings.gpu_adapter, g_settings.gpu_adapter,
g_settings.gpu_disable_shader_cache ? std::string_view() : std::string_view(EmuFolders::Cache), g_settings.gpu_disable_shader_cache ? std::string_view() : std::string_view(EmuFolders::Cache),
SHADER_CACHE_VERSION, g_settings.gpu_use_debug_device, System::IsVSyncEffectivelyEnabled(), SHADER_CACHE_VERSION, g_settings.gpu_use_debug_device, System::IsVSyncEffectivelyEnabled(),
g_settings.gpu_threaded_presentation, exclusive_fullscreen_control, g_settings.gpu_threaded_presentation, exclusive_fullscreen_control,
static_cast<GPUDevice::FeatureMask>(disabled_features), &error)) static_cast<GPUDevice::FeatureMask>(disabled_features), &create_error))
{ {
Log_ErrorPrintf("Failed to create GPU device."); Log_ErrorFmt("Failed to create GPU device: {}", create_error.GetDescription());
if (g_gpu_device) if (g_gpu_device)
g_gpu_device->Destroy(); g_gpu_device->Destroy();
g_gpu_device.reset(); g_gpu_device.reset();
Host::ReportErrorAsync( Error::SetStringFmt(
"Error", fmt::format("Failed to create render device:\n\n{}\n\nThis may be due to your GPU not supporting the " error,
"chosen renderer ({}), or because your graphics drivers need to be updated.", TRANSLATE_FS("System", "Failed to create render device:\n\n{0}\n\nThis may be due to your GPU not supporting the "
error.GetDescription(), GPUDevice::RenderAPIToString(api))); "chosen renderer ({1}), or because your graphics drivers need to be updated."),
create_error.GetDescription(), GPUDevice::RenderAPIToString(api));
return false; return false;
} }
if (!ImGuiManager::Initialize(g_settings.display_osd_scale / 100.0f, g_settings.display_show_osd_messages, &error)) if (!ImGuiManager::Initialize(g_settings.display_osd_scale / 100.0f, g_settings.display_show_osd_messages,
&create_error))
{ {
Host::ReportErrorAsync("Error", fmt::format("Failed to initialize ImGuiManager: {}", error.GetDescription())); Log_ErrorFmt("Failed to initialize ImGuiManager: {}", create_error.GetDescription());
Error::SetStringFmt(error, "Failed to initialize ImGuiManager: {}", create_error.GetDescription());
g_gpu_device->Destroy(); g_gpu_device->Destroy();
g_gpu_device.reset(); g_gpu_device.reset();
return false; return false;
@ -379,4 +382,3 @@ void Host::ReleaseGPUDevice()
g_gpu_device->Destroy(); g_gpu_device->Destroy();
g_gpu_device.reset(); g_gpu_device.reset();
} }

View file

@ -18,6 +18,7 @@
#include <string_view> #include <string_view>
#include <vector> #include <vector>
class Error;
class SettingsInterface; class SettingsInterface;
struct WindowInfo; struct WindowInfo;
enum class AudioBackend : u8; enum class AudioBackend : u8;
@ -91,7 +92,7 @@ void DisplayLoadingScreen(const char* message, int progress_min = -1, int progre
void RunOnCPUThread(std::function<void()> function, bool block = false); void RunOnCPUThread(std::function<void()> function, bool block = false);
/// Attempts to create the rendering device backend. /// Attempts to create the rendering device backend.
bool CreateGPUDevice(RenderAPI api); bool CreateGPUDevice(RenderAPI api, Error* error);
/// Handles fullscreen transitions and such. /// Handles fullscreen transitions and such.
void UpdateDisplayWindow(); void UpdateDisplayWindow();

View file

@ -108,7 +108,7 @@ static void ClearRunningGame();
static void DestroySystem(); static void DestroySystem();
static std::string GetMediaPathFromSaveState(const char* path); static std::string GetMediaPathFromSaveState(const char* path);
static bool DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display, bool is_memory_state); static bool DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display, bool is_memory_state);
static bool CreateGPU(GPURenderer renderer, bool is_switching); static bool CreateGPU(GPURenderer renderer, bool is_switching, Error* error);
static bool SaveUndoLoadState(); static bool SaveUndoLoadState();
static void WarnAboutUnsafeSettings(); static void WarnAboutUnsafeSettings();
static void LogUnsafeSettingsToConsole(const SmallStringBase& messages); static void LogUnsafeSettingsToConsole(const SmallStringBase& messages);
@ -126,7 +126,7 @@ static void DoRewind();
static void SaveRunaheadState(); static void SaveRunaheadState();
static bool DoRunahead(); static bool DoRunahead();
static bool Initialize(bool force_software_renderer); static bool Initialize(bool force_software_renderer, Error* error);
static bool FastForwardToFirstFrame(); static bool FastForwardToFirstFrame();
static bool UpdateGameSettingsLayer(); static bool UpdateGameSettingsLayer();
@ -938,10 +938,11 @@ bool System::RecreateGPU(GPURenderer renderer, bool force_recreate_device, bool
Host::ReleaseGPUDevice(); Host::ReleaseGPUDevice();
} }
if (!CreateGPU(renderer, true)) Error error;
if (!CreateGPU(renderer, true, &error))
{ {
if (!IsStartupCancelled()) if (!IsStartupCancelled())
Host::ReportErrorAsync("Error", "Failed to recreate GPU."); Host::ReportErrorAsync("Error", error.GetDescription());
DestroySystem(); DestroySystem();
return false; return false;
@ -1474,7 +1475,7 @@ bool System::BootSystem(SystemBootParameters parameters, Error* error)
} }
// Component setup. // Component setup.
if (!Initialize(parameters.force_software_renderer)) if (!Initialize(parameters.force_software_renderer, error))
{ {
s_state = State::Shutdown; s_state = State::Shutdown;
ClearRunningGame(); ClearRunningGame();
@ -1579,7 +1580,7 @@ bool System::BootSystem(SystemBootParameters parameters, Error* error)
return true; return true;
} }
bool System::Initialize(bool force_software_renderer) bool System::Initialize(bool force_software_renderer, Error* error)
{ {
g_ticks_per_second = ScaleTicksToOverclock(MASTER_CLOCK); g_ticks_per_second = ScaleTicksToOverclock(MASTER_CLOCK);
s_max_slice_ticks = ScaleTicksToOverclock(MASTER_CLOCK / 10); s_max_slice_ticks = ScaleTicksToOverclock(MASTER_CLOCK / 10);
@ -1636,7 +1637,7 @@ bool System::Initialize(bool force_software_renderer)
CPU::CodeCache::Initialize(); CPU::CodeCache::Initialize();
if (!CreateGPU(force_software_renderer ? GPURenderer::Software : g_settings.gpu_renderer, false)) if (!CreateGPU(force_software_renderer ? GPURenderer::Software : g_settings.gpu_renderer, false, error))
{ {
Bus::Shutdown(); Bus::Shutdown();
CPU::Shutdown(); CPU::Shutdown();
@ -2076,7 +2077,7 @@ void System::RecreateSystem()
PauseSystem(true); PauseSystem(true);
} }
bool System::CreateGPU(GPURenderer renderer, bool is_switching) bool System::CreateGPU(GPURenderer renderer, bool is_switching, Error* error)
{ {
const RenderAPI api = Settings::GetRenderAPIForRenderer(renderer); const RenderAPI api = Settings::GetRenderAPIForRenderer(renderer);
@ -2085,13 +2086,13 @@ bool System::CreateGPU(GPURenderer renderer, bool is_switching)
{ {
if (g_gpu_device) if (g_gpu_device)
{ {
Log_WarningPrintf("Recreating GPU device, expecting %s got %s", GPUDevice::RenderAPIToString(api), Log_WarningFmt("Recreating GPU device, expecting {} got {}", GPUDevice::RenderAPIToString(api),
GPUDevice::RenderAPIToString(g_gpu_device->GetRenderAPI())); GPUDevice::RenderAPIToString(g_gpu_device->GetRenderAPI()));
PostProcessing::Shutdown(); PostProcessing::Shutdown();
} }
Host::ReleaseGPUDevice(); Host::ReleaseGPUDevice();
if (!Host::CreateGPUDevice(api)) if (!Host::CreateGPUDevice(api, error))
{ {
Host::ReleaseRenderWindow(); Host::ReleaseRenderWindow();
return false; return false;
@ -2108,8 +2109,8 @@ bool System::CreateGPU(GPURenderer renderer, bool is_switching)
if (!g_gpu) if (!g_gpu)
{ {
Log_ErrorPrintf("Failed to initialize %s renderer, falling back to software renderer", Log_ErrorFmt("Failed to initialize {} renderer, falling back to software renderer",
Settings::GetRendererName(renderer)); Settings::GetRendererName(renderer));
Host::AddFormattedOSDMessage( Host::AddFormattedOSDMessage(
30.0f, TRANSLATE("OSDMessage", "Failed to initialize %s renderer, falling back to software renderer."), 30.0f, TRANSLATE("OSDMessage", "Failed to initialize %s renderer, falling back to software renderer."),
Settings::GetRendererName(renderer)); Settings::GetRendererName(renderer));
@ -2117,7 +2118,7 @@ bool System::CreateGPU(GPURenderer renderer, bool is_switching)
g_gpu = GPU::CreateSoftwareRenderer(); g_gpu = GPU::CreateSoftwareRenderer();
if (!g_gpu) if (!g_gpu)
{ {
Log_ErrorPrintf("Failed to create fallback software renderer."); Log_ErrorPrint("Failed to create fallback software renderer.");
if (!s_keep_gpu_device_on_shutdown) if (!s_keep_gpu_device_on_shutdown)
{ {
PostProcessing::Shutdown(); PostProcessing::Shutdown();

View file

@ -718,8 +718,11 @@ void EmuThread::startFullscreenUI()
setInitialState(s_start_fullscreen_ui_fullscreen ? std::optional<bool>(true) : std::optional<bool>()); setInitialState(s_start_fullscreen_ui_fullscreen ? std::optional<bool>(true) : std::optional<bool>());
m_run_fullscreen_ui = true; m_run_fullscreen_ui = true;
if (!Host::CreateGPUDevice(Settings::GetRenderAPIForRenderer(g_settings.gpu_renderer)) || !FullscreenUI::Initialize()) Error error;
if (!Host::CreateGPUDevice(Settings::GetRenderAPIForRenderer(g_settings.gpu_renderer), &error) ||
!FullscreenUI::Initialize())
{ {
Host::ReportErrorAsync("Error", error.GetDescription());
Host::ReleaseGPUDevice(); Host::ReleaseGPUDevice();
Host::ReleaseRenderWindow(); Host::ReleaseRenderWindow();
m_run_fullscreen_ui = false; m_run_fullscreen_ui = false;