- Added some sad attempt to fix small upscale annoyances. It's very hackish but better than nothing :p 
- Small cleanups

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2169 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
ramapcsx2 2009-11-09 00:32:52 +00:00
parent de00eb95e7
commit 03fc72dd3f
2 changed files with 324 additions and 299 deletions

View File

@ -164,28 +164,26 @@ public:
{ {
if(m_vt.m_max.p.z > 0xffffff) if(m_vt.m_max.p.z > 0xffffff)
{ {
//ASSERT(m_vt.m_min.p.z > 0xffffff); ASSERT(m_vt.m_min.p.z > 0xffffff);
// Fixme :Following conditional fixes some dialog frame in Wild Arms 3, but may not be what was intended. // Fixme :Following conditional fixes some dialog frame in Wild Arms 3, but may not be what was intended.
if (m_vt.m_min.p.z > 0xffffff) if (m_vt.m_min.p.z > 0xffffff)
{ {
vs_sel.bppz = 1; vs_sel.bppz = 1;
om_dssel.ztst = ZTST_ALWAYS; om_dssel.ztst = ZTST_ALWAYS;
} }
//else printf ("GSdx: Z issue, please report\n");
} }
} }
else if(context->ZBUF.PSM == PSM_PSMZ16 || context->ZBUF.PSM == PSM_PSMZ16S) else if(context->ZBUF.PSM == PSM_PSMZ16 || context->ZBUF.PSM == PSM_PSMZ16S)
{ {
if(m_vt.m_max.p.z > 0xffff) if(m_vt.m_max.p.z > 0xffff)
{ {
//ASSERT(m_vt.m_min.p.z > 0xffff); // sfex capcom logo ASSERT(m_vt.m_min.p.z > 0xffff); // sfex capcom logo
// Fixme : Same as above, I guess. // Fixme : Same as above, I guess.
if (m_vt.m_min.p.z > 0xffff) if (m_vt.m_min.p.z > 0xffff)
{ {
vs_sel.bppz = 2; vs_sel.bppz = 2;
om_dssel.ztst = ZTST_ALWAYS; om_dssel.ztst = ZTST_ALWAYS;
} }
//else printf ("GSdx: Z issue, please report\n");
} }
} }
} }
@ -199,9 +197,8 @@ public:
float ox2 = 2.0f * m_pixelcenter.x / rt->GetWidth(); float ox2 = 2.0f * m_pixelcenter.x / rt->GetWidth();
float oy2 = 2.0f * m_pixelcenter.y / rt->GetHeight(); float oy2 = 2.0f * m_pixelcenter.y / rt->GetHeight();
float adjust_offset = 0.0f; vs_cb.VertexScale = GSVector4(sx, -sy, 1.0f / UINT_MAX, 0.0f);
float adjust_size = 0.0f; vs_cb.VertexOffset = GSVector4(ox * sx + ox2 + 1, -(oy * sy + oy2 + 1), 0.0f, -1.0f);
// gs // gs
GSDeviceDX::GSSelector gs_sel; GSDeviceDX::GSSelector gs_sel;
@ -265,22 +262,54 @@ public:
int tw = (int)(1 << context->TEX0.TW); int tw = (int)(1 << context->TEX0.TW);
int th = (int)(1 << context->TEX0.TH); int th = (int)(1 << context->TEX0.TH);
int multiplier = upscale_Multiplier();
GSVector4 WH(tw, th, w, h); GSVector4 WH(tw, th, w, h);
//if (w > 0 && w < 129) { adjust_size = 0.0001f; adjust_offset = -0.000000f; } //0.07f for ar tonelico but max 0.007f for shadow hearts) //Try to avoid small, common glitches with upscaling. This only takes care of slight
//else if (w > 128 && w < 257) { adjust_size = 0.0010f; adjust_offset = -0.000000f; } //0.007f; WA games want stuffx at 0.52 //variations however. The bigger ones, where upscaling intruduces pixels with no data
//else if (w > 256 && w < 513) { adjust_size = 0.4000f; adjust_offset = -0.000000f; } //offset -0.0005f; //cannot be fixed generally here. (Wild Arms games do this with their text.)
//else if (w > 512 && w < 1025){ adjust_size = 0.4000f; adjust_offset = -0.000000f; } //TotA battle blur wants -0.000015f, but that's too much for WA games. if ( multiplier == 2 ) {
if (tw < 17) {}
else if (tw < 33) {}
else if (tw < 65) {}
else if (tw < 129) {}
else if (tw < 257) {}
else if (tw < 513) {vs_cb.VertexScale.x *= 1.0f - ((float)1 * -0.00002f); }
else if (tw < 1025) {}
//adjust_offset = -0.001f; } //0.07f for ar tonelico but max 0.007f for shadow hearts) if (th < 17) {}
//adjust_offset = 0.0002f; } //0.007f; else if (th < 33) {}
//adjust_offset = -0.0005f; } //offset -0.0005f; else if (th < 65) {}
//adjust_offset = -0.000006f; } //TotA battle blur wants -0.000015f, but that's too much for WA games. else if (th < 129) {}
else if (th < 257) {}
else if (th < 513) {vs_cb.VertexScale.y *= 1.0f - ((float)1 * -0.00001f); }
else if (th < 1025) {}
}
if(PRIM->FST) if(PRIM->FST)
{ {
vs_cb.TextureScale = GSVector4((1.0f / 16)) / (WH.xyxy() + adjust_size); vs_cb.TextureScale = GSVector4(1.0f / 16) / WH.xyxy();
//Try to avoid small, common glitches with upscaling. This only takes care of slight
//variations however. The bigger ones, where upscaling intruduces pixels with no data
//cannot be fixed generally here. (Wild Arms games do this with their text.)
if ( multiplier == 2 ) {
if (tw < 17) {}
else if (tw < 33) {}
else if (tw < 65) {}
else if (tw < 129) {vs_cb.TextureScale.x *= 1.0f - ((float)4 * 0.0001f); }
else if (tw < 257) {vs_cb.TextureScale.x *= 1.0f - ((float)2 * 0.0001f);}
else if (tw < 513) {vs_cb.TextureScale.x *= 1.0f - ((float)6 * 0.0001f); }
else if (tw < 1025) {}
if (th < 17) {}
else if (th < 33) {vs_cb.TextureScale.y *= 1.0f - ((float)2 * 0.0001f); } //ar tonelico bg
else if (th < 65) {}
else if (th < 129) {vs_cb.TextureScale.y *= 1.0f - ((float)2 * 0.0001f); }
else if (th < 257) {vs_cb.TextureScale.y *= 1.0f - ((float)2 * 0.0001f); }
else if (th < 513) {vs_cb.TextureScale.y *= 1.0f - ((float)4 * 0.0001f); }
else if (th < 1025) {}
}
ps_sel.fst = 1; ps_sel.fst = 1;
} }
@ -303,8 +332,6 @@ public:
ps_sel.tfx = 4; ps_sel.tfx = 4;
} }
vs_cb.VertexScale = GSVector4(sx, -sy, 1.0f / UINT_MAX, 0.0f);
vs_cb.VertexOffset = GSVector4(ox * sx + ox2 + 1 + adjust_offset, -(oy * sy + oy2 + 1 + adjust_offset), 0.0f, -1.0f);
// rs // rs
GSVector4i scissor = GSVector4i(GSVector4(rt->GetScale()).xyxy() * context->scissor.in).rintersect(GSVector4i(rt->GetSize()).zwxy()); GSVector4i scissor = GSVector4i(GSVector4(rt->GetScale()).xyxy() * context->scissor.in).rintersect(GSVector4i(rt->GetSize()).zwxy());

View File

@ -491,6 +491,9 @@ void GSTextureCache::IncAge()
//} //}
} }
//Fixme: Several issues in here. Not handling depth stencil, pitch conversion doesnt work.
//The alternative version isn't much better though :p
#if 1
GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* dst) GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* dst)
{ {
Source* src = new Source(m_renderer); Source* src = new Source(m_renderer);
@ -560,18 +563,13 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
// sfex3 uses this trick (bw: 10 -> 5, wraps the right side below the left) // 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) 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); src->m_texture = m_renderer->m_dev->CreateRenderTarget(dstsize.x, dstsize.y, false);
GSVector4 size = GSVector4(dstsize).xyxy(); GSVector4 size = GSVector4(dstsize).xyxy();
GSVector4 scale = GSVector4(dst->m_texture->GetScale()).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 *= (dst->m_TEX0.TBW/TEX0.TBW);
}
int blockWidth = 64; int blockWidth = 64;
int blockHeight = TEX0.PSM == PSM_PSMCT32 || TEX0.PSM == PSM_PSMCT24 ? 32 : 64; int blockHeight = TEX0.PSM == PSM_PSMCT32 || TEX0.PSM == PSM_PSMCT24 ? 32 : 64;
@ -725,278 +723,278 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
return src; return src;
} }
#else
//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);
// //WIP fog / blur / depth of field handling. src->m_TEX0 = TEX0;
//GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, Target* dst) src->m_TEXA = TEXA;
//{
// Source* src = new Source(m_renderer); int tw = 1 << TEX0.TW;
// int th = 1 << TEX0.TH;
// src->m_TEX0 = TEX0; int tp = (int)TEX0.TW << 6;
// src->m_TEXA = TEXA;
// if(dst == NULL)
// int tw = 1 << TEX0.TW; {
// int th = 1 << TEX0.TH; if(m_paltex && GSLocalMemory::m_psm[TEX0.PSM].pal > 0)
// int tp = (int)TEX0.TW << 6; {
// src->m_fmt = FMT_8;
// if(dst == NULL)
// { src->m_texture = m_renderer->m_dev->CreateTexture(tw, th, Get8bitFormat());
// if(m_paltex && GSLocalMemory::m_psm[TEX0.PSM].pal > 0) src->m_palette = m_renderer->m_dev->CreateTexture(256, 1);
// { }
// src->m_fmt = FMT_8; else
// {
// src->m_texture = m_renderer->m_dev->CreateTexture(tw, th, Get8bitFormat()); src->m_fmt = FMT_32;
// src->m_palette = m_renderer->m_dev->CreateTexture(256, 1);
// } src->m_texture = m_renderer->m_dev->CreateTexture(tw, th);
// else }
// { }
// src->m_fmt = FMT_32; else
// {
// src->m_texture = m_renderer->m_dev->CreateTexture(tw, th); // TODO: clean up this mess
// }
// } src->m_target = true;
// else
// { dst->Update();
// // TODO: clean up this mess
// if(dst->m_type != RenderTarget)
// src->m_target = true; {
// //src->m_target = false; //no idea what depth stencil needs ><
// dst->Update(); //printf("type stencil\n");
// }
// if(dst->m_type != RenderTarget)
// { GSTexture* tmp = NULL;
// //src->m_target = false; //no idea what depth stencil needs ><
// //printf("type stencil\n"); if(dst->m_texture->IsMSAA())
// } {
// tmp = dst->m_texture;
// GSTexture* tmp = NULL;
// dst->m_texture = m_renderer->m_dev->Resolve(dst->m_texture);
// if(dst->m_texture->IsMSAA()) }
// {
// tmp = 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)
//
// dst->m_texture = m_renderer->m_dev->Resolve(dst->m_texture); int w = (int)(dst->m_texture->GetScale().x * tw);
// } int h = (int)(dst->m_texture->GetScale().y * th);
//
// // 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) GSVector2i dstsize = dst->m_texture->GetSize();
//
// int w = (int)(dst->m_texture->GetScale().x * tw); //Hacked up to figure out how fog / depth / blur effects are done. Works in Xenosaga 3.
// int h = (int)(dst->m_texture->GetScale().y * th); if ((tw == 1024 && th == 1024) && dst->m_TEX0.TBW != TEX0.TBW){
//
// GSVector2i dstsize = dst->m_texture->GetSize(); if(dst->m_type != RenderTarget)
// {
// //Hacked up to figure out how fog / depth / blur effects are done. Works in Xenosaga 3. src->m_texture = m_renderer->m_dev->CreateDepthStencil(dstsize.x, dstsize.y, false);
// if ((tw == 1024 && th == 1024) && dst->m_TEX0.TBW != TEX0.TBW){ }
// else{
// if(dst->m_type != RenderTarget) src->m_texture = m_renderer->m_dev->CreateRenderTarget(dstsize.x, dstsize.y, false);
// { }
// src->m_texture = m_renderer->m_dev->CreateDepthStencil(dstsize.x, dstsize.y, false);
// } GSVector4 size = GSVector4(dstsize).xyxy()*2 ; // * 2 to force the effect overlay into the right position
// else{ GSVector4 scale = GSVector4(dst->m_texture->GetScale()).xyxy(); //Not needed right now, but good for testing
// src->m_texture = m_renderer->m_dev->CreateRenderTarget(dstsize.x, dstsize.y, false);
// } GSVector4 br (0.0f, 0.0f, 1024.0f, 1024.0f); // entire RT
// GSVector4 sr = br * scale / size;
// GSVector4 size = GSVector4(dstsize).xyxy()*2 ; // * 2 to force the effect overlay into the right position GSVector4 dr = br * scale;
// GSVector4 scale = GSVector4(dst->m_texture->GetScale()).xyxy(); //Not needed right now, but good for testing
// m_renderer->m_dev->StretchRect(dst->m_texture, sr, src->m_texture, dr);
// GSVector4 br (0.0f, 0.0f, 1024.0f, 1024.0f); // entire RT
// GSVector4 sr = br * scale / size; }
// GSVector4 dr = br * scale; // pitch conversion
// else if(dst->m_TEX0.TBW != TEX0.TBW) // && dst->m_TEX0.PSM == TEX0.PSM
// m_renderer->m_dev->StretchRect(dst->m_texture, sr, src->m_texture, dr); {
// // sfex3 uses this trick (bw: 10 -> 5, wraps the right side below the left)
// }
// // pitch conversion // ASSERT(dst->m_TEX0.TBW > TEX0.TBW); // otherwise scale.x need to be reduced to make the larger texture fit (TODO)
// else if(dst->m_TEX0.TBW != TEX0.TBW) // && dst->m_TEX0.PSM == TEX0.PSM
// { if(dst->m_type != RenderTarget)
// // sfex3 uses this trick (bw: 10 -> 5, wraps the right side below the left) {
// src->m_texture = m_renderer->m_dev->CreateDepthStencil(dstsize.x, dstsize.y, false);
// // ASSERT(dst->m_TEX0.TBW > TEX0.TBW); // otherwise scale.x need to be reduced to make the larger texture fit (TODO) }
// else{
// if(dst->m_type != RenderTarget) src->m_texture = m_renderer->m_dev->CreateRenderTarget(dstsize.x, dstsize.y, false);
// { }
// src->m_texture = m_renderer->m_dev->CreateDepthStencil(dstsize.x, dstsize.y, false);
// } GSVector4 size = GSVector4(dstsize).xyxy();
// else{ GSVector4 scale = GSVector4(dst->m_texture->GetScale()).xyxy();
// src->m_texture = m_renderer->m_dev->CreateRenderTarget(dstsize.x, dstsize.y, false);
// } if (dst->m_TEX0.TBW < TEX0.TBW) // otherwise scale.x need to be reduced to make the larger texture fit
// {
// GSVector4 size = GSVector4(dstsize).xyxy(); scale.x = ((float)dst->m_TEX0.TBW / (float)TEX0.TBW) ;
// GSVector4 scale = GSVector4(dst->m_texture->GetScale()).xyxy(); //printf("scale.x = %f \n", scale.x);
// }
// if (dst->m_TEX0.TBW < TEX0.TBW) // otherwise scale.x need to be reduced to make the larger texture fit
// { int blockWidth = 64;
// scale.x = ((float)dst->m_TEX0.TBW / (float)TEX0.TBW) ; int blockHeight = TEX0.PSM == PSM_PSMCT32 || TEX0.PSM == PSM_PSMCT24 ? 32 : 64;
// //printf("scale.x = %f \n", scale.x);
// } GSVector4i br(0, 0, blockWidth, blockHeight);
//
// int blockWidth = 64; int sw = (int)dst->m_TEX0.TBW << 6;
// int blockHeight = TEX0.PSM == PSM_PSMCT32 || TEX0.PSM == PSM_PSMCT24 ? 32 : 64;
// int dw = (int)TEX0.TBW << 6;
// GSVector4i br(0, 0, blockWidth, blockHeight); int dh = 1 << TEX0.TH;
//
// int sw = (int)dst->m_TEX0.TBW << 6; if(sw != 0)
// for(int dy = 0; dy < dh; dy += blockHeight)
// int dw = (int)TEX0.TBW << 6; {
// int dh = 1 << TEX0.TH; for(int dx = 0; dx < dw; dx += blockWidth)
// {
// if(sw != 0) int o = dy * dw / blockHeight + dx;
// for(int dy = 0; dy < dh; dy += blockHeight)
// { int sx = o % sw;
// for(int dx = 0; dx < dw; dx += blockWidth) int sy = o / sw;
// { //printf("sx = %d ,sy = %d ,sw = %d ,o = %d \n",sx,sy,sw,o);
// int o = dy * dw / blockHeight + dx; GSVector4 sr = GSVector4(GSVector4i(sx, sy).xyxy() + br) * scale / size;
// GSVector4 dr = GSVector4(GSVector4i(dx, dy).xyxy() + br) * scale;
// int sx = o % sw;
// int sy = o / sw; m_renderer->m_dev->StretchRect(dst->m_texture, sr, src->m_texture, dr);
// //printf("sx = %d ,sy = %d ,sw = %d ,o = %d \n",sx,sy,sw,o);
// GSVector4 sr = GSVector4(GSVector4i(sx, sy).xyxy() + br) * scale / size; // TODO: this is quite a lot of StretchRect, do it with one Draw
// GSVector4 dr = GSVector4(GSVector4i(dx, dy).xyxy() + br) * scale; }
// }
// m_renderer->m_dev->StretchRect(dst->m_texture, sr, src->m_texture, dr); }
// else if(tw < tp)
// // TODO: this is quite a lot of StretchRect, do it with one Draw {
// } // 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))
// else if(tw < tp) {
// { delete src;
// // FIXME: timesplitters blurs the render target by blending itself over a couple of times return false;
// }
// if(tw == 256 && th == 128 && tp == 512 && (TEX0.TBP0 == 0 || TEX0.TBP0 == 0x00e00)) }
// {
// delete src; // width/height conversion
// return false;
// } GSVector2 scale = dst->m_texture->GetScale();
// }
// GSVector4 dr(0, 0, w, h);
// // width/height conversion
// //if(dst->m_type != RenderTarget) {
// GSVector2 scale = dst->m_texture->GetScale(); if(w > dstsize.x)
// {
// GSVector4 dr(0, 0, w, h); scale.x = (float)dstsize.x / tw;
// dr.z = (float)dstsize.x * scale.x / dst->m_texture->GetScale().x;
// //if(dst->m_type != RenderTarget) { w = dstsize.x;
// if(w > dstsize.x) }
// {
// scale.x = (float)dstsize.x / tw; if(h > dstsize.y)
// dr.z = (float)dstsize.x * scale.x / dst->m_texture->GetScale().x; {
// w = dstsize.x; scale.y = (float)dstsize.y / th;
// } dr.w = (float)dstsize.y * scale.y / dst->m_texture->GetScale().y;
// h = dstsize.y;
// 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;
// if(dst->m_type == RenderTarget) dt = m_renderer->m_dev->CreateRenderTarget(w, h, false);
// else dt = m_renderer->m_dev->CreateDepthStencil(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:
// // Unhandled texture format
// 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_PSMZ32:
// src->m_fmt = FMT_32;
// break;
// case PSM_PSMZ24:
// src->m_fmt = FMT_24;
// break;
// case PSM_PSMZ16:
// 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;
//} //}
GSVector4 sr(0, 0, w, h);
GSTexture* st = src->m_texture ? src->m_texture : dst->m_texture;
GSTexture* dt;
if(dst->m_type == RenderTarget) dt = m_renderer->m_dev->CreateRenderTarget(w, h, false);
else dt = m_renderer->m_dev->CreateDepthStencil(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:
// Unhandled texture format
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_PSMZ32:
src->m_fmt = FMT_32;
break;
case PSM_PSMZ24:
src->m_fmt = FMT_24;
break;
case PSM_PSMZ16:
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;
}
#endif
GSTextureCache::Target* GSTextureCache::CreateTarget(const GIFRegTEX0& TEX0, int w, int h, int type) GSTextureCache::Target* GSTextureCache::CreateTarget(const GIFRegTEX0& TEX0, int w, int h, int type)
{ {
Target* t = new Target(m_renderer); Target* t = new Target(m_renderer);