summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h56
-rw-r--r--src/video_core/fence_manager.h72
-rw-r--r--src/video_core/gpu.cpp4
-rw-r--r--src/video_core/gpu.h12
-rw-r--r--src/video_core/query_cache.h39
-rw-r--r--src/video_core/rasterizer_interface.h1
-rw-r--r--src/video_core/renderer_opengl/gl_fence_manager.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_fence_manager.h2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp5
-rw-r--r--src/video_core/renderer_vulkan/vk_fence_manager.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_fence_manager.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp2
-rw-r--r--src/video_core/texture_cache/texture_cache.h50
13 files changed, 117 insertions, 132 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index 372545080..f3aa35295 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -154,12 +154,9 @@ public:
std::lock_guard lock{mutex};
std::vector<MapInterval> objects = GetMapsInRange(addr, size);
- for (auto& object : objects) {
- if (object->IsModified() && object->IsRegistered()) {
- return true;
- }
- }
- return false;
+ return std::any_of(objects.begin(), objects.end(), [](const MapInterval& map) {
+ return map->IsModified() && map->IsRegistered();
+ });
}
/// Mark the specified region as being invalidated
@@ -199,9 +196,9 @@ public:
}
void CommitAsyncFlushes() {
- if (uncommited_flushes) {
+ if (uncommitted_flushes) {
auto commit_list = std::make_shared<std::list<MapInterval>>();
- for (auto& map : *uncommited_flushes) {
+ for (auto& map : *uncommitted_flushes) {
if (map->IsRegistered() && map->IsModified()) {
// TODO(Blinkhawk): Implement backend asynchronous flushing
// AsyncFlushMap(map)
@@ -209,41 +206,34 @@ public:
}
}
if (!commit_list->empty()) {
- commited_flushes.push_back(commit_list);
+ committed_flushes.push_back(commit_list);
} else {
- commited_flushes.emplace_back();
+ committed_flushes.emplace_back();
}
} else {
- commited_flushes.emplace_back();
+ committed_flushes.emplace_back();
}
- uncommited_flushes.reset();
+ uncommitted_flushes.reset();
}
- bool ShouldWaitAsyncFlushes() {
- if (commited_flushes.empty()) {
- return false;
- }
- auto& flush_list = commited_flushes.front();
- if (!flush_list) {
+ bool ShouldWaitAsyncFlushes() const {
+ if (committed_flushes.empty()) {
return false;
}
- return true;
+ return committed_flushes.front() != nullptr;
}
- bool HasUncommitedFlushes() {
- if (uncommited_flushes) {
- return true;
- }
- return false;
+ bool HasUncommittedFlushes() const {
+ return uncommitted_flushes != nullptr;
}
void PopAsyncFlushes() {
- if (commited_flushes.empty()) {
+ if (committed_flushes.empty()) {
return;
}
- auto& flush_list = commited_flushes.front();
+ auto& flush_list = committed_flushes.front();
if (!flush_list) {
- commited_flushes.pop_front();
+ committed_flushes.pop_front();
return;
}
for (MapInterval& map : *flush_list) {
@@ -252,7 +242,7 @@ public:
FlushMap(map);
}
}
- commited_flushes.pop_front();
+ committed_flushes.pop_front();
}
virtual BufferType GetEmptyBuffer(std::size_t size) = 0;
@@ -568,10 +558,10 @@ private:
}
void MarkForAsyncFlush(MapInterval& map) {
- if (!uncommited_flushes) {
- uncommited_flushes = std::make_shared<std::unordered_set<MapInterval>>();
+ if (!uncommitted_flushes) {
+ uncommitted_flushes = std::make_shared<std::unordered_set<MapInterval>>();
}
- uncommited_flushes->insert(map);
+ uncommitted_flushes->insert(map);
}
VideoCore::RasterizerInterface& rasterizer;
@@ -605,8 +595,8 @@ private:
std::vector<u8> staging_buffer;
std::list<MapInterval> marked_for_unregister;
- std::shared_ptr<std::unordered_set<MapInterval>> uncommited_flushes{};
- std::list<std::shared_ptr<std::list<MapInterval>>> commited_flushes;
+ std::shared_ptr<std::unordered_set<MapInterval>> uncommitted_flushes{};
+ std::list<std::shared_ptr<std::list<MapInterval>>> committed_flushes;
std::recursive_mutex mutex;
};
diff --git a/src/video_core/fence_manager.h b/src/video_core/fence_manager.h
index 99a138b5b..9fe9c1bf2 100644
--- a/src/video_core/fence_manager.h
+++ b/src/video_core/fence_manager.h
@@ -28,15 +28,15 @@ public:
FenceBase(GPUVAddr address, u32 payload, bool is_stubbed)
: address{address}, payload{payload}, is_semaphore{true}, is_stubbed{is_stubbed} {}
- constexpr GPUVAddr GetAddress() const {
+ GPUVAddr GetAddress() const {
return address;
}
- constexpr u32 GetPayload() const {
+ u32 GetPayload() const {
return payload;
}
- constexpr bool IsSemaphore() const {
+ bool IsSemaphore() const {
return is_semaphore;
}
@@ -54,12 +54,8 @@ class FenceManager {
public:
void SignalSemaphore(GPUVAddr addr, u32 value) {
TryReleasePendingFences();
- bool should_flush = texture_cache.HasUncommitedFlushes();
- should_flush |= buffer_cache.HasUncommitedFlushes();
- should_flush |= query_cache.HasUncommitedFlushes();
- texture_cache.CommitAsyncFlushes();
- buffer_cache.CommitAsyncFlushes();
- query_cache.CommitAsyncFlushes();
+ bool should_flush = ShouldFlush();
+ CommitAsyncFlushes();
TFence new_fence = CreateFence(addr, value, !should_flush);
fences.push(new_fence);
QueueFence(new_fence);
@@ -71,12 +67,8 @@ public:
void SignalSyncPoint(u32 value) {
TryReleasePendingFences();
- bool should_flush = texture_cache.HasUncommitedFlushes();
- should_flush |= buffer_cache.HasUncommitedFlushes();
- should_flush |= query_cache.HasUncommitedFlushes();
- texture_cache.CommitAsyncFlushes();
- buffer_cache.CommitAsyncFlushes();
- query_cache.CommitAsyncFlushes();
+ bool should_flush = ShouldFlush();
+ CommitAsyncFlushes();
TFence new_fence = CreateFence(value, !should_flush);
fences.push(new_fence);
QueueFence(new_fence);
@@ -89,15 +81,10 @@ public:
void WaitPendingFences() {
while (!fences.empty()) {
TFence& current_fence = fences.front();
- bool should_wait = texture_cache.ShouldWaitAsyncFlushes();
- should_wait |= buffer_cache.ShouldWaitAsyncFlushes();
- should_wait |= query_cache.ShouldWaitAsyncFlushes();
- if (should_wait) {
+ if (ShouldWait()) {
WaitFence(current_fence);
}
- texture_cache.PopAsyncFlushes();
- buffer_cache.PopAsyncFlushes();
- query_cache.PopAsyncFlushes();
+ PopAsyncFlushes();
auto& gpu{system.GPU()};
if (current_fence->IsSemaphore()) {
auto& memory_manager{gpu.MemoryManager()};
@@ -116,10 +103,18 @@ protected:
: system{system}, rasterizer{rasterizer}, texture_cache{texture_cache},
buffer_cache{buffer_cache}, query_cache{query_cache} {}
+ virtual ~FenceManager() {}
+
+ /// Creates a Sync Point Fence Interface, does not create a backend fence if 'is_stubbed' is
+ /// true
virtual TFence CreateFence(u32 value, bool is_stubbed) = 0;
+ /// Creates a Semaphore Fence Interface, does not create a backend fence if 'is_stubbed' is true
virtual TFence CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) = 0;
+ /// Queues a fence into the backend if the fence isn't stubbed.
virtual void QueueFence(TFence& fence) = 0;
- virtual bool IsFenceSignaled(TFence& fence) = 0;
+ /// Notifies that the backend fence has been signaled/reached in host GPU.
+ virtual bool IsFenceSignaled(TFence& fence) const = 0;
+ /// Waits until a fence has been signalled by the host GPU.
virtual void WaitFence(TFence& fence) = 0;
Core::System& system;
@@ -132,15 +127,10 @@ private:
void TryReleasePendingFences() {
while (!fences.empty()) {
TFence& current_fence = fences.front();
- bool should_wait = texture_cache.ShouldWaitAsyncFlushes();
- should_wait |= buffer_cache.ShouldWaitAsyncFlushes();
- should_wait |= query_cache.ShouldWaitAsyncFlushes();
- if (should_wait && !IsFenceSignaled(current_fence)) {
+ if (ShouldWait() && !IsFenceSignaled(current_fence)) {
return;
}
- texture_cache.PopAsyncFlushes();
- buffer_cache.PopAsyncFlushes();
- query_cache.PopAsyncFlushes();
+ PopAsyncFlushes();
auto& gpu{system.GPU()};
if (current_fence->IsSemaphore()) {
auto& memory_manager{gpu.MemoryManager()};
@@ -152,6 +142,28 @@ private:
}
}
+ bool ShouldWait() const {
+ return texture_cache.ShouldWaitAsyncFlushes() || buffer_cache.ShouldWaitAsyncFlushes() ||
+ query_cache.ShouldWaitAsyncFlushes();
+ }
+
+ bool ShouldFlush() const {
+ return texture_cache.HasUncommittedFlushes() || buffer_cache.HasUncommittedFlushes() ||
+ query_cache.HasUncommittedFlushes();
+ }
+
+ void PopAsyncFlushes() {
+ texture_cache.PopAsyncFlushes();
+ buffer_cache.PopAsyncFlushes();
+ query_cache.PopAsyncFlushes();
+ }
+
+ void CommitAsyncFlushes() {
+ texture_cache.CommitAsyncFlushes();
+ buffer_cache.CommitAsyncFlushes();
+ query_cache.CommitAsyncFlushes();
+ }
+
std::queue<TFence> fences;
};
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 85a6c7bb5..3b7572d61 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -125,7 +125,7 @@ bool GPU::CancelSyncptInterrupt(const u32 syncpoint_id, const u32 value) {
return true;
}
-u64 GPU::RequestFlush(CacheAddr addr, std::size_t size) {
+u64 GPU::RequestFlush(VAddr addr, std::size_t size) {
std::unique_lock lck{flush_request_mutex};
const u64 fence = ++last_flush_fence;
flush_requests.emplace_back(fence, addr, size);
@@ -137,7 +137,7 @@ void GPU::TickWork() {
while (!flush_requests.empty()) {
auto& request = flush_requests.front();
const u64 fence = request.fence;
- const CacheAddr addr = request.addr;
+ const VAddr addr = request.addr;
const std::size_t size = request.size;
flush_requests.pop_front();
flush_request_mutex.unlock();
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index 943a5b110..5e3eb94e9 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -155,16 +155,22 @@ public:
/// Calls a GPU method.
void CallMethod(const MethodCall& method_call);
+ /// Flush all current written commands into the host GPU for execution.
void FlushCommands();
+ /// Synchronizes CPU writes with Host GPU memory.
void SyncGuestHost();
+ /// Signal the ending of command list.
virtual void OnCommandListEnd();
- u64 RequestFlush(CacheAddr addr, std::size_t size);
+ /// Request a host GPU memory flush from the CPU.
+ u64 RequestFlush(VAddr addr, std::size_t size);
+ /// Obtains current flush request fence id.
u64 CurrentFlushRequestFence() const {
return current_flush_fence.load(std::memory_order_relaxed);
}
+ /// Tick pending requests within the GPU.
void TickWork();
/// Returns a reference to the Maxwell3D GPU engine.
@@ -336,10 +342,10 @@ private:
std::condition_variable sync_cv;
struct FlushRequest {
- FlushRequest(u64 fence, CacheAddr addr, std::size_t size)
+ FlushRequest(u64 fence, VAddr addr, std::size_t size)
: fence{fence}, addr{addr}, size{size} {}
u64 fence;
- CacheAddr addr;
+ VAddr addr;
std::size_t size;
};
diff --git a/src/video_core/query_cache.h b/src/video_core/query_cache.h
index 98d956b68..2f75f8801 100644
--- a/src/video_core/query_cache.h
+++ b/src/video_core/query_cache.h
@@ -176,41 +176,34 @@ public:
}
void CommitAsyncFlushes() {
- commited_flushes.push_back(uncommited_flushes);
- uncommited_flushes.reset();
+ committed_flushes.push_back(uncommitted_flushes);
+ uncommitted_flushes.reset();
}
- bool HasUncommitedFlushes() {
- if (uncommited_flushes) {
- return true;
- }
- return false;
+ bool HasUncommittedFlushes() const {
+ return uncommitted_flushes != nullptr;
}
- bool ShouldWaitAsyncFlushes() {
- if (commited_flushes.empty()) {
- return false;
- }
- auto& flush_list = commited_flushes.front();
- if (!flush_list) {
+ bool ShouldWaitAsyncFlushes() const {
+ if (committed_flushes.empty()) {
return false;
}
- return true;
+ return committed_flushes.front() != nullptr;
}
void PopAsyncFlushes() {
- if (commited_flushes.empty()) {
+ if (committed_flushes.empty()) {
return;
}
- auto& flush_list = commited_flushes.front();
+ auto& flush_list = committed_flushes.front();
if (!flush_list) {
- commited_flushes.pop_front();
+ committed_flushes.pop_front();
return;
}
for (VAddr query_address : *flush_list) {
FlushAndRemoveRegion(query_address, 4);
}
- commited_flushes.pop_front();
+ committed_flushes.pop_front();
}
protected:
@@ -268,10 +261,10 @@ private:
}
void AsyncFlushQuery(VAddr addr) {
- if (!uncommited_flushes) {
- uncommited_flushes = std::make_shared<std::unordered_set<VAddr>>();
+ if (!uncommitted_flushes) {
+ uncommitted_flushes = std::make_shared<std::unordered_set<VAddr>>();
}
- uncommited_flushes->insert(addr);
+ uncommitted_flushes->insert(addr);
}
static constexpr std::uintptr_t PAGE_SIZE = 4096;
@@ -286,8 +279,8 @@ private:
std::array<CounterStream, VideoCore::NumQueryTypes> streams;
- std::shared_ptr<std::unordered_set<VAddr>> uncommited_flushes{};
- std::list<std::shared_ptr<std::unordered_set<VAddr>>> commited_flushes;
+ std::shared_ptr<std::unordered_set<VAddr>> uncommitted_flushes{};
+ std::list<std::shared_ptr<std::unordered_set<VAddr>>> committed_flushes;
};
template <class QueryCache, class HostCounter>
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h
index 4e9c8fb59..603f61952 100644
--- a/src/video_core/rasterizer_interface.h
+++ b/src/video_core/rasterizer_interface.h
@@ -64,6 +64,7 @@ public:
/// Notify rasterizer that any caches of the specified region should be flushed to Switch memory
virtual void FlushRegion(VAddr addr, u64 size) = 0;
+ /// Check if the the specified memory area requires flushing to CPU Memory.
virtual bool MustFlushRegion(VAddr addr, u64 size) = 0;
/// Notify rasterizer that any caches of the specified region should be invalidated
diff --git a/src/video_core/renderer_opengl/gl_fence_manager.cpp b/src/video_core/renderer_opengl/gl_fence_manager.cpp
index aa57a0ae0..476c89940 100644
--- a/src/video_core/renderer_opengl/gl_fence_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_fence_manager.cpp
@@ -62,7 +62,7 @@ void FenceManagerOpenGL::QueueFence(Fence& fence) {
fence->Queue();
}
-bool FenceManagerOpenGL::IsFenceSignaled(Fence& fence) {
+bool FenceManagerOpenGL::IsFenceSignaled(Fence& fence) const {
return fence->IsSignaled();
}
diff --git a/src/video_core/renderer_opengl/gl_fence_manager.h b/src/video_core/renderer_opengl/gl_fence_manager.h
index c76e69cb8..c917b3343 100644
--- a/src/video_core/renderer_opengl/gl_fence_manager.h
+++ b/src/video_core/renderer_opengl/gl_fence_manager.h
@@ -46,7 +46,7 @@ protected:
Fence CreateFence(u32 value, bool is_stubbed) override;
Fence CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) override;
void QueueFence(Fence& fence) override;
- bool IsFenceSignaled(Fence& fence) override;
+ bool IsFenceSignaled(Fence& fence) const override;
void WaitFence(Fence& fence) override;
};
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 847d67159..d662657cf 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -653,9 +653,6 @@ void RasterizerOpenGL::FlushRegion(VAddr addr, u64 size) {
}
bool RasterizerOpenGL::MustFlushRegion(VAddr addr, u64 size) {
- if (!Settings::IsGPULevelExtreme()) {
- return buffer_cache.MustFlushRegion(addr, size);
- }
return texture_cache.MustFlushRegion(addr, size) || buffer_cache.MustFlushRegion(addr, size);
}
@@ -672,7 +669,7 @@ void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) {
void RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) {
MICROPROFILE_SCOPE(OpenGL_CacheManagement);
- if (!addr || !size) {
+ if (addr == 0 || size == 0) {
return;
}
texture_cache.OnCPUWrite(addr, size);
diff --git a/src/video_core/renderer_vulkan/vk_fence_manager.cpp b/src/video_core/renderer_vulkan/vk_fence_manager.cpp
index a2b2bc408..a02be5487 100644
--- a/src/video_core/renderer_vulkan/vk_fence_manager.cpp
+++ b/src/video_core/renderer_vulkan/vk_fence_manager.cpp
@@ -90,7 +90,7 @@ void VKFenceManager::QueueFence(Fence& fence) {
fence->Queue();
}
-bool VKFenceManager::IsFenceSignaled(Fence& fence) {
+bool VKFenceManager::IsFenceSignaled(Fence& fence) const {
return fence->IsSignaled();
}
diff --git a/src/video_core/renderer_vulkan/vk_fence_manager.h b/src/video_core/renderer_vulkan/vk_fence_manager.h
index 30651e9c7..04d07fe6a 100644
--- a/src/video_core/renderer_vulkan/vk_fence_manager.h
+++ b/src/video_core/renderer_vulkan/vk_fence_manager.h
@@ -63,7 +63,7 @@ protected:
Fence CreateFence(u32 value, bool is_stubbed) override;
Fence CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) override;
void QueueFence(Fence& fence) override;
- bool IsFenceSignaled(Fence& fence) override;
+ bool IsFenceSignaled(Fence& fence) const override;
void WaitFence(Fence& fence) override;
private:
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 4dc7555aa..2350cd5f4 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -533,7 +533,7 @@ void RasterizerVulkan::InvalidateRegion(VAddr addr, u64 size) {
}
void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) {
- if (!addr || !size) {
+ if (addr == 0 || size == 0) {
return;
}
texture_cache.OnCPUWrite(addr, size);
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index f3ca1ffd1..1148c3a34 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -120,15 +120,8 @@ public:
std::lock_guard lock{mutex};
auto surfaces = GetSurfacesInRegion(addr, size);
- if (surfaces.empty()) {
- return false;
- }
- for (const auto& surface : surfaces) {
- if (surface->IsModified()) {
- return true;
- }
- }
- return false;
+ return std::any_of(surfaces.begin(), surfaces.end(),
+ [](const TSurface& surface) { return surface->IsModified(); });
}
TView GetTextureSurface(const Tegra::Texture::TICEntry& tic,
@@ -333,41 +326,34 @@ public:
}
void CommitAsyncFlushes() {
- commited_flushes.push_back(uncommited_flushes);
- uncommited_flushes.reset();
+ committed_flushes.push_back(uncommitted_flushes);
+ uncommitted_flushes.reset();
}
- bool HasUncommitedFlushes() {
- if (uncommited_flushes) {
- return true;
- }
- return false;
+ bool HasUncommittedFlushes() const {
+ return uncommitted_flushes != nullptr;
}
- bool ShouldWaitAsyncFlushes() {
- if (commited_flushes.empty()) {
- return false;
- }
- auto& flush_list = commited_flushes.front();
- if (!flush_list) {
+ bool ShouldWaitAsyncFlushes() const {
+ if (committed_flushes.empty()) {
return false;
}
- return true;
+ return committed_flushes.front() != nullptr;
}
void PopAsyncFlushes() {
- if (commited_flushes.empty()) {
+ if (committed_flushes.empty()) {
return;
}
- auto& flush_list = commited_flushes.front();
+ auto& flush_list = committed_flushes.front();
if (!flush_list) {
- commited_flushes.pop_front();
+ committed_flushes.pop_front();
return;
}
for (TSurface& surface : *flush_list) {
FlushSurface(surface);
}
- commited_flushes.pop_front();
+ committed_flushes.pop_front();
}
protected:
@@ -1206,10 +1192,10 @@ private:
};
void AsyncFlushSurface(TSurface& surface) {
- if (!uncommited_flushes) {
- uncommited_flushes = std::make_shared<std::list<TSurface>>();
+ if (!uncommitted_flushes) {
+ uncommitted_flushes = std::make_shared<std::list<TSurface>>();
}
- uncommited_flushes->push_back(surface);
+ uncommitted_flushes->push_back(surface);
}
VideoCore::RasterizerInterface& rasterizer;
@@ -1258,8 +1244,8 @@ private:
std::list<TSurface> marked_for_unregister;
- std::shared_ptr<std::list<TSurface>> uncommited_flushes{};
- std::list<std::shared_ptr<std::list<TSurface>>> commited_flushes;
+ std::shared_ptr<std::list<TSurface>> uncommitted_flushes{};
+ std::list<std::shared_ptr<std::list<TSurface>>> committed_flushes;
StagingCache staging_cache;
std::recursive_mutex mutex;