mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-30 19:24:23 +01:00
Try to workaround Breath of Fire 3's render-to-tex.
It renders to two areas but textures with a high V to reach the second texture. We've been wrapping the V around but this may show the right buffer.
This commit is contained in:
1 parent
80301ef053
commit
3d8f078b6c
4 files changed
+81
-17
No files matched your search
+55
-15
@@ -883,17 +883,17 @@ bool SetDebugTexture() {
|
||||
}
|
||||
#endif
|
||||
|
||||
void TextureCache::SetTextureFramebuffer(TexCacheEntry *entry) {
|
||||
entry->framebuffer->usageFlags |= FB_USAGE_TEXTURE;
|
||||
void TextureCache::SetTextureFramebuffer(TexCacheEntry *entry, VirtualFramebuffer *framebuffer) {
|
||||
framebuffer->usageFlags |= FB_USAGE_TEXTURE;
|
||||
bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
|
||||
if (useBufferedRendering) {
|
||||
GLuint program = 0;
|
||||
if (entry->status & TexCacheEntry::STATUS_DEPALETTIZE) {
|
||||
program = depalShaderCache_->GetDepalettizeShader(entry->framebuffer->format);
|
||||
program = depalShaderCache_->GetDepalettizeShader(framebuffer->format);
|
||||
}
|
||||
if (program) {
|
||||
GLuint clutTexture = depalShaderCache_->GetClutTexture(clutHash_, clutBuf_);
|
||||
FBO *depalFBO = framebufferManager_->GetTempFBO(entry->framebuffer->renderWidth, entry->framebuffer->renderHeight, FBO_8888);
|
||||
FBO *depalFBO = framebufferManager_->GetTempFBO(framebuffer->renderWidth, framebuffer->renderHeight, FBO_8888);
|
||||
fbo_bind_as_render_target(depalFBO);
|
||||
static const float pos[12] = {
|
||||
-1, -1, -1,
|
||||
@@ -925,7 +925,7 @@ void TextureCache::SetTextureFramebuffer(TexCacheEntry *entry) {
|
||||
glBindTexture(GL_TEXTURE_2D, clutTexture);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
framebufferManager_->BindFramebufferColor(entry->framebuffer, true);
|
||||
framebufferManager_->BindFramebufferColor(framebuffer, true);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
entry->status |= TexCacheEntry::STATUS_TEXPARAM_DIRTY;
|
||||
@@ -939,7 +939,7 @@ void TextureCache::SetTextureFramebuffer(TexCacheEntry *entry) {
|
||||
#if !defined(USING_GLES2)
|
||||
glDisable(GL_LOGIC_OP);
|
||||
#endif
|
||||
glViewport(0, 0, entry->framebuffer->renderWidth, entry->framebuffer->renderHeight);
|
||||
glViewport(0, 0, framebuffer->renderWidth, framebuffer->renderHeight);
|
||||
|
||||
glVertexAttribPointer(a_position, 3, GL_FLOAT, GL_FALSE, 12, pos);
|
||||
glVertexAttribPointer(a_texcoord0, 2, GL_FLOAT, GL_FALSE, 8, uv);
|
||||
@@ -961,27 +961,67 @@ void TextureCache::SetTextureFramebuffer(TexCacheEntry *entry) {
|
||||
gstate_c.textureSimpleAlpha = alphaStatus == TexCacheEntry::STATUS_ALPHA_SIMPLE;
|
||||
} else {
|
||||
entry->status &= ~TexCacheEntry::STATUS_DEPALETTIZE;
|
||||
framebufferManager_->BindFramebufferColor(entry->framebuffer);
|
||||
framebufferManager_->BindFramebufferColor(framebuffer);
|
||||
|
||||
gstate_c.textureFullAlpha = entry->framebuffer->format == GE_FORMAT_565;
|
||||
gstate_c.textureFullAlpha = framebuffer->format == GE_FORMAT_565;
|
||||
gstate_c.textureSimpleAlpha = gstate_c.textureFullAlpha;
|
||||
}
|
||||
|
||||
// Keep the framebuffer alive.
|
||||
entry->framebuffer->last_frame_used = gpuStats.numFlips;
|
||||
framebuffer->last_frame_used = gpuStats.numFlips;
|
||||
|
||||
// We need to force it, since we may have set it on a texture before attaching.
|
||||
gstate_c.curTextureWidth = entry->framebuffer->bufferWidth;
|
||||
gstate_c.curTextureHeight = entry->framebuffer->bufferHeight;
|
||||
gstate_c.curTextureWidth = framebuffer->bufferWidth;
|
||||
gstate_c.curTextureHeight = framebuffer->bufferHeight;
|
||||
gstate_c.flipTexture = true;
|
||||
UpdateSamplingParams(*entry, true);
|
||||
} else {
|
||||
if (entry->framebuffer->fbo)
|
||||
entry->framebuffer->fbo = 0;
|
||||
if (framebuffer->fbo)
|
||||
framebuffer->fbo = 0;
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool TextureCache::SetOffsetTexture(u32 offset) {
|
||||
if (g_Config.iRenderingMode != FB_BUFFERED_MODE) {
|
||||
return false;
|
||||
}
|
||||
u32 texaddr = gstate.getTextureAddress(0);
|
||||
if (!Memory::IsValidAddress(texaddr) || !Memory::IsValidAddress(texaddr + offset)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
u64 cachekey = (u64)(texaddr & 0x0FFFFFFF) << 32;
|
||||
TexCache::iterator iter = cache.find(cachekey);
|
||||
if (iter == cache.end()) {
|
||||
return false;
|
||||
}
|
||||
TexCacheEntry *entry = &iter->second;
|
||||
|
||||
texaddr += offset;
|
||||
cachekey = (u64)(texaddr & 0x0FFFFFFF) << 32;
|
||||
|
||||
for (size_t i = 0, n = fbCache_.size(); i < n; ++i) {
|
||||
auto framebuffer = fbCache_[i];
|
||||
// This is a rough heuristic, because sometimes our framebuffers are too tall.
|
||||
static const u32 MAX_SUBAREA_Y_OFFSET = 32;
|
||||
|
||||
// Must be in VRAM so | 0x04000000 it is, and ignore any uncached bit.
|
||||
const u32 addr = (framebuffer->fb_address | 0x04000000) & 0x0FFFFFFF;
|
||||
const u64 cacheKeyStart = (u64)addr << 32;
|
||||
// If it has a clut, those are the low 32 bits, so it'll be inside this range.
|
||||
// Also, if it's a subsample of the buffer, it'll also be within the FBO.
|
||||
const u64 cacheKeyEnd = cacheKeyStart + ((u64)(framebuffer->fb_stride * MAX_SUBAREA_Y_OFFSET) << 32);
|
||||
|
||||
if (cachekey >= cacheKeyStart && cachekey < cacheKeyEnd) {
|
||||
SetTextureFramebuffer(entry, framebuffer);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void TextureCache::SetTexture(bool force) {
|
||||
#ifdef DEBUG_TEXTURES
|
||||
if (SetDebugTexture()) {
|
||||
@@ -1053,7 +1093,7 @@ void TextureCache::SetTexture(bool force) {
|
||||
// Check for FBO - slow!
|
||||
if (entry->framebuffer) {
|
||||
if (match) {
|
||||
SetTextureFramebuffer(entry);
|
||||
SetTextureFramebuffer(entry, entry->framebuffer);
|
||||
lastBoundTexture = -1;
|
||||
entry->lastFrame = gpuStats.numFlips;
|
||||
return;
|
||||
@@ -1266,7 +1306,7 @@ void TextureCache::SetTexture(bool force) {
|
||||
|
||||
// If we ended up with a framebuffer, attach it - no texture decoding needed.
|
||||
if (entry->framebuffer) {
|
||||
SetTextureFramebuffer(entry);
|
||||
SetTextureFramebuffer(entry, entry->framebuffer);
|
||||
lastBoundTexture = -1;
|
||||
entry->lastFrame = gpuStats.numFlips;
|
||||
return;
|
||||
|
||||
Reference in new issue
Block a user