mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-26 11:45:26 +00:00
Skip some code if things are outside framebuffers.
Small optimization.
This commit is contained in:
parent
4dbb4328ae
commit
fd4ba0093c
@ -327,7 +327,8 @@ FramebufferManager::FramebufferManager() :
|
||||
shaderManager_(0),
|
||||
usePostShader_(false),
|
||||
postShaderAtOutputResolution_(false),
|
||||
resized_(false)
|
||||
resized_(false),
|
||||
framebufRangeEnd_(0)
|
||||
#ifndef USING_GLES2
|
||||
,
|
||||
pixelBufObj_(0),
|
||||
@ -836,6 +837,11 @@ void FramebufferManager::DoSetRenderFrameBuffer() {
|
||||
glEnable(GL_DITHER); // why?
|
||||
currentRenderVfb_ = vfb;
|
||||
|
||||
u32 byteSize = vfb->fb_stride * vfb->height * (vfb->format == GE_FORMAT_8888 ? 4 : 2);
|
||||
if (fb_address + byteSize > framebufRangeEnd_) {
|
||||
framebufRangeEnd_ = ((fb_address + byteSize) & 0x3FFFFFFF) | 0x04000000;
|
||||
}
|
||||
|
||||
INFO_LOG(SCEGE, "Creating FBO for %08x : %i x %i x %i", vfb->fb_address, vfb->width, vfb->height, vfb->format);
|
||||
|
||||
// Let's check for depth buffer overlap. Might be interesting.
|
||||
@ -1798,6 +1804,11 @@ void FramebufferManager::UpdateFromMemory(u32 addr, int size, bool safe) {
|
||||
}
|
||||
|
||||
void FramebufferManager::NotifyFramebufferCopy(u32 src, u32 dst, int size) {
|
||||
if (!MayIntersectFramebuffer(src) && !MayIntersectFramebuffer(dst)) {
|
||||
// Don't waste time looking if neither can be a framebuffer.
|
||||
return;
|
||||
}
|
||||
|
||||
// MotoGP workaround
|
||||
for (size_t i = 0; i < vfbs_.size(); i++) {
|
||||
int bpp = vfbs_[i]->format == GE_FORMAT_8888 ? 4 : 2;
|
||||
@ -1867,6 +1878,11 @@ bool FramebufferManager::NotifyBlockTransferBefore(u32 dstBasePtr, int dstStride
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip checking if there's no framebuffers in that area.
|
||||
if (!MayIntersectFramebuffer(srcBasePtr) && !MayIntersectFramebuffer(dstBasePtr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
VirtualFramebuffer *dstBuffer = 0;
|
||||
VirtualFramebuffer *srcBuffer = 0;
|
||||
FindTransferFramebuffers(dstBuffer, srcBuffer, dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, bpp);
|
||||
@ -1903,7 +1919,8 @@ void FramebufferManager::NotifyBlockTransferAfter(u32 dstBasePtr, int dstStride,
|
||||
return;
|
||||
}
|
||||
|
||||
if (Memory::IsRAMAddress(srcBasePtr) && Memory::IsVRAMAddress(dstBasePtr)) {
|
||||
// TODO: This can probably just be handled by a normal block transfer upload, no?
|
||||
if (Memory::IsRAMAddress(srcBasePtr) && MayIntersectFramebuffer(dstBasePtr)) {
|
||||
// TODO: This causes glitches in Tactics Ogre if we don't implement both ways (which will probably be slow...)
|
||||
// The main thing this helps is videos, which will have a matching stride, and zero x/y.
|
||||
if (dstStride == srcStride && dstY == 0 && dstX == 0 && srcX == 0 && srcY == 0) {
|
||||
@ -1917,6 +1934,7 @@ void FramebufferManager::NotifyBlockTransferAfter(u32 dstBasePtr, int dstStride,
|
||||
u32 backBuffer = PrevDisplayFramebufAddr();
|
||||
u32 displayBuffer = DisplayFramebufAddr();
|
||||
|
||||
// TODO: Is this not handled by upload? Should we check !dstBuffer to avoid a double copy?
|
||||
if (((backBuffer != 0 && dstBasePtr == backBuffer) ||
|
||||
(displayBuffer != 0 && dstBasePtr == displayBuffer)) &&
|
||||
dstStride == 512 && height == 272) {
|
||||
@ -1924,15 +1942,17 @@ void FramebufferManager::NotifyBlockTransferAfter(u32 dstBasePtr, int dstStride,
|
||||
DrawFramebuffer(Memory::GetPointerUnchecked(dstBasePtr), GE_FORMAT_8888, 512, false);
|
||||
}
|
||||
|
||||
VirtualFramebuffer *dstBuffer = 0;
|
||||
VirtualFramebuffer *srcBuffer = 0;
|
||||
FindTransferFramebuffers(dstBuffer, srcBuffer, dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, bpp);
|
||||
if (MayIntersectFramebuffer(srcBasePtr) || MayIntersectFramebuffer(dstBasePtr)) {
|
||||
VirtualFramebuffer *dstBuffer = 0;
|
||||
VirtualFramebuffer *srcBuffer = 0;
|
||||
FindTransferFramebuffers(dstBuffer, srcBuffer, dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, bpp);
|
||||
|
||||
if (dstBuffer && !srcBuffer) {
|
||||
WARN_LOG_REPORT_ONCE(btu, G3D, "Block transfer upload (not supported) %08x -> %08x", srcBasePtr, dstBasePtr);
|
||||
if (g_Config.bBlockTransferGPU) {
|
||||
u8 *srcBase = Memory::GetPointerUnchecked(srcBasePtr) + (srcX + srcY * srcStride) * bpp;
|
||||
DrawPixels(dstBuffer, dstX, dstY, srcBase, dstBuffer->format, srcStride * bpp, width, height);
|
||||
if (dstBuffer && !srcBuffer) {
|
||||
WARN_LOG_REPORT_ONCE(btu, G3D, "Block transfer upload (not supported) %08x -> %08x", srcBasePtr, dstBasePtr);
|
||||
if (g_Config.bBlockTransferGPU) {
|
||||
u8 *srcBase = Memory::GetPointerUnchecked(srcBasePtr) + (srcX + srcY * srcStride) * bpp;
|
||||
DrawPixels(dstBuffer, dstX, dstY, srcBase, dstBuffer->format, srcStride * bpp, width, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,6 +200,16 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool MayIntersectFramebuffer(u32 start) {
|
||||
// Clear the cache/kernel bits.
|
||||
start = start & 0x3FFFFFFF;
|
||||
// Most games only have two framebuffers at the start.
|
||||
if (start >= framebufRangeEnd_ || start < PSP_GetVidMemBase()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void NotifyFramebufferCopy(u32 src, u32 dest, int size);
|
||||
|
||||
void DestroyFramebuf(VirtualFramebuffer *vfb);
|
||||
@ -261,7 +271,10 @@ private:
|
||||
bool resized_;
|
||||
bool useBufferedRendering_;
|
||||
bool updateVRAM_;
|
||||
|
||||
|
||||
// The range of PSP memory that may contain FBOs. So we can skip iterating.
|
||||
u32 framebufRangeEnd_;
|
||||
|
||||
std::vector<VirtualFramebuffer *> bvfbs_; // blitting FBOs
|
||||
std::map<std::pair<int, int>, FBO *> renderCopies_;
|
||||
|
||||
|
@ -1955,8 +1955,9 @@ void GLES_GPU::InvalidateCacheInternal(u32 addr, int size, GPUInvalidationType t
|
||||
else
|
||||
textureCache_.InvalidateAll(type);
|
||||
|
||||
if (type != GPU_INVALIDATE_ALL)
|
||||
if (type != GPU_INVALIDATE_ALL && framebufferManager_.MayIntersectFramebuffer(addr)) {
|
||||
framebufferManager_.UpdateFromMemory(addr, size, type == GPU_INVALIDATE_SAFE);
|
||||
}
|
||||
}
|
||||
|
||||
void GLES_GPU::UpdateMemory(u32 dest, u32 src, int size) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user