diff --git a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp index 39d32487bd..ff3fb4d56c 100644 --- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp @@ -965,22 +965,24 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode) auto insert_texture_fetch = [this](const std::array& functions) { const auto type = m_prog.get_texture_dimension(dst.tex_num); - std::string mask = ""; + const auto ref_mask = (1 << dst.tex_num); + std::string swz_mask = ""; auto select = static_cast(type); if (type == rsx::texture_dimension_extended::texture_dimension_2d) { - if (m_prog.shadow_textures & (1 << dst.tex_num)) + if (m_prog.shadow_textures & ref_mask) { - m_shadow_sampled_textures |= (1 << dst.tex_num); + properties.shadow_sampler_mask |= ref_mask; select = 4; - mask = ".xxxx"; + swz_mask = ".xxxx"; } else { - m_2d_sampled_textures |= (1 << dst.tex_num); - if (m_prog.redirected_textures & (1 << dst.tex_num)) + properties.tex2d_sampler_mask |= ref_mask; + if (m_prog.redirected_textures & ref_mask) { + properties.redirected_sampler_mask |= ref_mask; select = 5; } } @@ -993,7 +995,7 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode) } auto function = functions[select]; - SetDst(getFunction(function) + mask); + 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 82824f121b..8e1d65517a 100644 --- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.h +++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.h @@ -209,9 +209,6 @@ protected: const RSXFragmentProgram &m_prog; 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(usz elementCount) = 0; @@ -273,7 +270,12 @@ public: struct { - u16 in_register_mask = 0; + u16 in_register_mask = 0; + + u16 tex2d_sampler_mask = 0; + u16 shadow_sampler_mask = 0; + u16 redirected_sampler_mask = 0; + bool has_lit_op = false; bool has_gather_op = false; bool has_no_output = false; diff --git a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp index e457c30eb6..e422273d9e 100644 --- a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp @@ -129,20 +129,17 @@ void GLFragmentDecompilerThread::insertConstants(std::stringstream & OS) const auto mask = (1 << index); - if (m_prog.redirected_textures & mask) + if (properties.redirected_sampler_mask & mask) { // Provide a stencil view of the main resource for the S channel OS << "uniform u" << samplerType << " " << PI.name << "_stencil;\n"; } - else if (m_prog.shadow_textures & mask) + else if (properties.shadow_sampler_mask & mask) { - if (m_shadow_sampled_textures & mask) - { - if (m_2d_sampled_textures & mask) - rsx_log.error("Texture unit %d is sampled as both a shadow texture and a depth texture", index); - else - samplerType = "sampler2DShadow"; - } + if (properties.tex2d_sampler_mask & mask) + rsx_log.error("Texture unit %d is sampled as both a shadow texture and a depth texture", index); + else + samplerType = "sampler2DShadow"; } OS << "uniform " << samplerType << " " << PI.name << ";\n"; @@ -202,10 +199,10 @@ void GLFragmentDecompilerThread::insertGlobalFunctions(std::stringstream &OS) m_shader_props.domain = glsl::glsl_fragment_program; m_shader_props.require_lit_emulation = properties.has_lit_op; m_shader_props.fp32_outputs = !!(m_prog.ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS); - m_shader_props.require_depth_conversion = m_prog.redirected_textures != 0; + m_shader_props.require_depth_conversion = properties.redirected_sampler_mask != 0; m_shader_props.require_wpos = !!(properties.in_register_mask & in_wpos); m_shader_props.require_texture_ops = properties.has_tex_op; - m_shader_props.require_shadow_ops = m_prog.shadow_textures != 0; + m_shader_props.require_shadow_ops = properties.shadow_sampler_mask != 0; m_shader_props.require_texture_expand = properties.has_exp_tex_op; m_shader_props.emulate_coverage_tests = true; // g_cfg.video.antialiasing_level == msaa_level::none; m_shader_props.emulate_shadow_compare = device_props.emulate_depth_compare; diff --git a/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp b/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp index 7e03a5f867..20d874bf18 100644 --- a/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp @@ -130,15 +130,12 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS) const auto mask = (1 << index); - if (m_prog.shadow_textures & mask) + if (properties.shadow_sampler_mask & mask) { - if (m_shadow_sampled_textures & mask) - { - if (m_2d_sampled_textures & mask) - rsx_log.error("Texture unit %d is sampled as both a shadow texture and a depth texture", index); - else - samplerType = "sampler2DShadow"; - } + if (properties.tex2d_sampler_mask & mask) + rsx_log.error("Texture unit %d is sampled as both a shadow texture and a depth texture", index); + else + samplerType = "sampler2DShadow"; } vk::glsl::program_input in; @@ -151,7 +148,7 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS) OS << "layout(set=0, binding=" << location++ << ") uniform " << samplerType << " " << PI.name << ";\n"; - if (m_prog.redirected_textures & mask) + if (properties.redirected_sampler_mask & mask) { // Insert stencil mirror declaration in.name += "_stencil"; @@ -236,10 +233,10 @@ void VKFragmentDecompilerThread::insertGlobalFunctions(std::stringstream &OS) m_shader_props.domain = glsl::glsl_fragment_program; m_shader_props.require_lit_emulation = properties.has_lit_op; m_shader_props.fp32_outputs = !!(m_prog.ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS); - m_shader_props.require_depth_conversion = m_prog.redirected_textures != 0; + m_shader_props.require_depth_conversion = properties.redirected_sampler_mask != 0; m_shader_props.require_wpos = !!(properties.in_register_mask & in_wpos); m_shader_props.require_texture_ops = properties.has_tex_op; - m_shader_props.require_shadow_ops = m_prog.shadow_textures != 0; + m_shader_props.require_shadow_ops = properties.shadow_sampler_mask != 0; m_shader_props.require_texture_expand = properties.has_exp_tex_op; m_shader_props.emulate_coverage_tests = g_cfg.video.antialiasing_level == msaa_level::none; m_shader_props.emulate_shadow_compare = device_props.emulate_depth_compare;