mirror of
https://git.suyu.dev/suyu/suyu
synced 2024-11-02 05:17:52 +00:00
GPU: Refactor synchronization on Async GPU
This commit is contained in:
parent
a60a22d9c2
commit
da8f17715d
11 changed files with 56 additions and 7 deletions
|
@ -32,6 +32,7 @@ void DmaPusher::DispatchCalls() {
|
|||
}
|
||||
}
|
||||
gpu.FlushCommands();
|
||||
gpu.SyncGuestHost();
|
||||
}
|
||||
|
||||
bool DmaPusher::Step() {
|
||||
|
|
|
@ -403,9 +403,13 @@ void Maxwell3D::ProcessQueryGet() {
|
|||
"Units other than CROP are unimplemented");
|
||||
|
||||
switch (regs.query.query_get.operation) {
|
||||
case Regs::QueryOperation::Release:
|
||||
StampQueryResult(regs.query.query_sequence, regs.query.query_get.short_query == 0);
|
||||
case Regs::QueryOperation::Release: {
|
||||
rasterizer.FlushCommands();
|
||||
rasterizer.SyncGuestHost();
|
||||
const u64 result = regs.query.query_sequence;
|
||||
StampQueryResult(result, regs.query.query_get.short_query == 0);
|
||||
break;
|
||||
}
|
||||
case Regs::QueryOperation::Acquire:
|
||||
// TODO(Blinkhawk): Under this operation, the GPU waits for the CPU to write a value that
|
||||
// matches the current payload.
|
||||
|
|
|
@ -142,6 +142,9 @@ void GPU::FlushCommands() {
|
|||
renderer->Rasterizer().FlushCommands();
|
||||
}
|
||||
|
||||
void GPU::SyncGuestHost() {
|
||||
renderer->Rasterizer().SyncGuestHost();
|
||||
}
|
||||
// Note that, traditionally, methods are treated as 4-byte addressable locations, and hence
|
||||
// their numbers are written down multiplied by 4 in Docs. Here we are not multiply by 4.
|
||||
// So the values you see in docs might be multiplied by 4.
|
||||
|
|
|
@ -156,6 +156,7 @@ public:
|
|||
void CallMethod(const MethodCall& method_call);
|
||||
|
||||
void FlushCommands();
|
||||
void SyncGuestHost();
|
||||
|
||||
/// Returns a reference to the Maxwell3D GPU engine.
|
||||
Engines::Maxwell3D& Maxwell3D();
|
||||
|
|
|
@ -40,7 +40,7 @@ static void RunThread(VideoCore::RendererBase& renderer, Core::Frontend::Graphic
|
|||
} else if (const auto data = std::get_if<FlushRegionCommand>(&next.data)) {
|
||||
renderer.Rasterizer().FlushRegion(data->addr, data->size);
|
||||
} else if (const auto data = std::get_if<InvalidateRegionCommand>(&next.data)) {
|
||||
renderer.Rasterizer().InvalidateRegion(data->addr, data->size);
|
||||
renderer.Rasterizer().OnCPUWrite(data->addr, data->size);
|
||||
} else if (std::holds_alternative<EndProcessingCommand>(next.data)) {
|
||||
return;
|
||||
} else {
|
||||
|
@ -82,12 +82,12 @@ void ThreadManager::FlushRegion(VAddr addr, u64 size) {
|
|||
}
|
||||
|
||||
void ThreadManager::InvalidateRegion(VAddr addr, u64 size) {
|
||||
system.Renderer().Rasterizer().InvalidateRegion(addr, size);
|
||||
system.Renderer().Rasterizer().OnCPUWrite(addr, size);
|
||||
}
|
||||
|
||||
void ThreadManager::FlushAndInvalidateRegion(VAddr addr, u64 size) {
|
||||
// Skip flush on asynch mode, as FlushAndInvalidateRegion is not used for anything too important
|
||||
InvalidateRegion(addr, size);
|
||||
system.Renderer().Rasterizer().OnCPUWrite(addr, size);
|
||||
}
|
||||
|
||||
void ThreadManager::WaitIdle() const {
|
||||
|
|
|
@ -58,6 +58,12 @@ public:
|
|||
/// Notify rasterizer that any caches of the specified region should be invalidated
|
||||
virtual void InvalidateRegion(VAddr addr, u64 size) = 0;
|
||||
|
||||
/// Notify rasterizer that any caches of the specified region are desync with guest
|
||||
virtual void OnCPUWrite(VAddr addr, u64 size) = 0;
|
||||
|
||||
/// Sync memory between guest and host.
|
||||
virtual void SyncGuestHost() = 0;
|
||||
|
||||
/// Notify rasterizer that any caches of the specified region should be flushed to Switch memory
|
||||
/// and invalidated
|
||||
virtual void FlushAndInvalidateRegion(VAddr addr, u64 size) = 0;
|
||||
|
|
|
@ -660,6 +660,22 @@ void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) {
|
|||
query_cache.InvalidateRegion(addr, size);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) {
|
||||
MICROPROFILE_SCOPE(OpenGL_CacheManagement);
|
||||
if (!addr || !size) {
|
||||
return;
|
||||
}
|
||||
texture_cache.OnCPUWrite(addr, size);
|
||||
shader_cache.InvalidateRegion(addr, size);
|
||||
buffer_cache.InvalidateRegion(addr, size);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SyncGuestHost() {
|
||||
MICROPROFILE_SCOPE(OpenGL_CacheManagement);
|
||||
texture_cache.SyncGuestHost();
|
||||
// buffer_cache.SyncGuestHost();
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) {
|
||||
if (Settings::IsGPULevelExtreme()) {
|
||||
FlushRegion(addr, size);
|
||||
|
|
|
@ -67,6 +67,8 @@ public:
|
|||
void FlushAll() override;
|
||||
void FlushRegion(VAddr addr, u64 size) override;
|
||||
void InvalidateRegion(VAddr addr, u64 size) override;
|
||||
void OnCPUWrite(VAddr addr, u64 size) override;
|
||||
void SyncGuestHost() override;
|
||||
void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
|
||||
void FlushCommands() override;
|
||||
void TickFrame() override;
|
||||
|
|
|
@ -524,6 +524,20 @@ void RasterizerVulkan::InvalidateRegion(VAddr addr, u64 size) {
|
|||
query_cache.InvalidateRegion(addr, size);
|
||||
}
|
||||
|
||||
void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) {
|
||||
if (!addr || !size) {
|
||||
return;
|
||||
}
|
||||
texture_cache.OnCPUWrite(addr, size);
|
||||
pipeline_cache.InvalidateRegion(addr, size);
|
||||
buffer_cache.InvalidateRegion(addr, size);
|
||||
}
|
||||
|
||||
void RasterizerVulkan::SyncGuestHost() {
|
||||
texture_cache.SyncGuestHost();
|
||||
// buffer_cache.SyncGuestHost();
|
||||
}
|
||||
|
||||
void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size) {
|
||||
FlushRegion(addr, size);
|
||||
InvalidateRegion(addr, size);
|
||||
|
|
|
@ -119,6 +119,8 @@ public:
|
|||
void FlushAll() override;
|
||||
void FlushRegion(VAddr addr, u64 size) override;
|
||||
void InvalidateRegion(VAddr addr, u64 size) override;
|
||||
void OnCPUWrite(VAddr addr, u64 size) override;
|
||||
void SyncGuestHost() override;
|
||||
void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
|
||||
void FlushCommands() override;
|
||||
void TickFrame() override;
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void OnCPUWrite(CacheAddr addr, std::size_t size) {
|
||||
void OnCPUWrite(VAddr addr, std::size_t size) {
|
||||
std::lock_guard lock{mutex};
|
||||
|
||||
for (const auto& surface : GetSurfacesInRegion(addr, size)) {
|
||||
|
@ -549,7 +549,7 @@ private:
|
|||
}
|
||||
const auto& final_params = new_surface->GetSurfaceParams();
|
||||
if (cr_params.type != final_params.type) {
|
||||
if (Settings::values.use_accurate_gpu_emulation) {
|
||||
if (Settings::IsGPULevelExtreme()) {
|
||||
BufferCopy(current_surface, new_surface);
|
||||
}
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue