diff --git a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp index 933459af3d..2f0495e022 100644 --- a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp @@ -201,6 +201,7 @@ void GLFragmentDecompilerThread::insertGlobalFunctions(std::stringstream &OS) m_shader_props.require_tex1D_ops = properties.has_tex1D; m_shader_props.require_tex2D_ops = properties.has_tex2D; m_shader_props.require_tex3D_ops = properties.has_tex3D; + m_shader_props.require_shadowProj_ops = properties.shadow_sampler_mask != 0 && properties.has_texShadowProj; glsl::insert_glsl_legacy_function(OS, m_shader_props); } diff --git a/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.cpp index 78cb3479ec..1408bd636c 100644 --- a/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.cpp @@ -1145,6 +1145,19 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode) AddCode("_enable_texture_expand();"); } + // Shadow proj + switch (func_id) + { + case FUNCTION::TEXTURE_SAMPLE1D_SHADOW_PROJ: + case FUNCTION::TEXTURE_SAMPLE2D_SHADOW_PROJ: + case FUNCTION::TEXTURE_SAMPLE2DMS_SHADOW_PROJ: + case FUNCTION::TEXTURE_SAMPLE3D_SHADOW_PROJ: + properties.has_texShadowProj = true; + break; + default: + break; + } + SetDst(getFunction(func_id) + swz_mask); if (dst.exp_tex) diff --git a/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.h b/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.h index e866a240c7..15e450dab7 100644 --- a/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.h +++ b/rpcs3/Emu/RSX/Program/FragmentProgramDecompiler.h @@ -292,6 +292,7 @@ public: bool has_tex1D = false; bool has_tex2D = false; bool has_tex3D = false; + bool has_texShadowProj = false; } properties; diff --git a/rpcs3/Emu/RSX/Program/GLSLCommon.cpp b/rpcs3/Emu/RSX/Program/GLSLCommon.cpp index f62ac0db09..e9875ab3a4 100644 --- a/rpcs3/Emu/RSX/Program/GLSLCommon.cpp +++ b/rpcs3/Emu/RSX/Program/GLSLCommon.cpp @@ -416,6 +416,11 @@ namespace glsl enabled_options.push_back("_ENABLE_TEX3D"); } + if (props.require_shadowProj_ops) + { + enabled_options.push_back("_ENABLE_SHADOWPROJ"); + } + program_common::define_glsl_switches(OS, enabled_options); enabled_options.clear(); diff --git a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl index afb79919fe..1c7e162afe 100644 --- a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl +++ b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXProg/RSXFragmentTextureOps.glsl @@ -27,9 +27,9 @@ R"( #define COORD_SCALE1(index, coord1) _texcoord_xform(coord1, texture_parameters[index]) #define COORD_SCALE2(index, coord2) _texcoord_xform(coord2, texture_parameters[index]) #define COORD_SCALE3(index, coord3) _texcoord_xform(coord3, texture_parameters[index]) -#define COORD_PROJ1(index, coord2) COORD_SCALE1(coord2.x / coord2.y, texture_parameters[index]) -#define COORD_PROJ2(index, coord3) COORD_SCALE2(coord3.xy / coord3.z, texture_parameters[index]) -#define COORD_PROJ3(index, coord4) COORD_SCALE3(coord4.xyz / coord4.w, texture_parameters[index]) +#define COORD_PROJ1(index, coord2) COORD_SCALE1(index, coord2.x / coord2.y) +#define COORD_PROJ2(index, coord3) COORD_SCALE2(index, coord3.xy / coord3.z) +#define COORD_PROJ3(index, coord4) COORD_SCALE3(index, coord4.xyz / coord4.w) #ifdef _ENABLE_TEX1D #define TEX1D(index, coord1) _process_texel(texture(TEX_NAME(index), COORD_SCALE1(index, coord1)), TEX_FLAGS(index)) @@ -106,7 +106,7 @@ vec2 _texcoord_xform(const in vec2 coord, const in sampler_info params) } #endif -#ifdef _ENABLE_TEX3D +#if defined(_ENABLE_TEX3D) || defined(_ENABLE_SHADOWPROJ) vec3 _texcoord_xform(const in vec3 coord, const in sampler_info params) { vec3 result = fma( diff --git a/rpcs3/Emu/RSX/Program/GLSLTypes.h b/rpcs3/Emu/RSX/Program/GLSLTypes.h index 41b192fa68..e50b2d62e1 100644 --- a/rpcs3/Emu/RSX/Program/GLSLTypes.h +++ b/rpcs3/Emu/RSX/Program/GLSLTypes.h @@ -47,5 +47,6 @@ namespace glsl bool require_tex1D_ops : 1; // Include 1D texture stuff bool require_tex2D_ops : 1; // Include 2D texture stuff bool require_tex3D_ops : 1; // Include 3D texture stuff (including cubemap) + bool require_shadowProj_ops : 1; // Include shadow2DProj projection textures (1D is unsupported anyway) }; }; diff --git a/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp b/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp index e2e9b1039c..6e2b04439f 100644 --- a/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp @@ -253,6 +253,7 @@ void VKFragmentDecompilerThread::insertGlobalFunctions(std::stringstream &OS) m_shader_props.require_tex1D_ops = properties.has_tex1D; m_shader_props.require_tex2D_ops = properties.has_tex2D; m_shader_props.require_tex3D_ops = properties.has_tex3D; + m_shader_props.require_shadowProj_ops = properties.shadow_sampler_mask != 0 && properties.has_texShadowProj; glsl::insert_glsl_legacy_function(OS, m_shader_props); }