Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 81 additions & 8 deletions rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "stdafx.h"
#include "Emu/Memory/vm.h"
#include "Emu/System.h"
#include "../rsx_methods.h"

#include "FragmentProgramDecompiler.h"

Expand Down Expand Up @@ -460,7 +461,9 @@ void FragmentProgramDecompiler::AddCodeCond(const std::string& dst, const std::s
}

// NOTE: dst = _select(dst, src, cond) is equivalent to dst = cond? src : dst;
const auto cond = ShaderVariable(dst).match_size(GetRawCond());
const auto dst_var = ShaderVariable(dst);
const auto raw_cond = dst_var.add_mask(GetRawCond());
const auto cond = dst_var.match_size(raw_cond);
AddCode(dst + " = _select(" + dst + ", " + src_prefix + src + ", " + cond + ");");
}

Expand Down Expand Up @@ -518,27 +521,97 @@ template<typename T> std::string FragmentProgramDecompiler::GetSRC(T src)
"ssa"
};

//TODO: Investigate effect of input modifier on this type
// NOTE: Hw testing showed the following:
// 1. Reading from registers 1 and 2 (COL0 and COL1) is clamped to (0, 1)
// 2. Reading from registers 4-12 (inclusive) is not clamped, but..
// 3. If the texcoord control mask is enabled, the last 2 values are always 0 and hpos.w!
const std::string reg_var = (dst.src_attr_reg_num < std::size(reg_table))? reg_table[dst.src_attr_reg_num] : "unk";
bool insert = true;

switch (dst.src_attr_reg_num)
{
case 0x00:
{
// WPOS
ret += reg_table[0];
properties.has_wpos_input = true;
insert = false;
break;
default:
if (dst.src_attr_reg_num < std::size(reg_table))
}
case 0x01:
case 0x02:
{
// COL0, COL1
if (!src2.use_index_reg)
{
ret += m_parr.AddParam(PF_PARAM_IN, getFloatTypeName(4), reg_table[dst.src_attr_reg_num]);
ret += "_saturate(" + reg_var + ")";
apply_precision_modifier = false;
}
else
{
// Raw access
ret += reg_var;
}
break;
}
case 0x03:
{
// FOGC
if (!src2.use_index_reg)
{
ret += reg_var;
}
else
{
// Raw access
ret += "fog_c";
}
break;
}
case 0x4:
case 0x5:
case 0x6:
case 0x7:
case 0x8:
case 0x9:
case 0xA:
case 0xB:
case 0xC:
case 0xD:
{
// TEX0 - TEX9
// Texcoord mask seems to reset the last 2 arguments to 0 and 1 if set
if (m_prog.texcoord_is_2d(dst.src_attr_reg_num - 4))
{
ret += getFloatTypeName(4) + "(" + reg_var + ".x, " + reg_var + ".y, 0., in_w)";
properties.has_w_access = true;
}
else
{
ret += reg_var;
}
break;
}
default:
{
// SSA (winding direction register)
// UNK
if (reg_var == "unk")
{
LOG_ERROR(RSX, "Bad src reg num: %d", u32{ dst.src_attr_reg_num });
ret += m_parr.AddParam(PF_PARAM_IN, getFloatTypeName(4), "unk");
Emu.Pause();
}

ret += reg_var;
apply_precision_modifier = false;
break;
}
}

if (insert)
{
m_parr.AddParam(PF_PARAM_IN, getFloatTypeName(4), reg_var);
}

properties.in_register_mask |= (1 << dst.src_attr_reg_num);
}
break;

Expand Down
22 changes: 21 additions & 1 deletion rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,16 +252,36 @@ class FragmentProgramDecompiler
virtual void insertMainEnd(std::stringstream &OS) = 0;

public:
enum : u16
{
in_wpos = (1 << 0),
in_diff_color = (1 << 1),
in_spec_color = (1 << 2),
in_fogc = (1 << 3),
in_tc0 = (1 << 4),
in_tc1 = (1 << 5),
in_tc2 = (1 << 6),
in_tc3 = (1 << 7),
in_tc4 = (1 << 8),
in_tc5 = (1 << 9),
in_tc6 = (1 << 10),
in_tc7 = (1 << 11),
in_tc8 = (1 << 12),
in_tc9 = (1 << 13),
in_ssa = (1 << 14)
};

struct
{
u16 in_register_mask = 0;
bool has_lit_op = false;
bool has_gather_op = false;
bool has_wpos_input = false;
bool has_no_output = false;
bool has_discard_op = false;
bool has_tex_op = false;
bool has_divsq = false;
bool has_clamp = false;
bool has_w_access = false;
}
properties;

Expand Down
14 changes: 10 additions & 4 deletions rpcs3/Emu/RSX/Common/GLSLCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -603,9 +603,14 @@ namespace glsl
//NOTE: Memory layout is fetched as byteswapped BGRA [GBAR] (GOW collection, DS2, DeS)
//The A component (Z) is useless (should contain stencil8 or just 1)
OS <<
"vec4 decodeLinearDepth(float depth_value)\n"
"vec4 decode_depth24(float depth_value, uint depth_float)\n"
"{\n"
" uint value = uint(depth_value * 16777215.);\n"
" uint value;\n"
" if (depth_float == 0)\n"
" value = uint(depth_value * 16777215.);\n"
" else\n"
" value = (floatBitsToUint(depth_value) >> 7) & 0xffffff;\n"
"\n"
" uint b = (value & 0xff);\n"
" uint g = (value >> 8) & 0xff;\n"
" uint r = (value >> 16) & 0xff;\n"
Expand All @@ -625,9 +630,10 @@ namespace glsl

"vec4 texture2DReconstruct(sampler2D tex, usampler2D stencil_tex, vec2 coord, float remap)\n"
"{\n"
" vec4 result = decodeLinearDepth(texture(tex, coord.xy).r);\n"
" uint control_bits = floatBitsToUint(remap);\n"
" vec4 result = decode_depth24(texture(tex, coord.xy).r, control_bits >> 16);\n"
" result.z = float(texture(stencil_tex, coord.xy).x) / 255.f;\n"
" uint remap_vector = floatBitsToUint(remap) & 0xFF;\n"
" uint remap_vector = control_bits & 0xFF;\n"
" if (remap_vector == 0xE4) return result;\n\n"
" vec4 tmp;\n"
" uint remap_a = remap_vector & 0x3;\n"
Expand Down
9 changes: 3 additions & 6 deletions rpcs3/Emu/RSX/Common/ProgramStateCache.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "stdafx.h"
#include "stdafx.h"
#include "ProgramStateCache.h"
#include "Emu/System.h"

Expand Down Expand Up @@ -424,9 +424,7 @@ size_t fragment_program_storage_hash::operator()(const RSXFragmentProgram& progr
hash ^= program.ctrl;
hash ^= program.texture_dimensions;
hash ^= program.unnormalized_coords;
hash ^= program.back_color_diffuse_output;
hash ^= program.back_color_specular_output;
hash ^= program.front_back_color_enabled;
hash ^= program.two_sided_lighting;
hash ^= program.shadow_textures;
hash ^= program.redirected_textures;

Expand All @@ -436,8 +434,7 @@ size_t fragment_program_storage_hash::operator()(const RSXFragmentProgram& progr
bool fragment_program_compare::operator()(const RSXFragmentProgram& binary1, const RSXFragmentProgram& binary2) const
{
if (binary1.ctrl != binary2.ctrl || binary1.texture_dimensions != binary2.texture_dimensions || binary1.unnormalized_coords != binary2.unnormalized_coords ||
binary1.back_color_diffuse_output != binary2.back_color_diffuse_output || binary1.back_color_specular_output != binary2.back_color_specular_output ||
binary1.front_back_color_enabled != binary2.front_back_color_enabled ||
binary1.two_sided_lighting != binary2.two_sided_lighting ||
binary1.shadow_textures != binary2.shadow_textures || binary1.redirected_textures != binary2.redirected_textures)
return false;

Expand Down
66 changes: 56 additions & 10 deletions rpcs3/Emu/RSX/Common/ShaderParam.h
Original file line number Diff line number Diff line change
Expand Up @@ -311,18 +311,64 @@ class ShaderVariable
return result;
}
}

std::string add_mask(const std::string& other_var) const
{
if (swizzles.back() != "xyzw")
{
return other_var + "." + swizzles.back();
}

return other_var;
}
};

struct vertex_reg_info
{
std::string name; //output name
bool need_declare; //needs explicit declaration as output (not language in-built)
std::string src_reg; //reg to get data from
std::string src_reg_mask; //input swizzle mask
bool need_cast; //needs casting
std::string cond; //update on condition
std::string default_val; //fallback value on cond fail
std::string dst_alias; //output name override
bool check_mask; //check program output control mask for this output
u32 check_mask_value; //program output control mask for testing
enum mask_test_type : u8
{
any = 0, // Any bit set
none = 1, // No bits set
all = 2, // All bits set
xall = 3 // Some bits set
};

std::string name; // output name
bool need_declare; // needs explicit declaration as output (not language in-built)
std::string src_reg; // reg to get data from
std::string src_reg_mask; // input swizzle mask
bool need_cast; // needs casting
std::string cond; // update on condition
std::string default_val; // fallback value on cond fail
std::string dst_alias; // output name override
bool check_mask; // check program output control mask for this output
u32 check_mask_value; // program output control mask for testing

mask_test_type check_flags; // whole mask must match

bool test(u32 mask) const
{
if (!check_mask)
return true;

const u32 val = (mask & check_mask_value);
switch (check_flags)
{
case none:
return (val == 0);
case any:
return (val != 0);
case all:
return (val == check_mask_value);
case xall:
return (val && val != check_mask_value);
default:
fmt::throw_exception("Unreachable" HERE);
}
}

bool declare(u32 mask) const
{
return test(mask);
}
};
9 changes: 8 additions & 1 deletion rpcs3/Emu/RSX/Common/TextureUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,19 @@ namespace rsx
transfer = 2
};

enum format_type : u8
{
color = 0,
depth_uint = 1,
depth_float = 2
};

//Sampled image descriptor
struct sampled_image_descriptor_base
{
texture_upload_context upload_context = texture_upload_context::shader_read;
rsx::texture_dimension_extended image_type = texture_dimension_extended::texture_dimension_2d;
bool is_depth_texture = false;
rsx::format_type format_class = rsx::format_type::color;
bool is_cyclic_reference = false;
f32 scale_x = 1.f;
f32 scale_y = 1.f;
Expand Down
4 changes: 3 additions & 1 deletion rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,9 @@ void VertexProgramDecompiler::AddCodeCond(const std::string& dst, const std::str
}

// NOTE: dst = _select(dst, src, cond) is equivalent to dst = cond? src : dst;
const auto cond = ShaderVariable(dst).match_size(GetRawCond());
const auto dst_var = ShaderVariable(dst);
const auto raw_cond = dst_var.add_mask(GetRawCond());
const auto cond = dst_var.match_size(raw_cond);
AddCode(dst + " = _select(" + dst + ", " + src + ", " + cond + ");");
}

Expand Down
19 changes: 17 additions & 2 deletions rpcs3/Emu/RSX/Common/surface_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ namespace rsx
u8 samples_x = 1;
u8 samples_y = 1;

format_type format_class = format_type::color;

std::unique_ptr<typename std::remove_pointer<image_storage_type>::type> resolve_surface;
surface_sample_layout sample_layout = surface_sample_layout::null;

Expand Down Expand Up @@ -279,16 +281,29 @@ namespace rsx
format_info.gcm_depth_format = format;
}

rsx::surface_color_format get_surface_color_format()
void set_depth_render_mode(bool integer)
{
if (is_depth_surface())
{
format_class = (integer) ? format_type::depth_uint : format_type::depth_float;
}
}

rsx::surface_color_format get_surface_color_format() const
{
return format_info.gcm_color_format;
}

rsx::surface_depth_format get_surface_depth_format()
rsx::surface_depth_format get_surface_depth_format() const
{
return format_info.gcm_depth_format;
}

rsx::format_type get_format_type() const
{
return format_class;
}

bool dirty() const
{
return (state_flags != rsx::surface_state_flags::ready) || !old_contents.empty();
Expand Down
Loading