Throw away unused FBOs. This gets rid of extreme slowness of Star Soldier on Nexus S for whatever reason.

This commit is contained in:
Henrik Rydgard 2013-01-11 02:00:51 +01:00
parent 2f394fb7ed
commit 6ab6045baf
5 changed files with 35 additions and 6 deletions

View File

@ -208,7 +208,7 @@ void hleEnterVblank(u64 userdata, int cyclesLate) {
// Here we will be drawing to the non buffered front surface.
if (g_Config.bShowDebugStats && gpuStats.numDrawCalls) {
gpu->UpdateStats();
char stats[512];
char stats[2048];
sprintf(stats,
"Frames: %i\n"
"DL processing time: %0.2f ms\n"
@ -217,6 +217,7 @@ void hleEnterVblank(u64 userdata, int cyclesLate) {
"Draw calls: %i\n"
"Draw flushes: %i\n"
"Vertices Transformed: %i\n"
"FBOs active: %i\n"
"Textures active: %i\n"
"Textures decoded: %i\n"
"Texture invalidations: %i\n"
@ -231,6 +232,7 @@ void hleEnterVblank(u64 userdata, int cyclesLate) {
gpuStats.numDrawCalls,
gpuStats.numFlushes,
gpuStats.numVertsTransformed,
gpuStats.numFBOs,
gpuStats.numTextures,
gpuStats.numTexturesDecoded,
gpuStats.numTextureInvalidations,

View File

@ -37,6 +37,11 @@
extern u32 curTextureWidth;
extern u32 curTextureHeight;
// Aggressively delete unused FBO:s to save gpu memory.
enum {
FBO_OLD_AGE = 4
};
const int flushOnChangedBeforeCommandList[] = {
GE_CMD_VERTEXTYPE,
GE_CMD_BLENDMODE,
@ -200,6 +205,7 @@ void GLES_GPU::DumpNextFrame() {
void GLES_GPU::BeginFrame() {
TextureCache_StartFrame();
DecimateFBOs();
if (dumpNextFrame_) {
NOTICE_LOG(G3D, "DUMPING THIS FRAME");
@ -277,6 +283,17 @@ void GLES_GPU::CopyDisplayToOutput() {
BeginDebugDraw();
}
void GLES_GPU::DecimateFBOs() {
for (auto iter = vfbs_.begin(); iter != vfbs_.end();) {
if ((*iter)->last_frame_used + FBO_OLD_AGE < gpuStats.numFrames) {
fbo_destroy((*iter)->fbo);
vfbs_.erase(iter++);
}
else
++iter;
}
}
GLES_GPU::VirtualFramebuffer *GLES_GPU::GetDisplayFBO() {
for (auto iter = vfbs_.begin(); iter != vfbs_.end(); ++iter) {
if (((*iter)->fb_address & 0x3FFFFFF) == (displayFramebufPtr_ & 0x3FFFFFF)) {
@ -345,6 +362,7 @@ void GLES_GPU::SetRenderFrameBuffer() {
vfb->height = drawing_height;
vfb->format = fmt;
vfb->fbo = fbo_create(vfb->width * renderWidthFactor_, vfb->height * renderHeightFactor_, 1, true);
vfb->last_frame_used = gpuStats.numFrames;
vfbs_.push_back(vfb);
fbo_bind_as_render_target(vfb->fbo);
glstate.viewport.set(0, 0, renderWidth_, renderHeight_);
@ -362,6 +380,7 @@ void GLES_GPU::SetRenderFrameBuffer() {
fbo_bind_as_render_target(vfb->fbo);
glstate.viewport.set(0, 0, renderWidth_, renderHeight_);
currentRenderVfb_ = vfb;
vfb->last_frame_used = gpuStats.numFrames;
}
}
@ -1064,6 +1083,7 @@ void GLES_GPU::UpdateStats() {
gpuStats.numFragmentShaders = shaderManager_->NumFragmentShaders();
gpuStats.numShaders = shaderManager_->NumPrograms();
gpuStats.numTextures = TextureCache_NumLoadedTextures();
gpuStats.numFBOs = vfbs_.size();
}
void GLES_GPU::DoBlockTransfer() {

View File

@ -63,6 +63,9 @@ private:
void BeginDebugDraw();
void EndDebugDraw();
// Deletes old FBOs.
void DecimateFBOs();
FramebufferManager framebufferManager;
TransformDrawEngine transformDraw_;
ShaderManager *shaderManager_;
@ -86,6 +89,8 @@ private:
};
struct VirtualFramebuffer {
int last_frame_used;
u32 fb_address;
u32 z_address;
int fb_stride;

View File

@ -61,11 +61,12 @@ u16 *clutBuf16;
void TextureCache_Init() {
// TODO: Switch to aligned allocations for alignment. AllocateMemoryPages would do the trick.
tmpTexBuf32 = new u32[1024 * 512];
tmpTexBuf16 = new u16[1024 * 512];
tmpTexBufRearrange = new u32[1024 * 512];
clutBuf32 = new u32[4096];
clutBuf16 = new u16[4096];
// This is 5MB of temporary storage. Might be possible to shrink it.
tmpTexBuf32 = new u32[1024 * 512]; // 2MB
tmpTexBuf16 = new u16[1024 * 512]; // 1MB
tmpTexBufRearrange = new u32[1024 * 512]; // 2MB
clutBuf32 = new u32[4096]; // 4K
clutBuf16 = new u16[4096]; // 4K
}
void TextureCache_Shutdown() {

View File

@ -283,6 +283,7 @@ struct GPUStatistics
int numVertexShaders;
int numFragmentShaders;
int numShaders;
int numFBOs;
};
void InitGfxState();