glsl: add half float angle and trigonometry functions
Acked-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18540>
This commit is contained in:
committed by
Marge Bot
parent
3ff22ee4ae
commit
829c99def1
@@ -1036,7 +1036,6 @@ private:
|
||||
ir_dereference_record *record_ref(ir_variable *var, const char *field);
|
||||
|
||||
ir_expression *asin_expr(ir_variable *x, float p0, float p1);
|
||||
void do_atan(ir_factory &body, const glsl_type *type, ir_variable *res, operand y_over_x);
|
||||
|
||||
/**
|
||||
* Call function \param f with parameters specified as the linked
|
||||
@@ -1102,21 +1101,21 @@ private:
|
||||
#define B3(X) ir_function_signature *_##X(const glsl_type *, const glsl_type *, const glsl_type *);
|
||||
#define BA1(X) ir_function_signature *_##X(builtin_available_predicate, const glsl_type *);
|
||||
#define BA2(X) ir_function_signature *_##X(builtin_available_predicate, const glsl_type *, const glsl_type *);
|
||||
B1(radians)
|
||||
B1(degrees)
|
||||
B1(sin)
|
||||
B1(cos)
|
||||
B1(tan)
|
||||
B1(asin)
|
||||
B1(acos)
|
||||
B1(atan2)
|
||||
B1(atan)
|
||||
B1(sinh)
|
||||
B1(cosh)
|
||||
B1(tanh)
|
||||
B1(asinh)
|
||||
B1(acosh)
|
||||
B1(atanh)
|
||||
BA1(radians)
|
||||
BA1(degrees)
|
||||
BA1(sin)
|
||||
BA1(cos)
|
||||
BA1(tan)
|
||||
BA1(asin)
|
||||
BA1(acos)
|
||||
BA1(atan2)
|
||||
BA1(atan)
|
||||
BA1(sinh)
|
||||
BA1(cosh)
|
||||
BA1(tanh)
|
||||
BA1(asinh)
|
||||
BA1(acosh)
|
||||
BA1(atanh)
|
||||
B1(pow)
|
||||
B1(exp)
|
||||
B1(log)
|
||||
@@ -2120,31 +2119,39 @@ builtin_builder::create_builtins()
|
||||
_##NAME(gpu_shader_half_float, &glsl_type_builtin_f16vec4, &glsl_type_builtin_f16vec4), \
|
||||
NULL);
|
||||
|
||||
F(radians)
|
||||
F(degrees)
|
||||
F(sin)
|
||||
F(cos)
|
||||
F(tan)
|
||||
F(asin)
|
||||
F(acos)
|
||||
FHF(radians)
|
||||
FHF(degrees)
|
||||
FHF(sin)
|
||||
FHF(cos)
|
||||
FHF(tan)
|
||||
FHF(asin)
|
||||
FHF(acos)
|
||||
|
||||
add_function("atan",
|
||||
_atan(&glsl_type_builtin_float),
|
||||
_atan(&glsl_type_builtin_vec2),
|
||||
_atan(&glsl_type_builtin_vec3),
|
||||
_atan(&glsl_type_builtin_vec4),
|
||||
_atan2(&glsl_type_builtin_float),
|
||||
_atan2(&glsl_type_builtin_vec2),
|
||||
_atan2(&glsl_type_builtin_vec3),
|
||||
_atan2(&glsl_type_builtin_vec4),
|
||||
_atan(always_available, &glsl_type_builtin_float),
|
||||
_atan(always_available, &glsl_type_builtin_vec2),
|
||||
_atan(always_available, &glsl_type_builtin_vec3),
|
||||
_atan(always_available, &glsl_type_builtin_vec4),
|
||||
_atan2(always_available, &glsl_type_builtin_float),
|
||||
_atan2(always_available, &glsl_type_builtin_vec2),
|
||||
_atan2(always_available, &glsl_type_builtin_vec3),
|
||||
_atan2(always_available, &glsl_type_builtin_vec4),
|
||||
_atan(gpu_shader_half_float, &glsl_type_builtin_float16_t),
|
||||
_atan(gpu_shader_half_float, &glsl_type_builtin_f16vec2),
|
||||
_atan(gpu_shader_half_float, &glsl_type_builtin_f16vec3),
|
||||
_atan(gpu_shader_half_float, &glsl_type_builtin_f16vec4),
|
||||
_atan2(gpu_shader_half_float, &glsl_type_builtin_float16_t),
|
||||
_atan2(gpu_shader_half_float, &glsl_type_builtin_f16vec2),
|
||||
_atan2(gpu_shader_half_float, &glsl_type_builtin_f16vec3),
|
||||
_atan2(gpu_shader_half_float, &glsl_type_builtin_f16vec4),
|
||||
NULL);
|
||||
|
||||
F(sinh)
|
||||
F(cosh)
|
||||
F(tanh)
|
||||
F(asinh)
|
||||
F(acosh)
|
||||
F(atanh)
|
||||
FHF130(sinh)
|
||||
FHF130(cosh)
|
||||
FHF130(tanh)
|
||||
FHF130(asinh)
|
||||
FHF130(acosh)
|
||||
FHF130(atanh)
|
||||
F(pow)
|
||||
F(exp)
|
||||
F(log)
|
||||
@@ -6031,31 +6038,34 @@ builtin_builder::_##NAME(const glsl_type *return_type, \
|
||||
*/
|
||||
|
||||
ir_function_signature *
|
||||
builtin_builder::_radians(const glsl_type *type)
|
||||
builtin_builder::_radians(builtin_available_predicate avail,
|
||||
const glsl_type *type)
|
||||
{
|
||||
ir_variable *degrees = in_var(type, "degrees");
|
||||
MAKE_SIG(type, always_available, 1, degrees);
|
||||
body.emit(ret(mul(degrees, imm(0.0174532925f))));
|
||||
MAKE_SIG(type, avail, 1, degrees);
|
||||
body.emit(ret(mul(degrees, IMM_FP(type, 0.0174532925f))));
|
||||
return sig;
|
||||
}
|
||||
|
||||
ir_function_signature *
|
||||
builtin_builder::_degrees(const glsl_type *type)
|
||||
builtin_builder::_degrees(builtin_available_predicate avail,
|
||||
const glsl_type *type)
|
||||
{
|
||||
ir_variable *radians = in_var(type, "radians");
|
||||
MAKE_SIG(type, always_available, 1, radians);
|
||||
body.emit(ret(mul(radians, imm(57.29578f))));
|
||||
MAKE_SIG(type, avail, 1, radians);
|
||||
body.emit(ret(mul(radians, IMM_FP(type, 57.29578f))));
|
||||
return sig;
|
||||
}
|
||||
|
||||
UNOP(sin, ir_unop_sin, always_available)
|
||||
UNOP(cos, ir_unop_cos, always_available)
|
||||
UNOPA(sin, ir_unop_sin)
|
||||
UNOPA(cos, ir_unop_cos)
|
||||
|
||||
ir_function_signature *
|
||||
builtin_builder::_tan(const glsl_type *type)
|
||||
builtin_builder::_tan(builtin_available_predicate avail,
|
||||
const glsl_type *type)
|
||||
{
|
||||
ir_variable *theta = in_var(type, "theta");
|
||||
MAKE_SIG(type, always_available, 1, theta);
|
||||
MAKE_SIG(type, avail, 1, theta);
|
||||
body.emit(ret(div(sin(theta), cos(theta))));
|
||||
return sig;
|
||||
}
|
||||
@@ -6064,14 +6074,14 @@ ir_expression *
|
||||
builtin_builder::asin_expr(ir_variable *x, float p0, float p1)
|
||||
{
|
||||
return mul(sign(x),
|
||||
sub(imm(M_PI_2f),
|
||||
mul(sqrt(sub(imm(1.0f), abs(x))),
|
||||
add(imm(M_PI_2f),
|
||||
sub(IMM_FP(x->type, M_PI_2f),
|
||||
mul(sqrt(sub(IMM_FP(x->type, 1.0f), abs(x))),
|
||||
add(IMM_FP(x->type, M_PI_2f),
|
||||
mul(abs(x),
|
||||
add(imm(M_PI_4f - 1.0f),
|
||||
add(IMM_FP(x->type, (M_PI_4f - 1.0f)),
|
||||
mul(abs(x),
|
||||
add(imm(p0),
|
||||
mul(abs(x), imm(p1))))))))));
|
||||
add(IMM_FP(x->type, p0),
|
||||
mul(abs(x), IMM_FP(x->type, p1))))))))));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6111,10 +6121,11 @@ builtin_builder::call(ir_function *f, ir_variable *ret, exec_list params)
|
||||
}
|
||||
|
||||
ir_function_signature *
|
||||
builtin_builder::_asin(const glsl_type *type)
|
||||
builtin_builder::_asin(builtin_available_predicate avail,
|
||||
const glsl_type *type)
|
||||
{
|
||||
ir_variable *x = in_var(type, "x");
|
||||
MAKE_SIG(type, always_available, 1, x);
|
||||
MAKE_SIG(type, avail, 1, x);
|
||||
|
||||
body.emit(ret(asin_expr(x, 0.086566724f, -0.03102955f)));
|
||||
|
||||
@@ -6122,45 +6133,49 @@ builtin_builder::_asin(const glsl_type *type)
|
||||
}
|
||||
|
||||
ir_function_signature *
|
||||
builtin_builder::_acos(const glsl_type *type)
|
||||
builtin_builder::_acos(builtin_available_predicate avail,
|
||||
const glsl_type *type)
|
||||
{
|
||||
ir_variable *x = in_var(type, "x");
|
||||
MAKE_SIG(type, always_available, 1, x);
|
||||
MAKE_SIG(type, avail, 1, x);
|
||||
|
||||
body.emit(ret(sub(imm(M_PI_2f), asin_expr(x, 0.08132463f, -0.02363318f))));
|
||||
body.emit(ret(sub(IMM_FP(type, M_PI_2f), asin_expr(x, 0.08132463f, -0.02363318f))));
|
||||
|
||||
return sig;
|
||||
}
|
||||
|
||||
ir_function_signature *
|
||||
builtin_builder::_sinh(const glsl_type *type)
|
||||
builtin_builder::_sinh(builtin_available_predicate avail,
|
||||
const glsl_type *type)
|
||||
{
|
||||
ir_variable *x = in_var(type, "x");
|
||||
MAKE_SIG(type, v130, 1, x);
|
||||
MAKE_SIG(type, avail, 1, x);
|
||||
|
||||
/* 0.5 * (e^x - e^(-x)) */
|
||||
body.emit(ret(mul(imm(0.5f), sub(exp(x), exp(neg(x))))));
|
||||
body.emit(ret(mul(IMM_FP(type, 0.5f), sub(exp(x), exp(neg(x))))));
|
||||
|
||||
return sig;
|
||||
}
|
||||
|
||||
ir_function_signature *
|
||||
builtin_builder::_cosh(const glsl_type *type)
|
||||
builtin_builder::_cosh(builtin_available_predicate avail,
|
||||
const glsl_type *type)
|
||||
{
|
||||
ir_variable *x = in_var(type, "x");
|
||||
MAKE_SIG(type, v130, 1, x);
|
||||
MAKE_SIG(type, avail, 1, x);
|
||||
|
||||
/* 0.5 * (e^x + e^(-x)) */
|
||||
body.emit(ret(mul(imm(0.5f), add(exp(x), exp(neg(x))))));
|
||||
body.emit(ret(mul(IMM_FP(type, 0.5f), add(exp(x), exp(neg(x))))));
|
||||
|
||||
return sig;
|
||||
}
|
||||
|
||||
ir_function_signature *
|
||||
builtin_builder::_tanh(const glsl_type *type)
|
||||
builtin_builder::_tanh(builtin_available_predicate avail,
|
||||
const glsl_type *type)
|
||||
{
|
||||
ir_variable *x = in_var(type, "x");
|
||||
MAKE_SIG(type, v130, 1, x);
|
||||
MAKE_SIG(type, avail, 1, x);
|
||||
|
||||
/* Clamp x to [-10, +10] to avoid precision problems.
|
||||
* When x > 10, e^(-x) is so small relative to e^x that it gets flushed to
|
||||
@@ -6168,7 +6183,7 @@ builtin_builder::_tanh(const glsl_type *type)
|
||||
* direction when x < -10.
|
||||
*/
|
||||
ir_variable *t = body.make_temp(type, "tmp");
|
||||
body.emit(assign(t, min2(max2(x, imm(-10.0f)), imm(10.0f))));
|
||||
body.emit(assign(t, min2(max2(x, IMM_FP(type, -10.0f)), IMM_FP(type, 10.0f))));
|
||||
|
||||
/* (e^x - e^(-x)) / (e^x + e^(-x)) */
|
||||
body.emit(ret(div(sub(exp(t), exp(neg(t))),
|
||||
@@ -6178,34 +6193,37 @@ builtin_builder::_tanh(const glsl_type *type)
|
||||
}
|
||||
|
||||
ir_function_signature *
|
||||
builtin_builder::_asinh(const glsl_type *type)
|
||||
builtin_builder::_asinh(builtin_available_predicate avail,
|
||||
const glsl_type *type)
|
||||
{
|
||||
ir_variable *x = in_var(type, "x");
|
||||
MAKE_SIG(type, v130, 1, x);
|
||||
MAKE_SIG(type, avail, 1, x);
|
||||
|
||||
body.emit(ret(mul(sign(x), log(add(abs(x), sqrt(add(mul(x, x),
|
||||
imm(1.0f))))))));
|
||||
IMM_FP(type, 1.0f))))))));
|
||||
return sig;
|
||||
}
|
||||
|
||||
ir_function_signature *
|
||||
builtin_builder::_acosh(const glsl_type *type)
|
||||
builtin_builder::_acosh(builtin_available_predicate avail,
|
||||
const glsl_type *type)
|
||||
{
|
||||
ir_variable *x = in_var(type, "x");
|
||||
MAKE_SIG(type, v130, 1, x);
|
||||
MAKE_SIG(type, avail, 1, x);
|
||||
|
||||
body.emit(ret(log(add(x, sqrt(sub(mul(x, x), imm(1.0f)))))));
|
||||
body.emit(ret(log(add(x, sqrt(sub(mul(x, x), IMM_FP(type, 1.0f)))))));
|
||||
return sig;
|
||||
}
|
||||
|
||||
ir_function_signature *
|
||||
builtin_builder::_atanh(const glsl_type *type)
|
||||
builtin_builder::_atanh(builtin_available_predicate avail,
|
||||
const glsl_type *type)
|
||||
{
|
||||
ir_variable *x = in_var(type, "x");
|
||||
MAKE_SIG(type, v130, 1, x);
|
||||
MAKE_SIG(type, avail, 1, x);
|
||||
|
||||
body.emit(ret(mul(imm(0.5f), log(div(add(imm(1.0f), x),
|
||||
sub(imm(1.0f), x))))));
|
||||
body.emit(ret(mul(IMM_FP(type, 0.5f), log(div(add(IMM_FP(type, 1.0f), x),
|
||||
sub(IMM_FP(type, 1.0f), x))))));
|
||||
return sig;
|
||||
}
|
||||
/** @} */
|
||||
@@ -6224,7 +6242,7 @@ UNOP(exp, ir_unop_exp, always_available)
|
||||
UNOP(log, ir_unop_log, always_available)
|
||||
UNOP(exp2, ir_unop_exp2, always_available)
|
||||
UNOP(log2, ir_unop_log2, always_available)
|
||||
UNOP(atan, ir_unop_atan, always_available)
|
||||
UNOPA(atan, ir_unop_atan)
|
||||
UNOPA(sqrt, ir_unop_sqrt)
|
||||
UNOPA(inversesqrt, ir_unop_rsq)
|
||||
|
||||
@@ -6425,9 +6443,10 @@ builtin_builder::_isinf(builtin_available_predicate avail, const glsl_type *type
|
||||
}
|
||||
|
||||
ir_function_signature *
|
||||
builtin_builder::_atan2(const glsl_type *x_type)
|
||||
builtin_builder::_atan2(builtin_available_predicate avail,
|
||||
const glsl_type *x_type)
|
||||
{
|
||||
return binop(always_available, ir_binop_atan2, x_type, x_type, x_type);
|
||||
return binop(avail, ir_binop_atan2, x_type, x_type, x_type);
|
||||
}
|
||||
|
||||
ir_function_signature *
|
||||
|
||||
Reference in New Issue
Block a user