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) {
|
bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size, bool isMemset, u32 skipDrawReason) {
|
||||||
if (updateVRAM_ || size == 0) {
|
if (updateVRAM_ || size == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -62,6 +62,7 @@ struct VirtualFramebuffer {
|
||||||
u32 clutUpdatedBytes;
|
u32 clutUpdatedBytes;
|
||||||
bool memoryUpdated;
|
bool memoryUpdated;
|
||||||
bool depthUpdated;
|
bool depthUpdated;
|
||||||
|
bool firstFrameSaved;
|
||||||
|
|
||||||
u32 fb_address;
|
u32 fb_address;
|
||||||
u32 z_address;
|
u32 z_address;
|
||||||
|
@ -252,6 +253,7 @@ protected:
|
||||||
void ShowScreenResolution();
|
void ShowScreenResolution();
|
||||||
|
|
||||||
bool ShouldDownloadFramebuffer(const VirtualFramebuffer *vfb) const;
|
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;
|
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);
|
VirtualFramebuffer *FindDownloadTempBuffer(VirtualFramebuffer *vfb);
|
||||||
virtual bool CreateDownloadTempBuffer(VirtualFramebuffer *nvfb) = 0;
|
virtual bool CreateDownloadTempBuffer(VirtualFramebuffer *nvfb) = 0;
|
||||||
|
|
|
@ -401,6 +401,8 @@ namespace DX9 {
|
||||||
void FramebufferManagerDX9::NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth) {
|
void FramebufferManagerDX9::NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth) {
|
||||||
if (ShouldDownloadFramebuffer(vfb) && !vfb->memoryUpdated) {
|
if (ShouldDownloadFramebuffer(vfb) && !vfb->memoryUpdated) {
|
||||||
ReadFramebufferToMemory(vfb, true, 0, 0, vfb->width, vfb->height);
|
ReadFramebufferToMemory(vfb, true, 0, 0, vfb->width, vfb->height);
|
||||||
|
} else {
|
||||||
|
DownloadFramebufferOnSwitch(prevVfb);
|
||||||
}
|
}
|
||||||
textureCache_->ForgetLastTexture();
|
textureCache_->ForgetLastTexture();
|
||||||
|
|
||||||
|
@ -704,6 +706,8 @@ namespace DX9 {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferManagerDX9::CopyDisplayToOutput() {
|
void FramebufferManagerDX9::CopyDisplayToOutput() {
|
||||||
|
DownloadFramebufferOnSwitch(currentRenderVfb_);
|
||||||
|
|
||||||
fbo_unbind();
|
fbo_unbind();
|
||||||
currentRenderVfb_ = 0;
|
currentRenderVfb_ = 0;
|
||||||
|
|
||||||
|
@ -1218,9 +1222,6 @@ namespace DX9 {
|
||||||
if (vfb != displayFramebuf_ && vfb != prevDisplayFramebuf_ && vfb != prevPrevDisplayFramebuf_) {
|
if (vfb != displayFramebuf_ && vfb != prevDisplayFramebuf_ && vfb != prevPrevDisplayFramebuf_) {
|
||||||
if (age > FBO_OLD_AGE) {
|
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);
|
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);
|
DestroyFramebuf(vfb);
|
||||||
vfbs_.erase(vfbs_.begin() + i--);
|
vfbs_.erase(vfbs_.begin() + i--);
|
||||||
}
|
}
|
||||||
|
@ -1269,12 +1270,6 @@ namespace DX9 {
|
||||||
for (size_t i = 0; i < vfbs_.size(); ++i) {
|
for (size_t i = 0; i < vfbs_.size(); ++i) {
|
||||||
VirtualFramebuffer *vfb = vfbs_[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);
|
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);
|
DestroyFramebuf(vfb);
|
||||||
}
|
}
|
||||||
vfbs_.clear();
|
vfbs_.clear();
|
||||||
|
|
|
@ -654,6 +654,8 @@ void FramebufferManager::NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb)
|
||||||
void FramebufferManager::NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth) {
|
void FramebufferManager::NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth) {
|
||||||
if (ShouldDownloadFramebuffer(vfb) && !vfb->memoryUpdated) {
|
if (ShouldDownloadFramebuffer(vfb) && !vfb->memoryUpdated) {
|
||||||
ReadFramebufferToMemory(vfb, true, 0, 0, vfb->width, vfb->height);
|
ReadFramebufferToMemory(vfb, true, 0, 0, vfb->width, vfb->height);
|
||||||
|
} else {
|
||||||
|
DownloadFramebufferOnSwitch(prevVfb);
|
||||||
}
|
}
|
||||||
textureCache_->ForgetLastTexture();
|
textureCache_->ForgetLastTexture();
|
||||||
|
|
||||||
|
@ -911,9 +913,10 @@ struct CardboardSettings * FramebufferManager::GetCardboardSettings(struct Cardb
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferManager::CopyDisplayToOutput() {
|
void FramebufferManager::CopyDisplayToOutput() {
|
||||||
fbo_unbind();
|
DownloadFramebufferOnSwitch(currentRenderVfb_);
|
||||||
glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_);
|
|
||||||
|
|
||||||
|
glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_);
|
||||||
|
fbo_unbind();
|
||||||
currentRenderVfb_ = 0;
|
currentRenderVfb_ = 0;
|
||||||
|
|
||||||
if (displayFramebufPtr_ == 0) {
|
if (displayFramebufPtr_ == 0) {
|
||||||
|
@ -1895,9 +1898,6 @@ void FramebufferManager::DecimateFBOs() {
|
||||||
if (vfb != displayFramebuf_ && vfb != prevDisplayFramebuf_ && vfb != prevPrevDisplayFramebuf_) {
|
if (vfb != displayFramebuf_ && vfb != prevDisplayFramebuf_ && vfb != prevPrevDisplayFramebuf_) {
|
||||||
if (age > FBO_OLD_AGE) {
|
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);
|
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);
|
DestroyFramebuf(vfb);
|
||||||
vfbs_.erase(vfbs_.begin() + i--);
|
vfbs_.erase(vfbs_.begin() + i--);
|
||||||
}
|
}
|
||||||
|
@ -1936,12 +1936,6 @@ void FramebufferManager::DestroyAllFBOs(bool forceDelete) {
|
||||||
for (size_t i = 0; i < vfbs_.size(); ++i) {
|
for (size_t i = 0; i < vfbs_.size(); ++i) {
|
||||||
VirtualFramebuffer *vfb = vfbs_[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);
|
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);
|
DestroyFramebuf(vfb);
|
||||||
}
|
}
|
||||||
vfbs_.clear();
|
vfbs_.clear();
|
||||||
|
|
|
@ -628,6 +628,8 @@ void FramebufferManagerVulkan::NotifyRenderFramebufferCreated(VirtualFramebuffer
|
||||||
void FramebufferManagerVulkan::NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth) {
|
void FramebufferManagerVulkan::NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth) {
|
||||||
if (ShouldDownloadFramebuffer(vfb) && !vfb->memoryUpdated) {
|
if (ShouldDownloadFramebuffer(vfb) && !vfb->memoryUpdated) {
|
||||||
ReadFramebufferToMemory(vfb, true, 0, 0, vfb->width, vfb->height);
|
ReadFramebufferToMemory(vfb, true, 0, 0, vfb->width, vfb->height);
|
||||||
|
} else {
|
||||||
|
DownloadFramebufferOnSwitch(prevVfb);
|
||||||
}
|
}
|
||||||
textureCache_->ForgetLastTexture();
|
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
|
// 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.
|
// is worth the needed refactoring trouble though.
|
||||||
|
|
||||||
// fbo_unbind();
|
|
||||||
|
|
||||||
|
DownloadFramebufferOnSwitch(currentRenderVfb_);
|
||||||
|
|
||||||
|
// fbo_unbind();
|
||||||
currentRenderVfb_ = 0;
|
currentRenderVfb_ = 0;
|
||||||
|
|
||||||
if (useBufferedRendering_) {
|
if (useBufferedRendering_) {
|
||||||
|
@ -1551,9 +1555,6 @@ void FramebufferManagerVulkan::DecimateFBOs() {
|
||||||
if (vfb != displayFramebuf_ && vfb != prevDisplayFramebuf_ && vfb != prevPrevDisplayFramebuf_) {
|
if (vfb != displayFramebuf_ && vfb != prevDisplayFramebuf_ && vfb != prevPrevDisplayFramebuf_) {
|
||||||
if (age > FBO_OLD_AGE) {
|
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);
|
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);
|
DestroyFramebuf(vfb);
|
||||||
vfbs_.erase(vfbs_.begin() + i--);
|
vfbs_.erase(vfbs_.begin() + i--);
|
||||||
}
|
}
|
||||||
|
@ -1570,12 +1571,6 @@ void FramebufferManagerVulkan::DestroyAllFBOs(bool forceDelete) {
|
||||||
for (size_t i = 0; i < vfbs_.size(); ++i) {
|
for (size_t i = 0; i < vfbs_.size(); ++i) {
|
||||||
VirtualFramebuffer *vfb = vfbs_[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);
|
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);
|
DestroyFramebuf(vfb);
|
||||||
}
|
}
|
||||||
vfbs_.clear();
|
vfbs_.clear();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue