From 1ae2dcf1924f7801a60504d4d08b0b56f7c7f917 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 26 Oct 2024 01:41:26 +1000 Subject: [PATCH] GPU: Propagate initialization error to caller Avoids double error popup. --- src/core/gpu.cpp | 45 ++++++++++++++++++++++----------------------- src/core/gpu.h | 8 ++++---- src/core/gpu_hw.cpp | 18 +++++++----------- src/core/gpu_hw.h | 2 +- src/core/gpu_sw.cpp | 10 +++++----- src/core/gpu_sw.h | 2 +- src/core/system.cpp | 6 +++--- 7 files changed, 43 insertions(+), 48 deletions(-) diff --git a/src/core/gpu.cpp b/src/core/gpu.cpp index b4d764d56f..c5a12b6509 100644 --- a/src/core/gpu.cpp +++ b/src/core/gpu.cpp @@ -95,7 +95,7 @@ GPU::~GPU() g_gpu_device->RecycleTexture(std::move(m_chroma_smoothing_texture)); } -bool GPU::Initialize() +bool GPU::Initialize(Error* error) { if (!System::IsReplayingGPUDump()) s_crtc_tick_event.Activate(); @@ -107,11 +107,8 @@ bool GPU::Initialize() m_console_is_pal = System::IsPALRegion(); UpdateCRTCConfig(); - if (!CompileDisplayPipelines(true, true, g_settings.display_24bit_chroma_smoothing)) - { - Host::ReportErrorAsync("Error", "Failed to compile base GPU pipelines."); + if (!CompileDisplayPipelines(true, true, g_settings.display_24bit_chroma_smoothing, error)) return false; - } #ifdef PSX_GPU_STATS s_active_gpu_cycles = 0; @@ -152,7 +149,7 @@ void GPU::UpdateSettings(const Settings& old_settings) if (!CompileDisplayPipelines(g_settings.display_scaling != old_settings.display_scaling, g_settings.display_deinterlacing_mode != old_settings.display_deinterlacing_mode, g_settings.display_24bit_chroma_smoothing != - old_settings.display_24bit_chroma_smoothing)) + old_settings.display_24bit_chroma_smoothing, nullptr)) { Panic("Failed to compile display pipeline on settings change."); } @@ -1650,7 +1647,7 @@ void GPU::ReadCLUT(u16* dest, GPUTexturePaletteReg reg, bool clut_is_8bit) } } -bool GPU::CompileDisplayPipelines(bool display, bool deinterlace, bool chroma_smoothing) +bool GPU::CompileDisplayPipelines(bool display, bool deinterlace, bool chroma_smoothing, Error* error) { GPUShaderGen shadergen(g_gpu_device->GetRenderAPI(), g_gpu_device->GetFeatures().dual_source_blend, g_gpu_device->GetFeatures().framebuffer_fetch); @@ -1693,8 +1690,10 @@ bool GPU::CompileDisplayPipelines(bool display, bool deinterlace, bool chroma_sm break; } - std::unique_ptr vso = g_gpu_device->CreateShader(GPUShaderStage::Vertex, shadergen.GetLanguage(), vs); - std::unique_ptr fso = g_gpu_device->CreateShader(GPUShaderStage::Fragment, shadergen.GetLanguage(), fs); + std::unique_ptr vso = + g_gpu_device->CreateShader(GPUShaderStage::Vertex, shadergen.GetLanguage(), vs, error); + std::unique_ptr fso = + g_gpu_device->CreateShader(GPUShaderStage::Fragment, shadergen.GetLanguage(), fs, error); if (!vso || !fso) return false; GL_OBJECT_NAME(vso, "Display Vertex Shader"); @@ -1702,7 +1701,7 @@ bool GPU::CompileDisplayPipelines(bool display, bool deinterlace, bool chroma_sm Settings::GetDisplayScalingName(g_settings.display_scaling)); plconfig.vertex_shader = vso.get(); plconfig.fragment_shader = fso.get(); - if (!(m_display_pipeline = g_gpu_device->CreatePipeline(plconfig))) + if (!(m_display_pipeline = g_gpu_device->CreatePipeline(plconfig, error))) return false; GL_OBJECT_NAME_FMT(m_display_pipeline, "Display Pipeline [{}]", Settings::GetDisplayScalingName(g_settings.display_scaling)); @@ -1713,14 +1712,14 @@ bool GPU::CompileDisplayPipelines(bool display, bool deinterlace, bool chroma_sm plconfig.SetTargetFormats(GPUTexture::Format::RGBA8); std::unique_ptr vso = g_gpu_device->CreateShader(GPUShaderStage::Vertex, shadergen.GetLanguage(), - shadergen.GenerateScreenQuadVertexShader()); + shadergen.GenerateScreenQuadVertexShader(), error); if (!vso) return false; GL_OBJECT_NAME(vso, "Deinterlace Vertex Shader"); std::unique_ptr fso; if (!(fso = g_gpu_device->CreateShader(GPUShaderStage::Fragment, shadergen.GetLanguage(), - shadergen.GenerateInterleavedFieldExtractFragmentShader()))) + shadergen.GenerateInterleavedFieldExtractFragmentShader(), error))) { return false; } @@ -1730,7 +1729,7 @@ bool GPU::CompileDisplayPipelines(bool display, bool deinterlace, bool chroma_sm plconfig.layout = GPUPipeline::Layout::SingleTextureAndPushConstants; plconfig.vertex_shader = vso.get(); plconfig.fragment_shader = fso.get(); - if (!(m_deinterlace_extract_pipeline = g_gpu_device->CreatePipeline(plconfig))) + if (!(m_deinterlace_extract_pipeline = g_gpu_device->CreatePipeline(plconfig, error))) return false; GL_OBJECT_NAME(m_deinterlace_extract_pipeline, "Deinterlace Field Extract Pipeline"); @@ -1744,7 +1743,7 @@ bool GPU::CompileDisplayPipelines(bool display, bool deinterlace, bool chroma_sm case DisplayDeinterlacingMode::Weave: { if (!(fso = g_gpu_device->CreateShader(GPUShaderStage::Fragment, shadergen.GetLanguage(), - shadergen.GenerateDeinterlaceWeaveFragmentShader()))) + shadergen.GenerateDeinterlaceWeaveFragmentShader(), error))) { return false; } @@ -1754,7 +1753,7 @@ bool GPU::CompileDisplayPipelines(bool display, bool deinterlace, bool chroma_sm plconfig.layout = GPUPipeline::Layout::SingleTextureAndPushConstants; plconfig.vertex_shader = vso.get(); plconfig.fragment_shader = fso.get(); - if (!(m_deinterlace_pipeline = g_gpu_device->CreatePipeline(plconfig))) + if (!(m_deinterlace_pipeline = g_gpu_device->CreatePipeline(plconfig, error))) return false; GL_OBJECT_NAME(m_deinterlace_pipeline, "Weave Deinterlace Pipeline"); @@ -1764,7 +1763,7 @@ bool GPU::CompileDisplayPipelines(bool display, bool deinterlace, bool chroma_sm case DisplayDeinterlacingMode::Blend: { if (!(fso = g_gpu_device->CreateShader(GPUShaderStage::Fragment, shadergen.GetLanguage(), - shadergen.GenerateDeinterlaceBlendFragmentShader()))) + shadergen.GenerateDeinterlaceBlendFragmentShader(), error))) { return false; } @@ -1774,7 +1773,7 @@ bool GPU::CompileDisplayPipelines(bool display, bool deinterlace, bool chroma_sm plconfig.layout = GPUPipeline::Layout::MultiTextureAndPushConstants; plconfig.vertex_shader = vso.get(); plconfig.fragment_shader = fso.get(); - if (!(m_deinterlace_pipeline = g_gpu_device->CreatePipeline(plconfig))) + if (!(m_deinterlace_pipeline = g_gpu_device->CreatePipeline(plconfig, error))) return false; GL_OBJECT_NAME(m_deinterlace_pipeline, "Blend Deinterlace Pipeline"); @@ -1784,7 +1783,7 @@ bool GPU::CompileDisplayPipelines(bool display, bool deinterlace, bool chroma_sm case DisplayDeinterlacingMode::Adaptive: { fso = g_gpu_device->CreateShader(GPUShaderStage::Fragment, shadergen.GetLanguage(), - shadergen.GenerateFastMADReconstructFragmentShader()); + shadergen.GenerateFastMADReconstructFragmentShader(), error); if (!fso) return false; @@ -1792,7 +1791,7 @@ bool GPU::CompileDisplayPipelines(bool display, bool deinterlace, bool chroma_sm plconfig.layout = GPUPipeline::Layout::MultiTextureAndPushConstants; plconfig.fragment_shader = fso.get(); - if (!(m_deinterlace_pipeline = g_gpu_device->CreatePipeline(plconfig))) + if (!(m_deinterlace_pipeline = g_gpu_device->CreatePipeline(plconfig, error))) return false; GL_OBJECT_NAME(m_deinterlace_pipeline, "FastMAD Reconstruct Pipeline"); @@ -1815,9 +1814,9 @@ bool GPU::CompileDisplayPipelines(bool display, bool deinterlace, bool chroma_sm plconfig.SetTargetFormats(GPUTexture::Format::RGBA8); std::unique_ptr vso = g_gpu_device->CreateShader(GPUShaderStage::Vertex, shadergen.GetLanguage(), - shadergen.GenerateScreenQuadVertexShader()); - std::unique_ptr fso = g_gpu_device->CreateShader(GPUShaderStage::Fragment, shadergen.GetLanguage(), - shadergen.GenerateChromaSmoothingFragmentShader()); + shadergen.GenerateScreenQuadVertexShader(), error); + std::unique_ptr fso = g_gpu_device->CreateShader( + GPUShaderStage::Fragment, shadergen.GetLanguage(), shadergen.GenerateChromaSmoothingFragmentShader(), error); if (!vso || !fso) return false; GL_OBJECT_NAME(vso, "Chroma Smoothing Vertex Shader"); @@ -1825,7 +1824,7 @@ bool GPU::CompileDisplayPipelines(bool display, bool deinterlace, bool chroma_sm plconfig.vertex_shader = vso.get(); plconfig.fragment_shader = fso.get(); - if (!(m_chroma_smoothing_pipeline = g_gpu_device->CreatePipeline(plconfig))) + if (!(m_chroma_smoothing_pipeline = g_gpu_device->CreatePipeline(plconfig, error))) return false; GL_OBJECT_NAME(m_chroma_smoothing_pipeline, "Chroma Smoothing Pipeline"); } diff --git a/src/core/gpu.h b/src/core/gpu.h index d6b7f10dee..c8c6fbe0fd 100644 --- a/src/core/gpu.h +++ b/src/core/gpu.h @@ -92,7 +92,7 @@ class GPU virtual const Threading::Thread* GetSWThread() const = 0; virtual bool IsHardwareRenderer() const = 0; - virtual bool Initialize(); + virtual bool Initialize(Error* error); virtual void Reset(bool clear_vram); virtual bool DoState(StateWrapper& sw, GPUTexture** save_to_texture, bool update_display); @@ -184,8 +184,8 @@ class GPU float ComputeVerticalFrequency() const; float ComputeDisplayAspectRatio() const; - static std::unique_ptr CreateHardwareRenderer(); - static std::unique_ptr CreateSoftwareRenderer(); + static std::unique_ptr CreateHardwareRenderer(Error* error); + static std::unique_ptr CreateSoftwareRenderer(Error* error); // Converts window coordinates into horizontal ticks and scanlines. Returns false if out of range. Used for lightguns. void ConvertScreenCoordinatesToDisplayCoordinates(float window_x, float window_y, float* display_x, @@ -631,7 +631,7 @@ class GPU Stats m_stats = {}; private: - bool CompileDisplayPipelines(bool display, bool deinterlace, bool chroma_smoothing); + bool CompileDisplayPipelines(bool display, bool deinterlace, bool chroma_smoothing, Error* error); using GP0CommandHandler = bool (GPU::*)(); using GP0CommandHandlerTable = std::array; diff --git a/src/core/gpu_hw.cpp b/src/core/gpu_hw.cpp index 9e4e04aadd..67a480cd8d 100644 --- a/src/core/gpu_hw.cpp +++ b/src/core/gpu_hw.cpp @@ -245,9 +245,9 @@ bool GPU_HW::IsHardwareRenderer() const return true; } -bool GPU_HW::Initialize() +bool GPU_HW::Initialize(Error* error) { - if (!GPU::Initialize()) + if (!GPU::Initialize(error)) return false; const GPUDevice::Features features = g_gpu_device->GetFeatures(); @@ -275,16 +275,12 @@ bool GPU_HW::Initialize() PrintSettingsToLog(); - Error error; - if (!CompilePipelines(&error)) - { - ERROR_LOG("Failed to compile pipelines: {}", error.GetDescription()); + if (!CompilePipelines(error)) return false; - } if (!CreateBuffers()) { - ERROR_LOG("Failed to create framebuffer"); + Error::SetStringView(error, "Failed to create framebuffer"); return false; } @@ -4214,11 +4210,11 @@ void GPU_HW::DrawRendererStats() } } -std::unique_ptr GPU::CreateHardwareRenderer() +std::unique_ptr GPU::CreateHardwareRenderer(Error* error) { std::unique_ptr gpu(std::make_unique()); - if (!gpu->Initialize()) - return nullptr; + if (!gpu->Initialize(error)) + gpu.reset(); return gpu; } diff --git a/src/core/gpu_hw.h b/src/core/gpu_hw.h index 05d461283b..dfffcb32cf 100644 --- a/src/core/gpu_hw.h +++ b/src/core/gpu_hw.h @@ -66,7 +66,7 @@ class GPU_HW final : public GPU const Threading::Thread* GetSWThread() const override; bool IsHardwareRenderer() const override; - bool Initialize() override; + bool Initialize(Error* error) override; void Reset(bool clear_vram) override; bool DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display) override; diff --git a/src/core/gpu_sw.cpp b/src/core/gpu_sw.cpp index 3e93cc9600..3a01f705cb 100644 --- a/src/core/gpu_sw.cpp +++ b/src/core/gpu_sw.cpp @@ -36,9 +36,9 @@ bool GPU_SW::IsHardwareRenderer() const return false; } -bool GPU_SW::Initialize() +bool GPU_SW::Initialize(Error* error) { - if (!GPU::Initialize() || !m_backend.Initialize(g_settings.gpu_use_thread)) + if (!GPU::Initialize(error) || !m_backend.Initialize(g_settings.gpu_use_thread)) return false; static constexpr const std::array formats_for_16bit = {GPUTexture::Format::RGB565, GPUTexture::Format::RGBA5551, @@ -810,11 +810,11 @@ void GPU_SW::UpdateCLUT(GPUTexturePaletteReg reg, bool clut_is_8bit) m_backend.PushCommand(cmd); } -std::unique_ptr GPU::CreateSoftwareRenderer() +std::unique_ptr GPU::CreateSoftwareRenderer(Error* error) { std::unique_ptr gpu(std::make_unique()); - if (!gpu->Initialize()) - return nullptr; + if (!gpu->Initialize(error)) + gpu.reset(); return gpu; } diff --git a/src/core/gpu_sw.h b/src/core/gpu_sw.h index a4a11e4d4b..2251843aab 100644 --- a/src/core/gpu_sw.h +++ b/src/core/gpu_sw.h @@ -29,7 +29,7 @@ class GPU_SW final : public GPU const Threading::Thread* GetSWThread() const override; bool IsHardwareRenderer() const override; - bool Initialize() override; + bool Initialize(Error* error) override; bool DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_display) override; void Reset(bool clear_vram) override; void UpdateSettings(const Settings& old_settings) override; diff --git a/src/core/system.cpp b/src/core/system.cpp index efacc36829..529963e600 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -2466,9 +2466,9 @@ bool System::CreateGPU(GPURenderer renderer, bool is_switching, bool fullscreen, } if (renderer == GPURenderer::Software) - g_gpu = GPU::CreateSoftwareRenderer(); + g_gpu = GPU::CreateSoftwareRenderer(error); else - g_gpu = GPU::CreateHardwareRenderer(); + g_gpu = GPU::CreateHardwareRenderer(error); if (!g_gpu) { @@ -2479,7 +2479,7 @@ bool System::CreateGPU(GPURenderer renderer, bool is_switching, bool fullscreen, Settings::GetRendererName(renderer)), Host::OSD_CRITICAL_ERROR_DURATION); g_gpu.reset(); - g_gpu = GPU::CreateSoftwareRenderer(); + g_gpu = GPU::CreateSoftwareRenderer(error); if (!g_gpu) { ERROR_LOG("Failed to create fallback software renderer.");