mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-15 06:00:05 +00:00
video_core: Fix crash when no debug context is provided. (#7324)
This commit is contained in:
parent
7bacb78ce3
commit
6069fac76d
@ -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) {
|
||||||
|
@ -30,8 +30,9 @@ 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_unit,
|
||||||
gs_setup},
|
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) {
|
||||||
|
debug_context->OnEvent(DebugContext::Event::VertexShaderInvocation,
|
||||||
std::addressof(immediate.input_vertex));
|
std::addressof(immediate.input_vertex));
|
||||||
SCOPE_EXIT({ debug_context.OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr); });
|
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) {
|
||||||
|
debug_context->OnEvent(DebugContext::Event::VertexShaderInvocation,
|
||||||
std::addressof(input));
|
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);
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user