video_core: Fix crash when no debug context is provided. (#7324)

This commit is contained in:
Steveice10 2024-01-07 10:29:43 -08:00 committed by GitHub
parent 7bacb78ce3
commit 6069fac76d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 19 deletions

View file

@ -29,7 +29,7 @@ struct GPU::Impl {
Core::Timing& timing; Core::Timing& timing;
Core::System& system; Core::System& system;
Memory::MemorySystem& memory; Memory::MemorySystem& memory;
Pica::DebugContext& debug_context; std::shared_ptr<Pica::DebugContext> debug_context;
Pica::PicaCore pica; Pica::PicaCore pica;
GraphicsDebugger gpu_debugger; GraphicsDebugger gpu_debugger;
std::unique_ptr<RendererBase> renderer; std::unique_ptr<RendererBase> renderer;
@ -41,7 +41,7 @@ struct GPU::Impl {
explicit Impl(Core::System& system, Frontend::EmuWindow& emu_window, explicit Impl(Core::System& system, Frontend::EmuWindow& emu_window,
Frontend::EmuWindow* secondary_window) Frontend::EmuWindow* secondary_window)
: timing{system.CoreTiming()}, system{system}, memory{system.Memory()}, : 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)}, renderer{VideoCore::CreateRenderer(emu_window, secondary_window, pica, system)},
rasterizer{renderer->Rasterizer()}, sw_blitter{std::make_unique<SwRenderer::SwBlitter>( rasterizer{renderer->Rasterizer()}, sw_blitter{std::make_unique<SwRenderer::SwBlitter>(
memory, rasterizer)} {} memory, rasterizer)} {}
@ -201,7 +201,9 @@ void GPU::Execute(const Service::GSP::Command& command) {
} }
// Notify debugger that a GSP command was processed. // 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) { 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; framebuffer.active_fb = info.shown_fb;
// Notify debugger about the buffer swap. // 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) { if (screen_id == 0) {
MicroProfileFlip(); MicroProfileFlip();
@ -382,7 +386,9 @@ void GPU::MemoryTransfer() {
MICROPROFILE_SCOPE(GPU_DisplayTransfer); MICROPROFILE_SCOPE(GPU_DisplayTransfer);
// Notify debugger about the display transfer. // 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 // Perform memory transfer
if (config.is_texture_copy) { if (config.is_texture_copy) {

View file

@ -30,9 +30,10 @@ union CommandHeader {
}; };
static_assert(sizeof(CommandHeader) == sizeof(u32), "CommandHeader has incorrect size!"); static_assert(sizeof(CommandHeader) == sizeof(u32), "CommandHeader has incorrect size!");
PicaCore::PicaCore(Memory::MemorySystem& memory_, DebugContext& debug_context_) PicaCore::PicaCore(Memory::MemorySystem& memory_, std::shared_ptr<DebugContext> debug_context_)
: memory{memory_}, debug_context{debug_context_}, geometry_pipeline{regs.internal, gs_unit, : memory{memory_}, debug_context{std::move(debug_context_)}, geometry_pipeline{regs.internal,
gs_setup}, gs_unit,
gs_setup},
shader_engine{CreateEngine(Settings::values.use_shader_jit.GetValue())} { shader_engine{CreateEngine(Settings::values.use_shader_jit.GetValue())} {
SetFramebufferDefaults(); SetFramebufferDefaults();
@ -138,8 +139,10 @@ void PicaCore::WriteInternalReg(u32 id, u32 value, u32 mask) {
DebugUtils::OnPicaRegWrite(id, mask, regs.internal.reg_array[id]); DebugUtils::OnPicaRegWrite(id, mask, regs.internal.reg_array[id]);
// Track events. // Track events.
debug_context.OnEvent(DebugContext::Event::PicaCommandLoaded, &id); if (debug_context) {
SCOPE_EXIT({ debug_context.OnEvent(DebugContext::Event::PicaCommandProcessed, &id); }); debug_context->OnEvent(DebugContext::Event::PicaCommandLoaded, &id);
SCOPE_EXIT({ debug_context->OnEvent(DebugContext::Event::PicaCommandProcessed, &id); });
}
switch (id) { switch (id) {
// Trigger IRQ // Trigger IRQ
@ -427,9 +430,12 @@ void PicaCore::DrawImmediate() {
shader_engine->SetupBatch(vs_setup, regs.internal.vs.main_offset); shader_engine->SetupBatch(vs_setup, regs.internal.vs.main_offset);
// Track vertex in the debug recorder. // Track vertex in the debug recorder.
debug_context.OnEvent(DebugContext::Event::VertexShaderInvocation, if (debug_context) {
std::addressof(immediate.input_vertex)); debug_context->OnEvent(DebugContext::Event::VertexShaderInvocation,
SCOPE_EXIT({ debug_context.OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr); }); std::addressof(immediate.input_vertex));
SCOPE_EXIT(
{ debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr); });
}
ShaderUnit shader_unit; ShaderUnit shader_unit;
AttributeBuffer output{}; AttributeBuffer output{};
@ -459,8 +465,11 @@ void PicaCore::DrawArrays(bool is_indexed) {
MICROPROFILE_SCOPE(GPU_Drawing); MICROPROFILE_SCOPE(GPU_Drawing);
// Track vertex in the debug recorder. // Track vertex in the debug recorder.
debug_context.OnEvent(DebugContext::Event::IncomingPrimitiveBatch, nullptr); if (debug_context) {
SCOPE_EXIT({ debug_context.OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr); }); debug_context->OnEvent(DebugContext::Event::IncomingPrimitiveBatch, nullptr);
SCOPE_EXIT(
{ debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr); });
}
const bool accelerate_draw = [this] { const bool accelerate_draw = [this] {
// Geometry shaders cannot be accelerated due to register preservation. // 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); loader.LoadVertex(base_address, index, vertex, input, input_default_attributes);
// Record vertex processing to the debugger. // Record vertex processing to the debugger.
debug_context.OnEvent(DebugContext::Event::VertexShaderInvocation, if (debug_context) {
std::addressof(input)); debug_context->OnEvent(DebugContext::Event::VertexShaderInvocation,
std::addressof(input));
}
// Invoke the vertex shader for this vertex. // Invoke the vertex shader for this vertex.
shader_unit.LoadInput(regs.internal.vs, input); shader_unit.LoadInput(regs.internal.vs, input);

View file

@ -29,7 +29,7 @@ class ShaderEngine;
class PicaCore { class PicaCore {
public: public:
explicit PicaCore(Memory::MemorySystem& memory, DebugContext& debug_context_); explicit PicaCore(Memory::MemorySystem& memory, std::shared_ptr<DebugContext> debug_context_);
~PicaCore(); ~PicaCore();
void BindRasterizer(VideoCore::RasterizerInterface* rasterizer); void BindRasterizer(VideoCore::RasterizerInterface* rasterizer);
@ -274,7 +274,7 @@ private:
private: private:
Memory::MemorySystem& memory; Memory::MemorySystem& memory;
VideoCore::RasterizerInterface* rasterizer; VideoCore::RasterizerInterface* rasterizer;
DebugContext& debug_context; std::shared_ptr<DebugContext> debug_context;
Service::GSP::InterruptHandler signal_interrupt; Service::GSP::InterruptHandler signal_interrupt;
GeometryPipeline geometry_pipeline; GeometryPipeline geometry_pipeline;
PrimitiveAssembler primitive_assembler; PrimitiveAssembler primitive_assembler;