mirror of https://git.suyu.dev/suyu/suyu
Address Feedback.
This commit is contained in:
parent
ec2f3e48e1
commit
f616dc0b59
|
@ -154,12 +154,9 @@ public:
|
||||||
std::lock_guard lock{mutex};
|
std::lock_guard lock{mutex};
|
||||||
|
|
||||||
std::vector<MapInterval> objects = GetMapsInRange(addr, size);
|
std::vector<MapInterval> objects = GetMapsInRange(addr, size);
|
||||||
for (auto& object : objects) {
|
return std::any_of(objects.begin(), objects.end(), [](const MapInterval& map) {
|
||||||
if (object->IsModified() && object->IsRegistered()) {
|
return map->IsModified() && map->IsRegistered();
|
||||||
return true;
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark the specified region as being invalidated
|
/// Mark the specified region as being invalidated
|
||||||
|
@ -199,9 +196,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommitAsyncFlushes() {
|
void CommitAsyncFlushes() {
|
||||||
if (uncommited_flushes) {
|
if (uncommitted_flushes) {
|
||||||
auto commit_list = std::make_shared<std::list<MapInterval>>();
|
auto commit_list = std::make_shared<std::list<MapInterval>>();
|
||||||
for (auto& map : *uncommited_flushes) {
|
for (auto& map : *uncommitted_flushes) {
|
||||||
if (map->IsRegistered() && map->IsModified()) {
|
if (map->IsRegistered() && map->IsModified()) {
|
||||||
// TODO(Blinkhawk): Implement backend asynchronous flushing
|
// TODO(Blinkhawk): Implement backend asynchronous flushing
|
||||||
// AsyncFlushMap(map)
|
// AsyncFlushMap(map)
|
||||||
|
@ -209,41 +206,34 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!commit_list->empty()) {
|
if (!commit_list->empty()) {
|
||||||
commited_flushes.push_back(commit_list);
|
committed_flushes.push_back(commit_list);
|
||||||
} else {
|
} else {
|
||||||
commited_flushes.emplace_back();
|
committed_flushes.emplace_back();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
commited_flushes.emplace_back();
|
committed_flushes.emplace_back();
|
||||||
}
|
}
|
||||||
uncommited_flushes.reset();
|
uncommitted_flushes.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShouldWaitAsyncFlushes() {
|
bool ShouldWaitAsyncFlushes() const {
|
||||||
if (commited_flushes.empty()) {
|
if (committed_flushes.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto& flush_list = commited_flushes.front();
|
return committed_flushes.front() != nullptr;
|
||||||
if (!flush_list) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasUncommitedFlushes() {
|
bool HasUncommittedFlushes() const {
|
||||||
if (uncommited_flushes) {
|
return uncommitted_flushes != nullptr;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopAsyncFlushes() {
|
void PopAsyncFlushes() {
|
||||||
if (commited_flushes.empty()) {
|
if (committed_flushes.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto& flush_list = commited_flushes.front();
|
auto& flush_list = committed_flushes.front();
|
||||||
if (!flush_list) {
|
if (!flush_list) {
|
||||||
commited_flushes.pop_front();
|
committed_flushes.pop_front();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (MapInterval& map : *flush_list) {
|
for (MapInterval& map : *flush_list) {
|
||||||
|
@ -252,7 +242,7 @@ public:
|
||||||
FlushMap(map);
|
FlushMap(map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
commited_flushes.pop_front();
|
committed_flushes.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual BufferType GetEmptyBuffer(std::size_t size) = 0;
|
virtual BufferType GetEmptyBuffer(std::size_t size) = 0;
|
||||||
|
@ -568,10 +558,10 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void MarkForAsyncFlush(MapInterval& map) {
|
void MarkForAsyncFlush(MapInterval& map) {
|
||||||
if (!uncommited_flushes) {
|
if (!uncommitted_flushes) {
|
||||||
uncommited_flushes = std::make_shared<std::unordered_set<MapInterval>>();
|
uncommitted_flushes = std::make_shared<std::unordered_set<MapInterval>>();
|
||||||
}
|
}
|
||||||
uncommited_flushes->insert(map);
|
uncommitted_flushes->insert(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoCore::RasterizerInterface& rasterizer;
|
VideoCore::RasterizerInterface& rasterizer;
|
||||||
|
@ -605,8 +595,8 @@ private:
|
||||||
std::vector<u8> staging_buffer;
|
std::vector<u8> staging_buffer;
|
||||||
std::list<MapInterval> marked_for_unregister;
|
std::list<MapInterval> marked_for_unregister;
|
||||||
|
|
||||||
std::shared_ptr<std::unordered_set<MapInterval>> uncommited_flushes{};
|
std::shared_ptr<std::unordered_set<MapInterval>> uncommitted_flushes{};
|
||||||
std::list<std::shared_ptr<std::list<MapInterval>>> commited_flushes;
|
std::list<std::shared_ptr<std::list<MapInterval>>> committed_flushes;
|
||||||
|
|
||||||
std::recursive_mutex mutex;
|
std::recursive_mutex mutex;
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,15 +28,15 @@ public:
|
||||||
FenceBase(GPUVAddr address, u32 payload, bool is_stubbed)
|
FenceBase(GPUVAddr address, u32 payload, bool is_stubbed)
|
||||||
: address{address}, payload{payload}, is_semaphore{true}, is_stubbed{is_stubbed} {}
|
: address{address}, payload{payload}, is_semaphore{true}, is_stubbed{is_stubbed} {}
|
||||||
|
|
||||||
constexpr GPUVAddr GetAddress() const {
|
GPUVAddr GetAddress() const {
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr u32 GetPayload() const {
|
u32 GetPayload() const {
|
||||||
return payload;
|
return payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool IsSemaphore() const {
|
bool IsSemaphore() const {
|
||||||
return is_semaphore;
|
return is_semaphore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,12 +54,8 @@ class FenceManager {
|
||||||
public:
|
public:
|
||||||
void SignalSemaphore(GPUVAddr addr, u32 value) {
|
void SignalSemaphore(GPUVAddr addr, u32 value) {
|
||||||
TryReleasePendingFences();
|
TryReleasePendingFences();
|
||||||
bool should_flush = texture_cache.HasUncommitedFlushes();
|
bool should_flush = ShouldFlush();
|
||||||
should_flush |= buffer_cache.HasUncommitedFlushes();
|
CommitAsyncFlushes();
|
||||||
should_flush |= query_cache.HasUncommitedFlushes();
|
|
||||||
texture_cache.CommitAsyncFlushes();
|
|
||||||
buffer_cache.CommitAsyncFlushes();
|
|
||||||
query_cache.CommitAsyncFlushes();
|
|
||||||
TFence new_fence = CreateFence(addr, value, !should_flush);
|
TFence new_fence = CreateFence(addr, value, !should_flush);
|
||||||
fences.push(new_fence);
|
fences.push(new_fence);
|
||||||
QueueFence(new_fence);
|
QueueFence(new_fence);
|
||||||
|
@ -71,12 +67,8 @@ public:
|
||||||
|
|
||||||
void SignalSyncPoint(u32 value) {
|
void SignalSyncPoint(u32 value) {
|
||||||
TryReleasePendingFences();
|
TryReleasePendingFences();
|
||||||
bool should_flush = texture_cache.HasUncommitedFlushes();
|
bool should_flush = ShouldFlush();
|
||||||
should_flush |= buffer_cache.HasUncommitedFlushes();
|
CommitAsyncFlushes();
|
||||||
should_flush |= query_cache.HasUncommitedFlushes();
|
|
||||||
texture_cache.CommitAsyncFlushes();
|
|
||||||
buffer_cache.CommitAsyncFlushes();
|
|
||||||
query_cache.CommitAsyncFlushes();
|
|
||||||
TFence new_fence = CreateFence(value, !should_flush);
|
TFence new_fence = CreateFence(value, !should_flush);
|
||||||
fences.push(new_fence);
|
fences.push(new_fence);
|
||||||
QueueFence(new_fence);
|
QueueFence(new_fence);
|
||||||
|
@ -89,15 +81,10 @@ public:
|
||||||
void WaitPendingFences() {
|
void WaitPendingFences() {
|
||||||
while (!fences.empty()) {
|
while (!fences.empty()) {
|
||||||
TFence& current_fence = fences.front();
|
TFence& current_fence = fences.front();
|
||||||
bool should_wait = texture_cache.ShouldWaitAsyncFlushes();
|
if (ShouldWait()) {
|
||||||
should_wait |= buffer_cache.ShouldWaitAsyncFlushes();
|
|
||||||
should_wait |= query_cache.ShouldWaitAsyncFlushes();
|
|
||||||
if (should_wait) {
|
|
||||||
WaitFence(current_fence);
|
WaitFence(current_fence);
|
||||||
}
|
}
|
||||||
texture_cache.PopAsyncFlushes();
|
PopAsyncFlushes();
|
||||||
buffer_cache.PopAsyncFlushes();
|
|
||||||
query_cache.PopAsyncFlushes();
|
|
||||||
auto& gpu{system.GPU()};
|
auto& gpu{system.GPU()};
|
||||||
if (current_fence->IsSemaphore()) {
|
if (current_fence->IsSemaphore()) {
|
||||||
auto& memory_manager{gpu.MemoryManager()};
|
auto& memory_manager{gpu.MemoryManager()};
|
||||||
|
@ -116,10 +103,18 @@ protected:
|
||||||
: system{system}, rasterizer{rasterizer}, texture_cache{texture_cache},
|
: system{system}, rasterizer{rasterizer}, texture_cache{texture_cache},
|
||||||
buffer_cache{buffer_cache}, query_cache{query_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;
|
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;
|
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 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;
|
virtual void WaitFence(TFence& fence) = 0;
|
||||||
|
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
|
@ -132,15 +127,10 @@ private:
|
||||||
void TryReleasePendingFences() {
|
void TryReleasePendingFences() {
|
||||||
while (!fences.empty()) {
|
while (!fences.empty()) {
|
||||||
TFence& current_fence = fences.front();
|
TFence& current_fence = fences.front();
|
||||||
bool should_wait = texture_cache.ShouldWaitAsyncFlushes();
|
if (ShouldWait() && !IsFenceSignaled(current_fence)) {
|
||||||
should_wait |= buffer_cache.ShouldWaitAsyncFlushes();
|
|
||||||
should_wait |= query_cache.ShouldWaitAsyncFlushes();
|
|
||||||
if (should_wait && !IsFenceSignaled(current_fence)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
texture_cache.PopAsyncFlushes();
|
PopAsyncFlushes();
|
||||||
buffer_cache.PopAsyncFlushes();
|
|
||||||
query_cache.PopAsyncFlushes();
|
|
||||||
auto& gpu{system.GPU()};
|
auto& gpu{system.GPU()};
|
||||||
if (current_fence->IsSemaphore()) {
|
if (current_fence->IsSemaphore()) {
|
||||||
auto& memory_manager{gpu.MemoryManager()};
|
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;
|
std::queue<TFence> fences;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ bool GPU::CancelSyncptInterrupt(const u32 syncpoint_id, const u32 value) {
|
||||||
return true;
|
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};
|
std::unique_lock lck{flush_request_mutex};
|
||||||
const u64 fence = ++last_flush_fence;
|
const u64 fence = ++last_flush_fence;
|
||||||
flush_requests.emplace_back(fence, addr, size);
|
flush_requests.emplace_back(fence, addr, size);
|
||||||
|
@ -137,7 +137,7 @@ void GPU::TickWork() {
|
||||||
while (!flush_requests.empty()) {
|
while (!flush_requests.empty()) {
|
||||||
auto& request = flush_requests.front();
|
auto& request = flush_requests.front();
|
||||||
const u64 fence = request.fence;
|
const u64 fence = request.fence;
|
||||||
const CacheAddr addr = request.addr;
|
const VAddr addr = request.addr;
|
||||||
const std::size_t size = request.size;
|
const std::size_t size = request.size;
|
||||||
flush_requests.pop_front();
|
flush_requests.pop_front();
|
||||||
flush_request_mutex.unlock();
|
flush_request_mutex.unlock();
|
||||||
|
|
|
@ -155,16 +155,22 @@ public:
|
||||||
/// Calls a GPU method.
|
/// Calls a GPU method.
|
||||||
void CallMethod(const MethodCall& method_call);
|
void CallMethod(const MethodCall& method_call);
|
||||||
|
|
||||||
|
/// Flush all current written commands into the host GPU for execution.
|
||||||
void FlushCommands();
|
void FlushCommands();
|
||||||
|
/// Synchronizes CPU writes with Host GPU memory.
|
||||||
void SyncGuestHost();
|
void SyncGuestHost();
|
||||||
|
/// Signal the ending of command list.
|
||||||
virtual void OnCommandListEnd();
|
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 {
|
u64 CurrentFlushRequestFence() const {
|
||||||
return current_flush_fence.load(std::memory_order_relaxed);
|
return current_flush_fence.load(std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Tick pending requests within the GPU.
|
||||||
void TickWork();
|
void TickWork();
|
||||||
|
|
||||||
/// Returns a reference to the Maxwell3D GPU engine.
|
/// Returns a reference to the Maxwell3D GPU engine.
|
||||||
|
@ -336,10 +342,10 @@ private:
|
||||||
std::condition_variable sync_cv;
|
std::condition_variable sync_cv;
|
||||||
|
|
||||||
struct FlushRequest {
|
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} {}
|
: fence{fence}, addr{addr}, size{size} {}
|
||||||
u64 fence;
|
u64 fence;
|
||||||
CacheAddr addr;
|
VAddr addr;
|
||||||
std::size_t size;
|
std::size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -176,41 +176,34 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommitAsyncFlushes() {
|
void CommitAsyncFlushes() {
|
||||||
commited_flushes.push_back(uncommited_flushes);
|
committed_flushes.push_back(uncommitted_flushes);
|
||||||
uncommited_flushes.reset();
|
uncommitted_flushes.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasUncommitedFlushes() {
|
bool HasUncommittedFlushes() const {
|
||||||
if (uncommited_flushes) {
|
return uncommitted_flushes != nullptr;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShouldWaitAsyncFlushes() {
|
bool ShouldWaitAsyncFlushes() const {
|
||||||
if (commited_flushes.empty()) {
|
if (committed_flushes.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto& flush_list = commited_flushes.front();
|
return committed_flushes.front() != nullptr;
|
||||||
if (!flush_list) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopAsyncFlushes() {
|
void PopAsyncFlushes() {
|
||||||
if (commited_flushes.empty()) {
|
if (committed_flushes.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto& flush_list = commited_flushes.front();
|
auto& flush_list = committed_flushes.front();
|
||||||
if (!flush_list) {
|
if (!flush_list) {
|
||||||
commited_flushes.pop_front();
|
committed_flushes.pop_front();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (VAddr query_address : *flush_list) {
|
for (VAddr query_address : *flush_list) {
|
||||||
FlushAndRemoveRegion(query_address, 4);
|
FlushAndRemoveRegion(query_address, 4);
|
||||||
}
|
}
|
||||||
commited_flushes.pop_front();
|
committed_flushes.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -268,10 +261,10 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsyncFlushQuery(VAddr addr) {
|
void AsyncFlushQuery(VAddr addr) {
|
||||||
if (!uncommited_flushes) {
|
if (!uncommitted_flushes) {
|
||||||
uncommited_flushes = std::make_shared<std::unordered_set<VAddr>>();
|
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;
|
static constexpr std::uintptr_t PAGE_SIZE = 4096;
|
||||||
|
@ -286,8 +279,8 @@ private:
|
||||||
|
|
||||||
std::array<CounterStream, VideoCore::NumQueryTypes> streams;
|
std::array<CounterStream, VideoCore::NumQueryTypes> streams;
|
||||||
|
|
||||||
std::shared_ptr<std::unordered_set<VAddr>> uncommited_flushes{};
|
std::shared_ptr<std::unordered_set<VAddr>> uncommitted_flushes{};
|
||||||
std::list<std::shared_ptr<std::unordered_set<VAddr>>> commited_flushes;
|
std::list<std::shared_ptr<std::unordered_set<VAddr>>> committed_flushes;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class QueryCache, class HostCounter>
|
template <class QueryCache, class HostCounter>
|
||||||
|
|
|
@ -64,6 +64,7 @@ public:
|
||||||
/// Notify rasterizer that any caches of the specified region should be flushed to Switch memory
|
/// Notify rasterizer that any caches of the specified region should be flushed to Switch memory
|
||||||
virtual void FlushRegion(VAddr addr, u64 size) = 0;
|
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;
|
virtual bool MustFlushRegion(VAddr addr, u64 size) = 0;
|
||||||
|
|
||||||
/// Notify rasterizer that any caches of the specified region should be invalidated
|
/// Notify rasterizer that any caches of the specified region should be invalidated
|
||||||
|
|
|
@ -62,7 +62,7 @@ void FenceManagerOpenGL::QueueFence(Fence& fence) {
|
||||||
fence->Queue();
|
fence->Queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FenceManagerOpenGL::IsFenceSignaled(Fence& fence) {
|
bool FenceManagerOpenGL::IsFenceSignaled(Fence& fence) const {
|
||||||
return fence->IsSignaled();
|
return fence->IsSignaled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ protected:
|
||||||
Fence CreateFence(u32 value, bool is_stubbed) override;
|
Fence CreateFence(u32 value, bool is_stubbed) override;
|
||||||
Fence CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) override;
|
Fence CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) override;
|
||||||
void QueueFence(Fence& fence) override;
|
void QueueFence(Fence& fence) override;
|
||||||
bool IsFenceSignaled(Fence& fence) override;
|
bool IsFenceSignaled(Fence& fence) const override;
|
||||||
void WaitFence(Fence& fence) override;
|
void WaitFence(Fence& fence) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -653,9 +653,6 @@ void RasterizerOpenGL::FlushRegion(VAddr addr, u64 size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RasterizerOpenGL::MustFlushRegion(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);
|
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) {
|
void RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) {
|
||||||
MICROPROFILE_SCOPE(OpenGL_CacheManagement);
|
MICROPROFILE_SCOPE(OpenGL_CacheManagement);
|
||||||
if (!addr || !size) {
|
if (addr == 0 || size == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
texture_cache.OnCPUWrite(addr, size);
|
texture_cache.OnCPUWrite(addr, size);
|
||||||
|
|
|
@ -90,7 +90,7 @@ void VKFenceManager::QueueFence(Fence& fence) {
|
||||||
fence->Queue();
|
fence->Queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VKFenceManager::IsFenceSignaled(Fence& fence) {
|
bool VKFenceManager::IsFenceSignaled(Fence& fence) const {
|
||||||
return fence->IsSignaled();
|
return fence->IsSignaled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ protected:
|
||||||
Fence CreateFence(u32 value, bool is_stubbed) override;
|
Fence CreateFence(u32 value, bool is_stubbed) override;
|
||||||
Fence CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) override;
|
Fence CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) override;
|
||||||
void QueueFence(Fence& fence) override;
|
void QueueFence(Fence& fence) override;
|
||||||
bool IsFenceSignaled(Fence& fence) override;
|
bool IsFenceSignaled(Fence& fence) const override;
|
||||||
void WaitFence(Fence& fence) override;
|
void WaitFence(Fence& fence) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -533,7 +533,7 @@ void RasterizerVulkan::InvalidateRegion(VAddr addr, u64 size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) {
|
void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) {
|
||||||
if (!addr || !size) {
|
if (addr == 0 || size == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
texture_cache.OnCPUWrite(addr, size);
|
texture_cache.OnCPUWrite(addr, size);
|
||||||
|
|
|
@ -120,15 +120,8 @@ public:
|
||||||
std::lock_guard lock{mutex};
|
std::lock_guard lock{mutex};
|
||||||
|
|
||||||
auto surfaces = GetSurfacesInRegion(addr, size);
|
auto surfaces = GetSurfacesInRegion(addr, size);
|
||||||
if (surfaces.empty()) {
|
return std::any_of(surfaces.begin(), surfaces.end(),
|
||||||
return false;
|
[](const TSurface& surface) { return surface->IsModified(); });
|
||||||
}
|
|
||||||
for (const auto& surface : surfaces) {
|
|
||||||
if (surface->IsModified()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TView GetTextureSurface(const Tegra::Texture::TICEntry& tic,
|
TView GetTextureSurface(const Tegra::Texture::TICEntry& tic,
|
||||||
|
@ -333,41 +326,34 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommitAsyncFlushes() {
|
void CommitAsyncFlushes() {
|
||||||
commited_flushes.push_back(uncommited_flushes);
|
committed_flushes.push_back(uncommitted_flushes);
|
||||||
uncommited_flushes.reset();
|
uncommitted_flushes.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasUncommitedFlushes() {
|
bool HasUncommittedFlushes() const {
|
||||||
if (uncommited_flushes) {
|
return uncommitted_flushes != nullptr;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShouldWaitAsyncFlushes() {
|
bool ShouldWaitAsyncFlushes() const {
|
||||||
if (commited_flushes.empty()) {
|
if (committed_flushes.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto& flush_list = commited_flushes.front();
|
return committed_flushes.front() != nullptr;
|
||||||
if (!flush_list) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopAsyncFlushes() {
|
void PopAsyncFlushes() {
|
||||||
if (commited_flushes.empty()) {
|
if (committed_flushes.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto& flush_list = commited_flushes.front();
|
auto& flush_list = committed_flushes.front();
|
||||||
if (!flush_list) {
|
if (!flush_list) {
|
||||||
commited_flushes.pop_front();
|
committed_flushes.pop_front();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (TSurface& surface : *flush_list) {
|
for (TSurface& surface : *flush_list) {
|
||||||
FlushSurface(surface);
|
FlushSurface(surface);
|
||||||
}
|
}
|
||||||
commited_flushes.pop_front();
|
committed_flushes.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -1206,10 +1192,10 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
void AsyncFlushSurface(TSurface& surface) {
|
void AsyncFlushSurface(TSurface& surface) {
|
||||||
if (!uncommited_flushes) {
|
if (!uncommitted_flushes) {
|
||||||
uncommited_flushes = std::make_shared<std::list<TSurface>>();
|
uncommitted_flushes = std::make_shared<std::list<TSurface>>();
|
||||||
}
|
}
|
||||||
uncommited_flushes->push_back(surface);
|
uncommitted_flushes->push_back(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoCore::RasterizerInterface& rasterizer;
|
VideoCore::RasterizerInterface& rasterizer;
|
||||||
|
@ -1258,8 +1244,8 @@ private:
|
||||||
|
|
||||||
std::list<TSurface> marked_for_unregister;
|
std::list<TSurface> marked_for_unregister;
|
||||||
|
|
||||||
std::shared_ptr<std::list<TSurface>> uncommited_flushes{};
|
std::shared_ptr<std::list<TSurface>> uncommitted_flushes{};
|
||||||
std::list<std::shared_ptr<std::list<TSurface>>> commited_flushes;
|
std::list<std::shared_ptr<std::list<TSurface>>> committed_flushes;
|
||||||
|
|
||||||
StagingCache staging_cache;
|
StagingCache staging_cache;
|
||||||
std::recursive_mutex mutex;
|
std::recursive_mutex mutex;
|
||||||
|
|
Loading…
Reference in New Issue