mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-06 14:24:21 +01:00
Merge pull request #6383 from unknownbrackets/gpu-minor
Check for closest render-to-tex, ignore high bits of fb addr
This commit is contained in:
commit
5f57e7ebaf
3 files changed
+34
-26
No files matched your search
@@ -876,7 +876,7 @@ void FramebufferManager::DoSetRenderFrameBuffer() {
|
||||
gstate_c.cutRTOffsetX = 0;
|
||||
for (i = 0; i < vfbs_.size(); ++i) {
|
||||
VirtualFramebuffer *v = vfbs_[i];
|
||||
if (MaskedEqual(v->fb_address, fb_address)) {
|
||||
if (v->fb_address == fb_address) {
|
||||
vfb = v;
|
||||
// Update fb stride in case it changed
|
||||
vfb->fb_stride = fb_stride;
|
||||
@@ -935,7 +935,7 @@ void FramebufferManager::DoSetRenderFrameBuffer() {
|
||||
float renderWidthFactor = (float)PSP_CoreParameter().renderWidth / 480.0f;
|
||||
float renderHeightFactor = (float)PSP_CoreParameter().renderHeight / 272.0f;
|
||||
|
||||
if (hackForce04154000Download_ && MaskedEqual(fb_address, 0x04154000)) {
|
||||
if (hackForce04154000Download_ && fb_address == 0x00154000) {
|
||||
renderWidthFactor = 1.0;
|
||||
renderHeightFactor = 1.0;
|
||||
}
|
||||
@@ -997,18 +997,18 @@ void FramebufferManager::DoSetRenderFrameBuffer() {
|
||||
// Let's check for depth buffer overlap. Might be interesting.
|
||||
bool sharingReported = false;
|
||||
for (size_t i = 0, end = vfbs_.size(); i < end; ++i) {
|
||||
if (vfbs_[i]->z_stride != 0 && MaskedEqual(fb_address, vfbs_[i]->z_address)) {
|
||||
if (vfbs_[i]->z_stride != 0 && fb_address == vfbs_[i]->z_address) {
|
||||
// If it's clearing it, most likely it just needs more video memory.
|
||||
// Technically it could write something interesting and the other might not clear, but that's not likely.
|
||||
if (!gstate.isModeClear() || !gstate.isClearModeColorMask() || !gstate.isClearModeAlphaMask()) {
|
||||
WARN_LOG_REPORT(SCEGE, "FBO created from existing depthbuffer as color, %08x/%08x and %08x/%08x", fb_address, z_address, vfbs_[i]->fb_address, vfbs_[i]->z_address);
|
||||
}
|
||||
} else if (z_stride != 0 && MaskedEqual(z_address, vfbs_[i]->fb_address)) {
|
||||
} else if (z_stride != 0 && z_address == vfbs_[i]->fb_address) {
|
||||
// If it's clearing it, then it's probably just the reverse of the above case.
|
||||
if (!gstate.isModeClear() || !gstate.isClearModeDepthMask()) {
|
||||
WARN_LOG_REPORT(SCEGE, "FBO using existing buffer as depthbuffer, %08x/%08x and %08x/%08x", fb_address, z_address, vfbs_[i]->fb_address, vfbs_[i]->z_address);
|
||||
}
|
||||
} else if (vfbs_[i]->z_stride != 0 && MaskedEqual(z_address, vfbs_[i]->z_address) && fb_address != vfbs_[i]->fb_address && !sharingReported) {
|
||||
} else if (vfbs_[i]->z_stride != 0 && z_address == vfbs_[i]->z_address && fb_address != vfbs_[i]->fb_address && !sharingReported) {
|
||||
// This happens a lot, but virtually always it's cleared.
|
||||
// It's possible the other might not clear, but when every game is reported it's not useful.
|
||||
if (!gstate.isModeClear() || !gstate.isClearModeDepthMask()) {
|
||||
@@ -1115,7 +1115,7 @@ void FramebufferManager::BlitFramebufferDepth(VirtualFramebuffer *sourceframebuf
|
||||
return;
|
||||
}
|
||||
|
||||
if (MaskedEqual(sourceframebuffer->z_address, targetframebuffer->z_address) &&
|
||||
if (sourceframebuffer->z_address == targetframebuffer->z_address &&
|
||||
sourceframebuffer->z_stride != 0 &&
|
||||
targetframebuffer->z_stride != 0 &&
|
||||
sourceframebuffer->renderWidth == targetframebuffer->renderWidth &&
|
||||
@@ -1180,7 +1180,7 @@ void FramebufferManager::BindFramebufferColor(VirtualFramebuffer *framebuffer, b
|
||||
if (GPUStepping::IsStepping()) {
|
||||
skipCopy = true;
|
||||
}
|
||||
if (!skipCopy && currentRenderVfb_ && MaskedEqual(framebuffer->fb_address, gstate.getFrameBufRawAddress())) {
|
||||
if (!skipCopy && currentRenderVfb_ && framebuffer->fb_address == gstate.getFrameBufRawAddress()) {
|
||||
// TODO: Maybe merge with bvfbs_? Not sure if those could be packing, and they're created at a different size.
|
||||
FBO *renderCopy = GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, framebuffer->colorDepth);
|
||||
if (renderCopy) {
|
||||
@@ -1342,7 +1342,7 @@ void FramebufferManager::CopyDisplayToOutput() {
|
||||
}
|
||||
|
||||
inline bool FramebufferManager::ShouldDownloadFramebuffer(const VirtualFramebuffer *vfb) const {
|
||||
return updateVRAM_ || (hackForce04154000Download_ && MaskedEqual(vfb->fb_address, 0x04154000));
|
||||
return updateVRAM_ || (hackForce04154000Download_ && vfb->fb_address == 0x00154000);
|
||||
}
|
||||
|
||||
void FramebufferManager::ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync, int x, int y, int w, int h) {
|
||||
@@ -1363,7 +1363,7 @@ void FramebufferManager::ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool s
|
||||
// We maintain a separate vector of framebuffer objects for blitting.
|
||||
for (size_t i = 0; i < bvfbs_.size(); ++i) {
|
||||
VirtualFramebuffer *v = bvfbs_[i];
|
||||
if (MaskedEqual(v->fb_address, vfb->fb_address) && v->format == vfb->format) {
|
||||
if (v->fb_address == vfb->fb_address && v->format == vfb->format) {
|
||||
if (v->bufferWidth == vfb->bufferWidth && v->bufferHeight == vfb->bufferHeight) {
|
||||
nvfb = v;
|
||||
v->fb_stride = vfb->fb_stride;
|
||||
|
||||
+22
-14
@@ -221,7 +221,12 @@ void TextureCache::ClearNextFrame() {
|
||||
void TextureCache::AttachFramebufferValid(TexCacheEntry *entry, VirtualFramebuffer *framebuffer, const AttachedFramebufferInfo &fbInfo) {
|
||||
const bool hasInvalidFramebuffer = entry->framebuffer == 0 || entry->invalidHint == -1;
|
||||
const bool hasOlderFramebuffer = entry->framebuffer != 0 && entry->framebuffer->last_frame_render < framebuffer->last_frame_render;
|
||||
if (hasInvalidFramebuffer || hasOlderFramebuffer) {
|
||||
bool hasFartherFramebuffer = false;
|
||||
if (!hasInvalidFramebuffer && !hasOlderFramebuffer) {
|
||||
// If it's valid, but the offset is greater, then we still win.
|
||||
hasFartherFramebuffer = fbTexInfo_[entry->addr].yOffset > fbInfo.yOffset;
|
||||
}
|
||||
if (hasInvalidFramebuffer || hasOlderFramebuffer || hasFartherFramebuffer) {
|
||||
entry->framebuffer = framebuffer;
|
||||
entry->invalidHint = 0;
|
||||
entry->status &= ~TextureCache::TexCacheEntry::STATUS_DEPALETTIZE;
|
||||
@@ -260,18 +265,16 @@ bool TextureCache::AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualF
|
||||
return false;
|
||||
|
||||
DEBUG_LOG(G3D, "Render to texture detected at %08x!", address);
|
||||
if (!entry->framebuffer || entry->invalidHint == -1) {
|
||||
if (framebuffer->fb_stride != entry->bufw) {
|
||||
WARN_LOG_REPORT_ONCE(diffStrides1, G3D, "Render to texture with different strides %d != %d", entry->bufw, framebuffer->fb_stride);
|
||||
}
|
||||
if (entry->format != framebuffer->format) {
|
||||
WARN_LOG_REPORT_ONCE(diffFormat1, G3D, "Render to texture with different formats %d != %d", entry->format, framebuffer->format);
|
||||
// Let's avoid rendering when we know the format is wrong. May be a video/etc. updating memory.
|
||||
DetachFramebuffer(entry, address, framebuffer);
|
||||
} else {
|
||||
AttachFramebufferValid(entry, framebuffer, fbInfo);
|
||||
return true;
|
||||
}
|
||||
if (framebuffer->fb_stride != entry->bufw) {
|
||||
WARN_LOG_REPORT_ONCE(diffStrides1, G3D, "Render to texture with different strides %d != %d", entry->bufw, framebuffer->fb_stride);
|
||||
}
|
||||
if (entry->format != framebuffer->format) {
|
||||
WARN_LOG_REPORT_ONCE(diffFormat1, G3D, "Render to texture with different formats %d != %d", entry->format, framebuffer->format);
|
||||
// Let's avoid rendering when we know the format is wrong. May be a video/etc. updating memory.
|
||||
DetachFramebuffer(entry, address, framebuffer);
|
||||
} else {
|
||||
AttachFramebufferValid(entry, framebuffer, fbInfo);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// Apply to buffered mode only.
|
||||
@@ -317,7 +320,6 @@ bool TextureCache::AttachFramebuffer(TexCacheEntry *entry, u32 address, VirtualF
|
||||
WARN_LOG_REPORT_ONCE(subareaClut, G3D, "Render to texture using CLUT with offset at %08x +%dx%d", address, fbInfo.xOffset, fbInfo.yOffset);
|
||||
}
|
||||
AttachFramebufferValid(entry, framebuffer, fbInfo);
|
||||
fbTexInfo_[entry->addr] = fbInfo;
|
||||
entry->status |= TexCacheEntry::STATUS_DEPALETTIZE;
|
||||
// We'll validate it compiles later.
|
||||
return true;
|
||||
@@ -1120,6 +1122,12 @@ bool TextureCache::SetOffsetTexture(u32 offset) {
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
SetTextureFramebuffer(entry, entry->framebuffer);
|
||||
lastBoundTexture = -1;
|
||||
entry->lastFrame = gpuStats.numFlips;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -215,13 +215,13 @@ struct GPUgstate
|
||||
float tgenMatrix[12];
|
||||
float boneMatrix[12 * 8]; // Eight bone matrices.
|
||||
|
||||
// Framebuffer
|
||||
u32 getFrameBufRawAddress() const { return (fbptr & 0xFFFFFF) | ((fbwidth & 0xFF0000) << 8); }
|
||||
// We ignore the high bits of the framebuffer in fbwidth - even 0x08000000 renders to vRAM.
|
||||
u32 getFrameBufRawAddress() const { return (fbptr & 0xFFFFFF); }
|
||||
// 0x44000000 is uncached VRAM.
|
||||
u32 getFrameBufAddress() const { return 0x44000000 | getFrameBufRawAddress(); }
|
||||
GEBufferFormat FrameBufFormat() const { return static_cast<GEBufferFormat>(framebufpixformat & 3); }
|
||||
int FrameBufStride() const { return fbwidth&0x7FC; }
|
||||
u32 getDepthBufRawAddress() const { return (zbptr & 0xFFFFFF) | ((zbwidth & 0xFF0000) << 8); }
|
||||
u32 getDepthBufRawAddress() const { return (zbptr & 0xFFFFFF); }
|
||||
u32 getDepthBufAddress() const { return 0x44000000 | getDepthBufRawAddress(); }
|
||||
int DepthBufStride() const { return zbwidth&0x7FC; }
|
||||
|
||||
|
||||
Reference in new issue
Block a user