FenceManager: Manage syncpoints and rename fences to semaphores.

This commit is contained in:
Fernando Sahmkow 2020-02-19 13:40:37 -04:00
parent 96bb961a64
commit b7bc3c2549
11 changed files with 123 additions and 25 deletions

View file

@ -22,7 +22,11 @@ namespace VideoCommon {
class FenceBase {
public:
FenceBase(GPUVAddr address, u32 payload) : address{address}, payload{payload} {}
FenceBase(u32 payload, bool is_stubbed)
: address{}, payload{payload}, is_semaphore{false}, is_stubbed{is_stubbed} {}
FenceBase(GPUVAddr address, u32 payload, bool is_stubbed)
: address{address}, payload{payload}, is_semaphore{true}, is_stubbed{is_stubbed} {}
constexpr GPUVAddr GetAddress() const {
return address;
@ -32,22 +36,49 @@ public:
return payload;
}
constexpr bool IsSemaphore() const {
return is_semaphore;
}
private:
GPUVAddr address;
u32 payload;
bool is_semaphore;
protected:
bool is_stubbed;
};
template <typename TFence, typename TTextureCache, typename TTBufferCache>
class FenceManager {
public:
void SignalFence(GPUVAddr addr, u32 value) {
void SignalSemaphore(GPUVAddr addr, u32 value) {
TryReleasePendingFences();
bool should_flush = texture_cache.HasUncommitedFlushes();
should_flush |= buffer_cache.HasUncommitedFlushes();
texture_cache.CommitAsyncFlushes();
buffer_cache.CommitAsyncFlushes();
TFence new_fence = CreateFence(addr, value);
TFence new_fence = CreateFence(addr, value, !should_flush);
fences.push(new_fence);
QueueFence(new_fence);
rasterizer.FlushCommands();
if (should_flush) {
rasterizer.FlushCommands();
}
rasterizer.SyncGuestHost();
}
void SignalSyncPoint(u32 value) {
TryReleasePendingFences();
bool should_flush = texture_cache.HasUncommitedFlushes();
should_flush |= buffer_cache.HasUncommitedFlushes();
texture_cache.CommitAsyncFlushes();
buffer_cache.CommitAsyncFlushes();
TFence new_fence = CreateFence(value, !should_flush);
fences.push(new_fence);
QueueFence(new_fence);
if (should_flush) {
rasterizer.FlushCommands();
}
rasterizer.SyncGuestHost();
}
@ -62,8 +93,12 @@ public:
texture_cache.PopAsyncFlushes();
buffer_cache.PopAsyncFlushes();
auto& gpu{system.GPU()};
auto& memory_manager{gpu.MemoryManager()};
memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload());
if (current_fence->IsSemaphore()) {
auto& memory_manager{gpu.MemoryManager()};
memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload());
} else {
gpu.IncrementSyncPoint(current_fence->GetPayload());
}
fences.pop();
}
}
@ -74,7 +109,8 @@ protected:
: system{system}, rasterizer{rasterizer}, texture_cache{texture_cache}, buffer_cache{
buffer_cache} {}
virtual TFence CreateFence(GPUVAddr addr, u32 value) = 0;
virtual TFence CreateFence(u32 value, bool is_stubbed) = 0;
virtual TFence CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) = 0;
virtual void QueueFence(TFence& fence) = 0;
virtual bool IsFenceSignaled(TFence& fence) = 0;
virtual void WaitFence(TFence& fence) = 0;
@ -96,8 +132,12 @@ private:
texture_cache.PopAsyncFlushes();
buffer_cache.PopAsyncFlushes();
auto& gpu{system.GPU()};
auto& memory_manager{gpu.MemoryManager()};
memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload());
if (current_fence->IsSemaphore()) {
auto& memory_manager{gpu.MemoryManager()};
memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload());
} else {
gpu.IncrementSyncPoint(current_fence->GetPayload());
}
fences.pop();
}
}