Cleanup download process a bit more.

This commit is contained in:
Unknown W. Brackets 2016-01-04 20:51:43 -08:00
parent 4176ee241f
commit a6c64f74d1
6 changed files with 85 additions and 73 deletions

View File

@ -768,6 +768,16 @@ VirtualFramebuffer *FramebufferManagerCommon::FindDownloadTempBuffer(VirtualFram
nvfb->drawnWidth = vfb->drawnWidth;
nvfb->drawnHeight = vfb->drawnHeight;
nvfb->drawnFormat = vfb->format;
nvfb->colorDepth = vfb->colorDepth;
if (!CreateDownloadTempBuffer(nvfb)) {
delete nvfb;
return nullptr;
}
bvfbs_.push_back(nvfb);
} else {
UpdateDownloadTempBuffer(nvfb);
}
nvfb->usageFlags |= FB_USAGE_RENDERTARGET;

View File

@ -245,6 +245,8 @@ protected:
bool ShouldDownloadFramebuffer(const VirtualFramebuffer *vfb) 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);
virtual bool CreateDownloadTempBuffer(VirtualFramebuffer *nvfb) = 0;
virtual void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) = 0;
void OptimizeDownloadRange(VirtualFramebuffer *vfb, int &x, int &y, int &w, int &h);
void UpdateFramebufUsage(VirtualFramebuffer *vfb);

View File

@ -849,34 +849,34 @@ namespace DX9 {
if (vfb) {
// We'll pseudo-blit framebuffers here to get a resized version of vfb.
VirtualFramebuffer *nvfb = FindDownloadTempBuffer(vfb);
// Create a new fbo if none was found for the size
if (!nvfb->fbo_dx9) {
nvfb->colorDepth = FBO_8888;
textureCache_->ForgetLastTexture();
nvfb->fbo_dx9 = fbo_create(nvfb->width, nvfb->height, 1, true, (FBOColorDepth)nvfb->colorDepth);
if (!(nvfb->fbo_dx9)) {
ERROR_LOG(SCEGE, "Error creating FBO! %i x %i", nvfb->renderWidth, nvfb->renderHeight);
delete nvfb;
return;
}
bvfbs_.push_back(nvfb);
fbo_bind_as_render_target(nvfb->fbo_dx9);
ClearBuffer();
} else {
textureCache_->ForgetLastTexture();
}
OptimizeDownloadRange(vfb, x, y, w, h);
BlitFramebuffer(nvfb, x, y, vfb, x, y, w, h, 0);
PackFramebufferDirectx9_(nvfb, x, y, w, h);
textureCache_->ForgetLastTexture();
RebindFramebuffer();
}
}
bool FramebufferManagerDX9::CreateDownloadTempBuffer(VirtualFramebuffer *nvfb) {
nvfb->colorDepth = FBO_8888;
nvfb->fbo_dx9 = fbo_create(nvfb->width, nvfb->height, 1, true, (FBOColorDepth)nvfb->colorDepth);
if (!(nvfb->fbo_dx9)) {
ERROR_LOG(SCEGE, "Error creating FBO! %i x %i", nvfb->renderWidth, nvfb->renderHeight);
return false;
}
fbo_bind_as_render_target(nvfb->fbo_dx9);
ClearBuffer();
return true;
}
void FramebufferManagerDX9::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) {
// Nothing to do here.
}
void FramebufferManagerDX9::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp) {
if (!dst->fbo || !src->fbo || !useBufferedRendering_) {
// This can happen if they recently switched from non-buffered.

View File

@ -105,6 +105,8 @@ protected:
virtual void NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb) override;
virtual void NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth) override;
virtual void NotifyRenderFramebufferUpdated(VirtualFramebuffer *vfb, bool vfbFormatChanged) override;
virtual bool CreateDownloadTempBuffer(VirtualFramebuffer *nvfb) override;
virtual void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) override;
private:
void CompileDraw2DProgram();

View File

@ -1217,59 +1217,6 @@ void FramebufferManager::ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool s
if (vfb) {
// We'll pseudo-blit framebuffers here to get a resized version of vfb.
VirtualFramebuffer *nvfb = FindDownloadTempBuffer(vfb);
// Create a new fbo if none was found for the size
if (!nvfb->fbo) {
// When updating VRAM, it need to be exact format.
switch (vfb->format) {
case GE_FORMAT_4444:
nvfb->colorDepth = FBO_4444;
break;
case GE_FORMAT_5551:
nvfb->colorDepth = FBO_5551;
break;
case GE_FORMAT_565:
nvfb->colorDepth = FBO_565;
break;
case GE_FORMAT_8888:
default:
nvfb->colorDepth = FBO_8888;
break;
}
if (gstate_c.Supports(GPU_PREFER_CPU_DOWNLOAD)) {
nvfb->colorDepth = vfb->colorDepth;
}
textureCache_->ForgetLastTexture();
nvfb->fbo = fbo_create(nvfb->width, nvfb->height, 1, false, (FBOColorDepth)nvfb->colorDepth);
if (!(nvfb->fbo)) {
ERROR_LOG(SCEGE, "Error creating FBO! %i x %i", nvfb->renderWidth, nvfb->renderHeight);
delete nvfb;
return;
}
bvfbs_.push_back(nvfb);
fbo_bind_as_render_target(nvfb->fbo);
ClearBuffer();
glDisable(GL_DITHER);
} else {
textureCache_->ForgetLastTexture();
if (gl_extensions.IsGLES) {
if (nvfb->fbo) {
fbo_bind_as_render_target(nvfb->fbo);
}
// Some tiled mobile GPUs benefit IMMENSELY from clearing an FBO before rendering
// to it. This broke stuff before, so now it only clears on the first use of an
// FBO in a frame. This means that some games won't be able to avoid the on-some-GPUs
// performance-crushing framebuffer reloads from RAM, but we'll have to live with that.
if (nvfb->last_frame_render != gpuStats.numFlips) {
ClearBuffer();
}
}
}
OptimizeDownloadRange(vfb, x, y, w, h);
BlitFramebuffer(nvfb, x, y, vfb, x, y, w, h, 0);
@ -1289,10 +1236,59 @@ void FramebufferManager::ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool s
}
}
textureCache_->ForgetLastTexture();
RebindFramebuffer();
}
}
bool FramebufferManager::CreateDownloadTempBuffer(VirtualFramebuffer *nvfb) {
// When updating VRAM, it need to be exact format.
if (!gstate_c.Supports(GPU_PREFER_CPU_DOWNLOAD)) {
switch (nvfb->format) {
case GE_FORMAT_4444:
nvfb->colorDepth = FBO_4444;
break;
case GE_FORMAT_5551:
nvfb->colorDepth = FBO_5551;
break;
case GE_FORMAT_565:
nvfb->colorDepth = FBO_565;
break;
case GE_FORMAT_8888:
default:
nvfb->colorDepth = FBO_8888;
break;
}
}
nvfb->fbo = fbo_create(nvfb->width, nvfb->height, 1, false, (FBOColorDepth)nvfb->colorDepth);
if (!(nvfb->fbo)) {
ERROR_LOG(SCEGE, "Error creating FBO! %i x %i", nvfb->renderWidth, nvfb->renderHeight);
return false;
}
fbo_bind_as_render_target(nvfb->fbo);
ClearBuffer();
glDisable(GL_DITHER);
return true;
}
void FramebufferManager::UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) {
if (gl_extensions.IsGLES) {
if (nvfb->fbo) {
fbo_bind_as_render_target(nvfb->fbo);
}
// Some tiled mobile GPUs benefit IMMENSELY from clearing an FBO before rendering
// to it. This broke stuff before, so now it only clears on the first use of an
// FBO in a frame. This means that some games won't be able to avoid the on-some-GPUs
// performance-crushing framebuffer reloads from RAM, but we'll have to live with that.
if (nvfb->last_frame_render != gpuStats.numFlips) {
ClearBuffer();
}
}
}
void FramebufferManager::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp) {
if (!dst->fbo || !src->fbo || !useBufferedRendering_) {
// This can happen if they recently switched from non-buffered.

View File

@ -135,6 +135,8 @@ protected:
virtual void NotifyRenderFramebufferCreated(VirtualFramebuffer *vfb) override;
virtual void NotifyRenderFramebufferSwitched(VirtualFramebuffer *prevVfb, VirtualFramebuffer *vfb, bool isClearingDepth) override;
virtual void NotifyRenderFramebufferUpdated(VirtualFramebuffer *vfb, bool vfbFormatChanged) override;
virtual bool CreateDownloadTempBuffer(VirtualFramebuffer *nvfb) override;
virtual void UpdateDownloadTempBuffer(VirtualFramebuffer *nvfb) override;
private:
void UpdatePostShaderUniforms(int bufferWidth, int bufferHeight, int renderWidth, int renderHeight);