diff --git a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp index 28a8967b9d..177cde5019 100644 --- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp @@ -521,6 +521,7 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode) SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_DEPTH_RGBA)); else SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D)); + m_2d_sampled_textures |= (1 << dst.tex_num); return true; case rsx::texture_dimension_extended::texture_dimension_cubemap: SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE)); @@ -541,6 +542,8 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode) return true; case rsx::texture_dimension_extended::texture_dimension_2d: SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_PROJ)); + if (m_prog.shadow_textures & (1 << dst.tex_num)) + m_shadow_sampled_textures |= (1 << dst.tex_num); return true; case rsx::texture_dimension_extended::texture_dimension_cubemap: SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_PROJ)); @@ -558,6 +561,7 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode) return true; case rsx::texture_dimension_extended::texture_dimension_2d: SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_GRAD)); + m_2d_sampled_textures |= (1 << dst.tex_num); return true; case rsx::texture_dimension_extended::texture_dimension_cubemap: SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_GRAD)); @@ -576,6 +580,7 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode) return true; case rsx::texture_dimension_extended::texture_dimension_2d: SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLE2D_LOD)); + m_2d_sampled_textures |= (1 << dst.tex_num); return true; case rsx::texture_dimension_extended::texture_dimension_cubemap: SetDst(getFunction(FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE_LOD)); diff --git a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.h b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.h index 6d47544813..a66a716b15 100644 --- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.h +++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.h @@ -88,7 +88,11 @@ class FragmentProgramDecompiler bool handle_tex_srb(u32 opcode); protected: const RSXFragmentProgram &m_prog; - u32 m_ctrl; + u32 m_ctrl = 0; + + u32 m_2d_sampled_textures = 0; //Mask of textures sampled as texture2D (conflicts with samplerShadow fetch) + u32 m_shadow_sampled_textures = 0; //Mask of textures sampled as boolean shadow comparisons + /** returns the type name of float vectors. */ virtual std::string getFloatTypeName(size_t elementCount) = 0; diff --git a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp index 2a7cfa2c7d..81c4bc9d6b 100644 --- a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp @@ -107,8 +107,18 @@ void GLFragmentDecompilerThread::insertConstants(std::stringstream & OS) std::string samplerType = PT.type; int index = atoi(&PI.name.data()[3]); - if ((m_prog.shadow_textures & (1 << index)) > 0) - samplerType = "sampler2DShadow"; + const auto mask = (1 << index); + + if (m_prog.shadow_textures & mask) + { + if (m_shadow_sampled_textures & mask) + { + if (m_2d_sampled_textures & mask) + LOG_ERROR(RSX, "Texture unit %d is sampled as both a shadow texture and a depth texture", index); + else + samplerType = "sampler2DShadow"; + } + } OS << "uniform " << samplerType << " " << PI.name << ";" << std::endl; } diff --git a/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp b/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp index bda40c7bcd..7d6a22edb3 100644 --- a/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp @@ -123,10 +123,22 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS) std::string samplerType = PT.type; int index = atoi(&PI.name.data()[3]); - if (m_prog.unnormalized_coords & (1 << index)) + const auto mask = (1 << index); + + if (m_prog.unnormalized_coords & mask) + { samplerType = "sampler2DRect"; - else if (m_prog.shadow_textures & (1 << index)) - samplerType = "sampler2DShadow"; + } + else if (m_prog.shadow_textures & mask) + { + if (m_shadow_sampled_textures & mask) + { + if (m_2d_sampled_textures & mask) + LOG_ERROR(RSX, "Texture unit %d is sampled as both a shadow texture and a depth texture", index); + else + samplerType = "sampler2DShadow"; + } + } vk::glsl::program_input in; in.location = location;