diff options
| author | 2019-06-07 12:56:30 -0400 | |
|---|---|---|
| committer | 2019-07-05 15:49:11 -0400 | |
| commit | 82b829625b89a706dd0d867c529f533fe928710c (patch) | |
| tree | 1d5e4bfcde8843e377ae51e3f0741b9abaa1a26a /src/video_core | |
| parent | nv_services: Correct buffer queue fencing and GPFifo fencing (diff) | |
| download | yuzu-82b829625b89a706dd0d867c529f533fe928710c.tar.gz yuzu-82b829625b89a706dd0d867c529f533fe928710c.tar.xz yuzu-82b829625b89a706dd0d867c529f533fe928710c.zip | |
video_core: Implement GPU side Syncpoints
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/gpu.cpp | 24 | ||||
| -rw-r--r-- | src/video_core/gpu.h | 24 |
3 files changed, 51 insertions, 2 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 8755b8af4..224c27bd2 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp | |||
| @@ -346,8 +346,9 @@ void Maxwell3D::ProcessSyncPoint() { | |||
| 346 | const u32 sync_point = regs.sync_info.sync_point.Value(); | 346 | const u32 sync_point = regs.sync_info.sync_point.Value(); |
| 347 | const u32 increment = regs.sync_info.increment.Value(); | 347 | const u32 increment = regs.sync_info.increment.Value(); |
| 348 | const u32 cache_flush = regs.sync_info.unknown.Value(); | 348 | const u32 cache_flush = regs.sync_info.unknown.Value(); |
| 349 | LOG_DEBUG(HW_GPU, "Syncpoint set {}, increment: {}, unk: {}", sync_point, increment, | 349 | if (increment) { |
| 350 | cache_flush); | 350 | system.GPU().IncrementSyncPoint(sync_point); |
| 351 | } | ||
| 351 | } | 352 | } |
| 352 | 353 | ||
| 353 | void Maxwell3D::DrawArrays() { | 354 | void Maxwell3D::DrawArrays() { |
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 52706505b..1d12f0493 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -66,6 +66,30 @@ const DmaPusher& GPU::DmaPusher() const { | |||
| 66 | return *dma_pusher; | 66 | return *dma_pusher; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | void GPU::IncrementSyncPoint(const u32 syncpoint_id) { | ||
| 70 | syncpoints[syncpoint_id]++; | ||
| 71 | if (!events[syncpoint_id].empty()) { | ||
| 72 | u32 value = syncpoints[syncpoint_id].load(); | ||
| 73 | auto it = events[syncpoint_id].begin(); | ||
| 74 | while (it != events[syncpoint_id].end()) { | ||
| 75 | if (value >= it->value) { | ||
| 76 | TriggerCpuInterrupt(it->event_id); | ||
| 77 | it = events[syncpoint_id].erase(it); | ||
| 78 | continue; | ||
| 79 | } | ||
| 80 | it++; | ||
| 81 | } | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | u32 GPU::GetSyncpointValue(const u32 syncpoint_id) const { | ||
| 86 | return syncpoints[syncpoint_id].load(); | ||
| 87 | } | ||
| 88 | |||
| 89 | void GPU::RegisterEvent(const u32 event_id, const u32 syncpoint_id, const u32 value) { | ||
| 90 | events[syncpoint_id].emplace_back(event_id, value); | ||
| 91 | } | ||
| 92 | |||
| 69 | u32 RenderTargetBytesPerPixel(RenderTargetFormat format) { | 93 | u32 RenderTargetBytesPerPixel(RenderTargetFormat format) { |
| 70 | ASSERT(format != RenderTargetFormat::NONE); | 94 | ASSERT(format != RenderTargetFormat::NONE); |
| 71 | 95 | ||
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index fe6628923..4c97d6c6f 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -5,8 +5,11 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <atomic> | ||
| 9 | #include <list> | ||
| 8 | #include <memory> | 10 | #include <memory> |
| 9 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 12 | #include "core/hle/service/nvdrv/nvdata.h" | ||
| 10 | #include "core/hle/service/nvflinger/buffer_queue.h" | 13 | #include "core/hle/service/nvflinger/buffer_queue.h" |
| 11 | #include "video_core/dma_pusher.h" | 14 | #include "video_core/dma_pusher.h" |
| 12 | 15 | ||
| @@ -164,6 +167,12 @@ public: | |||
| 164 | /// Returns a reference to the GPU DMA pusher. | 167 | /// Returns a reference to the GPU DMA pusher. |
| 165 | Tegra::DmaPusher& DmaPusher(); | 168 | Tegra::DmaPusher& DmaPusher(); |
| 166 | 169 | ||
| 170 | void IncrementSyncPoint(const u32 syncpoint_id); | ||
| 171 | |||
| 172 | u32 GetSyncpointValue(const u32 syncpoint_id) const; | ||
| 173 | |||
| 174 | void RegisterEvent(const u32 event_id, const u32 sync_point_id, const u32 value); | ||
| 175 | |||
| 167 | /// Returns a const reference to the GPU DMA pusher. | 176 | /// Returns a const reference to the GPU DMA pusher. |
| 168 | const Tegra::DmaPusher& DmaPusher() const; | 177 | const Tegra::DmaPusher& DmaPusher() const; |
| 169 | 178 | ||
| @@ -228,6 +237,11 @@ public: | |||
| 228 | /// Notify rasterizer that any caches of the specified region should be flushed and invalidated | 237 | /// Notify rasterizer that any caches of the specified region should be flushed and invalidated |
| 229 | virtual void FlushAndInvalidateRegion(CacheAddr addr, u64 size) = 0; | 238 | virtual void FlushAndInvalidateRegion(CacheAddr addr, u64 size) = 0; |
| 230 | 239 | ||
| 240 | protected: | ||
| 241 | virtual void TriggerCpuInterrupt(const u32 event_id) const { | ||
| 242 | // Todo implement this | ||
| 243 | } | ||
| 244 | |||
| 231 | private: | 245 | private: |
| 232 | void ProcessBindMethod(const MethodCall& method_call); | 246 | void ProcessBindMethod(const MethodCall& method_call); |
| 233 | void ProcessSemaphoreTriggerMethod(); | 247 | void ProcessSemaphoreTriggerMethod(); |
| @@ -262,6 +276,16 @@ private: | |||
| 262 | std::unique_ptr<Engines::MaxwellDMA> maxwell_dma; | 276 | std::unique_ptr<Engines::MaxwellDMA> maxwell_dma; |
| 263 | /// Inline memory engine | 277 | /// Inline memory engine |
| 264 | std::unique_ptr<Engines::KeplerMemory> kepler_memory; | 278 | std::unique_ptr<Engines::KeplerMemory> kepler_memory; |
| 279 | |||
| 280 | std::array<std::atomic<u32>, Service::Nvidia::MaxSyncPoints> syncpoints{}; | ||
| 281 | |||
| 282 | struct Event { | ||
| 283 | Event(const u32 event_id, const u32 value) : event_id(event_id), value(value) {} | ||
| 284 | u32 event_id; | ||
| 285 | u32 value; | ||
| 286 | }; | ||
| 287 | |||
| 288 | std::array<std::list<Event>, Service::Nvidia::MaxSyncPoints> events; | ||
| 265 | }; | 289 | }; |
| 266 | 290 | ||
| 267 | #define ASSERT_REG_POSITION(field_name, position) \ | 291 | #define ASSERT_REG_POSITION(field_name, position) \ |