FP/VP: Implemented more instructions

Mimic legacy instructions
This commit is contained in:
DH 2016-06-28 23:12:59 +03:00
parent 05d1fc4389
commit 58805ef0f6
5 changed files with 178 additions and 31 deletions

View File

@ -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;"));

View File

@ -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);

View File

@ -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)
{

View File

@ -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>

View File

@ -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