diff options
| -rw-r--r-- | src/core/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/core/core.cpp | 12 | ||||
| -rw-r--r-- | src/core/core.h | 10 | ||||
| -rw-r--r-- | src/core/hardware_interrupt_manager.cpp | 21 | ||||
| -rw-r--r-- | src/core/hardware_interrupt_manager.h | 24 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/interface.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/interface.h | 2 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/nvdrv.h | 5 | ||||
| -rw-r--r-- | src/video_core/gpu.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/gpu.h | 5 | ||||
| -rw-r--r-- | src/video_core/gpu_asynch.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/gpu_asynch.h | 3 | ||||
| -rw-r--r-- | src/video_core/gpu_synch.h | 3 |
13 files changed, 90 insertions, 13 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index c22585bfb..12f06a189 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -111,6 +111,8 @@ add_library(core STATIC | |||
| 111 | frontend/scope_acquire_window_context.h | 111 | frontend/scope_acquire_window_context.h |
| 112 | gdbstub/gdbstub.cpp | 112 | gdbstub/gdbstub.cpp |
| 113 | gdbstub/gdbstub.h | 113 | gdbstub/gdbstub.h |
| 114 | hardware_interrupt_manager.cpp | ||
| 115 | hardware_interrupt_manager.h | ||
| 114 | hle/ipc.h | 116 | hle/ipc.h |
| 115 | hle/ipc_helpers.h | 117 | hle/ipc_helpers.h |
| 116 | hle/kernel/address_arbiter.cpp | 118 | hle/kernel/address_arbiter.cpp |
diff --git a/src/core/core.cpp b/src/core/core.cpp index 262411db8..d7f43f5ec 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include "core/file_sys/vfs_concat.h" | 19 | #include "core/file_sys/vfs_concat.h" |
| 20 | #include "core/file_sys/vfs_real.h" | 20 | #include "core/file_sys/vfs_real.h" |
| 21 | #include "core/gdbstub/gdbstub.h" | 21 | #include "core/gdbstub/gdbstub.h" |
| 22 | #include "core/hardware_interrupt_manager.h" | ||
| 22 | #include "core/hle/kernel/client_port.h" | 23 | #include "core/hle/kernel/client_port.h" |
| 23 | #include "core/hle/kernel/kernel.h" | 24 | #include "core/hle/kernel/kernel.h" |
| 24 | #include "core/hle/kernel/process.h" | 25 | #include "core/hle/kernel/process.h" |
| @@ -150,7 +151,7 @@ struct System::Impl { | |||
| 150 | if (!renderer->Init()) { | 151 | if (!renderer->Init()) { |
| 151 | return ResultStatus::ErrorVideoCore; | 152 | return ResultStatus::ErrorVideoCore; |
| 152 | } | 153 | } |
| 153 | 154 | interrupt_manager = std::make_unique<Core::Hardware::InterruptManager>(system); | |
| 154 | gpu_core = VideoCore::CreateGPU(system); | 155 | gpu_core = VideoCore::CreateGPU(system); |
| 155 | 156 | ||
| 156 | is_powered_on = true; | 157 | is_powered_on = true; |
| @@ -297,6 +298,7 @@ struct System::Impl { | |||
| 297 | std::unique_ptr<VideoCore::RendererBase> renderer; | 298 | std::unique_ptr<VideoCore::RendererBase> renderer; |
| 298 | std::unique_ptr<Tegra::GPU> gpu_core; | 299 | std::unique_ptr<Tegra::GPU> gpu_core; |
| 299 | std::shared_ptr<Tegra::DebugContext> debug_context; | 300 | std::shared_ptr<Tegra::DebugContext> debug_context; |
| 301 | std::unique_ptr<Core::Hardware::InterruptManager> interrupt_manager; | ||
| 300 | CpuCoreManager cpu_core_manager; | 302 | CpuCoreManager cpu_core_manager; |
| 301 | bool is_powered_on = false; | 303 | bool is_powered_on = false; |
| 302 | 304 | ||
| @@ -440,6 +442,14 @@ const Tegra::GPU& System::GPU() const { | |||
| 440 | return *impl->gpu_core; | 442 | return *impl->gpu_core; |
| 441 | } | 443 | } |
| 442 | 444 | ||
| 445 | Core::Hardware::InterruptManager& System::InterruptManager() { | ||
| 446 | return *impl->interrupt_manager; | ||
| 447 | } | ||
| 448 | |||
| 449 | const Core::Hardware::InterruptManager& System::InterruptManager() const { | ||
| 450 | return *impl->interrupt_manager; | ||
| 451 | } | ||
| 452 | |||
| 443 | VideoCore::RendererBase& System::Renderer() { | 453 | VideoCore::RendererBase& System::Renderer() { |
| 444 | return *impl->renderer; | 454 | return *impl->renderer; |
| 445 | } | 455 | } |
diff --git a/src/core/core.h b/src/core/core.h index 70adb7af9..53e6fdb7b 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
| @@ -66,6 +66,10 @@ namespace Core::Timing { | |||
| 66 | class CoreTiming; | 66 | class CoreTiming; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | namespace Core::Hardware { | ||
| 70 | class InterruptManager; | ||
| 71 | } | ||
| 72 | |||
| 69 | namespace Core { | 73 | namespace Core { |
| 70 | 74 | ||
| 71 | class ARM_Interface; | 75 | class ARM_Interface; |
| @@ -230,6 +234,12 @@ public: | |||
| 230 | /// Provides a constant reference to the core timing instance. | 234 | /// Provides a constant reference to the core timing instance. |
| 231 | const Timing::CoreTiming& CoreTiming() const; | 235 | const Timing::CoreTiming& CoreTiming() const; |
| 232 | 236 | ||
| 237 | /// Provides a reference to the interrupt manager instance. | ||
| 238 | Core::Hardware::InterruptManager& InterruptManager(); | ||
| 239 | |||
| 240 | /// Provides a constant reference to the interrupt manager instance. | ||
| 241 | const Core::Hardware::InterruptManager& InterruptManager() const; | ||
| 242 | |||
| 233 | /// Provides a reference to the kernel instance. | 243 | /// Provides a reference to the kernel instance. |
| 234 | Kernel::KernelCore& Kernel(); | 244 | Kernel::KernelCore& Kernel(); |
| 235 | 245 | ||
diff --git a/src/core/hardware_interrupt_manager.cpp b/src/core/hardware_interrupt_manager.cpp new file mode 100644 index 000000000..463d2916c --- /dev/null +++ b/src/core/hardware_interrupt_manager.cpp | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | |||
| 2 | #include "core/core.h" | ||
| 3 | #include "core/hardware_interrupt_manager.h" | ||
| 4 | #include "core/hle/service/nvdrv/interface.h" | ||
| 5 | #include "core/hle/service/sm/sm.h" | ||
| 6 | |||
| 7 | namespace Core::Hardware { | ||
| 8 | |||
| 9 | InterruptManager::InterruptManager(Core::System& system_in) : system(system_in) { | ||
| 10 | gpu_interrupt_event = | ||
| 11 | system.CoreTiming().RegisterEvent("GPUInterrupt", [this](u64 event_index, s64) { | ||
| 12 | auto nvdrv = system.ServiceManager().GetService<Service::Nvidia::NVDRV>("nvdrv"); | ||
| 13 | nvdrv->SignalGPUInterrupt(static_cast<u32>(event_index)); | ||
| 14 | }); | ||
| 15 | } | ||
| 16 | |||
| 17 | void InterruptManager::InterruptGPU(const u32 event_index) { | ||
| 18 | system.CoreTiming().ScheduleEvent(10, gpu_interrupt_event, static_cast<u64>(event_index)); | ||
| 19 | } | ||
| 20 | |||
| 21 | } // namespace Core::Hardware | ||
diff --git a/src/core/hardware_interrupt_manager.h b/src/core/hardware_interrupt_manager.h new file mode 100644 index 000000000..fc565c88b --- /dev/null +++ b/src/core/hardware_interrupt_manager.h | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include "common/common_types.h" | ||
| 4 | #include "core/core_timing.h" | ||
| 5 | |||
| 6 | namespace Core { | ||
| 7 | class System; | ||
| 8 | } | ||
| 9 | |||
| 10 | namespace Core::Hardware { | ||
| 11 | |||
| 12 | class InterruptManager { | ||
| 13 | public: | ||
| 14 | InterruptManager(Core::System& system); | ||
| 15 | ~InterruptManager() = default; | ||
| 16 | |||
| 17 | void InterruptGPU(const u32 event_index); | ||
| 18 | |||
| 19 | private: | ||
| 20 | Core::System& system; | ||
| 21 | Core::Timing::EventType* gpu_interrupt_event{}; | ||
| 22 | }; | ||
| 23 | |||
| 24 | } // namespace Core::Hardware | ||
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp index 76482d16e..d95ba18cb 100644 --- a/src/core/hle/service/nvdrv/interface.cpp +++ b/src/core/hle/service/nvdrv/interface.cpp | |||
| @@ -140,8 +140,6 @@ NVDRV::NVDRV(std::shared_ptr<Module> nvdrv, const char* name) | |||
| 140 | RegisterHandlers(functions); | 140 | RegisterHandlers(functions); |
| 141 | 141 | ||
| 142 | auto& kernel = Core::System::GetInstance().Kernel(); | 142 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 143 | query_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic, | ||
| 144 | "NVDRV::query_event"); | ||
| 145 | } | 143 | } |
| 146 | 144 | ||
| 147 | NVDRV::~NVDRV() = default; | 145 | NVDRV::~NVDRV() = default; |
diff --git a/src/core/hle/service/nvdrv/interface.h b/src/core/hle/service/nvdrv/interface.h index 421b01017..09cf4bb12 100644 --- a/src/core/hle/service/nvdrv/interface.h +++ b/src/core/hle/service/nvdrv/interface.h | |||
| @@ -35,8 +35,6 @@ private: | |||
| 35 | std::shared_ptr<Module> nvdrv; | 35 | std::shared_ptr<Module> nvdrv; |
| 36 | 36 | ||
| 37 | u64 pid{}; | 37 | u64 pid{}; |
| 38 | |||
| 39 | Kernel::EventPair query_event; | ||
| 40 | }; | 38 | }; |
| 41 | 39 | ||
| 42 | } // namespace Service::Nvidia | 40 | } // namespace Service::Nvidia |
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h index 9a4cdc60f..d299f2877 100644 --- a/src/core/hle/service/nvdrv/nvdrv.h +++ b/src/core/hle/service/nvdrv/nvdrv.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <unordered_map> | 8 | #include <unordered_map> |
| 9 | #include <vector> | 9 | #include <vector> |
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "core/hle/kernel/writable_event.h" | ||
| 11 | #include "core/hle/service/nvdrv/nvdata.h" | 12 | #include "core/hle/service/nvdrv/nvdata.h" |
| 12 | #include "core/hle/service/service.h" | 13 | #include "core/hle/service/service.h" |
| 13 | 14 | ||
| @@ -15,10 +16,6 @@ namespace Service::NVFlinger { | |||
| 15 | class NVFlinger; | 16 | class NVFlinger; |
| 16 | } | 17 | } |
| 17 | 18 | ||
| 18 | namespace Kernel { | ||
| 19 | class WritableEvent; | ||
| 20 | } | ||
| 21 | |||
| 22 | namespace Service::Nvidia { | 19 | namespace Service::Nvidia { |
| 23 | 20 | ||
| 24 | namespace Devices { | 21 | namespace Devices { |
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 1d12f0493..06eb570ab 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -29,7 +29,8 @@ u32 FramebufferConfig::BytesPerPixel(PixelFormat format) { | |||
| 29 | UNREACHABLE(); | 29 | UNREACHABLE(); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | GPU::GPU(Core::System& system, VideoCore::RendererBase& renderer) : renderer{renderer} { | 32 | GPU::GPU(Core::System& system, VideoCore::RendererBase& renderer) |
| 33 | : system{system}, renderer{renderer} { | ||
| 33 | auto& rasterizer{renderer.Rasterizer()}; | 34 | auto& rasterizer{renderer.Rasterizer()}; |
| 34 | memory_manager = std::make_unique<Tegra::MemoryManager>(rasterizer); | 35 | memory_manager = std::make_unique<Tegra::MemoryManager>(rasterizer); |
| 35 | dma_pusher = std::make_unique<Tegra::DmaPusher>(*this); | 36 | dma_pusher = std::make_unique<Tegra::DmaPusher>(*this); |
| @@ -87,6 +88,10 @@ u32 GPU::GetSyncpointValue(const u32 syncpoint_id) const { | |||
| 87 | } | 88 | } |
| 88 | 89 | ||
| 89 | void GPU::RegisterEvent(const u32 event_id, const u32 syncpoint_id, const u32 value) { | 90 | void GPU::RegisterEvent(const u32 event_id, const u32 syncpoint_id, const u32 value) { |
| 91 | for (auto& ev : events[syncpoint_id]) { | ||
| 92 | if (ev.event_id == event_id && ev.value == value) | ||
| 93 | return; | ||
| 94 | } | ||
| 90 | events[syncpoint_id].emplace_back(event_id, value); | 95 | events[syncpoint_id].emplace_back(event_id, value); |
| 91 | } | 96 | } |
| 92 | 97 | ||
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 4c97d6c6f..c3e5311fa 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -238,9 +238,7 @@ public: | |||
| 238 | virtual void FlushAndInvalidateRegion(CacheAddr addr, u64 size) = 0; | 238 | virtual void FlushAndInvalidateRegion(CacheAddr addr, u64 size) = 0; |
| 239 | 239 | ||
| 240 | protected: | 240 | protected: |
| 241 | virtual void TriggerCpuInterrupt(const u32 event_id) const { | 241 | virtual void TriggerCpuInterrupt(const u32 event_id) const = 0; |
| 242 | // Todo implement this | ||
| 243 | } | ||
| 244 | 242 | ||
| 245 | private: | 243 | private: |
| 246 | void ProcessBindMethod(const MethodCall& method_call); | 244 | void ProcessBindMethod(const MethodCall& method_call); |
| @@ -260,6 +258,7 @@ private: | |||
| 260 | protected: | 258 | protected: |
| 261 | std::unique_ptr<Tegra::DmaPusher> dma_pusher; | 259 | std::unique_ptr<Tegra::DmaPusher> dma_pusher; |
| 262 | VideoCore::RendererBase& renderer; | 260 | VideoCore::RendererBase& renderer; |
| 261 | Core::System& system; | ||
| 263 | 262 | ||
| 264 | private: | 263 | private: |
| 265 | std::unique_ptr<Tegra::MemoryManager> memory_manager; | 264 | std::unique_ptr<Tegra::MemoryManager> memory_manager; |
diff --git a/src/video_core/gpu_asynch.cpp b/src/video_core/gpu_asynch.cpp index d4e2553a9..7060f9a89 100644 --- a/src/video_core/gpu_asynch.cpp +++ b/src/video_core/gpu_asynch.cpp | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "core/core.h" | ||
| 6 | #include "core/hardware_interrupt_manager.h" | ||
| 5 | #include "video_core/gpu_asynch.h" | 7 | #include "video_core/gpu_asynch.h" |
| 6 | #include "video_core/gpu_thread.h" | 8 | #include "video_core/gpu_thread.h" |
| 7 | #include "video_core/renderer_base.h" | 9 | #include "video_core/renderer_base.h" |
| @@ -38,4 +40,9 @@ void GPUAsynch::FlushAndInvalidateRegion(CacheAddr addr, u64 size) { | |||
| 38 | gpu_thread.FlushAndInvalidateRegion(addr, size); | 40 | gpu_thread.FlushAndInvalidateRegion(addr, size); |
| 39 | } | 41 | } |
| 40 | 42 | ||
| 43 | void GPUAsynch::TriggerCpuInterrupt(const u32 event_id) const { | ||
| 44 | auto& interrupt_manager = system.InterruptManager(); | ||
| 45 | interrupt_manager.InterruptGPU(event_id); | ||
| 46 | } | ||
| 47 | |||
| 41 | } // namespace VideoCommon | 48 | } // namespace VideoCommon |
diff --git a/src/video_core/gpu_asynch.h b/src/video_core/gpu_asynch.h index 30be74cba..d49e9b96e 100644 --- a/src/video_core/gpu_asynch.h +++ b/src/video_core/gpu_asynch.h | |||
| @@ -27,6 +27,9 @@ public: | |||
| 27 | void InvalidateRegion(CacheAddr addr, u64 size) override; | 27 | void InvalidateRegion(CacheAddr addr, u64 size) override; |
| 28 | void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override; | 28 | void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override; |
| 29 | 29 | ||
| 30 | protected: | ||
| 31 | void TriggerCpuInterrupt(const u32 event_id) const override; | ||
| 32 | |||
| 30 | private: | 33 | private: |
| 31 | GPUThread::ThreadManager gpu_thread; | 34 | GPUThread::ThreadManager gpu_thread; |
| 32 | }; | 35 | }; |
diff --git a/src/video_core/gpu_synch.h b/src/video_core/gpu_synch.h index 3031fcf72..09bda854a 100644 --- a/src/video_core/gpu_synch.h +++ b/src/video_core/gpu_synch.h | |||
| @@ -25,6 +25,9 @@ public: | |||
| 25 | void FlushRegion(CacheAddr addr, u64 size) override; | 25 | void FlushRegion(CacheAddr addr, u64 size) override; |
| 26 | void InvalidateRegion(CacheAddr addr, u64 size) override; | 26 | void InvalidateRegion(CacheAddr addr, u64 size) override; |
| 27 | void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override; | 27 | void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override; |
| 28 | |||
| 29 | protected: | ||
| 30 | void TriggerCpuInterrupt(const u32 event_id) const override {} | ||
| 28 | }; | 31 | }; |
| 29 | 32 | ||
| 30 | } // namespace VideoCommon | 33 | } // namespace VideoCommon |