rsx: Do not rely on program env state, instead, always use program ucode analysis results when doing codegen

- Some things can be present in program env but not ucode state
  e.g A texture can be active and bound in a redirected manner but not actually be used in ucode
  In such a case, only the ucode analysis or decompilation can decide whether to inject decoding routines
This commit is contained in:
kd-11 2020-12-24 21:44:15 +03:00 committed by kd-11
parent bee76fc8d1
commit a96b4412d3
4 changed files with 31 additions and 33 deletions

View file

@ -965,22 +965,24 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode)
auto insert_texture_fetch = [this](const std::array<FUNCTION, 6>& functions) auto insert_texture_fetch = [this](const std::array<FUNCTION, 6>& functions)
{ {
const auto type = m_prog.get_texture_dimension(dst.tex_num); 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<u8>(type); auto select = static_cast<u8>(type);
if (type == rsx::texture_dimension_extended::texture_dimension_2d) 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; select = 4;
mask = ".xxxx"; swz_mask = ".xxxx";
} }
else else
{ {
m_2d_sampled_textures |= (1 << dst.tex_num); properties.tex2d_sampler_mask |= ref_mask;
if (m_prog.redirected_textures & (1 << dst.tex_num)) if (m_prog.redirected_textures & ref_mask)
{ {
properties.redirected_sampler_mask |= ref_mask;
select = 5; select = 5;
} }
} }
@ -993,7 +995,7 @@ bool FragmentProgramDecompiler::handle_tex_srb(u32 opcode)
} }
auto function = functions[select]; auto function = functions[select];
SetDst(getFunction(function) + mask); SetDst(getFunction(function) + swz_mask);
if (dst.exp_tex) if (dst.exp_tex)
{ {

View file

@ -209,9 +209,6 @@ protected:
const RSXFragmentProgram &m_prog; const RSXFragmentProgram &m_prog;
u32 m_ctrl = 0; 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. /** returns the type name of float vectors.
*/ */
virtual std::string getFloatTypeName(usz elementCount) = 0; virtual std::string getFloatTypeName(usz elementCount) = 0;
@ -274,6 +271,11 @@ public:
struct 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_lit_op = false;
bool has_gather_op = false; bool has_gather_op = false;
bool has_no_output = false; bool has_no_output = false;

View file

@ -129,21 +129,18 @@ void GLFragmentDecompilerThread::insertConstants(std::stringstream & OS)
const auto mask = (1 << index); 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 // Provide a stencil view of the main resource for the S channel
OS << "uniform u" << samplerType << " " << PI.name << "_stencil;\n"; 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 (properties.tex2d_sampler_mask & 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); rsx_log.error("Texture unit %d is sampled as both a shadow texture and a depth texture", index);
else else
samplerType = "sampler2DShadow"; samplerType = "sampler2DShadow";
} }
}
OS << "uniform " << samplerType << " " << PI.name << ";\n"; 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.domain = glsl::glsl_fragment_program;
m_shader_props.require_lit_emulation = properties.has_lit_op; 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.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_wpos = !!(properties.in_register_mask & in_wpos);
m_shader_props.require_texture_ops = properties.has_tex_op; 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.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_coverage_tests = true; // g_cfg.video.antialiasing_level == msaa_level::none;
m_shader_props.emulate_shadow_compare = device_props.emulate_depth_compare; m_shader_props.emulate_shadow_compare = device_props.emulate_depth_compare;

View file

@ -130,16 +130,13 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
const auto mask = (1 << index); const auto mask = (1 << index);
if (m_prog.shadow_textures & mask) if (properties.shadow_sampler_mask & mask)
{ {
if (m_shadow_sampled_textures & mask) if (properties.tex2d_sampler_mask & 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); rsx_log.error("Texture unit %d is sampled as both a shadow texture and a depth texture", index);
else else
samplerType = "sampler2DShadow"; samplerType = "sampler2DShadow";
} }
}
vk::glsl::program_input in; vk::glsl::program_input in;
in.location = location; in.location = location;
@ -151,7 +148,7 @@ void VKFragmentDecompilerThread::insertConstants(std::stringstream & OS)
OS << "layout(set=0, binding=" << location++ << ") uniform " << samplerType << " " << PI.name << ";\n"; 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 // Insert stencil mirror declaration
in.name += "_stencil"; in.name += "_stencil";
@ -236,10 +233,10 @@ void VKFragmentDecompilerThread::insertGlobalFunctions(std::stringstream &OS)
m_shader_props.domain = glsl::glsl_fragment_program; m_shader_props.domain = glsl::glsl_fragment_program;
m_shader_props.require_lit_emulation = properties.has_lit_op; 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.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_wpos = !!(properties.in_register_mask & in_wpos);
m_shader_props.require_texture_ops = properties.has_tex_op; 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.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_coverage_tests = g_cfg.video.antialiasing_level == msaa_level::none;
m_shader_props.emulate_shadow_compare = device_props.emulate_depth_compare; m_shader_props.emulate_shadow_compare = device_props.emulate_depth_compare;