Centralize PerformStencil* and Invalidate* functions

This commit is contained in:
Henrik Rydgard 2016-12-21 18:33:08 +01:00
parent 866d4a645f
commit 98ebf9ed6f
10 changed files with 65 additions and 172 deletions

View file

@ -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);

View file

@ -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();
}

View file

@ -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_;

View file

@ -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);
}

View file

@ -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();

View file

@ -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);
}

View file

@ -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<u64> curTickEst_;

View file

@ -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();
}

View file

@ -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();

View file

@ -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();