From 26db661a05b6353107f841700eb925aa382201a3 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 21 Dec 2024 14:10:46 +1000 Subject: [PATCH] GPU: Remove global indirection --- src/core/bus.cpp | 4 +- src/core/dma.cpp | 10 ++-- src/core/gpu.cpp | 26 +++++----- src/core/gpu.h | 3 +- src/core/gpu_dump.cpp | 6 +-- src/core/gpu_hw_texture_cache.cpp | 1 - src/core/gpu_sw_rasterizer.inl | 80 +++++++++++++++++-------------- src/core/guncon.cpp | 6 +-- src/core/imgui_overlays.cpp | 8 ++-- src/core/justifier.cpp | 16 +++---- src/core/system.cpp | 31 ++++++------ src/core/timers.cpp | 12 ++--- src/duckstation-qt/qthost.cpp | 2 +- 13 files changed, 107 insertions(+), 98 deletions(-) diff --git a/src/core/bus.cpp b/src/core/bus.cpp index ea2fe9851..9686ba82d 100644 --- a/src/core/bus.cpp +++ b/src/core/bus.cpp @@ -1875,7 +1875,7 @@ template u32 Bus::HWHandlers::GPURead(PhysicalMemoryAddress address) { const u32 offset = address & GPU_MASK; - u32 value = g_gpu->ReadRegister(FIXUP_WORD_OFFSET(size, offset)); + u32 value = g_gpu.ReadRegister(FIXUP_WORD_OFFSET(size, offset)); value = FIXUP_WORD_READ_VALUE(size, offset, value); BUS_CYCLES(2); return value; @@ -1885,7 +1885,7 @@ template void Bus::HWHandlers::GPUWrite(PhysicalMemoryAddress address, u32 value) { const u32 offset = address & GPU_MASK; - g_gpu->WriteRegister(FIXUP_WORD_OFFSET(size, offset), FIXUP_WORD_WRITE_VALUE(size, offset, value)); + g_gpu.WriteRegister(FIXUP_WORD_OFFSET(size, offset), FIXUP_WORD_WRITE_VALUE(size, offset, value)); } template diff --git a/src/core/dma.cpp b/src/core/dma.cpp index d980df4c9..21e71758a 100644 --- a/src/core/dma.cpp +++ b/src/core/dma.cpp @@ -802,9 +802,9 @@ TickCount DMA::TransferMemoryToDevice(u32 address, u32 increment, u32 word_count { case Channel::GPU: { - if (g_gpu->BeginDMAWrite()) [[likely]] + if (g_gpu.BeginDMAWrite()) [[likely]] { - if (GPUDump::Recorder* dump = g_gpu->GetGPUDump()) [[unlikely]] + if (GPUDump::Recorder* dump = g_gpu.GetGPUDump()) [[unlikely]] { // No wraparound? dump->BeginGP0Packet(word_count); @@ -831,10 +831,10 @@ TickCount DMA::TransferMemoryToDevice(u32 address, u32 increment, u32 word_count { u32 value; std::memcpy(&value, &ram_pointer[address], sizeof(u32)); - g_gpu->DMAWrite(address, value); + g_gpu.DMAWrite(address, value); address = (address + increment) & mask; } - g_gpu->EndDMAWrite(); + g_gpu.EndDMAWrite(); } } break; @@ -900,7 +900,7 @@ TickCount DMA::TransferDeviceToMemory(u32 address, u32 increment, u32 word_count switch (channel) { case Channel::GPU: - g_gpu->DMARead(dest_pointer, word_count); + g_gpu.DMARead(dest_pointer, word_count); break; case Channel::CDROM: diff --git a/src/core/gpu.cpp b/src/core/gpu.cpp index 367d8282b..6c0948473 100644 --- a/src/core/gpu.cpp +++ b/src/core/gpu.cpp @@ -45,7 +45,7 @@ LOG_CHANNEL(GPU); -std::unique_ptr g_gpu; +ALIGN_TO_CACHE_LINE GPU g_gpu; // aligning VRAM to 4K is fine, since the ARM64 instructions compute 4K page aligned addresses // or it would be, except we want to import the memory for readbacks on metal.. @@ -60,13 +60,13 @@ u16 g_gpu_clut[GPU_CLUT_SIZE]; const GPU::GP0CommandHandlerTable GPU::s_GP0_command_handler_table = GPU::GenerateGP0CommandHandlerTable(); static TimingEvent s_crtc_tick_event( - "GPU CRTC Tick", 1, 1, [](void* param, TickCount ticks, TickCount ticks_late) { g_gpu->CRTCTickEvent(ticks); }, + "GPU CRTC Tick", 1, 1, [](void* param, TickCount ticks, TickCount ticks_late) { g_gpu.CRTCTickEvent(ticks); }, nullptr); static TimingEvent s_command_tick_event( - "GPU Command Tick", 1, 1, [](void* param, TickCount ticks, TickCount ticks_late) { g_gpu->CommandTickEvent(ticks); }, + "GPU Command Tick", 1, 1, [](void* param, TickCount ticks, TickCount ticks_late) { g_gpu.CommandTickEvent(ticks); }, nullptr); static TimingEvent s_frame_done_event( - "Frame Done", 1, 1, [](void* param, TickCount ticks, TickCount ticks_late) { g_gpu->FrameDoneEvent(ticks); }, + "Frame Done", 1, 1, [](void* param, TickCount ticks, TickCount ticks_late) { g_gpu.FrameDoneEvent(ticks); }, nullptr); // #define PSX_GPU_STATS @@ -77,14 +77,7 @@ static u32 s_active_gpu_cycles_frames = 0; GPU::GPU() = default; -GPU::~GPU() -{ - s_command_tick_event.Deactivate(); - s_crtc_tick_event.Deactivate(); - s_frame_done_event.Deactivate(); - - StopRecordingGPUDump(); -} +GPU::~GPU() = default; void GPU::Initialize() { @@ -104,6 +97,15 @@ void GPU::Initialize() #endif } +void GPU::Shutdown() +{ + s_command_tick_event.Deactivate(); + s_crtc_tick_event.Deactivate(); + s_frame_done_event.Deactivate(); + + StopRecordingGPUDump(); +} + void GPU::UpdateSettings(const Settings& old_settings) { m_force_progressive_scan = (g_settings.display_deinterlacing_mode == DisplayDeinterlacingMode::Progressive); diff --git a/src/core/gpu.h b/src/core/gpu.h index a1258f6b5..c663d5071 100644 --- a/src/core/gpu.h +++ b/src/core/gpu.h @@ -95,6 +95,7 @@ public: ~GPU(); void Initialize(); + void Shutdown(); void Reset(bool clear_vram); bool DoState(StateWrapper& sw, bool update_display); void DoMemoryState(StateWrapper& sw, System::MemorySaveState& mss, bool update_display); @@ -561,6 +562,6 @@ private: static const GP0CommandHandlerTable s_GP0_command_handler_table; }; -extern std::unique_ptr g_gpu; +extern GPU g_gpu; extern u16 g_vram[VRAM_SIZE / sizeof(u16)]; extern u16 g_gpu_clut[GPU_CLUT_SIZE]; diff --git a/src/core/gpu_dump.cpp b/src/core/gpu_dump.cpp index 5b32be867..25a70acdd 100644 --- a/src/core/gpu_dump.cpp +++ b/src/core/gpu_dump.cpp @@ -76,7 +76,7 @@ std::unique_ptr GPUDump::Recorder::Create(std::string path, s ret = std::unique_ptr(new Recorder(std::move(fp), num_frames, std::move(path))); ret->WriteHeaders(serial); - g_gpu->WriteCurrentVideoModeToDump(ret.get()); + g_gpu.WriteCurrentVideoModeToDump(ret.get()); ret->WriteCurrentVRAM(); // Write start of stream. @@ -285,7 +285,7 @@ void GPUDump::Recorder::WriteHeaders(std::string_view serial) // Write textual video mode. BeginPacket(PacketType::TextualVideoFormat); - WriteString(g_gpu->IsInPALMode() ? "PAL" : "NTSC"); + WriteString(g_gpu.IsInPALMode() ? "PAL" : "NTSC"); EndPacket(); // Write DuckStation version. @@ -520,7 +520,7 @@ void GPUDump::Player::ProcessPacket(const PacketRef& pkt) if (pkt.type <= PacketType::VSyncEvent) { // gp0/gp1/vsync => direct to gpu - g_gpu->ProcessGPUDumpPacket(pkt.type, pkt.data); + g_gpu.ProcessGPUDumpPacket(pkt.type, pkt.data); return; } } diff --git a/src/core/gpu_hw_texture_cache.cpp b/src/core/gpu_hw_texture_cache.cpp index cba1b7985..0b7a3182e 100644 --- a/src/core/gpu_hw_texture_cache.cpp +++ b/src/core/gpu_hw_texture_cache.cpp @@ -3483,7 +3483,6 @@ void GPUTextureCache::ReloadTextureReplacements(bool show_info) PurgeUnreferencedTexturesFromCache(); - DebugAssert(g_gpu); UpdateVRAMTrackingState(); InvalidateSources(); diff --git a/src/core/gpu_sw_rasterizer.inl b/src/core/gpu_sw_rasterizer.inl index 3deb0a9b8..67d0e34f8 100644 --- a/src/core/gpu_sw_rasterizer.inl +++ b/src/core/gpu_sw_rasterizer.inl @@ -506,10 +506,11 @@ struct PixelVectors } // namespace template -ALWAYS_INLINE_RELEASE static void -ShadePixel(const PixelVectors& pv, GPUTextureMode texture_mode, GPUTransparencyMode transparency_mode, - u32 start_x, u32 y, GSVectorNi vertex_color_rg, GSVectorNi vertex_color_ba, GSVectorNi texcoord_x, - GSVectorNi texcoord_y, GSVectorNi preserve_mask, GSVectorNi dither) +ALWAYS_INLINE_RELEASE static void ShadePixel(const PixelVectors& RESTRICT pv, + GPUTextureMode texture_mode, GPUTransparencyMode transparency_mode, + u32 start_x, u32 y, GSVectorNi vertex_color_rg, GSVectorNi vertex_color_ba, + GSVectorNi texcoord_x, GSVectorNi texcoord_y, GSVectorNi preserve_mask, + GSVectorNi dither) { static constexpr GSVectorNi coord_mask_x = GSVectorNi::cxpr(VRAM_WIDTH_MASK); static constexpr GSVectorNi coord_mask_y = GSVectorNi::cxpr(VRAM_HEIGHT_MASK); @@ -693,7 +694,7 @@ ShadePixel(const PixelVectors& pv, GPUTextureMode texture_mode, } template -static void DrawRectangle(const GPUBackendDrawRectangleCommand* cmd) +static void DrawRectangle(const GPUBackendDrawRectangleCommand* RESTRICT cmd) { const s32 origin_x = cmd->x; const s32 origin_y = cmd->y; @@ -765,8 +766,9 @@ static void DrawRectangle(const GPUBackendDrawRectangleCommand* cmd) // TODO: Vectorize line draw. template -static void DrawLine(const GPUBackendDrawLineCommand* cmd, const GPUBackendDrawLineCommand::Vertex* p0, - const GPUBackendDrawLineCommand::Vertex* p1) +static void DrawLine(const GPUBackendDrawLineCommand* RESTRICT cmd, + const GPUBackendDrawLineCommand::Vertex* RESTRICT p0, + const GPUBackendDrawLineCommand::Vertex* RESTRICT p1) { static constexpr u32 XY_SHIFT = 32; static constexpr u32 RGB_SHIFT = 12; @@ -971,8 +973,8 @@ struct TrianglePart #ifndef USE_VECTOR template -static void DrawSpan(const GPUBackendDrawCommand* cmd, s32 y, s32 x_start, s32 x_bound, UVStepper uv, - const UVSteps& uvstep, RGBStepper rgb, const RGBSteps& rgbstep) +static void DrawSpan(const GPUBackendDrawCommand* RESTRICT cmd, s32 y, s32 x_start, s32 x_bound, UVStepper uv, + const UVSteps& RESTRICT uvstep, RGBStepper rgb, const RGBSteps& RESTRICT rgbstep) { s32 width = x_bound - x_start; s32 current_x = TruncateGPUVertexPosition(x_start); @@ -1011,9 +1013,10 @@ static void DrawSpan(const GPUBackendDrawCommand* cmd, s32 y, s32 x_start, s32 x } template -ALWAYS_INLINE_RELEASE static void DrawTrianglePart(const GPUBackendDrawCommand* cmd, const TrianglePart& tp, - const UVStepper& uv, const UVSteps& uvstep, const RGBStepper& rgb, - const RGBSteps& rgbstep) +ALWAYS_INLINE_RELEASE static void DrawTrianglePart(const GPUBackendDrawCommand* RESTRICT cmd, + const TrianglePart& RESTRICT tp, const UVStepper& RESTRICT uv, + const UVSteps& RESTRICT uvstep, const RGBStepper& RESTRICT rgb, + const RGBSteps& RESTRICT rgbstep) { static constexpr auto unfp_xy = [](s64 xfp) -> s32 { return static_cast(static_cast(xfp) >> 32); }; @@ -1150,9 +1153,10 @@ struct TriangleVectors : PixelVectors } // namespace template -ALWAYS_INLINE_RELEASE static void DrawSpan(const GPUBackendDrawCommand* cmd, s32 y, s32 x_start, s32 x_bound, - UVStepper uv, const UVSteps& uvstep, RGBStepper rgb, const RGBSteps& rgbstep, - const TriangleVectors& tv) +ALWAYS_INLINE_RELEASE static void DrawSpan(const GPUBackendDrawCommand* RESTRICT cmd, s32 y, s32 x_start, s32 x_bound, + UVStepper uv, const UVSteps& RESTRICT uvstep, RGBStepper rgb, + const RGBSteps& RESTRICT rgbstep, + const TriangleVectors& RESTRICT tv) { s32 width = x_bound - x_start; s32 current_x = TruncateGPUVertexPosition(x_start); @@ -1255,9 +1259,10 @@ ALWAYS_INLINE_RELEASE static void DrawSpan(const GPUBackendDrawCommand* cmd, s32 } template -ALWAYS_INLINE_RELEASE static void DrawTrianglePart(const GPUBackendDrawCommand* cmd, const TrianglePart& tp, - const UVStepper& uv, const UVSteps& uvstep, const RGBStepper& rgb, - const RGBSteps& rgbstep) +ALWAYS_INLINE_RELEASE static void DrawTrianglePart(const GPUBackendDrawCommand* RESTRICT cmd, + const TrianglePart& RESTRICT tp, const UVStepper& RESTRICT uv, + const UVSteps& RESTRICT uvstep, const RGBStepper& RESTRICT rgb, + const RGBSteps& RESTRICT rgbstep) { static constexpr auto unfp_xy = [](s64 xfp) -> s32 { return static_cast(static_cast(xfp) >> 32); }; @@ -1356,13 +1361,15 @@ ALWAYS_INLINE_RELEASE static void DrawTrianglePart(const GPUBackendDrawCommand* #endif // USE_VECTOR template -static void DrawTriangle(const GPUBackendDrawCommand* cmd, const GPUBackendDrawPolygonCommand::Vertex* v0, - const GPUBackendDrawPolygonCommand::Vertex* v1, const GPUBackendDrawPolygonCommand::Vertex* v2) +static void DrawTriangle(const GPUBackendDrawCommand* RESTRICT cmd, + const GPUBackendDrawPolygonCommand::Vertex* RESTRICT v0, + const GPUBackendDrawPolygonCommand::Vertex* RESTRICT v1, + const GPUBackendDrawPolygonCommand::Vertex* RESTRICT v2) { #ifdef CHECK_VECTOR - const GPUBackendDrawPolygonCommand::Vertex* orig_v0 = v0; - const GPUBackendDrawPolygonCommand::Vertex* orig_v1 = v1; - const GPUBackendDrawPolygonCommand::Vertex* orig_v2 = v2; + const GPUBackendDrawPolygonCommand::Vertex* RESTRICT orig_v0 = v0; + const GPUBackendDrawPolygonCommand::Vertex* RESTRICT orig_v1 = v1; + const GPUBackendDrawPolygonCommand::Vertex* RESTRICT orig_v2 = v2; #endif // Sort vertices so that v0 is the top vertex, v1 is the bottom vertex, and v2 is the side vertex. @@ -1417,8 +1424,8 @@ static void DrawTriangle(const GPUBackendDrawCommand* cmd, const GPUBackendDrawP const u32 ofi = BoolToUInt32(!right_facing); TrianglePart triparts[2]; - TrianglePart& tpo = triparts[vo]; - TrianglePart& tpp = triparts[vo ^ 1]; + TrianglePart& RESTRICT tpo = triparts[vo]; + TrianglePart& RESTRICT tpp = triparts[vo ^ 1]; tpo.start_y = vertices[0 ^ vo]->y; tpo.end_y = vertices[1 ^ vo]->y; tpp.start_y = vertices[1 ^ vp]->y; @@ -1469,7 +1476,7 @@ static void DrawTriangle(const GPUBackendDrawCommand* cmd, const GPUBackendDrawP // Undo the start of the vertex, so that when we add the offset for each line, it starts at the beginning value. UVStepper uv; RGBStepper rgb; - const GPUBackendDrawPolygonCommand::Vertex* top_left_vertex = vertices[tl]; + const GPUBackendDrawPolygonCommand::Vertex* RESTRICT top_left_vertex = vertices[tl]; if constexpr (texture_enable) { uv.Init(top_left_vertex->u, top_left_vertex->v); @@ -1542,7 +1549,7 @@ static void FillVRAMImpl(u32 x, u32 y, u32 width, u32 height, u32 color, bool in { const u32 row = (y + yoffs) % VRAM_HEIGHT; - u16* row_ptr = &g_vram[row * VRAM_WIDTH + x]; + u16* RESTRICT row_ptr = &g_vram[row * VRAM_WIDTH + x]; u32 xoffs = 0; for (; xoffs < aligned_width; xoffs += vector_width, row_ptr += vector_width) GSVector4i::store(row_ptr, fill); @@ -1563,7 +1570,7 @@ static void FillVRAMImpl(u32 x, u32 y, u32 width, u32 height, u32 color, bool in if ((row & u32(1)) == active_field) continue; - u16* row_ptr = &g_vram[row * VRAM_WIDTH + x]; + u16* RESTRICT row_ptr = &g_vram[row * VRAM_WIDTH + x]; u32 xoffs = 0; for (; xoffs < aligned_width; xoffs += vector_width, row_ptr += vector_width) GSVector4i::store(row_ptr, fill); @@ -1579,7 +1586,7 @@ static void FillVRAMImpl(u32 x, u32 y, u32 width, u32 height, u32 color, bool in if ((row & u32(1)) == active_field) continue; - u16* row_ptr = &g_vram[row * VRAM_WIDTH]; + u16* RESTRICT row_ptr = &g_vram[row * VRAM_WIDTH]; for (u32 xoffs = 0; xoffs < width; xoffs++) { const u32 col = (x + xoffs) % VRAM_WIDTH; @@ -1593,7 +1600,7 @@ static void FillVRAMImpl(u32 x, u32 y, u32 width, u32 height, u32 color, bool in for (u32 yoffs = 0; yoffs < height; yoffs++) { const u32 row = (y + yoffs) % VRAM_HEIGHT; - u16* row_ptr = &g_vram[row * VRAM_WIDTH]; + u16* RESTRICT row_ptr = &g_vram[row * VRAM_WIDTH]; for (u32 xoffs = 0; xoffs < width; xoffs++) { const u32 col = (x + xoffs) % VRAM_WIDTH; @@ -1622,7 +1629,7 @@ static void FillVRAMImpl(u32 x, u32 y, u32 width, u32 height, u32 color, bool in if ((row & u32(1)) == active_field) continue; - u16* row_ptr = &g_vram[row * VRAM_WIDTH]; + u16* RESTRICT row_ptr = &g_vram[row * VRAM_WIDTH]; for (u32 xoffs = 0; xoffs < width; xoffs++) { const u32 col = (x + xoffs) % VRAM_WIDTH; @@ -1635,7 +1642,7 @@ static void FillVRAMImpl(u32 x, u32 y, u32 width, u32 height, u32 color, bool in for (u32 yoffs = 0; yoffs < height; yoffs++) { const u32 row = (y + yoffs) % VRAM_HEIGHT; - u16* row_ptr = &g_vram[row * VRAM_WIDTH]; + u16* RESTRICT row_ptr = &g_vram[row * VRAM_WIDTH]; for (u32 xoffs = 0; xoffs < width; xoffs++) { const u32 col = (x + xoffs) % VRAM_WIDTH; @@ -1646,12 +1653,13 @@ static void FillVRAMImpl(u32 x, u32 y, u32 width, u32 height, u32 color, bool in #endif } -static void WriteVRAMImpl(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask) +static void WriteVRAMImpl(u32 x, u32 y, u32 width, u32 height, const void* RESTRICT data, bool set_mask, + bool check_mask) { // Fast path when the copy is not oversized. if ((x + width) <= VRAM_WIDTH && (y + height) <= VRAM_HEIGHT && !set_mask && !check_mask) { - const u16* src_ptr = static_cast(data); + const u16* RESTRICT src_ptr = static_cast(data); u16* dst_ptr = &g_vram[y * VRAM_WIDTH + x]; for (u32 yoffs = 0; yoffs < height; yoffs++) { @@ -1664,7 +1672,7 @@ static void WriteVRAMImpl(u32 x, u32 y, u32 width, u32 height, const void* data, { // Slow path when we need to handle wrap-around. // During transfer/render operations, if ((dst_pixel & mask_and) == 0) { pixel = src_pixel | mask_or } - const u16* src_ptr = static_cast(data); + const u16* RESTRICT src_ptr = static_cast(data); const u16 mask_and = check_mask ? 0x8000u : 0x0000u; const u16 mask_or = set_mask ? 0x8000u : 0x0000u; @@ -1713,7 +1721,7 @@ static void WriteVRAMImpl(u32 x, u32 y, u32 width, u32 height, const void* data, for (; col < width;) { // TODO: Handle unaligned reads... - u16* pixel_ptr = &dst_row_ptr[(x + col++) % VRAM_WIDTH]; + u16* RESTRICT pixel_ptr = &dst_row_ptr[(x + col++) % VRAM_WIDTH]; if (((*pixel_ptr) & mask_and) == 0) *pixel_ptr = *(src_ptr++) | mask_or; } diff --git a/src/core/guncon.cpp b/src/core/guncon.cpp index c2a75c452..88ef2ede7 100644 --- a/src/core/guncon.cpp +++ b/src/core/guncon.cpp @@ -207,12 +207,12 @@ void GunCon::UpdatePosition() float display_x, display_y; const auto& [window_x, window_y] = (m_has_relative_binds) ? GetAbsolutePositionFromRelativeAxes() : InputManager::GetPointerAbsolutePosition(m_cursor_index); - g_gpu->ConvertScreenCoordinatesToDisplayCoordinates(window_x, window_y, &display_x, &display_y); + g_gpu.ConvertScreenCoordinatesToDisplayCoordinates(window_x, window_y, &display_x, &display_y); // are we within the active display area? u32 tick, line; if (display_x < 0 || display_y < 0 || - !g_gpu->ConvertDisplayCoordinatesToBeamTicksAndLines(display_x, display_y, m_x_scale, &tick, &line) || + !g_gpu.ConvertDisplayCoordinatesToBeamTicksAndLines(display_x, display_y, m_x_scale, &tick, &line) || m_shoot_offscreen) { DEBUG_LOG("Lightgun out of range for window coordinates {:.0f},{:.0f}", window_x, window_y); @@ -222,7 +222,7 @@ void GunCon::UpdatePosition() } // 8MHz units for X = 44100*768*11/7 = 53222400 / 8000000 = 6.6528 - const double divider = static_cast(g_gpu->GetCRTCFrequency()) / 8000000.0; + const double divider = static_cast(g_gpu.GetCRTCFrequency()) / 8000000.0; m_position_x = static_cast(static_cast(tick) / static_cast(divider)); m_position_y = static_cast(line); DEBUG_LOG("Lightgun window coordinates {:.0f},{:.0f} -> tick {} line {} 8mhz ticks {}", display_x, display_y, tick, diff --git a/src/core/imgui_overlays.cpp b/src/core/imgui_overlays.cpp index 1fa9b5a79..c9de11ddb 100644 --- a/src/core/imgui_overlays.cpp +++ b/src/core/imgui_overlays.cpp @@ -85,7 +85,7 @@ static constexpr const char* DEBUG_WINDOW_CONFIG_SECTION = "DebugWindows"; static constexpr const std::array s_debug_window_info = {{ {"SPU", "SPU State", ":icons/applications-system.png", &SPU::DrawDebugStateWindow, 800, 915}, {"CDROM", "CD-ROM State", ":icons/applications-system.png", &CDROM::DrawDebugWindow, 800, 540}, - {"GPU", "GPU State", ":icons/applications-system.png", [](float sc) { g_gpu->DrawDebugStateWindow(sc); }, 450, 550}, + {"GPU", "GPU State", ":icons/applications-system.png", [](float sc) { g_gpu.DrawDebugStateWindow(sc); }, 450, 550}, {"DMA", "DMA State", ":icons/applications-system.png", &DMA::DrawDebugStateWindow, 860, 180}, {"MDEC", "MDEC State", ":icons/applications-system.png", &MDEC::DrawDebugStateWindow, 300, 350}, {"Timers", "Timers State", ":icons/applications-system.png", &Timers::DrawDebugStateWindow, 800, 95}, @@ -323,9 +323,9 @@ void ImGuiManager::DrawPerformanceOverlay(const GPUBackend* gpu, float& position if (g_gpu_settings.display_show_resolution) { const u32 resolution_scale = gpu->GetResolutionScale(); - const auto [display_width, display_height] = g_gpu->GetFullDisplayResolution(); // NOTE: Racey read. - const bool interlaced = g_gpu->IsInterlacedDisplayEnabled(); - const bool pal = g_gpu->IsInPALMode(); + const auto [display_width, display_height] = g_gpu.GetFullDisplayResolution(); // NOTE: Racey read. + const bool interlaced = g_gpu.IsInterlacedDisplayEnabled(); + const bool pal = g_gpu.IsInPALMode(); text.format("{}x{} {} {} [{}x]", display_width * resolution_scale, display_height * resolution_scale, pal ? "PAL" : "NTSC", interlaced ? "Interlaced" : "Progressive", resolution_scale); DRAW_LINE(fixed_font, text, IM_COL32(255, 255, 255, 255)); diff --git a/src/core/justifier.cpp b/src/core/justifier.cpp index 89fcacd2e..3c85a9254 100644 --- a/src/core/justifier.cpp +++ b/src/core/justifier.cpp @@ -215,12 +215,12 @@ void Justifier::UpdatePosition() float display_x, display_y; const auto [window_x, window_y] = (m_has_relative_binds) ? GetAbsolutePositionFromRelativeAxes() : InputManager::GetPointerAbsolutePosition(m_cursor_index); - g_gpu->ConvertScreenCoordinatesToDisplayCoordinates(window_x, window_y, &display_x, &display_y); + g_gpu.ConvertScreenCoordinatesToDisplayCoordinates(window_x, window_y, &display_x, &display_y); // are we within the active display area? u32 tick, line; if (display_x < 0 || display_y < 0 || - !g_gpu->ConvertDisplayCoordinatesToBeamTicksAndLines(display_x, display_y, m_x_scale, &tick, &line) || + !g_gpu.ConvertDisplayCoordinatesToBeamTicksAndLines(display_x, display_y, m_x_scale, &tick, &line) || m_shoot_offscreen) { DEV_LOG("Lightgun out of range for window coordinates {:.0f},{:.0f}", window_x, window_y); @@ -234,11 +234,11 @@ void Justifier::UpdatePosition() m_irq_tick = static_cast(static_cast(tick) + System::ScaleTicksToOverclock(static_cast(m_tick_offset))); m_irq_first_line = static_cast(std::clamp(static_cast(line) + m_first_line_offset, - static_cast(g_gpu->GetCRTCActiveStartLine()), - static_cast(g_gpu->GetCRTCActiveEndLine()))); + static_cast(g_gpu.GetCRTCActiveStartLine()), + static_cast(g_gpu.GetCRTCActiveEndLine()))); m_irq_last_line = static_cast(std::clamp(static_cast(line) + m_last_line_offset, - static_cast(g_gpu->GetCRTCActiveStartLine()), - static_cast(g_gpu->GetCRTCActiveEndLine()))); + static_cast(g_gpu.GetCRTCActiveStartLine()), + static_cast(g_gpu.GetCRTCActiveEndLine()))); DEV_LOG("Lightgun window coordinates {},{} -> dpy {},{} -> tick {} line {} [{}-{}]", window_x, window_y, display_x, display_y, tick, line, m_irq_first_line, m_irq_last_line); @@ -255,7 +255,7 @@ void Justifier::UpdateIRQEvent() return; u32 current_tick, current_line; - g_gpu->GetBeamPosition(¤t_tick, ¤t_line); + g_gpu.GetBeamPosition(¤t_tick, ¤t_line); u32 target_line; if (current_line < m_irq_first_line || current_line >= m_irq_last_line) @@ -263,7 +263,7 @@ void Justifier::UpdateIRQEvent() else target_line = current_line + 1; - const TickCount ticks_until_pos = g_gpu->GetSystemTicksUntilTicksAndLine(m_irq_tick, target_line); + const TickCount ticks_until_pos = g_gpu.GetSystemTicksUntilTicksAndLine(m_irq_tick, target_line); DEBUG_LOG("Triggering IRQ in {} ticks @ tick {} line {}", ticks_until_pos, m_irq_tick, target_line); m_irq_event.Schedule(ticks_until_pos); } diff --git a/src/core/system.cpp b/src/core/system.cpp index d8b9470a3..ca141a18e 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -713,7 +713,7 @@ void System::UpdateOverclock() s_state.max_slice_ticks = ScaleTicksToOverclock(MASTER_CLOCK / 10); SPU::CPUClockChanged(); CDROM::CPUClockChanged(); - g_gpu->CPUClockChanged(); + g_gpu.CPUClockChanged(); Timers::CPUClocksChanged(); UpdateThrottlePeriod(); } @@ -1882,9 +1882,8 @@ bool System::Initialize(std::unique_ptr disc, DiscRegion disc_region, b !CDROM::InsertMedia(std::move(disc), disc_region, s_state.running_game_serial, s_state.running_game_title, error)) return false; - // TODO: Drop pointer - g_gpu = std::make_unique(); - g_gpu->Initialize(); + // TODO: Drop class + g_gpu.Initialize(); // This can fail due to the application being closed during startup. if (!GPUThread::CreateGPUBackend(s_state.running_game_serial, @@ -1965,7 +1964,7 @@ void System::DestroySystem() Timers::Shutdown(); Pad::Shutdown(); CDROM::Shutdown(); - g_gpu.reset(); + g_gpu.Shutdown(); DMA::Shutdown(); PIO::Shutdown(); CPU::CodeCache::Shutdown(); @@ -2100,7 +2099,7 @@ void System::FrameDone() } // Late submission of frame. This is needed because the input poll can determine whether we need to rewind. - g_gpu->QueuePresentCurrentFrame(); + g_gpu.QueuePresentCurrentFrame(); SaveMemoryState(AllocateMemoryState()); } @@ -2386,7 +2385,7 @@ bool System::DoState(StateWrapper& sw, bool update_display) if (!sw.DoMarker("InterruptController") || !InterruptController::DoState(sw)) return false; - if (!sw.DoMarker("GPU") || !g_gpu->DoState(sw, update_display)) + if (!sw.DoMarker("GPU") || !g_gpu.DoState(sw, update_display)) return false; if (!sw.DoMarker("CDROM") || !CDROM::DoState(sw)) @@ -2682,7 +2681,7 @@ void System::DoMemoryState(StateWrapper& sw, MemorySaveState& mss, bool update_d SAVE_COMPONENT("DMA", DMA::DoState(sw)); SAVE_COMPONENT("InterruptController", InterruptController::DoState(sw)); - g_gpu->DoMemoryState(sw, mss, update_display); + g_gpu.DoMemoryState(sw, mss, update_display); SAVE_COMPONENT("CDROM", CDROM::DoState(sw)); SAVE_COMPONENT("Pad", Pad::DoState(sw, true)); @@ -2731,7 +2730,7 @@ void System::InternalReset() PIO::Reset(); DMA::Reset(); InterruptController::Reset(); - g_gpu->Reset(true); + g_gpu.Reset(true); CDROM::Reset(); Pad::Reset(); Timers::Reset(); @@ -3957,7 +3956,7 @@ bool System::DumpVRAM(const char* filename) if (!IsValid()) return false; - return g_gpu->DumpVRAMToFile(filename); + return g_gpu.DumpVRAMToFile(filename); } bool System::DumpSPURAM(const char* filename) @@ -5198,7 +5197,7 @@ bool System::StartRecordingGPUDump(const char* path /*= nullptr*/, u32 num_frame if (!path) path = (auto_path = GetScreenshotPath("psxgpu")).c_str(); - return g_gpu->StartRecordingGPUDump(path, num_frames); + return g_gpu.StartRecordingGPUDump(path, num_frames); } void System::StopRecordingGPUDump() @@ -5206,7 +5205,7 @@ void System::StopRecordingGPUDump() if (!IsValid()) return; - g_gpu->StopRecordingGPUDump(); + g_gpu.StopRecordingGPUDump(); } static std::string_view GetCaptureTypeForMessage(bool capture_video, bool capture_audio) @@ -5686,9 +5685,9 @@ void System::RequestDisplaySize(float scale /*= 0.0f*/) } else { - requested_width = static_cast(g_gpu->GetCRTCDisplayWidth()) * scale; - requested_height = static_cast(g_gpu->GetCRTCDisplayHeight()) * scale; - g_gpu->ApplyPixelAspectRatioToSize(g_gpu->ComputePixelAspectRatio(), &requested_width, &requested_height); + requested_width = static_cast(g_gpu.GetCRTCDisplayWidth()) * scale; + requested_height = static_cast(g_gpu.GetCRTCDisplayHeight()) * scale; + g_gpu.ApplyPixelAspectRatioToSize(g_gpu.ComputePixelAspectRatio(), &requested_width, &requested_height); } if (g_settings.display_rotation == DisplayRotation::Rotate90 || @@ -5734,7 +5733,7 @@ void System::UpdateGTEAspectRatio() { // Pre-apply the native aspect ratio correction to the window size. // MatchWindow does not correct the display aspect ratio, so we need to apply it here. - const float correction = g_gpu->ComputeAspectRatioCorrection(); + const float correction = g_gpu.ComputeAspectRatioCorrection(); custom_num = static_cast(std::max(std::round(static_cast(main_window_info.surface_width) / correction), 1.0f)); custom_denom = std::max(main_window_info.surface_height, 1u); diff --git a/src/core/timers.cpp b/src/core/timers.cpp index c58d6e7ca..4917b2e45 100644 --- a/src/core/timers.cpp +++ b/src/core/timers.cpp @@ -315,8 +315,8 @@ u32 Timers::ReadRegister(u32 offset) if (timer_index < 2 && cs.external_counting_enabled) { // timers 0/1 depend on the GPU - if (timer_index == 0 || g_gpu->IsCRTCScanlinePending()) - g_gpu->SynchronizeCRTC(); + if (timer_index == 0 || g_gpu.IsCRTCScanlinePending()) + g_gpu.SynchronizeCRTC(); } s_state.sysclk_event.InvokeEarly(); @@ -329,8 +329,8 @@ u32 Timers::ReadRegister(u32 offset) if (timer_index < 2 && cs.external_counting_enabled) { // timers 0/1 depend on the GPU - if (timer_index == 0 || g_gpu->IsCRTCScanlinePending()) - g_gpu->SynchronizeCRTC(); + if (timer_index == 0 || g_gpu.IsCRTCScanlinePending()) + g_gpu.SynchronizeCRTC(); } s_state.sysclk_event.InvokeEarly(); @@ -365,8 +365,8 @@ void Timers::WriteRegister(u32 offset, u32 value) if (timer_index < 2 && cs.external_counting_enabled) { // timers 0/1 depend on the GPU - if (timer_index == 0 || g_gpu->IsCRTCScanlinePending()) - g_gpu->SynchronizeCRTC(); + if (timer_index == 0 || g_gpu.IsCRTCScanlinePending()) + g_gpu.SynchronizeCRTC(); } s_state.sysclk_event.InvokeEarly(); diff --git a/src/duckstation-qt/qthost.cpp b/src/duckstation-qt/qthost.cpp index ffec2e7e9..8ec0e6593 100644 --- a/src/duckstation-qt/qthost.cpp +++ b/src/duckstation-qt/qthost.cpp @@ -2081,7 +2081,7 @@ void EmuThread::updatePerformanceCounters(const GPUBackend* gpu_backend) if (gpu_backend) { const u32 render_scale = gpu_backend->GetResolutionScale(); - std::tie(render_width, render_height) = g_gpu->GetFullDisplayResolution(); + std::tie(render_width, render_height) = g_gpu.GetFullDisplayResolution(); render_width *= render_scale; render_height *= render_scale; }