diff options
author | Lioncash <mathew1800@gmail.com> | 2018-08-03 12:55:58 -0400 |
---|---|---|
committer | Lioncash <mathew1800@gmail.com> | 2018-08-04 02:36:57 -0400 |
commit | 6030c5ce412e44ddcfe0a31c6747a017166bf33d (patch) | |
tree | 2b79fa019f07e601b5170e92e93b69788ffde949 /src/core | |
parent | 762fcaf5dec6ab6de92cb2481ae0d1392bc3482a (diff) |
video_core: Eliminate the g_renderer global variable
We move the initialization of the renderer to the core class, while
keeping the creation of it and any other specifics in video_core. This
way we can ensure that the renderer is initialized and doesn't give
unfettered access to the renderer. This also makes dependencies on types
more explicit.
For example, the GPU class doesn't need to depend on the
existence of a renderer, it only needs to care about whether or not it
has a rasterizer, but since it was accessing the global variable, it was
also making the renderer a part of its dependency chain. By adjusting
the interface, we can get rid of this dependency.
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/core.cpp | 9 | ||||
-rw-r--r-- | src/core/core.h | 22 | ||||
-rw-r--r-- | src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | 6 | ||||
-rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | 11 | ||||
-rw-r--r-- | src/core/hle/service/nvflinger/nvflinger.cpp | 6 | ||||
-rw-r--r-- | src/core/memory.cpp | 18 | ||||
-rw-r--r-- | src/core/settings.cpp | 6 |
7 files changed, 54 insertions, 24 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index 9824769cfa..29222babaa 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -18,6 +18,7 @@ #include "core/loader/loader.h" #include "core/settings.h" #include "file_sys/vfs_real.h" +#include "video_core/renderer_base.h" #include "video_core/video_core.h" namespace Core { @@ -174,7 +175,6 @@ System::ResultStatus System::Init(EmuWindow& emu_window) { cpu_cores[index] = std::make_shared<Cpu>(cpu_exclusive_monitor, cpu_barrier, index); } - gpu_core = std::make_unique<Tegra::GPU>(); telemetry_session = std::make_unique<Core::TelemetrySession>(); service_manager = std::make_shared<Service::SM::ServiceManager>(); @@ -182,10 +182,13 @@ System::ResultStatus System::Init(EmuWindow& emu_window) { Service::Init(service_manager); GDBStub::Init(); - if (!VideoCore::Init(emu_window)) { + renderer = VideoCore::CreateRenderer(emu_window); + if (!renderer->Init()) { return ResultStatus::ErrorVideoCore; } + gpu_core = std::make_unique<Tegra::GPU>(*renderer->Rasterizer()); + // Create threads for CPU cores 1-3, and build thread_to_cpu map // CPU core 0 is run on the main thread thread_to_cpu[std::this_thread::get_id()] = cpu_cores[0]; @@ -217,7 +220,7 @@ void System::Shutdown() { perf_results.frametime * 1000.0); // Shutdown emulation session - VideoCore::Shutdown(); + renderer.reset(); GDBStub::Shutdown(); Service::Shutdown(); Kernel::Shutdown(); diff --git a/src/core/core.h b/src/core/core.h index ed475ac4ef..059db4262c 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -27,6 +27,10 @@ namespace Service::SM { class ServiceManager; } +namespace VideoCore { +class RendererBase; +} + namespace Core { class System { @@ -127,11 +131,26 @@ public: /// Gets a CPU interface to the CPU core with the specified index Cpu& CpuCore(size_t core_index); - /// Gets the GPU interface + /// Gets a mutable reference to the GPU interface Tegra::GPU& GPU() { return *gpu_core; } + /// Gets an immutable reference to the GPU interface. + const Tegra::GPU& GPU() const { + return *gpu_core; + } + + /// Gets a mutable reference to the renderer. + VideoCore::RendererBase& Renderer() { + return *renderer; + } + + /// Gets an immutable reference to the renderer. + const VideoCore::RendererBase& Renderer() const { + return *renderer; + } + /// Gets the scheduler for the CPU core that is currently running Kernel::Scheduler& CurrentScheduler() { return *CurrentCpuCore().Scheduler(); @@ -195,6 +214,7 @@ private: /// AppLoader used to load the current executing application std::unique_ptr<Loader::AppLoader> app_loader; + std::unique_ptr<VideoCore::RendererBase> renderer; std::unique_ptr<Tegra::GPU> gpu_core; std::shared_ptr<Tegra::DebugContext> debug_context; Kernel::SharedPtr<Kernel::Process> current_process; diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index ed69a4325d..2b74e6a339 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp @@ -30,9 +30,9 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3 addr, offset, width, height, stride, static_cast<PixelFormat>(format), transform, crop_rect}; - Core::System::GetInstance().perf_stats.EndGameFrame(); - - VideoCore::g_renderer->SwapBuffers(framebuffer); + auto& instance = Core::System::GetInstance(); + instance.perf_stats.EndGameFrame(); + instance.Renderer().SwapBuffers(framebuffer); } } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 57b128b40a..06151a1ea1 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp @@ -150,15 +150,16 @@ u32 nvhost_as_gpu::UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& ou LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset); - auto& gpu = Core::System::GetInstance().GPU(); - - auto itr = buffer_mappings.find(params.offset); - + const auto itr = buffer_mappings.find(params.offset); ASSERT_MSG(itr != buffer_mappings.end(), "Tried to unmap invalid mapping"); + auto& system_instance = Core::System::GetInstance(); + // Remove this memory region from the rasterizer cache. - VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(params.offset, itr->second.size); + system_instance.Renderer().Rasterizer()->FlushAndInvalidateRegion(params.offset, + itr->second.size); + auto& gpu = system_instance.GPU(); params.offset = gpu.memory_manager->UnmapBuffer(params.offset, itr->second.size); buffer_mappings.erase(itr->second.offset); diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 5344441e1d..0bf51062cb 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -127,9 +127,11 @@ void NVFlinger::Compose() { MicroProfileFlip(); if (buffer == boost::none) { + auto& system_instance = Core::System::GetInstance(); + // There was no queued buffer to draw, render previous frame - Core::System::GetInstance().perf_stats.EndGameFrame(); - VideoCore::g_renderer->SwapBuffers({}); + system_instance.perf_stats.EndGameFrame(); + system_instance.Renderer().SwapBuffers({}); continue; } diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 4b3bb7b31a..a8f08e1da5 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -326,34 +326,36 @@ void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached) } void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode) { + auto& system_instance = Core::System::GetInstance(); + // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be // null here - if (VideoCore::g_renderer == nullptr) { + if (!system_instance.IsPoweredOn()) { return; } VAddr end = start + size; - auto CheckRegion = [&](VAddr region_start, VAddr region_end) { + const auto CheckRegion = [&](VAddr region_start, VAddr region_end) { if (start >= region_end || end <= region_start) { // No overlap with region return; } - VAddr overlap_start = std::max(start, region_start); - VAddr overlap_end = std::min(end, region_end); + const VAddr overlap_start = std::max(start, region_start); + const VAddr overlap_end = std::min(end, region_end); - std::vector<Tegra::GPUVAddr> gpu_addresses = - Core::System::GetInstance().GPU().memory_manager->CpuToGpuAddress(overlap_start); + const std::vector<Tegra::GPUVAddr> gpu_addresses = + system_instance.GPU().memory_manager->CpuToGpuAddress(overlap_start); if (gpu_addresses.empty()) { return; } - u64 overlap_size = overlap_end - overlap_start; + const u64 overlap_size = overlap_end - overlap_start; for (const auto& gpu_address : gpu_addresses) { - auto* rasterizer = VideoCore::g_renderer->Rasterizer(); + auto* rasterizer = system_instance.Renderer().Rasterizer(); switch (mode) { case FlushMode::Flush: rasterizer->FlushRegion(gpu_address, overlap_size); diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 79e0b347b8..a4623223d1 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "core/core.h" #include "core/gdbstub/gdbstub.h" #include "core/hle/service/hid/hid.h" #include "core/settings.h" @@ -19,8 +20,9 @@ void Apply() { VideoCore::g_toggle_framelimit_enabled = values.toggle_framelimit; - if (VideoCore::g_renderer) { - VideoCore::g_renderer->UpdateCurrentFramebufferLayout(); + auto& system_instance = Core::System::GetInstance(); + if (system_instance.IsPoweredOn()) { + system_instance.Renderer().UpdateCurrentFramebufferLayout(); } Service::HID::ReloadInputDevices(); |