Fernando Sahmkow 7 лет назад
Родитель
Сommit
eef55f493b
3 измененных файлов с 19 добавлено и 0 удалено
  1. 6 0
      src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
  2. 2 0
      src/video_core/gpu.cpp
  3. 11 0
      src/video_core/gpu.h

+ 6 - 0
src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp

@@ -60,10 +60,12 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
     }
 
     auto& gpu = Core::System::GetInstance().GPU();
+    gpu.Guard(true);
     u32 current_syncpoint_value = gpu.GetSyncpointValue(params.syncpt_id);
     if (current_syncpoint_value >= params.threshold) {
         params.value = current_syncpoint_value;
         std::memcpy(output.data(), &params, sizeof(params));
+        gpu.Guard(false);
         return NvResult::Success;
     }
 
@@ -73,6 +75,7 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
 
     if (params.timeout == 0) {
         std::memcpy(output.data(), &params, sizeof(params));
+        gpu.Guard(false);
         return NvResult::Timeout;
     }
 
@@ -81,6 +84,7 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
         event_id = params.value & 0x00FF;
         if (event_id >= 64) {
             std::memcpy(output.data(), &params, sizeof(params));
+            gpu.Guard(false);
             return NvResult::BadParameter;
         }
     } else {
@@ -100,9 +104,11 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
         params.value |= event_id;
         gpu.RegisterEvent(event_id, params.syncpt_id, params.threshold);
         std::memcpy(output.data(), &params, sizeof(params));
+        gpu.Guard(false);
         return NvResult::Timeout;
     }
     std::memcpy(output.data(), &params, sizeof(params));
+    gpu.Guard(false);
     return NvResult::BadParameter;
 }
 

+ 2 - 0
src/video_core/gpu.cpp

@@ -69,6 +69,7 @@ const DmaPusher& GPU::DmaPusher() const {
 
 void GPU::IncrementSyncPoint(const u32 syncpoint_id) {
     syncpoints[syncpoint_id]++;
+    sync_guard.lock();
     if (!events[syncpoint_id].empty()) {
         u32 value = syncpoints[syncpoint_id].load();
         auto it = events[syncpoint_id].begin();
@@ -81,6 +82,7 @@ void GPU::IncrementSyncPoint(const u32 syncpoint_id) {
             it++;
         }
     }
+    sync_guard.unlock();
 }
 
 u32 GPU::GetSyncpointValue(const u32 syncpoint_id) const {

+ 11 - 0
src/video_core/gpu.h

@@ -12,6 +12,7 @@
 #include "core/hle/service/nvdrv/nvdata.h"
 #include "core/hle/service/nvflinger/buffer_queue.h"
 #include "video_core/dma_pusher.h"
+#include "common/spin_lock.h"
 
 using CacheAddr = std::uintptr_t;
 inline CacheAddr ToCacheAddr(const void* host_ptr) {
@@ -175,6 +176,14 @@ public:
 
     void CancelEvent(const u32 event_id, const u32 syncpoint_id, const u32 value);
 
+    void Guard(bool guard_set) {
+        if (guard_set) {
+            sync_guard.lock();
+        } else {
+            sync_guard.unlock();
+        }
+    }
+
     /// Returns a const reference to the GPU DMA pusher.
     const Tegra::DmaPusher& DmaPusher() const;
 
@@ -287,6 +296,8 @@ private:
     };
 
     std::array<std::list<Event>, Service::Nvidia::MaxSyncPoints> events;
+
+    Common::SpinLock sync_guard{};
 };
 
 #define ASSERT_REG_POSITION(field_name, position)                                                  \