Browse Source
Merge pull request #4869 from bunnei/improve-gpu-sync
Merge pull request #4869 from bunnei/improve-gpu-sync
Improvements to GPU synchronization & various refactoringpull/15/merge
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 448 additions and 117 deletions
-
2src/core/CMakeLists.txt
-
10src/core/core.cpp
-
33src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
-
4src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
-
135src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
-
20src/core/hle/service/nvdrv/devices/nvhost_gpu.h
-
17src/core/hle/service/nvdrv/nvdrv.cpp
-
14src/core/hle/service/nvdrv/nvdrv.h
-
39src/core/hle/service/nvdrv/syncpoint_manager.cpp
-
85src/core/hle/service/nvdrv/syncpoint_manager.h
-
4src/core/hle/service/nvflinger/nvflinger.cpp
-
80src/video_core/dma_pusher.cpp
-
49src/video_core/dma_pusher.h
-
48src/video_core/gpu.cpp
-
25src/video_core/gpu.h
@ -0,0 +1,39 @@ |
|||||
|
// Copyright 2020 yuzu emulator team
|
||||
|
// Licensed under GPLv2 or any later version
|
||||
|
// Refer to the license.txt file included.
|
||||
|
|
||||
|
#include "common/assert.h"
|
||||
|
#include "core/hle/service/nvdrv/syncpoint_manager.h"
|
||||
|
#include "video_core/gpu.h"
|
||||
|
|
||||
|
namespace Service::Nvidia { |
||||
|
|
||||
|
SyncpointManager::SyncpointManager(Tegra::GPU& gpu) : gpu{gpu} {} |
||||
|
|
||||
|
SyncpointManager::~SyncpointManager() = default; |
||||
|
|
||||
|
u32 SyncpointManager::RefreshSyncpoint(u32 syncpoint_id) { |
||||
|
syncpoints[syncpoint_id].min = gpu.GetSyncpointValue(syncpoint_id); |
||||
|
return GetSyncpointMin(syncpoint_id); |
||||
|
} |
||||
|
|
||||
|
u32 SyncpointManager::AllocateSyncpoint() { |
||||
|
for (u32 syncpoint_id = 1; syncpoint_id < MaxSyncPoints; syncpoint_id++) { |
||||
|
if (!syncpoints[syncpoint_id].is_allocated) { |
||||
|
syncpoints[syncpoint_id].is_allocated = true; |
||||
|
return syncpoint_id; |
||||
|
} |
||||
|
} |
||||
|
UNREACHABLE_MSG("No more available syncpoints!"); |
||||
|
return {}; |
||||
|
} |
||||
|
|
||||
|
u32 SyncpointManager::IncreaseSyncpoint(u32 syncpoint_id, u32 value) { |
||||
|
for (u32 index = 0; index < value; ++index) { |
||||
|
syncpoints[syncpoint_id].max.fetch_add(1, std::memory_order_relaxed); |
||||
|
} |
||||
|
|
||||
|
return GetSyncpointMax(syncpoint_id); |
||||
|
} |
||||
|
|
||||
|
} // namespace Service::Nvidia
|
||||
@ -0,0 +1,85 @@ |
|||||
|
// Copyright 2020 yuzu emulator team |
||||
|
// Licensed under GPLv2 or any later version |
||||
|
// Refer to the license.txt file included. |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <array> |
||||
|
#include <atomic> |
||||
|
|
||||
|
#include "common/common_types.h" |
||||
|
#include "core/hle/service/nvdrv/nvdata.h" |
||||
|
|
||||
|
namespace Tegra { |
||||
|
class GPU; |
||||
|
} |
||||
|
|
||||
|
namespace Service::Nvidia { |
||||
|
|
||||
|
class SyncpointManager final { |
||||
|
public: |
||||
|
explicit SyncpointManager(Tegra::GPU& gpu); |
||||
|
~SyncpointManager(); |
||||
|
|
||||
|
/** |
||||
|
* Returns true if the specified syncpoint is expired for the given value. |
||||
|
* @param syncpoint_id Syncpoint ID to check. |
||||
|
* @param value Value to check against the specified syncpoint. |
||||
|
* @returns True if the specified syncpoint is expired for the given value, otherwise False. |
||||
|
*/ |
||||
|
bool IsSyncpointExpired(u32 syncpoint_id, u32 value) const { |
||||
|
return (GetSyncpointMax(syncpoint_id) - value) >= (GetSyncpointMin(syncpoint_id) - value); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Gets the lower bound for the specified syncpoint. |
||||
|
* @param syncpoint_id Syncpoint ID to get the lower bound for. |
||||
|
* @returns The lower bound for the specified syncpoint. |
||||
|
*/ |
||||
|
u32 GetSyncpointMin(u32 syncpoint_id) const { |
||||
|
return syncpoints[syncpoint_id].min.load(std::memory_order_relaxed); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Gets the uper bound for the specified syncpoint. |
||||
|
* @param syncpoint_id Syncpoint ID to get the upper bound for. |
||||
|
* @returns The upper bound for the specified syncpoint. |
||||
|
*/ |
||||
|
u32 GetSyncpointMax(u32 syncpoint_id) const { |
||||
|
return syncpoints[syncpoint_id].max.load(std::memory_order_relaxed); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Refreshes the minimum value for the specified syncpoint. |
||||
|
* @param syncpoint_id Syncpoint ID to be refreshed. |
||||
|
* @returns The new syncpoint minimum value. |
||||
|
*/ |
||||
|
u32 RefreshSyncpoint(u32 syncpoint_id); |
||||
|
|
||||
|
/** |
||||
|
* Allocates a new syncoint. |
||||
|
* @returns The syncpoint ID for the newly allocated syncpoint. |
||||
|
*/ |
||||
|
u32 AllocateSyncpoint(); |
||||
|
|
||||
|
/** |
||||
|
* Increases the maximum value for the specified syncpoint. |
||||
|
* @param syncpoint_id Syncpoint ID to be increased. |
||||
|
* @param value Value to increase the specified syncpoint by. |
||||
|
* @returns The new syncpoint maximum value. |
||||
|
*/ |
||||
|
u32 IncreaseSyncpoint(u32 syncpoint_id, u32 value); |
||||
|
|
||||
|
private: |
||||
|
struct Syncpoint { |
||||
|
std::atomic<u32> min; |
||||
|
std::atomic<u32> max; |
||||
|
std::atomic<bool> is_allocated; |
||||
|
}; |
||||
|
|
||||
|
std::array<Syncpoint, MaxSyncPoints> syncpoints{}; |
||||
|
|
||||
|
Tegra::GPU& gpu; |
||||
|
}; |
||||
|
|
||||
|
} // namespace Service::Nvidia |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue