mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-17 04:39:34 +00:00
Fix wrong size generated of FBO for some games which uses it as render-to-texture
This commit is contained in:
parent
e03acc4c58
commit
c2a86d647f
@ -375,35 +375,40 @@ VirtualFramebuffer *FramebufferManager::GetDisplayFBO() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GetViewportDimensions(int &w, int &h) {
|
||||
float vpXa = getFloat24(gstate.viewportx1);
|
||||
float vpYa = getFloat24(gstate.viewporty1);
|
||||
w = (int)fabsf(vpXa * 2);
|
||||
h = (int)fabsf(vpYa * 2);
|
||||
}
|
||||
|
||||
// Heuristics to figure out the size of FBO to create.
|
||||
void GuessDrawingSize(int &drawing_width, int &drawing_height) {
|
||||
int viewport_width, viewport_height;
|
||||
int default_width = 480;
|
||||
int default_height = 272;
|
||||
int regionX2 = (gstate.getRegionX2() + 1) ;
|
||||
int regionY2 = (gstate.getRegionY2() + 1) ;
|
||||
int fb_stride = gstate.fbwidth & 0x3C0;
|
||||
GetViewportDimensions(viewport_width, viewport_height);
|
||||
int viewport_width = (int) gstate.getViewportX1();
|
||||
int viewport_height = (int) gstate.getViewportY1();
|
||||
int region_width = (gstate.getRegionX2() + 1) ;
|
||||
int region_height = (gstate.getRegionY2() + 1) ;
|
||||
int fb_width = gstate.fbwidth & 0x3C0;
|
||||
|
||||
// Generated FBO shouldn't greate than 512x512
|
||||
if ( viewport_width > 512 && viewport_height > 512 ) {
|
||||
viewport_width = default_width;
|
||||
viewport_height = default_height;
|
||||
DEBUG_LOG(HLE,"Viewport : %ix%i, Region : %ix%i, Stride: %i", viewport_width,viewport_height, region_width, region_height, fb_width);
|
||||
|
||||
// Just in case viewport return as 0x0 like FF Type-0
|
||||
if (viewport_width <= 1 && viewport_height <=1) {
|
||||
drawing_width = default_width;
|
||||
drawing_height = default_height;
|
||||
}
|
||||
|
||||
if (fb_stride < 512) {
|
||||
drawing_width = std::min(viewport_width, regionX2);
|
||||
drawing_height = std::min(viewport_height, regionY2);
|
||||
if (fb_width < 512) {
|
||||
if (fb_width != viewport_width) {
|
||||
drawing_width = viewport_width;
|
||||
drawing_height = viewport_height;
|
||||
} else {
|
||||
drawing_width = region_width;
|
||||
drawing_height = region_height;
|
||||
}
|
||||
} else {
|
||||
drawing_width = std::max(viewport_width, default_width);
|
||||
drawing_height = std::max(viewport_height, default_height);
|
||||
if (fb_width != region_width) {
|
||||
drawing_width = default_width;
|
||||
drawing_height = default_height;
|
||||
} else {
|
||||
drawing_width = region_width;
|
||||
drawing_height = region_height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,8 @@ inline void TextureCache::AttachFramebuffer(TexCacheEntry *entry, u32 address, V
|
||||
if (entry->format != framebuffer->format) {
|
||||
WARN_LOG_REPORT_ONCE(diffFormat1, HLE, "Render to texture with different formats %d != %d", entry->format, framebuffer->format);
|
||||
// If it already has one, let's hope that one is correct.
|
||||
AttachFramebufferInvalid(entry, framebuffer);
|
||||
// Try to not bind FB now as it seems to be attached some strange stuff on top of the original FB.
|
||||
//AttachFramebufferInvalid(entry, framebuffer);
|
||||
} else {
|
||||
AttachFramebufferValid(entry, framebuffer);
|
||||
}
|
||||
|
@ -20,6 +20,23 @@
|
||||
#include "../Globals.h"
|
||||
#include "ge_constants.h"
|
||||
|
||||
// PSP uses a curious 24-bit float - it's basically the top 24 bits of a regular IEEE754 32-bit float.
|
||||
// This is used for light positions, transform matrices, you name it.
|
||||
inline float getFloat24(unsigned int data)
|
||||
{
|
||||
data <<= 8;
|
||||
float f;
|
||||
memcpy(&f, &data, 4);
|
||||
return f;
|
||||
}
|
||||
|
||||
// in case we ever want to generate PSP display lists...
|
||||
inline unsigned int toFloat24(float f) {
|
||||
unsigned int i;
|
||||
memcpy(&i, &f, 4);
|
||||
return i >> 8;
|
||||
}
|
||||
|
||||
struct GPUgstate
|
||||
{
|
||||
// Getting rid of this ugly union in favor of the accessor functions
|
||||
@ -316,6 +333,8 @@ struct GPUgstate
|
||||
int getRegionY1() const { return (region1 >> 10) & 0x3FF; }
|
||||
int getRegionX2() const { return (region2 & 0x3FF); }
|
||||
int getRegionY2() const { return ((region2 >> 10) & 0x3FF); }
|
||||
float getViewportX1() const { return fabsf(getFloat24(viewportx1) * 2.0f); }
|
||||
float getViewportY1() const { return fabsf(getFloat24(viewporty1) * 2.0f); }
|
||||
|
||||
// Vertex type
|
||||
bool isModeThrough() const { return (vertType & GE_VTYPE_THROUGH) != 0; }
|
||||
@ -431,23 +450,6 @@ void InitGfxState();
|
||||
void ShutdownGfxState();
|
||||
void ReapplyGfxState();
|
||||
|
||||
// PSP uses a curious 24-bit float - it's basically the top 24 bits of a regular IEEE754 32-bit float.
|
||||
// This is used for light positions, transform matrices, you name it.
|
||||
inline float getFloat24(unsigned int data)
|
||||
{
|
||||
data <<= 8;
|
||||
float f;
|
||||
memcpy(&f, &data, 4);
|
||||
return f;
|
||||
}
|
||||
|
||||
// in case we ever want to generate PSP display lists...
|
||||
inline unsigned int toFloat24(float f) {
|
||||
unsigned int i;
|
||||
memcpy(&i, &f, 4);
|
||||
return i >> 8;
|
||||
}
|
||||
|
||||
class GPUInterface;
|
||||
|
||||
extern GPUgstate gstate;
|
||||
|
Loading…
x
Reference in New Issue
Block a user