Permalink
Browse files

Merge pull request #11776 from hrydgard/redefine-blocktransfer-setting

Only gate really expensive block transfers behind the setting.
  • Loading branch information...
hrydgard committed Feb 8, 2019
2 parents 9736bc4 + 11c8450 commit 857e0bbfa3ec1ff3b80d7739514aca618ab48d54
Showing with 38 additions and 52 deletions.
  1. +37 −50 GPU/Common/FramebufferCommon.cpp
  2. +1 −2 GPU/GPUCommon.cpp
@@ -1280,27 +1280,22 @@ bool FramebufferManagerCommon::NotifyFramebufferCopy(u32 src, u32 dst, int size,
} else {
WARN_LOG_REPORT_ONCE(dstnotsrccpy, G3D, "Inter-buffer memcpy %08x -> %08x", src, dst);
// Just do the blit!
if (g_Config.bBlockTransferGPU) {
BlitFramebuffer(dstBuffer, 0, dstY, srcBuffer, 0, srcY, srcBuffer->width, srcH, 0);
SetColorUpdated(dstBuffer, skipDrawReason);
RebindFramebuffer();
}
BlitFramebuffer(dstBuffer, 0, dstY, srcBuffer, 0, srcY, srcBuffer->width, srcH, 0);
SetColorUpdated(dstBuffer, skipDrawReason);
RebindFramebuffer();
}
return false;
} else if (dstBuffer) {
if (isMemset) {
gpuStats.numClears++;
}
WARN_LOG_ONCE(btucpy, G3D, "Memcpy fbo upload %08x -> %08x", src, dst);
if (g_Config.bBlockTransferGPU) {
FlushBeforeCopy();
const u8 *srcBase = Memory::GetPointerUnchecked(src);
DrawPixels(dstBuffer, 0, dstY, srcBase, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->width, dstH);
SetColorUpdated(dstBuffer, skipDrawReason);
RebindFramebuffer();
// This is a memcpy, let's still copy just in case.
return false;
}
FlushBeforeCopy();
const u8 *srcBase = Memory::GetPointerUnchecked(src);
DrawPixels(dstBuffer, 0, dstY, srcBase, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->width, dstH);
SetColorUpdated(dstBuffer, skipDrawReason);
RebindFramebuffer();
// This is a memcpy, let's still copy just in case.
return false;
} else if (srcBuffer) {
WARN_LOG_ONCE(btdcpy, G3D, "Memcpy fbo download %08x -> %08x", src, dst);
@@ -1638,29 +1633,23 @@ bool FramebufferManagerCommon::NotifyBlockTransferBefore(u32 dstBasePtr, int dst
if (srcBuffer == dstBuffer) {
if (srcX != dstX || srcY != dstY) {
WARN_LOG_ONCE(dstsrc, G3D, "Intra-buffer block transfer %08x -> %08x", srcBasePtr, dstBasePtr);
if (g_Config.bBlockTransferGPU) {
FlushBeforeCopy();
BlitFramebuffer(dstBuffer, dstX, dstY, srcBuffer, srcX, srcY, dstWidth, dstHeight, bpp);
RebindFramebuffer();
SetColorUpdated(dstBuffer, skipDrawReason);
return true;
}
FlushBeforeCopy();
BlitFramebuffer(dstBuffer, dstX, dstY, srcBuffer, srcX, srcY, dstWidth, dstHeight, bpp);
RebindFramebuffer();
SetColorUpdated(dstBuffer, skipDrawReason);
return true;
} else {
// Ignore, nothing to do. Tales of Phantasia X does this by accident.
if (g_Config.bBlockTransferGPU) {
return true;
}
return true;
}
} else {
WARN_LOG_ONCE(dstnotsrc, G3D, "Inter-buffer block transfer %08x -> %08x", srcBasePtr, dstBasePtr);
// Just do the blit!
if (g_Config.bBlockTransferGPU) {
FlushBeforeCopy();
BlitFramebuffer(dstBuffer, dstX, dstY, srcBuffer, srcX, srcY, dstWidth, dstHeight, bpp);
RebindFramebuffer();
SetColorUpdated(dstBuffer, skipDrawReason);
return true; // No need to actually do the memory copy behind, probably.
}
FlushBeforeCopy();
BlitFramebuffer(dstBuffer, dstX, dstY, srcBuffer, srcX, srcY, dstWidth, dstHeight, bpp);
RebindFramebuffer();
SetColorUpdated(dstBuffer, skipDrawReason);
return true; // No need to actually do the memory copy behind, probably.
}
return false;
} else if (dstBuffer) {
@@ -1718,26 +1707,24 @@ void FramebufferManagerCommon::NotifyBlockTransferAfter(u32 dstBasePtr, int dstS

if (dstBuffer && !srcBuffer) {
WARN_LOG_ONCE(btu, G3D, "Block transfer upload %08x -> %08x", srcBasePtr, dstBasePtr);
if (g_Config.bBlockTransferGPU) {
FlushBeforeCopy();
const u8 *srcBase = Memory::GetPointerUnchecked(srcBasePtr) + (srcX + srcY * srcStride) * bpp;
int dstBpp = dstBuffer->format == GE_FORMAT_8888 ? 4 : 2;
float dstXFactor = (float)bpp / dstBpp;
if (dstWidth > dstBuffer->width || dstHeight > dstBuffer->height) {
// The buffer isn't big enough, and we have a clear hint of size. Resize.
// This happens in Valkyrie Profile when uploading video at the ending.
ResizeFramebufFBO(dstBuffer, dstWidth, dstHeight, false, true);
// Make sure we don't flop back and forth.
dstBuffer->newWidth = std::max(dstWidth, (int)dstBuffer->width);
dstBuffer->newHeight = std::max(dstHeight, (int)dstBuffer->height);
dstBuffer->lastFrameNewSize = gpuStats.numFlips;
// Resizing may change the viewport/etc.
gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_CULLRANGE);
}
DrawPixels(dstBuffer, static_cast<int>(dstX * dstXFactor), dstY, srcBase, dstBuffer->format, static_cast<int>(srcStride * dstXFactor), static_cast<int>(dstWidth * dstXFactor), dstHeight);
SetColorUpdated(dstBuffer, skipDrawReason);
RebindFramebuffer();
FlushBeforeCopy();
const u8 *srcBase = Memory::GetPointerUnchecked(srcBasePtr) + (srcX + srcY * srcStride) * bpp;
int dstBpp = dstBuffer->format == GE_FORMAT_8888 ? 4 : 2;
float dstXFactor = (float)bpp / dstBpp;
if (dstWidth > dstBuffer->width || dstHeight > dstBuffer->height) {
// The buffer isn't big enough, and we have a clear hint of size. Resize.
// This happens in Valkyrie Profile when uploading video at the ending.
ResizeFramebufFBO(dstBuffer, dstWidth, dstHeight, false, true);
// Make sure we don't flop back and forth.
dstBuffer->newWidth = std::max(dstWidth, (int)dstBuffer->width);
dstBuffer->newHeight = std::max(dstHeight, (int)dstBuffer->height);
dstBuffer->lastFrameNewSize = gpuStats.numFlips;
// Resizing may change the viewport/etc.
gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_CULLRANGE);
}
DrawPixels(dstBuffer, static_cast<int>(dstX * dstXFactor), dstY, srcBase, dstBuffer->format, static_cast<int>(srcStride * dstXFactor), static_cast<int>(dstWidth * dstXFactor), dstHeight);
SetColorUpdated(dstBuffer, skipDrawReason);
RebindFramebuffer();
}
}
}
@@ -2717,9 +2717,8 @@ void GPUCommon::InvalidateCache(u32 addr, int size, GPUInvalidationType type) {
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) {
if (type == GPU_INVALIDATE_SAFE) {
framebufferManager_->UpdateFromMemory(addr, size, type == GPU_INVALIDATE_SAFE);
}
}

0 comments on commit 857e0bb

Please sign in to comment.