From 655038be45f54aa4bf41e4a587c64383489f3c88 Mon Sep 17 00:00:00 2001 From: ramapcsx2 Date: Sat, 31 Oct 2009 10:56:10 +0000 Subject: [PATCH] GSdx: - Fixed many flickering scene change transitions (FF12, Gust games, etc). - Found more info on how games do some special effects. Preliminary code included, but disabled. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2101 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/GSdx/GSRendererHW.h | 4 +- plugins/GSdx/GSTextureCache.cpp | 247 +++++++++++++++++++++++++++++++- 2 files changed, 249 insertions(+), 2 deletions(-) diff --git a/plugins/GSdx/GSRendererHW.h b/plugins/GSdx/GSRendererHW.h index aeaed71a1c..e3671690f9 100644 --- a/plugins/GSdx/GSRendererHW.h +++ b/plugins/GSdx/GSRendererHW.h @@ -466,7 +466,9 @@ protected: { __super::VSync(field); - m_tc->IncAge(); + // IncAge() gets rid of "old" textures, but it's not really needed. + // Doing it causes flickering on many game scene transitions. + //m_tc->IncAge(); m_skip = 0; diff --git a/plugins/GSdx/GSTextureCache.cpp b/plugins/GSdx/GSTextureCache.cpp index e3ec6fe451..519ed45ecf 100644 --- a/plugins/GSdx/GSTextureCache.cpp +++ b/plugins/GSdx/GSTextureCache.cpp @@ -451,7 +451,7 @@ void GSTextureCache::InvalidateLocalMem(const GSOffset* o, const GSVector4i& r) // TODO: ds */ } - +//Currently unused void GSTextureCache::IncAge() { int maxage = m_src.m_used ? 3 : 30; @@ -724,6 +724,251 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con return src; } + //WIP fog / blur / depth of field handling. +//GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* dst) +//{ +// Source* src = new Source(m_renderer); +// +// src->m_TEX0 = TEX0; +// src->m_TEXA = TEXA; +// +// int tw = 1 << TEX0.TW; +// int th = 1 << TEX0.TH; +// int tp = (int)TEX0.TW << 6; +// +// if(dst == NULL) +// { +// if(m_paltex && GSLocalMemory::m_psm[TEX0.PSM].pal > 0) +// { +// src->m_fmt = FMT_8; +// +// src->m_texture = m_renderer->m_dev->CreateTexture(tw, th, Get8bitFormat()); +// src->m_palette = m_renderer->m_dev->CreateTexture(256, 1); +// } +// else +// { +// src->m_fmt = FMT_32; +// +// src->m_texture = m_renderer->m_dev->CreateTexture(tw, th); +// } +// } +// else +// { +// // TODO: clean up this mess +// +// src->m_target = true; +// +// if(dst->m_type != RenderTarget) +// { +// // TODO +// +// delete src; +// +// return NULL; +// } +// +// dst->Update(); +// +// GSTexture* tmp = NULL; +// +// if(dst->m_texture->IsMSAA()) +// { +// tmp = dst->m_texture; +// +// dst->m_texture = m_renderer->m_dev->Resolve(dst->m_texture); +// } +// +// // do not round here!!! if edge becomes a black pixel and addressing mode is clamp => everything outside the clamped area turns into black (kh2 shadows) +// +// int w = (int)(dst->m_texture->GetScale().x * tw); +// int h = (int)(dst->m_texture->GetScale().y * th); +// +// GSVector2i dstsize = dst->m_texture->GetSize(); +// +// //Hacked up to figure out how fog / depth / blur effects are done. Works in Xenosaga 3. +// if ((tw == 1024 && th == 1024) && dst->m_TEX0.TBW != TEX0.TBW){ +// +// src->m_texture = m_renderer->m_dev->CreateRenderTarget(dstsize.x, dstsize.y, false); +// GSVector4 size = GSVector4(dstsize).xyxy() * 2; // * 2 to force the effect overlay into the right position +// GSVector4 scale = GSVector4(dst->m_texture->GetScale()).xyxy(); //Not needed right now, but good for testing +// +// GSVector4 br (0.0f, 0.0f, 1024.0f, 1024.0f); // entire RT +// GSVector4 sr = br * scale / size; +// GSVector4 dr = br * scale; +// +// m_renderer->m_dev->StretchRect(dst->m_texture, sr, src->m_texture, dr); +// } +// // pitch conversion //total mess right now, don't touch :p +// else if(dst->m_TEX0.TBW != TEX0.TBW) // && dst->m_TEX0.PSM == TEX0.PSM +// { +// // sfex3 uses this trick (bw: 10 -> 5, wraps the right side below the left) +// +// // ASSERT(dst->m_TEX0.TBW > TEX0.TBW); // otherwise scale.x need to be reduced to make the larger texture fit (TODO) +// +// src->m_texture = m_renderer->m_dev->CreateRenderTarget(dstsize.x, dstsize.y, false); +// +// GSVector4 size = GSVector4(dstsize).xyxy(); +// GSVector4 scale = GSVector4(dst->m_texture->GetScale()).xyxy(); +// +// if (dst->m_TEX0.TBW < TEX0.TBW) // otherwise scale.x need to be reduced to make the larger texture fit +// { +// // scale.x = ((float)dst->m_TEX0.TBW / (float)TEX0.TBW) ; +// // printf("scale.x = %f \n", scale.x); +// } +// +// int blockWidth = 64; +// int blockHeight = TEX0.PSM == PSM_PSMCT32 || TEX0.PSM == PSM_PSMCT24 ? 32 : 64; +// +// GSVector4i br(0, 0, blockWidth, blockHeight); +// +// int sw = (int)dst->m_TEX0.TBW << 6; +// +// int dw = (int)TEX0.TBW << 6; +// int dh = 1 << TEX0.TH; +// +// if(sw != 0) +// for(int dy = 0; dy < dh; dy += blockHeight) +// { +// for(int dx = 0; dx < dw; dx += blockWidth) +// { +// int o = dy * dw / blockHeight + dx; +// +// int sx = o % sw; +// int sy = o / sw; +// //printf("sx = %d ,sy = %d ,sw = %d ,o = %d \n",sx,sy,sw,o); +// GSVector4 sr = GSVector4(GSVector4i(sx, sy).xyxy() + br) * scale / size; +// GSVector4 dr = GSVector4(GSVector4i(dx, dy).xyxy() + br) * scale; +// +// m_renderer->m_dev->StretchRect(dst->m_texture, sr, src->m_texture, dr); +// +// // TODO: this is quite a lot of StretchRect, do it with one Draw +// } +// } +// } +// else if(tw < tp) +// { +// // FIXME: timesplitters blurs the render target by blending itself over a couple of times +// +// if(tw == 256 && th == 128 && tp == 512 && (TEX0.TBP0 == 0 || TEX0.TBP0 == 0x00e00)) +// { +// delete src; +// return false; +// } +// } +// // width/height conversion +// +// GSVector2 scale = dst->m_texture->GetScale(); +// +// GSVector4 dr(0, 0, w, h); +// +// if(w > dstsize.x) +// { +// scale.x = (float)dstsize.x / tw; +// dr.z = (float)dstsize.x * scale.x / dst->m_texture->GetScale().x; +// w = dstsize.x; +// } +// +// if(h > dstsize.y) +// { +// scale.y = (float)dstsize.y / th; +// dr.w = (float)dstsize.y * scale.y / dst->m_texture->GetScale().y; +// h = dstsize.y; +// } +// +// GSVector4 sr(0, 0, w, h); +// +// GSTexture* st = src->m_texture ? src->m_texture : dst->m_texture; +// GSTexture* dt = m_renderer->m_dev->CreateRenderTarget(w, h, false); +// +// if(!src->m_texture) +// { +// src->m_texture = dt; +// } +// +// if((sr == dr).alltrue()) +// { +// m_renderer->m_dev->CopyRect(st, dt, GSVector4i(0, 0, w, h)); +// } +// else +// { +// sr.z /= st->GetWidth(); +// sr.w /= st->GetHeight(); +// +// m_renderer->m_dev->StretchRect(st, sr, dt, dr); +// } +// +// if(dt != src->m_texture) +// { +// m_renderer->m_dev->Recycle(src->m_texture); +// +// src->m_texture = dt; +// } +// +// src->m_texture->SetScale(scale); +// +// switch(TEX0.PSM) +// { +// default: +// // Note: this assertion triggers in Xenosaga2 after the first intro scenes, when +// // gameplay first begins (in the city). +// ASSERT(0); +// case PSM_PSMCT32: +// src->m_fmt = FMT_32; +// break; +// case PSM_PSMCT24: +// src->m_fmt = FMT_24; +// break; +// case PSM_PSMCT16: +// case PSM_PSMCT16S: +// src->m_fmt = FMT_16; +// break; +// case PSM_PSMT8H: +// src->m_fmt = FMT_8H; +// src->m_palette = m_renderer->m_dev->CreateTexture(256, 1); +// break; +// case PSM_PSMT8: +// //Not sure, this wasn't handled at all. +// //Xenosaga 2 and 3 use it, Tales of Legendia as well. +// //It's always used for fog like effects. +// src->m_fmt = FMT_8; +// src->m_palette = m_renderer->m_dev->CreateTexture(256, 1); +// break; +// case PSM_PSMT4HL: +// src->m_fmt = FMT_4HL; +// src->m_palette = m_renderer->m_dev->CreateTexture(256, 1); +// break; +// case PSM_PSMT4HH: +// src->m_fmt = FMT_4HH; +// src->m_palette = m_renderer->m_dev->CreateTexture(256, 1); +// break; +// } +// +// if(tmp != NULL) +// { +// m_renderer->m_dev->Recycle(dst->m_texture); +// +// dst->m_texture = tmp; +// } +// } +// +// if(src->m_texture == NULL) +// { +// ASSERT(0); +// +// return NULL; +// } +// +// const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[TEX0.PSM]; +// +// if(psm.pal > 0) +// { +// memcpy(src->m_clut, (const uint32*)m_renderer->m_mem.m_clut, psm.pal * sizeof(uint32)); +// } +// +// m_src.Add(src, TEX0, m_renderer->m_context->offset.tex); +// +// return src; +//} GSTextureCache::Target* GSTextureCache::CreateTarget(const GIFRegTEX0& TEX0, int w, int h, int type) {