mirror of
https://github.com/RPCS3/rsx_program_decompiler.git
synced 2024-11-23 01:59:49 +00:00
FP/VP: Implemented more instructions
Mimic legacy instructions
This commit is contained in:
parent
05d1fc4389
commit
58805ef0f6
@ -30,6 +30,9 @@ namespace rsx
|
||||
template<int Count>
|
||||
using boolean_t = typename base::template boolean_t<Count>;
|
||||
|
||||
template<int Count>
|
||||
using integer_t = typename base::template integer_t<Count>;
|
||||
|
||||
struct context_t
|
||||
{
|
||||
decompiled_shader program;
|
||||
@ -573,6 +576,11 @@ namespace rsx
|
||||
}
|
||||
}
|
||||
|
||||
builder::writer_t set_dst(const integer_expr<1>& arg, u32 flags = none)
|
||||
{
|
||||
return set_dst(float_point_t<1>::ctor(arg), flags);
|
||||
}
|
||||
|
||||
builder::writer_t set_dst(const boolean_expr<4>& arg, u32 flags = none)
|
||||
{
|
||||
std::string arg_string;
|
||||
@ -593,6 +601,12 @@ namespace rsx
|
||||
return set_dst(float_point_expr<4>{ arg_string, std::string("xyzw"), is_single, 4 }, flags);
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
Type make_not_zero(Type arg)
|
||||
{
|
||||
return base::max(base::abs(arg), float_point_t<Type::type::count>::ctor(1e-15f)) * base::sign(arg);
|
||||
}
|
||||
|
||||
builder::expression_base_t decode_instruction()
|
||||
{
|
||||
switch (u32(instruction.data.dst.opcode) | (u32(instruction.data.src1.opcode_is_branch) << 6))
|
||||
@ -622,30 +636,38 @@ namespace rsx
|
||||
case (u32)opcode_t::frc: return set_dst(base::fract(src_swizzled_as_dst(0)), disable_swizzle_as_dst);
|
||||
case (u32)opcode_t::flr: return set_dst(base::floor(src_swizzled_as_dst(0)), disable_swizzle_as_dst);
|
||||
case (u32)opcode_t::kil: return conditional(typename base::void_expr{ "discard;" });
|
||||
case (u32)opcode_t::pk4: return base::unimplemented("PK4");
|
||||
case (u32)opcode_t::up4: return base::unimplemented("UP4");
|
||||
//case (u32)opcode_t::ddx: return set_dst(base::ddx(src(0).xy()), disable_swizzle_as_dst);
|
||||
//case (u32)opcode_t::ddy: return set_dst(base::ddy(src(0).xy()), disable_swizzle_as_dst);
|
||||
case (u32)opcode_t::pk4: return set_dst(base::pack_snorm_4x8(src(0)));
|
||||
case (u32)opcode_t::up4: return set_dst(base::unpack_snorm_4x8(integer_t<1>::ctor(src(0).x())));
|
||||
case (u32)opcode_t::ddx: return set_dst(base::ddx(src(0).xy()).xyxy(), disable_swizzle_as_dst);
|
||||
case (u32)opcode_t::ddy: return set_dst(base::ddy(src(0).xy()).xyxy(), disable_swizzle_as_dst);
|
||||
case (u32)opcode_t::tex: return set_dst(base::texture_fetch(texture_index(), texture_coords()), allow_bx2);
|
||||
case (u32)opcode_t::txp: return set_dst(base::texture_fetch(texture_index(), texture_coords() / src(0).w()), allow_bx2);
|
||||
case (u32)opcode_t::txd: return set_dst(base::texture_grad_fetch(texture_index(), texture_coords(), src(1), src(2)), allow_bx2);
|
||||
case (u32)opcode_t::rcp: return set_dst(float_point_t<1>::ctor(1.0f) / src(0).x(), disable_swizzle_as_dst);
|
||||
case (u32)opcode_t::rsq: return set_dst(base::rsqrt(src(0).x()), disable_swizzle_as_dst);
|
||||
case (u32)opcode_t::rcp: return set_dst(float_point_t<1>::ctor(1.0f) / make_not_zero(src(0).x()), disable_swizzle_as_dst);
|
||||
case (u32)opcode_t::rsq: return set_dst(base::rsqrt(make_not_zero(src(0).x())), disable_swizzle_as_dst);
|
||||
case (u32)opcode_t::ex2: return set_dst(base::exp2(src(0).x()), disable_swizzle_as_dst);
|
||||
case (u32)opcode_t::lg2: return set_dst(base::log2(src(0).x()), disable_swizzle_as_dst);
|
||||
case (u32)opcode_t::lit: return base::unimplemented("LIT");
|
||||
case (u32)opcode_t::lrp: return base::unimplemented("LRP");
|
||||
case (u32)opcode_t::str: return set_dst(1.0f);
|
||||
case (u32)opcode_t::sfl: return set_dst(0.0f);
|
||||
case (u32)opcode_t::lg2: return set_dst(base::log2(make_not_zero(src(0).x())), disable_swizzle_as_dst);
|
||||
case (u32)opcode_t::lit:
|
||||
{
|
||||
auto t = src(0);
|
||||
|
||||
float_point_expr<1> z_value{ (t.x() > 0.0f).text };
|
||||
z_value.assign("(" + z_value.text + " ? " + base::exp2(t.w() * base::log2(make_not_zero(t.y()))).text + " : 0.0)");
|
||||
|
||||
return set_dst(float_point_t<4>::ctor(1.0f, t.x(), z_value, 1.0f));
|
||||
}
|
||||
case (u32)opcode_t::lrp: return set_dst(src(2) * (float_point_t<4>::ctor(1.0f) - src(0) + (src(1) * src(0)).without_scope()));
|
||||
case (u32)opcode_t::str: return set_dst(float_point_expr<1>{ 1.0f });
|
||||
case (u32)opcode_t::sfl: return set_dst(float_point_expr<1>{ 0.0f });
|
||||
case (u32)opcode_t::cos: return set_dst(base::cos(src(0).x()), disable_swizzle_as_dst);
|
||||
case (u32)opcode_t::sin: return set_dst(base::sin(src(0).x()), disable_swizzle_as_dst);
|
||||
case (u32)opcode_t::pk2: return base::unimplemented("PK2");
|
||||
case (u32)opcode_t::up2: return base::unimplemented("UP2");
|
||||
case (u32)opcode_t::pk2: return set_dst(base::pack_snorm_2x16(src(0).xy()));
|
||||
case (u32)opcode_t::up2: return set_dst(base::unpack_snorm_2x16(integer_t<1>::ctor(src(0).x())).xyxy());
|
||||
case (u32)opcode_t::pow: return set_dst(base::pow(src_swizzled_as_dst(0), src_swizzled_as_dst(1)), disable_swizzle_as_dst);
|
||||
case (u32)opcode_t::pkb: return base::unimplemented("PKB");
|
||||
case (u32)opcode_t::upb: return base::unimplemented("UPB");
|
||||
case (u32)opcode_t::pk16: return base::unimplemented("PK16");
|
||||
case (u32)opcode_t::up16: return base::unimplemented("UP16");
|
||||
case (u32)opcode_t::pkb: return set_dst(base::pack_unorm_4x8(src(0)));
|
||||
case (u32)opcode_t::upb: return set_dst(base::unpack_unorm_4x8(integer_t<1>::ctor(src(0).x())));
|
||||
case (u32)opcode_t::pk16: return set_dst(base::pack_half_2x16(src(0).xy()));
|
||||
case (u32)opcode_t::up16: return set_dst(base::unpack_half_2x16(integer_t<1>::ctor(src(0).x())).xyxy());
|
||||
case (u32)opcode_t::bem: return base::unimplemented("BEM");
|
||||
case (u32)opcode_t::pkg: return base::unimplemented("PKG");
|
||||
case (u32)opcode_t::upg: return base::unimplemented("UPG");
|
||||
@ -661,13 +683,21 @@ namespace rsx
|
||||
case (u32)opcode_t::texbem: return base::unimplemented("TEXBEM");
|
||||
case (u32)opcode_t::txpbem: return base::unimplemented("TXPBEM");
|
||||
case (u32)opcode_t::bemlum: return base::unimplemented("BEMLUM");
|
||||
case (u32)opcode_t::refl: return base::unimplemented("REFL");
|
||||
case (u32)opcode_t::refl: return set_dst(src(0) - ((float_point_expr<1>{ 2.0f } * base::dot(src(0), src(1))).without_scope() * src(1)).without_scope());
|
||||
case (u32)opcode_t::timeswtex: return base::unimplemented("TIMESWTEX");
|
||||
case (u32)opcode_t::dp2: return set_dst(base::dot(src(0).xy(), src(1).xy()));
|
||||
case (u32)opcode_t::nrm: return set_dst(base::normalize(src(0).xyz()).xyzx());
|
||||
case (u32)opcode_t::div: return set_dst(src_swizzled_as_dst(0) / src(1).x(), disable_swizzle_as_dst);
|
||||
case (u32)opcode_t::divsq: return set_dst(src_swizzled_as_dst(0) / base::sqrt(src(1).x()), disable_swizzle_as_dst);
|
||||
case (u32)opcode_t::lif: return base::unimplemented("LIF");
|
||||
case (u32)opcode_t::div: return set_dst(src_swizzled_as_dst(0) / make_not_zero(src(1).x()), disable_swizzle_as_dst);
|
||||
case (u32)opcode_t::divsq: return set_dst(src_swizzled_as_dst(0) / base::sqrt(make_not_zero(src(1).x())), disable_swizzle_as_dst);
|
||||
case (u32)opcode_t::lif:
|
||||
{
|
||||
auto t = src(0);
|
||||
|
||||
float_point_expr<1> z_value{ (t.y() > 0.0f).text };
|
||||
z_value.assign("(" + z_value.text + " ? " + base::pow(float_point_expr<1>{ 2.0f }, t.w()).text + " : 0.0)");
|
||||
|
||||
return set_dst(float_point_t<4>::ctor(1.0f, t.x(), z_value, 1.0f));
|
||||
}
|
||||
case (u32)opcode_t::fenct: return base::comment("fenct");
|
||||
case (u32)opcode_t::fencb: return base::comment("fencb");
|
||||
case (u32)opcode_t::brk: return conditional(typename base::void_expr("break;"));
|
||||
|
@ -562,6 +562,12 @@ namespace rsx
|
||||
return expr;
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
Type make_not_zero(Type arg)
|
||||
{
|
||||
return base::max(base::abs(arg), float_point_t<Type::type::count>::ctor(1e-15f)) * base::sign(arg);
|
||||
}
|
||||
|
||||
typename base::expression_base_t decode_sca_instruction()
|
||||
{
|
||||
is_vec = false;
|
||||
@ -569,17 +575,17 @@ namespace rsx
|
||||
switch ((u32)instruction.data.d1.sca_opcode)
|
||||
{
|
||||
case (u32)sca_opcode_t::mov: return set_dst(src_swizzled_as_dst(2));
|
||||
case (u32)sca_opcode_t::rcp: return set_dst(float_point_t<1>::ctor(1.0f) / src_swizzled_as_dst(2));
|
||||
case (u32)sca_opcode_t::rcc: return set_dst(base::clamp(float_point_t<1>::ctor(1.0f) / src_swizzled_as_dst(2), 5.42101e-20f, 1.884467e19f));
|
||||
case (u32)sca_opcode_t::rsq: return set_dst(base::rsqrt(base::abs(src_swizzled_as_dst(2))));
|
||||
case (u32)sca_opcode_t::rcp: return set_dst(float_point_t<1>::ctor(1.0f) / make_not_zero(src_swizzled_as_dst(2)));
|
||||
case (u32)sca_opcode_t::rcc: return set_dst(base::clamp(float_point_t<1>::ctor(1.0f) / make_not_zero(src_swizzled_as_dst(2)), 5.42101e-20f, 1.884467e19f));
|
||||
case (u32)sca_opcode_t::rsq: return set_dst(base::rsqrt(base::max(base::abs(src_swizzled_as_dst(2)), float_point_expr<4>{ "1e-15f" })));
|
||||
case (u32)sca_opcode_t::exp: return set_dst(base::exp(src_swizzled_as_dst(2)));
|
||||
case (u32)sca_opcode_t::log: return set_dst(base::log(src_swizzled_as_dst(2)));
|
||||
case (u32)sca_opcode_t::log: return set_dst(base::log(make_not_zero(src_swizzled_as_dst(2))));
|
||||
case (u32)sca_opcode_t::lit:
|
||||
{
|
||||
auto t = src(2);
|
||||
|
||||
float_point_expr<1> z_value{ (t.x() > 0.0f).text };
|
||||
z_value.assign("(" + z_value.text + " ? " + base::exp2(t.w() * base::log2(t.y())).text + " : 0.0)");
|
||||
z_value.assign("(" + z_value.text + " ? " + base::exp2(t.w() * base::log2(make_not_zero(t.y()))).text + " : 0.0)");
|
||||
|
||||
return set_dst(swizzle_as_dst(float_point_t<4>::ctor(1.0f, t.x(), z_value, 1.0f)));
|
||||
}
|
||||
@ -631,14 +637,14 @@ namespace rsx
|
||||
case (u32)vec_opcode_t::add: return set_dst(src_swizzled_as_dst(0) + src_swizzled_as_dst(2));
|
||||
case (u32)vec_opcode_t::mad: return set_dst((src_swizzled_as_dst(0) * src_swizzled_as_dst(1)).without_scope() + src_swizzled_as_dst(2));
|
||||
case (u32)vec_opcode_t::dp3: return set_dst(base::dot(src(0).xyz(), src(1).xyz()));
|
||||
case (u32)vec_opcode_t::dph: return set_dst(base::dot(float_point_t<4>::ctor(src(0).xyz(), 1.0), src(1))); break;
|
||||
case (u32)vec_opcode_t::dph: return set_dst(base::dot(float_point_t<4>::ctor(src(0).xyz(), 1.0), src(1)));
|
||||
case (u32)vec_opcode_t::dp4: return set_dst(base::dot(src(0), src(1)));
|
||||
case (u32)vec_opcode_t::dst: break;
|
||||
case (u32)vec_opcode_t::dst: return set_dst(float_point_t<4>::ctor(1.0, src(0).y() * src(1).y(), src(0).z(), src(1).w()));
|
||||
case (u32)vec_opcode_t::min: return set_dst(base::min(src_swizzled_as_dst(0), src_swizzled_as_dst(1)));
|
||||
case (u32)vec_opcode_t::max: return set_dst(base::max(src_swizzled_as_dst(0), src_swizzled_as_dst(1)));
|
||||
case (u32)vec_opcode_t::slt: return set_dst(compare(base::compare_function::less, src_swizzled_as_dst(0), src_swizzled_as_dst(1)));
|
||||
case (u32)vec_opcode_t::sge: return set_dst(compare(base::compare_function::greater_equal, src_swizzled_as_dst(0), src_swizzled_as_dst(1)));
|
||||
case (u32)vec_opcode_t::arl: return typename base::writer_t{} += address_register() = integer_t<1>::ctor(src(0).x());
|
||||
case (u32)vec_opcode_t::arl: return typename base::writer_t{} += address_register() = base::clamp(integer_t<1>::ctor(src(0).x()), -512, 511);
|
||||
case (u32)vec_opcode_t::frc: return set_dst(base::fract(src_swizzled_as_dst(0)));
|
||||
case (u32)vec_opcode_t::flr: return set_dst(base::floor(src_swizzled_as_dst(0)));;
|
||||
case (u32)vec_opcode_t::seq: return set_dst(compare(base::compare_function::equal, src_swizzled_as_dst(0), src_swizzled_as_dst(1)));
|
||||
@ -647,7 +653,7 @@ namespace rsx
|
||||
case (u32)vec_opcode_t::sle: return set_dst(compare(base::compare_function::less_equal, src_swizzled_as_dst(0), src_swizzled_as_dst(1)));
|
||||
case (u32)vec_opcode_t::sne: return set_dst(compare(base::compare_function::not_equal, src_swizzled_as_dst(0), src_swizzled_as_dst(1)));
|
||||
case (u32)vec_opcode_t::str: return set_dst(1.0f);
|
||||
case (u32)vec_opcode_t::ssg: break;
|
||||
case (u32)vec_opcode_t::ssg: return set_dst(base::sign(src_swizzled_as_dst(0)));
|
||||
case (u32)vec_opcode_t::txl:
|
||||
{
|
||||
auto src_1 = src(1);
|
||||
|
@ -247,6 +247,12 @@ namespace shader_code
|
||||
return function_t<float_point_t<Count>, typename language::template function_name_t<function_class_t::function_normalize>>::invoke(arg);
|
||||
}
|
||||
|
||||
template<int Count>
|
||||
static expression_from<float_point_t<Count>> sign(const expression_t<clike_language::type_class_t::type_float, Count>& arg)
|
||||
{
|
||||
return function_t<float_point_t<Count>, typename language::template function_name_t<function_class_t::function_sign>>::invoke(arg);
|
||||
}
|
||||
|
||||
template<int Count>
|
||||
static expression_from<float_point_t<Count>> abs(const expression_t<clike_language::type_class_t::type_float, Count>& arg)
|
||||
{
|
||||
@ -351,6 +357,11 @@ namespace shader_code
|
||||
return function_t<float_point_t<Count>, typename language::template function_name_t<function_class_t::function_clamp>>::invoke(a, b, c);
|
||||
}
|
||||
template<int Count>
|
||||
static expression_from<integer_t<Count>> clamp(const expression_t<clike_language::type_class_t::type_int, Count>& a, const expression_t<clike_language::type_class_t::type_int, 1>& b, const expression_t<clike_language::type_class_t::type_int, 1>& c)
|
||||
{
|
||||
return function_t<integer_t<Count>, typename language::template function_name_t<function_class_t::function_clamp>>::invoke(a, b, c);
|
||||
}
|
||||
template<int Count>
|
||||
static expression_from<float_point_t<Count>> sqrt(const expression_t<clike_language::type_class_t::type_float, Count>& arg)
|
||||
{
|
||||
return function_t<float_point_t<Count>, typename language::template function_name_t<function_class_t::function_sqrt>>::invoke(arg);
|
||||
@ -396,6 +407,43 @@ namespace shader_code
|
||||
return function_t<float_point_t<Count>, typename language::template function_name_t<function_class_t::function_ddy>>::invoke(arg);
|
||||
}
|
||||
|
||||
static expression_from<integer_t<1>> pack_snorm_4x8(const expression_from<float_point_t<4>>& arg)
|
||||
{
|
||||
return function_t<integer_t<1>, typename language::template function_name_t<function_class_t::function_pack_snorm_4x8>>::invoke(arg);
|
||||
}
|
||||
static expression_from<float_point_t<4>> unpack_snorm_4x8(const expression_from<integer_t<1>>& arg)
|
||||
{
|
||||
return function_t<float_point_t<4>, typename language::template function_name_t<function_class_t::function_unpack_snorm_4x8>>::invoke(arg);
|
||||
}
|
||||
|
||||
static expression_from<integer_t<1>> pack_unorm_4x8(const expression_from<float_point_t<4>>& arg)
|
||||
{
|
||||
return function_t<integer_t<1>, typename language::template function_name_t<function_class_t::function_pack_unorm_4x8>>::invoke(arg);
|
||||
}
|
||||
static expression_from<float_point_t<4>> unpack_unorm_4x8(const expression_from<integer_t<1>>& arg)
|
||||
{
|
||||
return function_t<float_point_t<4>, typename language::template function_name_t<function_class_t::function_unpack_unorm_4x8>>::invoke(arg);
|
||||
}
|
||||
|
||||
static expression_from<integer_t<1>> pack_snorm_2x16(const expression_from<float_point_t<2>>& arg)
|
||||
{
|
||||
return function_t<integer_t<1>, typename language::template function_name_t<function_class_t::function_pack_snorm_2x16>>::invoke(arg);
|
||||
}
|
||||
static expression_from<float_point_t<2>> unpack_snorm_2x16(const expression_from<integer_t<1>>& arg)
|
||||
{
|
||||
return function_t<float_point_t<2>, typename language::template function_name_t<function_class_t::function_unpack_snorm_2x16>>::invoke(arg);
|
||||
}
|
||||
|
||||
static expression_from<integer_t<1>> pack_half_2x16(const expression_from<float_point_t<2>>& arg)
|
||||
{
|
||||
return function_t<integer_t<1>, typename language::template function_name_t<function_class_t::function_pack_half_2x16>>::invoke(arg);
|
||||
}
|
||||
static expression_from<float_point_t<2>> unpack_half_2x16(const expression_from<integer_t<1>>& arg)
|
||||
{
|
||||
return function_t<float_point_t<2>, typename language::template function_name_t<function_class_t::function_unpack_half_2x16>>::invoke(arg);
|
||||
}
|
||||
|
||||
|
||||
//predefined functions
|
||||
static expression_from<float_point_t<4>> texture_fetch(const expression_from<integer_t<1>>& texture, const expression_from<float_point_t<4>>& arg0)
|
||||
{
|
||||
|
@ -618,6 +618,7 @@ namespace shader_code
|
||||
enum function_class_t
|
||||
{
|
||||
function_abs,
|
||||
function_sign,
|
||||
function_fract,
|
||||
function_floor,
|
||||
function_exp,
|
||||
@ -647,7 +648,15 @@ namespace shader_code
|
||||
function_sqrt,
|
||||
function_rsqrt,
|
||||
function_ddx,
|
||||
function_ddy
|
||||
function_ddy,
|
||||
function_pack_snorm_4x8,
|
||||
function_unpack_snorm_4x8,
|
||||
function_pack_unorm_4x8,
|
||||
function_unpack_unorm_4x8,
|
||||
function_pack_snorm_2x16,
|
||||
function_unpack_snorm_2x16,
|
||||
function_pack_half_2x16,
|
||||
function_unpack_half_2x16,
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
|
@ -109,6 +109,12 @@ namespace shader_code
|
||||
static constexpr auto name = "abs";
|
||||
};
|
||||
|
||||
template<>
|
||||
struct function_name_t<clike_language::function_class_t::function_sign>
|
||||
{
|
||||
static constexpr auto name = "sign";
|
||||
};
|
||||
|
||||
template<>
|
||||
struct function_name_t<clike_language::function_class_t::function_normalize>
|
||||
{
|
||||
@ -288,6 +294,54 @@ namespace shader_code
|
||||
{
|
||||
static constexpr auto name = "dFdy";
|
||||
};
|
||||
|
||||
template<>
|
||||
struct function_name_t<clike_language::function_class_t::function_pack_snorm_4x8>
|
||||
{
|
||||
static constexpr auto name = "packSnorm4x8";
|
||||
};
|
||||
|
||||
template<>
|
||||
struct function_name_t<clike_language::function_class_t::function_unpack_snorm_4x8>
|
||||
{
|
||||
static constexpr auto name = "unpackSnorm4x8";
|
||||
};
|
||||
|
||||
template<>
|
||||
struct function_name_t<clike_language::function_class_t::function_pack_unorm_4x8>
|
||||
{
|
||||
static constexpr auto name = "packUnorm4x8";
|
||||
};
|
||||
|
||||
template<>
|
||||
struct function_name_t<clike_language::function_class_t::function_unpack_unorm_4x8>
|
||||
{
|
||||
static constexpr auto name = "unpackUnorm4x8";
|
||||
};
|
||||
|
||||
template<>
|
||||
struct function_name_t<clike_language::function_class_t::function_pack_snorm_2x16>
|
||||
{
|
||||
static constexpr auto name = "packSnorm2x16";
|
||||
};
|
||||
|
||||
template<>
|
||||
struct function_name_t<clike_language::function_class_t::function_unpack_snorm_2x16>
|
||||
{
|
||||
static constexpr auto name = "unpackSnorm2x16";
|
||||
};
|
||||
|
||||
template<>
|
||||
struct function_name_t<clike_language::function_class_t::function_pack_half_2x16>
|
||||
{
|
||||
static constexpr auto name = "packHalf2x16";
|
||||
};
|
||||
|
||||
template<>
|
||||
struct function_name_t<clike_language::function_class_t::function_unpack_half_2x16>
|
||||
{
|
||||
static constexpr auto name = "unpackHalf2x16";
|
||||
};
|
||||
}
|
||||
|
||||
struct glsl_language
|
||||
|
Loading…
Reference in New Issue
Block a user