diff --git a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp index ff3fb4d56c..b6b013c266 100644 --- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp @@ -969,7 +969,7 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode) std::string swz_mask = ""; auto select = static_cast(type); - if (type == rsx::texture_dimension_extended::texture_dimension_2d) + if (type != rsx::texture_dimension_extended::texture_dimension_3d) { if (m_prog.shadow_textures & ref_mask) { @@ -979,7 +979,7 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode) } else { - properties.tex2d_sampler_mask |= ref_mask; + properties.common_access_sampler_mask |= ref_mask; if (m_prog.redirected_textures & ref_mask) { properties.redirected_sampler_mask |= ref_mask; @@ -995,6 +995,14 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode) } auto function = functions[select]; + + if (function == FUNCTION::FUNCTION_TEXTURE_SHADOW2D && + type == rsx::texture_dimension_extended::texture_dimension_cubemap) + { + // Cubemap shadow override + function = FUNCTION::FUNCTION_TEXTURE_SHADOWCUBE; + } + SetDst(getFunction(function) + swz_mask); if (dst.exp_tex) diff --git a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.h b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.h index 8e1d65517a..8be95625a7 100644 --- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.h +++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.h @@ -272,7 +272,7 @@ public: { u16 in_register_mask = 0; - u16 tex2d_sampler_mask = 0; + u16 common_access_sampler_mask = 0; u16 shadow_sampler_mask = 0; u16 redirected_sampler_mask = 0; diff --git a/rpcs3/Emu/RSX/Common/GLSLCommon.cpp b/rpcs3/Emu/RSX/Common/GLSLCommon.cpp index 1d6cb0f377..3c10de7b76 100644 --- a/rpcs3/Emu/RSX/Common/GLSLCommon.cpp +++ b/rpcs3/Emu/RSX/Common/GLSLCommon.cpp @@ -859,14 +859,17 @@ namespace glsl { OS << "#define SHADOW_COORD(coord3, scale, flags) vec3(coord3.xy * scale, _test_bit(flags, DEPTH_FLOAT)? coord3.z : min(float(coord3.z), 1.0))\n" + "#define SHADOW_COORD4(coord4, scale, flags) vec4(SHADOW_COORD(coord4.xyz, scale, flags), coord4.w)\n" "#define SHADOW_COORD_PROJ(coord4, scale, flags) vec4(coord4.xy * scale, _test_bit(flags, DEPTH_FLOAT)? coord4.z : min(coord4.z, coord4.w), coord4.w)\n" "#define TEX2D_SHADOW(index, coord3) texture(TEX_NAME(index), SHADOW_COORD(coord3, texture_parameters[index].scale, TEX_FLAGS(index)))\n" + "#define TEX2D_SHADOWCUBE(index, coord4) texture(TEX_NAME(index), SHADOW_COORD4(coord4, texture_parameters[index].scale, TEX_FLAGS(index)))\n" "#define TEX2D_SHADOWPROJ(index, coord4) textureProj(TEX_NAME(index), SHADOW_COORD_PROJ(coord4, texture_parameters[index].scale, TEX_FLAGS(index)))\n"; } else { OS << "#define TEX2D_SHADOW(index, coord3) texture(TEX_NAME(index), coord3 * vec3(texture_parameters[index].scale, 1.))\n" + "#define TEX2D_SHADOWCUBE(index, coord4) texture(TEX_NAME(index), coord4 * vec3(texture_parameters[index].scale, 1., 1.))\n" "#define TEX2D_SHADOWPROJ(index, coord4) textureProj(TEX_NAME(index), coord4 * vec4(texture_parameters[index].scale, 1., 1.))\n"; } @@ -940,6 +943,8 @@ namespace glsl return "TEX2D_GRAD($_i, $0.xy, $1.xy, $2.xy)"; case FUNCTION::FUNCTION_TEXTURE_SHADOW2D: return "TEX2D_SHADOW($_i, $0.xyz)"; + case FUNCTION::FUNCTION_TEXTURE_SHADOWCUBE: + return "TEX2D_SHADOWCUBE($_i, $0)"; case FUNCTION::FUNCTION_TEXTURE_SHADOW2D_PROJ: return "TEX2D_SHADOWPROJ($_i, $0)"; case FUNCTION::FUNCTION_TEXTURE_SAMPLECUBE: diff --git a/rpcs3/Emu/RSX/Common/ShaderParam.h b/rpcs3/Emu/RSX/Common/ShaderParam.h index 1a2d0f9290..cdf98bb2b4 100644 --- a/rpcs3/Emu/RSX/Common/ShaderParam.h +++ b/rpcs3/Emu/RSX/Common/ShaderParam.h @@ -32,6 +32,7 @@ enum class FUNCTION FUNCTION_TEXTURE_SAMPLE2D_LOD, FUNCTION_TEXTURE_SAMPLE2D_GRAD, FUNCTION_TEXTURE_SHADOW2D, + FUNCTION_TEXTURE_SHADOWCUBE, FUNCTION_TEXTURE_SHADOW2D_PROJ, FUNCTION_TEXTURE_SAMPLECUBE, FUNCTION_TEXTURE_SAMPLECUBE_BIAS, diff --git a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp index 93f9db9621..b8ca75b0d7 100644 --- a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp @@ -136,10 +136,14 @@ void GLFragmentDecompilerThread::insertConstants(std::stringstream & OS) } else if (properties.shadow_sampler_mask & mask) { - if (properties.tex2d_sampler_mask & mask) + if (properties.common_access_sampler_mask & mask) + { rsx_log.error("Texture unit %d is sampled as both a shadow texture and a depth texture", index); + } else - samplerType = "sampler2DShadow"; + { + samplerType += "Shadow"; + } } OS << "uniform " << samplerType << " " << PI.name << ";\n"; diff --git a/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp b/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp index 7a59bcaf99..adb0c060b0 100644 --- a/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp @@ -134,10 +134,14 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS) if (properties.shadow_sampler_mask & mask) { - if (properties.tex2d_sampler_mask & mask) + if (properties.common_access_sampler_mask & mask) + { rsx_log.error("Texture unit %d is sampled as both a shadow texture and a depth texture", index); + } else - samplerType = "sampler2DShadow"; + { + samplerType += "Shadow"; + } } vk::glsl::program_input in;