Merge pull request #1349 from PCSX2/gsdx-channel-effect

Gsdx channel effect
This commit is contained in:
Gregory Hainaut 2016-05-08 19:03:18 +02:00
commit 5ecbc2889b
7 changed files with 134 additions and 66 deletions

View File

@ -534,6 +534,7 @@ bool IsCrcExcluded(string exclusionList, uint32 crc)
CRC::Game CRC::Lookup(uint32 crc)
{
printf("GSdx Lookup CRC:%X\n", crc);
if(m_map.empty())
{
string exclusions = theApp.GetConfig( "CrcHacksExclusions", "" );
@ -549,7 +550,7 @@ CRC::Game CRC::Lookup(uint32 crc)
, m_games[i].crc, m_games[i].title, m_games[i].region, m_map[m_games[i].crc]->title, m_map[m_games[i].crc]->region);
crcDups++;
}
m_map[m_games[i].crc] = &m_games[i];
}
//else

View File

@ -767,7 +767,8 @@ GLuint GSDeviceOGL::CompilePS(PSSelector sel)
+ format("#define PS_DFMT %d\n", sel.dfmt)
+ format("#define PS_DEPTH_FMT %d\n", sel.depth_fmt)
+ format("#define PS_CHANNEL_FETCH %d\n", sel.channel)
+ format("#define PS_URBAN_CHAOS_HACK %d\n", sel.urban_chaos_hack)
+ format("#define PS_URBAN_CHAOS_HLE %d\n", sel.urban_chaos_hle)
+ format("#define PS_TALES_OF_ABYSS_HLE %d\n", sel.tales_of_abyss_hle)
+ format("#define PS_AEM %d\n", sel.aem)
+ format("#define PS_TFX %d\n", sel.tfx)
+ format("#define PS_TCC %d\n", sel.tcc)

View File

@ -289,9 +289,10 @@ class GSDeviceOGL final : public GSDevice
// Hack
uint32 tcoffsethack:1;
uint32 urban_chaos_hack:1;
uint32 urban_chaos_hle:1;
uint32 tales_of_abyss_hle:1;
uint32 _free2:15;
uint32 _free2:14;
};
uint64 key;

View File

@ -295,31 +295,6 @@ bool GSC_AceCombat4(const GSFrameInfo& fi, int& skip)
return true;
}
bool GSC_Tekken5(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && (fi.FBP == 0x02d60 || fi.FBP == 0x02d80 || fi.FBP == 0x02ea0 || fi.FBP == 0x03620) && fi.FPSM == fi.TPSM && fi.TBP0 == 0x00000 && fi.TPSM == PSM_PSMCT32)
{
skip = 95;
}
else if(fi.TME && (fi.FBP == 0x02bc0 || fi.FBP == 0x02be0 || fi.FBP == 0x02d00) && fi.FPSM == fi.TPSM && fi.TBP0 == 0x00000 && fi.TPSM == PSM_PSMCT32)
{
skip = 2;
}
else if(fi.TME)
{
if( (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S) ||
(GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) )
{
skip = 24;
}
}
}
return true;
}
bool GSC_IkkiTousen(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
@ -354,30 +329,6 @@ bool GSC_Onimusha3(const GSFrameInfo& fi, int& skip)
return true;
}
bool GSC_TalesOfAbyss(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00e00) && fi.TBP0 == 0x01c00 && fi.TPSM == PSM_PSMT8) // copies the z buffer to the alpha channel of the fb
{
skip = 1000;
}
else if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00e00) && (fi.TBP0 == 0x03560 || fi.TBP0 == 0x038e0) && fi.TPSM == PSM_PSMCT32)
{
skip = 1;
}
}
else
{
if(fi.TME && fi.TPSM != PSM_PSMT8)
{
skip = 0;
}
}
return true;
}
bool GSC_Genji(const GSFrameInfo& fi, int& skip)
{
if( !skip && fi.TME && (fi.FBP == 0x700 || fi.FBP == 0x0) && fi.TBP0 == 0x1500 && fi.TPSM )
@ -1358,6 +1309,56 @@ bool GSC_SteambotChronicles(const GSFrameInfo& fi, int& skip)
////////////////////////////////////////////////////////////////////////////////
// Correctly emulated on OpenGL but can be used as potential speed hack
////////////////////////////////////////////////////////////////////////////////
bool GSC_TalesOfAbyss(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00e00) && fi.TBP0 == 0x01c00 && fi.TPSM == PSM_PSMT8) // copies the z buffer to the alpha channel of the fb
{
skip = 1000;
}
else if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00e00) && (fi.TBP0 == 0x03560 || fi.TBP0 == 0x038e0) && fi.TPSM == PSM_PSMCT32)
{
skip = 1;
}
}
else
{
if(fi.TME && fi.TPSM != PSM_PSMT8)
{
skip = 0;
}
}
return true;
}
bool GSC_Tekken5(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(fi.TME && (fi.FBP == 0x02d60 || fi.FBP == 0x02d80 || fi.FBP == 0x02ea0 || fi.FBP == 0x03620) && fi.FPSM == fi.TPSM && fi.TBP0 == 0x00000 && fi.TPSM == PSM_PSMCT32)
{
skip = 95;
}
else if(fi.TME && (fi.FBP == 0x02bc0 || fi.FBP == 0x02be0 || fi.FBP == 0x02d00) && fi.FPSM == fi.TPSM && fi.TBP0 == 0x00000 && fi.TPSM == PSM_PSMCT32)
{
skip = 2;
}
else if(fi.TME)
{
if( (fi.TPSM == PSM_PSMZ32 || fi.TPSM == PSM_PSMZ24 || fi.TPSM == PSM_PSMZ16 || fi.TPSM == PSM_PSMZ16S) ||
(GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)) )
{
skip = 24;
}
}
}
return true;
}
bool GSC_DeathByDegreesTekkenNinaWilliams(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
@ -2491,10 +2492,8 @@ void GSState::SetupCrcHack()
lut[CRC::Spartan] = GSC_Spartan;
lut[CRC::StarWarsForceUnleashed] = GSC_StarWarsForceUnleashed;
lut[CRC::SteambotChronicles] = GSC_SteambotChronicles;
lut[CRC::TalesOfAbyss] = GSC_TalesOfAbyss;
lut[CRC::TalesOfLegendia] = GSC_TalesOfLegendia;
lut[CRC::TalesofSymphonia] = GSC_TalesofSymphonia;
lut[CRC::Tekken5] = GSC_Tekken5;
lut[CRC::TimeSplitters2] = GSC_TimeSplitters2;
lut[CRC::TombRaiderAnniversary] = GSC_TombRaider;
lut[CRC::TombRaiderLegend] = GSC_TombRaiderLegend;
@ -2567,15 +2566,18 @@ void GSState::SetupCrcHack()
// Channel Effect
lut[CRC::DeathByDegreesTekkenNinaWilliams] = GSC_DeathByDegreesTekkenNinaWilliams;
lut[CRC::GT3] = GSC_GT3;
lut[CRC::GT4] = GSC_GT4;
lut[CRC::GTConcept] = GSC_GTConcept;
lut[CRC::JamesBondEverythingOrNothing] = GSC_JamesBondEverythingOrNothing;
lut[CRC::MetalGearSolid3] = GSC_MetalGearSolid3; // + accurate blending
lut[CRC::SkyGunner] = GSC_SkyGunner;
lut[CRC::StarWarsBattlefront2] = GSC_StarWarsBattlefront2;
lut[CRC::StarWarsBattlefront] = GSC_StarWarsBattlefront;
// Dedicated shader for channel effect
lut[CRC::TouristTrophy] = GSC_TouristTrophy;
lut[CRC::GT3] = GSC_GT3;
lut[CRC::GT4] = GSC_GT4;
lut[CRC::GTConcept] = GSC_GTConcept;
lut[CRC::TalesOfAbyss] = GSC_TalesOfAbyss;
lut[CRC::Tekken5] = GSC_Tekken5;
}
m_gsc = lut[m_game.title];

View File

@ -673,7 +673,41 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
//
// First let's check we really have a channel shuffle effect
if (m_channel_shuffle) {
if (m_context->CLAMP.WMS == 3 && ((m_context->CLAMP.MAXU & 0x8) == 8)) {
if (m_game.title == CRC::GT4 || m_game.title == CRC::GT3 || m_game.title == CRC::GTConcept || m_game.title == CRC::TouristTrophy) {
GL_INS("Gran Turismo RGB Channel");
ps_sel.channel = 7;
m_context->TEX0.TFX = TFX_DECAL;
rt = tex->m_from_target;
} else if (m_game.title == CRC::Tekken5) {
GL_INS("Tekken5 RGB Channel");
ps_sel.channel = 7;
m_context->FRAME.FBMSK = 0xFF000000;
// 12 pages: 2 calls by channel, 3 channels, 1 blit
// Minus current draw call
m_skip = 12 * (3 + 3 + 1) - 1;
rt = tex->m_from_target;
} else if ((tex->m_texture->GetType() == GSTexture::DepthStencil) && !(tex->m_32_bits_fmt)) {
// So far 2 games hit this code path. Urban Chaos and Tales of Abyss
// UC: will copy depth to green channel
// ToA: will copy depth to alpha channel
if ((m_context->FRAME.FBMSK & 0xFF0000) == 0xFF0000) {
// Green channel is masked
GL_INS("Tales Of Abyss Crazyness (MSB 16b depth to Alpha)");
ps_sel.tales_of_abyss_hle = 1;
} else {
GL_INS("Urban Chaos Crazyness (Green extraction)");
ps_sel.urban_chaos_hle = 1;
}
} else if (m_index.tail <= 64 && m_context->CLAMP.WMT == 3) {
// Blood will tell. I think it is channel effect too but again
// implemented in a different way. I don't want to add more CRC stuff. So
// let's disable channel when the signature is different
//
// Note: Tales Of Abyss and Tekken5 could hit this path too. Those games are
// handled above.
GL_INS("maybe not a channel!");
m_channel_shuffle = false;
} else if (m_context->CLAMP.WMS == 3 && ((m_context->CLAMP.MAXU & 0x8) == 8)) {
// Read either blue or Alpha. Let's go for Blue ;)
// MGS3/Kill Zone
GL_INS("Blue channel");
@ -683,9 +717,6 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
// Pop
GL_INS("Red channel");
ps_sel.channel = 1;
} else if ((tex->m_texture->GetType() == GSTexture::DepthStencil) && !(tex->m_32_bits_fmt)) {
GL_INS("Urban Chaos Crazyness");
ps_sel.urban_chaos_hack = 1;
} else {
GL_INS("channel not supported");
m_channel_shuffle = false;

View File

@ -235,7 +235,14 @@ vec4 sample_depth(vec2 st)
ivec2 uv = ivec2(uv_f);
vec4 t;
#if PS_URBAN_CHAOS_HACK == 1
#if PS_TALES_OF_ABYSS_HLE == 1
// Warning: UV can't be used in channel effect
int depth = fetch_raw_depth();
// Convert msb based on the palette
t = texelFetch(PaletteSampler, ivec2((depth >> 8) & 0xFF, 0), 0) * 255.0f;
#elif PS_URBAN_CHAOS_HLE == 1
// Depth buffer is read as a RGB5A1 texture. The game try to extract the green channel.
// So it will do a first channel trick to extract lsb, value is right-shifted.
// Then a new channel trick to extract msb which will shifted to the left.
@ -246,7 +253,7 @@ vec4 sample_depth(vec2 st)
int depth = fetch_raw_depth();
// Convert lsb based on the palette
t = texelFetch(PaletteSampler, ivec2((depth & 0xFF), 0), 0);
t = texelFetch(PaletteSampler, ivec2((depth & 0xFF), 0), 0) * 255.0f;
// Msb is easier
float green = float((depth >> 8) & 0xFF) * 36.0f;
@ -331,6 +338,13 @@ vec4 fetch_alpha()
return sample_p(rt.a) * 255.0f;
}
vec4 fetch_rgb()
{
vec4 rt = fetch_raw_color();
vec4 c = vec4(sample_p(rt.r).r, sample_p(rt.g).g, sample_p(rt.b).b, 1.0f);
return c * 255.0f;
}
//////////////////////////////////////////////////////////////////////
vec4 sample_color(vec2 st)
@ -500,6 +514,8 @@ vec4 ps_color()
vec4 T = fetch_blue();
#elif PS_CHANNEL_FETCH == 4
vec4 T = fetch_alpha();
#elif PS_CHANNEL_FETCH == 7
vec4 T = fetch_rgb();
#elif PS_DEPTH_FMT > 0
// Integral coordinate
vec4 T = sample_depth(PSin.t_int.zw);

View File

@ -1079,7 +1079,14 @@ static const char* const tfx_fs_all_glsl =
" ivec2 uv = ivec2(uv_f);\n"
"\n"
" vec4 t;\n"
"#if PS_URBAN_CHAOS_HACK == 1\n"
"#if PS_TALES_OF_ABYSS_HLE == 1\n"
" // Warning: UV can't be used in channel effect\n"
" int depth = fetch_raw_depth();\n"
"\n"
" // Convert msb based on the palette\n"
" t = texelFetch(PaletteSampler, ivec2((depth >> 8) & 0xFF, 0), 0) * 255.0f;\n"
"\n"
"#elif PS_URBAN_CHAOS_HLE == 1\n"
" // Depth buffer is read as a RGB5A1 texture. The game try to extract the green channel.\n"
" // So it will do a first channel trick to extract lsb, value is right-shifted.\n"
" // Then a new channel trick to extract msb which will shifted to the left.\n"
@ -1090,7 +1097,7 @@ static const char* const tfx_fs_all_glsl =
" int depth = fetch_raw_depth();\n"
"\n"
" // Convert lsb based on the palette\n"
" t = texelFetch(PaletteSampler, ivec2((depth & 0xFF), 0), 0);\n"
" t = texelFetch(PaletteSampler, ivec2((depth & 0xFF), 0), 0) * 255.0f;\n"
"\n"
" // Msb is easier\n"
" float green = float((depth >> 8) & 0xFF) * 36.0f;\n"
@ -1175,6 +1182,13 @@ static const char* const tfx_fs_all_glsl =
" return sample_p(rt.a) * 255.0f;\n"
"}\n"
"\n"
"vec4 fetch_rgb()\n"
"{\n"
" vec4 rt = fetch_raw_color();\n"
" vec4 c = vec4(sample_p(rt.r).r, sample_p(rt.g).g, sample_p(rt.b).b, 1.0f);\n"
" return c * 255.0f;\n"
"}\n"
"\n"
"//////////////////////////////////////////////////////////////////////\n"
"\n"
"vec4 sample_color(vec2 st)\n"
@ -1344,6 +1358,8 @@ static const char* const tfx_fs_all_glsl =
" vec4 T = fetch_blue();\n"
"#elif PS_CHANNEL_FETCH == 4\n"
" vec4 T = fetch_alpha();\n"
"#elif PS_CHANNEL_FETCH == 7\n"
" vec4 T = fetch_rgb();\n"
"#elif PS_DEPTH_FMT > 0\n"
" // Integral coordinate\n"
" vec4 T = sample_depth(PSin.t_int.zw);\n"