From c2b67ccb783ad8aa7053c56d5367d7d6abf6e760 Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Thu, 8 Sep 2016 23:26:38 +0200 Subject: [PATCH] gsdx ogl: implement an alternate shader for Jak Shadows The game sets the framebuffer as an input texture. So I did the same for openGL. Code is protected with a CRC. It is working because the game want to sample pixels. For the record, I tested it GTA too, it doesn't work as expected because the game will resize the framebuffer to a smaller one. So you don't have the guarantee that pixel will be read before a data write. Note: it requires at least accurate blending set on basic Note: I need CRC of all Jak games that suffers of this issue. Thanks you :) --- plugins/GSdx/GSCrc.cpp | 1 + plugins/GSdx/GSCrc.h | 1 + plugins/GSdx/GSDeviceOGL.cpp | 1 + plugins/GSdx/GSDeviceOGL.h | 3 ++- plugins/GSdx/GSRendererOGL.cpp | 12 ++++++++---- plugins/GSdx/res/glsl/tfx_fs.glsl | 4 ++++ plugins/GSdx/res/glsl_source.h | 4 ++++ 7 files changed, 21 insertions(+), 5 deletions(-) diff --git a/plugins/GSdx/GSCrc.cpp b/plugins/GSdx/GSCrc.cpp index f6b4dd700a..afe49ad76f 100644 --- a/plugins/GSdx/GSCrc.cpp +++ b/plugins/GSdx/GSCrc.cpp @@ -515,6 +515,7 @@ CRC::Game CRC::m_games[] = {0XE1BF5DCA, SuperManReturns, US, 0}, {0x06A7506A, SacredBlaze, JP, 0}, {0x4CE7FB04, ItadakiStreet, JP, 0}, + {0x12804727, Jak3, PAL, 0}, }; map CRC::m_map; diff --git a/plugins/GSdx/GSCrc.h b/plugins/GSdx/GSCrc.h index 5ee7ceba4b..bfd9c52259 100644 --- a/plugins/GSdx/GSCrc.h +++ b/plugins/GSdx/GSCrc.h @@ -175,6 +175,7 @@ public: SacredBlaze, SuperManReturns, ItadakiStreet, + Jak3, TitleCount, }; diff --git a/plugins/GSdx/GSDeviceOGL.cpp b/plugins/GSdx/GSDeviceOGL.cpp index 27bb0aeea5..de76d2c48c 100644 --- a/plugins/GSdx/GSDeviceOGL.cpp +++ b/plugins/GSdx/GSDeviceOGL.cpp @@ -943,6 +943,7 @@ GLuint GSDeviceOGL::CompilePS(PSSelector sel) + format("#define PS_CHANNEL_FETCH %d\n", sel.channel) + 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_TEX_IS_FB %d\n", sel.tex_is_fb) + format("#define PS_AEM %d\n", sel.aem) + format("#define PS_TFX %d\n", sel.tfx) + format("#define PS_TCC %d\n", sel.tcc) diff --git a/plugins/GSdx/GSDeviceOGL.h b/plugins/GSdx/GSDeviceOGL.h index bb3595083f..bc509d79a8 100644 --- a/plugins/GSdx/GSDeviceOGL.h +++ b/plugins/GSdx/GSDeviceOGL.h @@ -292,8 +292,9 @@ public: uint32 tcoffsethack:1; uint32 urban_chaos_hle:1; uint32 tales_of_abyss_hle:1; + uint32 tex_is_fb:1; // Jak Shadows - uint32 _free2:14; + uint32 _free2:13; }; uint64 key; diff --git a/plugins/GSdx/GSRendererOGL.cpp b/plugins/GSdx/GSRendererOGL.cpp index 3529798cf2..ce9991d6e2 100644 --- a/plugins/GSdx/GSRendererOGL.cpp +++ b/plugins/GSdx/GSRendererOGL.cpp @@ -1142,11 +1142,15 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour // Always check if primitive overlap. The function will return PRIM_OVERLAP_UNKNOW for non sprite primitive m_prim_overlap = PrimitiveOverlap(); -#ifdef ENABLE_OGL_DEBUG - if (PRIM->TME && m_sw_blending && (m_prim_overlap != PRIM_OVERLAP_NO) && (m_context->FRAME.Block() == m_context->TEX0.TBP0) && (m_vertex.next > 2)) { - GL_INS("ERROR: Source and Target are the same!"); + if ((m_context->FRAME.Block() == m_context->TEX0.TBP0) && PRIM->TME && m_sw_blending && (m_prim_overlap != PRIM_OVERLAP_NO) && (m_vertex.next > 2)) { + if (m_game.title == CRC::Jak3) { + GL_INS("ERROR: Source and Target are the same! Let's sample the framebuffer"); + m_ps_sel.tex_is_fb = 1; + m_require_full_barrier = true; + } else { + GL_INS("ERROR: Source and Target are the same!"); + } } -#endif EmulateTextureShuffleAndFbmask(); diff --git a/plugins/GSdx/res/glsl/tfx_fs.glsl b/plugins/GSdx/res/glsl/tfx_fs.glsl index d5c77dcb55..5eb59313c3 100644 --- a/plugins/GSdx/res/glsl/tfx_fs.glsl +++ b/plugins/GSdx/res/glsl/tfx_fs.glsl @@ -75,7 +75,11 @@ layout(early_fragment_tests) in; vec4 sample_c(vec2 uv) { +#if PS_TEX_IS_FB == 1 + return texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0); +#else return texture(TextureSampler, uv); +#endif } vec4 sample_p(float idx) diff --git a/plugins/GSdx/res/glsl_source.h b/plugins/GSdx/res/glsl_source.h index 0536866ffb..b004cdf88e 100644 --- a/plugins/GSdx/res/glsl_source.h +++ b/plugins/GSdx/res/glsl_source.h @@ -995,7 +995,11 @@ static const char* const tfx_fs_all_glsl = "\n" "vec4 sample_c(vec2 uv)\n" "{\n" + "#if PS_TEX_IS_FB == 1\n" + " return texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0);\n" + "#else\n" " return texture(TextureSampler, uv);\n" + "#endif\n" "}\n" "\n" "vec4 sample_p(float idx)\n"