diff --git a/GPU/Common/TextureCacheCommon.h b/GPU/Common/TextureCacheCommon.h index 82e0d0e7c4..4c2be709d6 100644 --- a/GPU/Common/TextureCacheCommon.h +++ b/GPU/Common/TextureCacheCommon.h @@ -52,6 +52,7 @@ public: virtual bool SetOffsetTexture(u32 offset) = 0; virtual void Invalidate(u32 addr, int size, GPUInvalidationType type) = 0; + virtual void InvalidateAll(GPUInvalidationType type) = 0; // FramebufferManager keeps TextureCache updated about what regions of memory are being rendered to. void NotifyFramebuffer(u32 address, VirtualFramebuffer *framebuffer, FramebufferNotification msg); diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 14fe75daf2..f832869d62 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -1888,56 +1888,6 @@ void GPU_DX9::GetStats(char *buffer, size_t bufsize) { ); } -void GPU_DX9::InvalidateCache(u32 addr, int size, GPUInvalidationType type) { - GPUEvent ev(GPU_EVENT_INVALIDATE_CACHE); - ev.invalidate_cache.addr = addr; - ev.invalidate_cache.size = size; - ev.invalidate_cache.type = type; - ScheduleEvent(ev); -} - -void GPU_DX9::InvalidateCacheInternal(u32 addr, int size, GPUInvalidationType type) { - if (size > 0) - textureCache_.Invalidate(addr, size, type); - else - textureCache_.InvalidateAll(type); - - if (type != GPU_INVALIDATE_ALL && framebufferManagerDX9_->MayIntersectFramebuffer(addr)) { - // If we're doing block transfers, we shouldn't need this, and it'll only confuse us. - // Vempire invalidates (with writeback) after drawing, but before blitting. - if (!g_Config.bBlockTransferGPU || type == GPU_INVALIDATE_SAFE) { - framebufferManagerDX9_->UpdateFromMemory(addr, size, type == GPU_INVALIDATE_SAFE); - } - } -} - -void GPU_DX9::NotifyVideoUpload(u32 addr, int size, int width, int format) { - if (Memory::IsVRAMAddress(addr)) { - framebufferManagerDX9_->NotifyVideoUpload(addr, size, width, (GEBufferFormat)format); - } - textureCache_.NotifyVideoUpload(addr, size, width, (GEBufferFormat)format); - InvalidateCache(addr, size, GPU_INVALIDATE_SAFE); -} - -void GPU_DX9::PerformStencilUploadInternal(u32 dest, int size) { - framebufferManagerDX9_->NotifyStencilUpload(dest, size); -} - -bool GPU_DX9::PerformStencilUpload(u32 dest, int size) { - if (framebufferManagerDX9_->MayIntersectFramebuffer(dest)) { - if (IsOnSeparateCPUThread()) { - GPUEvent ev(GPU_EVENT_FB_STENCIL_UPLOAD); - ev.fb_stencil_upload.dst = dest; - ev.fb_stencil_upload.size = size; - ScheduleEvent(ev); - } else { - PerformStencilUploadInternal(dest, size); - } - return true; - } - return false; -} - void GPU_DX9::ClearCacheNextFrame() { textureCache_.ClearNextFrame(); } diff --git a/GPU/Directx9/GPU_DX9.h b/GPU/Directx9/GPU_DX9.h index 7a96369c29..ac158e9948 100644 --- a/GPU/Directx9/GPU_DX9.h +++ b/GPU/Directx9/GPU_DX9.h @@ -48,9 +48,6 @@ public: void CopyDisplayToOutput() override; void BeginFrame() override; void GetStats(char *buffer, size_t bufsize) override; - void InvalidateCache(u32 addr, int size, GPUInvalidationType type) override; - void NotifyVideoUpload(u32 addr, int size, int width, int format) override; - bool PerformStencilUpload(u32 dest, int size) override; void ClearCacheNextFrame() override; void DeviceLost() override; // Only happens on Android. Drop all textures and shaders. void DeviceRestore() override; @@ -158,14 +155,12 @@ private: void Flush() { drawEngine_.Flush(); } - void ApplyDrawState(int prim); + // void ApplyDrawState(int prim); void CheckFlushOp(int cmd, u32 diff); void BuildReportingInfo(); void InitClearInternal(); void BeginFrameInternal(); void CopyDisplayToOutputInternal(); - void PerformStencilUploadInternal(u32 dest, int size); - void InvalidateCacheInternal(u32 addr, int size, GPUInvalidationType type); FramebufferManagerDX9 *framebufferManagerDX9_; TextureCacheDX9 textureCache_; diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index fd7b8e7053..ecdc37c284 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -2149,52 +2149,6 @@ void GPU_GLES::GetStats(char *buffer, size_t bufsize) { shaderManager_->NumPrograms()); } -void GPU_GLES::InvalidateCache(u32 addr, int size, GPUInvalidationType type) { - GPUEvent ev(GPU_EVENT_INVALIDATE_CACHE); - ev.invalidate_cache.addr = addr; - ev.invalidate_cache.size = size; - ev.invalidate_cache.type = type; - ScheduleEvent(ev); -} - -void GPU_GLES::InvalidateCacheInternal(u32 addr, int size, GPUInvalidationType type) { - if (size > 0) - textureCacheGL_->Invalidate(addr, size, type); - else - textureCacheGL_->InvalidateAll(type); - - if (type != GPU_INVALIDATE_ALL && framebufferManagerGL_->MayIntersectFramebuffer(addr)) { - // If we're doing block transfers, we shouldn't need this, and it'll only confuse us. - // Vempire invalidates (with writeback) after drawing, but before blitting. - if (!g_Config.bBlockTransferGPU || type == GPU_INVALIDATE_SAFE) { - framebufferManagerGL_->UpdateFromMemory(addr, size, type == GPU_INVALIDATE_SAFE); - } - } -} - -void GPU_GLES::NotifyVideoUpload(u32 addr, int size, int width, int format) { - if (Memory::IsVRAMAddress(addr)) { - framebufferManagerGL_->NotifyVideoUpload(addr, size, width, (GEBufferFormat)format); - } - textureCacheGL_->NotifyVideoUpload(addr, size, width, (GEBufferFormat)format); - InvalidateCache(addr, size, GPU_INVALIDATE_SAFE); -} - -bool GPU_GLES::PerformStencilUpload(u32 dest, int size) { - if (framebufferManagerGL_->MayIntersectFramebuffer(dest)) { - if (IsOnSeparateCPUThread()) { - GPUEvent ev(GPU_EVENT_FB_STENCIL_UPLOAD); - ev.fb_stencil_upload.dst = dest; - ev.fb_stencil_upload.size = size; - ScheduleEvent(ev); - } else { - PerformStencilUploadInternal(dest, size); - } - return true; - } - return false; -} - void GPU_GLES::ClearCacheNextFrame() { textureCacheGL_->ClearNextFrame(); } @@ -2292,10 +2246,6 @@ bool GPU_GLES::GetCurrentTexture(GPUDebugBuffer &buffer, int level) { #endif } -void GPU_GLES::PerformStencilUploadInternal(u32 dest, int size) { - framebufferManager_->NotifyStencilUpload(dest, size); -} - bool GPU_GLES::GetCurrentClut(GPUDebugBuffer &buffer) { return textureCacheGL_->GetCurrentClutBuffer(buffer); } diff --git a/GPU/GLES/GPU_GLES.h b/GPU/GLES/GPU_GLES.h index 12744d9109..fdd672808e 100644 --- a/GPU/GLES/GPU_GLES.h +++ b/GPU/GLES/GPU_GLES.h @@ -51,9 +51,7 @@ public: void CopyDisplayToOutput() override; void BeginFrame() override; void GetStats(char *buffer, size_t bufsize) override; - void InvalidateCache(u32 addr, int size, GPUInvalidationType type) override; - void NotifyVideoUpload(u32 addr, int size, int width, int format) override; - bool PerformStencilUpload(u32 dest, int size) override; + void ClearCacheNextFrame() override; void DeviceLost() override; // Only happens on Android. Drop all textures and shaders. void DeviceRestore() override; @@ -167,8 +165,6 @@ private: void InitClearInternal(); void BeginFrameInternal(); void CopyDisplayToOutputInternal(); - void PerformStencilUploadInternal(u32 dest, int size); - void InvalidateCacheInternal(u32 addr, int size, GPUInvalidationType type); void ReinitializeInternal(); inline void UpdateVsyncInterval(bool force); void UpdateCmdInfo(); diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 862c11ae7e..eb24c8a644 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -1495,3 +1495,53 @@ bool GPUCommon::PerformMemoryUpload(u32 dest, int size) { } return false; } + +void GPUCommon::InvalidateCache(u32 addr, int size, GPUInvalidationType type) { + GPUEvent ev(GPU_EVENT_INVALIDATE_CACHE); + ev.invalidate_cache.addr = addr; + ev.invalidate_cache.size = size; + ev.invalidate_cache.type = type; + ScheduleEvent(ev); +} + +void GPUCommon::InvalidateCacheInternal(u32 addr, int size, GPUInvalidationType type) { + if (size > 0) + textureCache_->Invalidate(addr, size, type); + else + textureCache_->InvalidateAll(type); + + if (type != GPU_INVALIDATE_ALL && framebufferManager_->MayIntersectFramebuffer(addr)) { + // If we're doing block transfers, we shouldn't need this, and it'll only confuse us. + // Vempire invalidates (with writeback) after drawing, but before blitting. + if (!g_Config.bBlockTransferGPU || type == GPU_INVALIDATE_SAFE) { + framebufferManager_->UpdateFromMemory(addr, size, type == GPU_INVALIDATE_SAFE); + } + } +} + +void GPUCommon::NotifyVideoUpload(u32 addr, int size, int width, int format) { + if (Memory::IsVRAMAddress(addr)) { + framebufferManager_->NotifyVideoUpload(addr, size, width, (GEBufferFormat)format); + } + textureCache_->NotifyVideoUpload(addr, size, width, (GEBufferFormat)format); + InvalidateCache(addr, size, GPU_INVALIDATE_SAFE); +} + +bool GPUCommon::PerformStencilUpload(u32 dest, int size) { + if (framebufferManager_->MayIntersectFramebuffer(dest)) { + if (IsOnSeparateCPUThread()) { + GPUEvent ev(GPU_EVENT_FB_STENCIL_UPLOAD); + ev.fb_stencil_upload.dst = dest; + ev.fb_stencil_upload.size = size; + ScheduleEvent(ev); + } else { + PerformStencilUploadInternal(dest, size); + } + return true; + } + return false; +} + +void GPUCommon::PerformStencilUploadInternal(u32 dest, int size) { + framebufferManager_->NotifyStencilUpload(dest, size); +} diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index 28c766984f..97853c3b36 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -65,6 +65,10 @@ public: bool PerformMemoryDownload(u32 dest, int size) override; bool PerformMemoryUpload(u32 dest, int size) override; + void InvalidateCache(u32 addr, int size, GPUInvalidationType type) override; + void NotifyVideoUpload(u32 addr, int size, int width, int format) override; + bool PerformStencilUpload(u32 dest, int size) override; + void Execute_OffsetAddr(u32 op, u32 diff); void Execute_Origin(u32 op, u32 diff); void Execute_Jump(u32 op, u32 diff); @@ -145,9 +149,6 @@ public: } protected: - void PerformMemoryCopyInternal(u32 dest, u32 src, int size); - void PerformMemorySetInternal(u32 dest, u8 v, int size); - // To avoid virtual calls to PreExecuteOp(). virtual void FastRunLoop(DisplayList &list) = 0; void SlowRunLoop(DisplayList &list); @@ -173,6 +174,11 @@ protected: void AdvanceVerts(u32 vertType, int count, int bytesRead); + void PerformMemoryCopyInternal(u32 dest, u32 src, int size); + void PerformMemorySetInternal(u32 dest, u8 v, int size); + void PerformStencilUploadInternal(u32 dest, int size); + void InvalidateCacheInternal(u32 addr, int size, GPUInvalidationType type); + // Allows early unlocking with a guard. Do not double unlock. class easy_guard { public: @@ -213,6 +219,7 @@ protected: bool resized_; private: + // For CPU/GPU sync. #ifdef __ANDROID__ alignas(16) std::atomic curTickEst_; diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 85eb8feee4..88df36e77c 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -1998,57 +1998,6 @@ void GPU_Vulkan::GetStats(char *buffer, size_t bufsize) { ); } -void GPU_Vulkan::InvalidateCache(u32 addr, int size, GPUInvalidationType type) { - GPUEvent ev(GPU_EVENT_INVALIDATE_CACHE); - ev.invalidate_cache.addr = addr; - ev.invalidate_cache.size = size; - ev.invalidate_cache.type = type; - ScheduleEvent(ev); -} - -void GPU_Vulkan::InvalidateCacheInternal(u32 addr, int size, GPUInvalidationType type) { - if (size > 0) - textureCacheVulkan_->Invalidate(addr, size, type); - else - textureCacheVulkan_->InvalidateAll(type); - - if (type != GPU_INVALIDATE_ALL && framebufferManager_->MayIntersectFramebuffer(addr)) { - // If we're doing block transfers, we shouldn't need this, and it'll only confuse us. - // Vempire invalidates (with writeback) after drawing, but before blitting. - if (!g_Config.bBlockTransferGPU || type == GPU_INVALIDATE_SAFE) { - framebufferManager_->UpdateFromMemory(addr, size, type == GPU_INVALIDATE_SAFE); - } - } -} - -void GPU_Vulkan::PerformStencilUploadInternal(u32 dest, int size) { - framebufferManager_->NotifyStencilUpload(dest, size); -} - -void GPU_Vulkan::NotifyVideoUpload(u32 addr, int size, int width, int format) { - if (Memory::IsVRAMAddress(addr)) { - // TODO - //framebufferManager_.NotifyVideoUpload(addr, size, width, (GEBufferFormat)format); - } - textureCacheVulkan_->NotifyVideoUpload(addr, size, width, (GEBufferFormat)format); - InvalidateCache(addr, size, GPU_INVALIDATE_SAFE); -} - -bool GPU_Vulkan::PerformStencilUpload(u32 dest, int size) { - if (framebufferManager_->MayIntersectFramebuffer(dest)) { - if (IsOnSeparateCPUThread()) { - GPUEvent ev(GPU_EVENT_FB_STENCIL_UPLOAD); - ev.fb_stencil_upload.dst = dest; - ev.fb_stencil_upload.size = size; - ScheduleEvent(ev); - } else { - PerformStencilUploadInternal(dest, size); - } - return true; - } - return false; -} - void GPU_Vulkan::ClearCacheNextFrame() { textureCacheVulkan_->ClearNextFrame(); } diff --git a/GPU/Vulkan/GPU_Vulkan.h b/GPU/Vulkan/GPU_Vulkan.h index 5cbc42497a..f178501f63 100644 --- a/GPU/Vulkan/GPU_Vulkan.h +++ b/GPU/Vulkan/GPU_Vulkan.h @@ -51,11 +51,8 @@ public: void ReapplyGfxStateInternal() override; void SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat format) override; void CopyDisplayToOutput() override; - void NotifyVideoUpload(u32 addr, int size, int width, int format) override; void BeginFrame() override; void GetStats(char *buffer, size_t bufsize) override; - void InvalidateCache(u32 addr, int size, GPUInvalidationType type) override; - bool PerformStencilUpload(u32 dest, int size) override; void ClearCacheNextFrame() override; void DeviceLost() override; // Only happens on Android. Drop all textures and shaders. void DeviceRestore() override; @@ -160,8 +157,6 @@ private: void InitClearInternal(); void BeginFrameInternal(); void CopyDisplayToOutputInternal(); - void PerformStencilUploadInternal(u32 dest, int size); - void InvalidateCacheInternal(u32 addr, int size, GPUInvalidationType type); void ReinitializeInternal(); inline void UpdateVsyncInterval(bool force); void UpdateCmdInfo(); diff --git a/GPU/Vulkan/TextureCacheVulkan.h b/GPU/Vulkan/TextureCacheVulkan.h index b0fe471449..213c43e491 100644 --- a/GPU/Vulkan/TextureCacheVulkan.h +++ b/GPU/Vulkan/TextureCacheVulkan.h @@ -95,8 +95,8 @@ public: void Clear(bool delete_them); void StartFrame(); void EndFrame(); - void Invalidate(u32 addr, int size, GPUInvalidationType type); - void InvalidateAll(GPUInvalidationType type); + void Invalidate(u32 addr, int size, GPUInvalidationType type) override; + void InvalidateAll(GPUInvalidationType type) override; void ClearNextFrame(); void DeviceLost();