Download single-use renders right away.
Should prevent issues with the memory being reused soon after, hopefully. See also #8781 and #7695.
This commit is contained in:
parent
6bbcf74926
commit
c12f835364
5 changed files with 30 additions and 30 deletions
|
@ -544,6 +544,20 @@ void FramebufferManagerCommon::UpdateFromMemory(u32 addr, int size, bool safe) {
|
|||
}
|
||||
}
|
||||
|
||||
void FramebufferManagerCommon::DownloadFramebufferOnSwitch(VirtualFramebuffer *vfb) {
|
||||
if (vfb && vfb->safeWidth > 0 && vfb->safeHeight > 0 && !vfb->firstFrameSaved) {
|
||||
// Some games will draw to some memory once, and use it as a render-to-texture later.
|
||||
// To support this, we save the first frame to memory when we have a save w/h.
|
||||
// Saving each frame would be slow.
|
||||
if (!g_Config.bDisableSlowFramebufEffects) {
|
||||
ReadFramebufferToMemory(vfb, true, 0, 0, vfb->safeWidth, vfb->safeHeight);
|
||||
vfb->firstFrameSaved = true;
|
||||
vfb->safeWidth = 0;
|
||||
vfb->safeHeight = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size, bool isMemset, u32 skipDrawReason) {
|
||||
if (updateVRAM_ || size == 0) {
|
||||
return false;
|
||||
|
|
|
@ -62,6 +62,7 @@ struct VirtualFramebuffer {
|
|||
u32 clutUpdatedBytes;
|
||||
bool memoryUpdated;
|
||||
bool depthUpdated;
|
||||
bool firstFrameSaved;
|
||||
|
||||
u32 fb_address;
|
||||
u32 z_address;
|
||||
|
@ -252,6 +253,7 @@ protected:
|
|||
void ShowScreenResolution();
|
||||
|
||||
bool ShouldDownloadFramebuffer(const VirtualFramebuffer *vfb) const;
|
||||
void DownloadFramebufferOnSwitch(VirtualFramebuffer *vfb);
|
||||
void FindTransferFramebuffers(VirtualFramebuffer *&dstBuffer, VirtualFramebuffer *&srcBuffer, u32 dstBasePtr, int dstStride, int &dstX, int &dstY, u32 srcBasePtr, int srcStride, int &srcX, int &srcY, int &srcWidth, int &srcHeight, int &dstWidth, int &dstHeight, int bpp) const;
|
||||
VirtualFramebuffer *FindDownloadTempBuffer(VirtualFramebuffer *vfb);
|
||||
virtual bool CreateDownloadTempBuffer(VirtualFramebuffer *nvfb) = 0;
|
||||
|
|
|
@ -401,6 +401,8 @@ namespace DX9 {
|
|||
void FramebufferManagerDX9::NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth) {
|
||||
if (ShouldDownloadFramebuffer(vfb) && !vfb->memoryUpdated) {
|
||||
ReadFramebufferToMemory(vfb, true, 0, 0, vfb->width, vfb->height);
|
||||
} else {
|
||||
DownloadFramebufferOnSwitch(prevVfb);
|
||||
}
|
||||
textureCache_->ForgetLastTexture();
|
||||
|
||||
|
@ -704,6 +706,8 @@ namespace DX9 {
|
|||
}
|
||||
|
||||
void FramebufferManagerDX9::CopyDisplayToOutput() {
|
||||
DownloadFramebufferOnSwitch(currentRenderVfb_);
|
||||
|
||||
fbo_unbind();
|
||||
currentRenderVfb_ = 0;
|
||||
|
||||
|
@ -1218,9 +1222,6 @@ namespace DX9 {
|
|||
if (vfb != displayFramebuf_ && vfb != prevDisplayFramebuf_ && vfb != prevPrevDisplayFramebuf_) {
|
||||
if (age > FBO_OLD_AGE) {
|
||||
INFO_LOG(SCEGE, "Decimating FBO for %08x (%i x %i x %i), age %i", vfb->fb_address, vfb->width, vfb->height, vfb->format, age);
|
||||
if (!g_Config.bDisableSlowFramebufEffects && vfb->safeWidth > 0 && vfb->safeHeight > 0) {
|
||||
ReadFramebufferToMemory(vfb, true, 0, 0, vfb->safeWidth, vfb->safeHeight);
|
||||
}
|
||||
DestroyFramebuf(vfb);
|
||||
vfbs_.erase(vfbs_.begin() + i--);
|
||||
}
|
||||
|
@ -1269,12 +1270,6 @@ namespace DX9 {
|
|||
for (size_t i = 0; i < vfbs_.size(); ++i) {
|
||||
VirtualFramebuffer *vfb = vfbs_[i];
|
||||
INFO_LOG(SCEGE, "Destroying FBO for %08x : %i x %i x %i", vfb->fb_address, vfb->width, vfb->height, vfb->format);
|
||||
if (!forceDelete && !g_Config.bDisableSlowFramebufEffects && vfb->safeWidth > 0 && vfb->safeHeight > 0) {
|
||||
// But also let's check if Memory is shut down already.
|
||||
if (Memory::IsActive()) {
|
||||
ReadFramebufferToMemory(vfb, true, 0, 0, vfb->safeWidth, vfb->safeHeight);
|
||||
}
|
||||
}
|
||||
DestroyFramebuf(vfb);
|
||||
}
|
||||
vfbs_.clear();
|
||||
|
|
|
@ -654,6 +654,8 @@ void FramebufferManager::NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb)
|
|||
void FramebufferManager::NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth) {
|
||||
if (ShouldDownloadFramebuffer(vfb) && !vfb->memoryUpdated) {
|
||||
ReadFramebufferToMemory(vfb, true, 0, 0, vfb->width, vfb->height);
|
||||
} else {
|
||||
DownloadFramebufferOnSwitch(prevVfb);
|
||||
}
|
||||
textureCache_->ForgetLastTexture();
|
||||
|
||||
|
@ -911,9 +913,10 @@ struct CardboardSettings * FramebufferManager::GetCardboardSettings(struct Cardb
|
|||
}
|
||||
|
||||
void FramebufferManager::CopyDisplayToOutput() {
|
||||
fbo_unbind();
|
||||
glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_);
|
||||
DownloadFramebufferOnSwitch(currentRenderVfb_);
|
||||
|
||||
glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_);
|
||||
fbo_unbind();
|
||||
currentRenderVfb_ = 0;
|
||||
|
||||
if (displayFramebufPtr_ == 0) {
|
||||
|
@ -1895,9 +1898,6 @@ void FramebufferManager::DecimateFBOs() {
|
|||
if (vfb != displayFramebuf_ && vfb != prevDisplayFramebuf_ && vfb != prevPrevDisplayFramebuf_) {
|
||||
if (age > FBO_OLD_AGE) {
|
||||
INFO_LOG(SCEGE, "Decimating FBO for %08x (%i x %i x %i), age %i", vfb->fb_address, vfb->width, vfb->height, vfb->format, age);
|
||||
if (!g_Config.bDisableSlowFramebufEffects && vfb->safeWidth > 0 && vfb->safeHeight > 0) {
|
||||
ReadFramebufferToMemory(vfb, true, 0, 0, vfb->safeWidth, vfb->safeHeight);
|
||||
}
|
||||
DestroyFramebuf(vfb);
|
||||
vfbs_.erase(vfbs_.begin() + i--);
|
||||
}
|
||||
|
@ -1936,12 +1936,6 @@ void FramebufferManager::DestroyAllFBOs(bool forceDelete) {
|
|||
for (size_t i = 0; i < vfbs_.size(); ++i) {
|
||||
VirtualFramebuffer *vfb = vfbs_[i];
|
||||
INFO_LOG(SCEGE, "Destroying FBO for %08x : %i x %i x %i", vfb->fb_address, vfb->width, vfb->height, vfb->format);
|
||||
if (!forceDelete && !g_Config.bDisableSlowFramebufEffects && vfb->safeWidth > 0 && vfb->safeHeight > 0) {
|
||||
// But also let's check if Memory is shut down already.
|
||||
if (Memory::IsActive()) {
|
||||
ReadFramebufferToMemory(vfb, true, 0, 0, vfb->safeWidth, vfb->safeHeight);
|
||||
}
|
||||
}
|
||||
DestroyFramebuf(vfb);
|
||||
}
|
||||
vfbs_.clear();
|
||||
|
|
|
@ -628,6 +628,8 @@ void FramebufferManagerVulkan::NotifyRenderFramebufferCreated(VirtualFramebuffer
|
|||
void FramebufferManagerVulkan::NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth) {
|
||||
if (ShouldDownloadFramebuffer(vfb) && !vfb->memoryUpdated) {
|
||||
ReadFramebufferToMemory(vfb, true, 0, 0, vfb->width, vfb->height);
|
||||
} else {
|
||||
DownloadFramebufferOnSwitch(prevVfb);
|
||||
}
|
||||
textureCache_->ForgetLastTexture();
|
||||
|
||||
|
@ -819,8 +821,10 @@ void FramebufferManagerVulkan::CopyDisplayToOutput() {
|
|||
// then in theory, we can even avoid starting up a render pass at all for the backbuffer (!). not sure if that
|
||||
// is worth the needed refactoring trouble though.
|
||||
|
||||
// fbo_unbind();
|
||||
|
||||
DownloadFramebufferOnSwitch(currentRenderVfb_);
|
||||
|
||||
// fbo_unbind();
|
||||
currentRenderVfb_ = 0;
|
||||
|
||||
if (useBufferedRendering_) {
|
||||
|
@ -1551,9 +1555,6 @@ void FramebufferManagerVulkan::DecimateFBOs() {
|
|||
if (vfb != displayFramebuf_ && vfb != prevDisplayFramebuf_ && vfb != prevPrevDisplayFramebuf_) {
|
||||
if (age > FBO_OLD_AGE) {
|
||||
INFO_LOG(SCEGE, "Decimating FBO for %08x (%i x %i x %i), age %i", vfb->fb_address, vfb->width, vfb->height, vfb->format, age);
|
||||
if (!g_Config.bDisableSlowFramebufEffects && vfb->safeWidth > 0 && vfb->safeHeight > 0) {
|
||||
ReadFramebufferToMemory(vfb, true, 0, 0, vfb->safeWidth, vfb->safeHeight);
|
||||
}
|
||||
DestroyFramebuf(vfb);
|
||||
vfbs_.erase(vfbs_.begin() + i--);
|
||||
}
|
||||
|
@ -1570,12 +1571,6 @@ void FramebufferManagerVulkan::DestroyAllFBOs(bool forceDelete) {
|
|||
for (size_t i = 0; i < vfbs_.size(); ++i) {
|
||||
VirtualFramebuffer *vfb = vfbs_[i];
|
||||
INFO_LOG(SCEGE, "Destroying FBO for %08x : %i x %i x %i", vfb->fb_address, vfb->width, vfb->height, vfb->format);
|
||||
if (!forceDelete && !g_Config.bDisableSlowFramebufEffects && vfb->safeWidth > 0 && vfb->safeHeight > 0) {
|
||||
// But also let's check if Memory is shut down already.
|
||||
if (Memory::IsActive()) {
|
||||
ReadFramebufferToMemory(vfb, true, 0, 0, vfb->safeWidth, vfb->safeHeight);
|
||||
}
|
||||
}
|
||||
DestroyFramebuf(vfb);
|
||||
}
|
||||
vfbs_.clear();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue