From 6069fac76de008a452cf6012abaf41704bc644a6 Mon Sep 17 00:00:00 2001 From: Steveice10 <1269164+Steveice10@users.noreply.github.com> Date: Sun, 7 Jan 2024 10:29:43 -0800 Subject: [PATCH] video_core: Fix crash when no debug context is provided. (#7324) --- src/video_core/gpu.cpp | 16 +++++++++----- src/video_core/pica/pica_core.cpp | 35 ++++++++++++++++++++----------- src/video_core/pica/pica_core.h | 4 ++-- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 3def26757..cc06078b9 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -29,7 +29,7 @@ struct GPU::Impl { Core::Timing& timing; Core::System& system; Memory::MemorySystem& memory; - Pica::DebugContext& debug_context; + std::shared_ptr debug_context; Pica::PicaCore pica; GraphicsDebugger gpu_debugger; std::unique_ptr renderer; @@ -41,7 +41,7 @@ struct GPU::Impl { explicit Impl(Core::System& system, Frontend::EmuWindow& emu_window, Frontend::EmuWindow* secondary_window) : timing{system.CoreTiming()}, system{system}, memory{system.Memory()}, - debug_context{*Pica::g_debug_context}, pica{memory, debug_context}, + debug_context{Pica::g_debug_context}, pica{memory, debug_context}, renderer{VideoCore::CreateRenderer(emu_window, secondary_window, pica, system)}, rasterizer{renderer->Rasterizer()}, sw_blitter{std::make_unique( memory, rasterizer)} {} @@ -201,7 +201,9 @@ void GPU::Execute(const Service::GSP::Command& command) { } // Notify debugger that a GSP command was processed. - impl->debug_context.OnEvent(Pica::DebugContext::Event::GSPCommandProcessed, &command); + if (impl->debug_context) { + impl->debug_context->OnEvent(Pica::DebugContext::Event::GSPCommandProcessed, &command); + } } void GPU::SetBufferSwap(u32 screen_id, const Service::GSP::FrameBufferInfo& info) { @@ -223,7 +225,9 @@ void GPU::SetBufferSwap(u32 screen_id, const Service::GSP::FrameBufferInfo& info framebuffer.active_fb = info.shown_fb; // Notify debugger about the buffer swap. - impl->debug_context.OnEvent(Pica::DebugContext::Event::BufferSwapped, nullptr); + if (impl->debug_context) { + impl->debug_context->OnEvent(Pica::DebugContext::Event::BufferSwapped, nullptr); + } if (screen_id == 0) { MicroProfileFlip(); @@ -382,7 +386,9 @@ void GPU::MemoryTransfer() { MICROPROFILE_SCOPE(GPU_DisplayTransfer); // Notify debugger about the display transfer. - impl->debug_context.OnEvent(Pica::DebugContext::Event::IncomingDisplayTransfer, nullptr); + if (impl->debug_context) { + impl->debug_context->OnEvent(Pica::DebugContext::Event::IncomingDisplayTransfer, nullptr); + } // Perform memory transfer if (config.is_texture_copy) { diff --git a/src/video_core/pica/pica_core.cpp b/src/video_core/pica/pica_core.cpp index 1d7594a2a..9c3fadde8 100644 --- a/src/video_core/pica/pica_core.cpp +++ b/src/video_core/pica/pica_core.cpp @@ -30,9 +30,10 @@ union CommandHeader { }; static_assert(sizeof(CommandHeader) == sizeof(u32), "CommandHeader has incorrect size!"); -PicaCore::PicaCore(Memory::MemorySystem& memory_, DebugContext& debug_context_) - : memory{memory_}, debug_context{debug_context_}, geometry_pipeline{regs.internal, gs_unit, - gs_setup}, +PicaCore::PicaCore(Memory::MemorySystem& memory_, std::shared_ptr debug_context_) + : memory{memory_}, debug_context{std::move(debug_context_)}, geometry_pipeline{regs.internal, + gs_unit, + gs_setup}, shader_engine{CreateEngine(Settings::values.use_shader_jit.GetValue())} { SetFramebufferDefaults(); @@ -138,8 +139,10 @@ void PicaCore::WriteInternalReg(u32 id, u32 value, u32 mask) { DebugUtils::OnPicaRegWrite(id, mask, regs.internal.reg_array[id]); // Track events. - debug_context.OnEvent(DebugContext::Event::PicaCommandLoaded, &id); - SCOPE_EXIT({ debug_context.OnEvent(DebugContext::Event::PicaCommandProcessed, &id); }); + if (debug_context) { + debug_context->OnEvent(DebugContext::Event::PicaCommandLoaded, &id); + SCOPE_EXIT({ debug_context->OnEvent(DebugContext::Event::PicaCommandProcessed, &id); }); + } switch (id) { // Trigger IRQ @@ -427,9 +430,12 @@ void PicaCore::DrawImmediate() { shader_engine->SetupBatch(vs_setup, regs.internal.vs.main_offset); // Track vertex in the debug recorder. - debug_context.OnEvent(DebugContext::Event::VertexShaderInvocation, - std::addressof(immediate.input_vertex)); - SCOPE_EXIT({ debug_context.OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr); }); + if (debug_context) { + debug_context->OnEvent(DebugContext::Event::VertexShaderInvocation, + std::addressof(immediate.input_vertex)); + SCOPE_EXIT( + { debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr); }); + } ShaderUnit shader_unit; AttributeBuffer output{}; @@ -459,8 +465,11 @@ void PicaCore::DrawArrays(bool is_indexed) { MICROPROFILE_SCOPE(GPU_Drawing); // Track vertex in the debug recorder. - debug_context.OnEvent(DebugContext::Event::IncomingPrimitiveBatch, nullptr); - SCOPE_EXIT({ debug_context.OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr); }); + if (debug_context) { + debug_context->OnEvent(DebugContext::Event::IncomingPrimitiveBatch, nullptr); + SCOPE_EXIT( + { debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr); }); + } const bool accelerate_draw = [this] { // Geometry shaders cannot be accelerated due to register preservation. @@ -554,8 +563,10 @@ void PicaCore::LoadVertices(bool is_indexed) { loader.LoadVertex(base_address, index, vertex, input, input_default_attributes); // Record vertex processing to the debugger. - debug_context.OnEvent(DebugContext::Event::VertexShaderInvocation, - std::addressof(input)); + if (debug_context) { + debug_context->OnEvent(DebugContext::Event::VertexShaderInvocation, + std::addressof(input)); + } // Invoke the vertex shader for this vertex. shader_unit.LoadInput(regs.internal.vs, input); diff --git a/src/video_core/pica/pica_core.h b/src/video_core/pica/pica_core.h index bb19a4f25..353945b53 100644 --- a/src/video_core/pica/pica_core.h +++ b/src/video_core/pica/pica_core.h @@ -29,7 +29,7 @@ class ShaderEngine; class PicaCore { public: - explicit PicaCore(Memory::MemorySystem& memory, DebugContext& debug_context_); + explicit PicaCore(Memory::MemorySystem& memory, std::shared_ptr debug_context_); ~PicaCore(); void BindRasterizer(VideoCore::RasterizerInterface* rasterizer); @@ -274,7 +274,7 @@ private: private: Memory::MemorySystem& memory; VideoCore::RasterizerInterface* rasterizer; - DebugContext& debug_context; + std::shared_ptr debug_context; Service::GSP::InterruptHandler signal_interrupt; GeometryPipeline geometry_pipeline; PrimitiveAssembler primitive_assembler;