[Mesa-dev] [PATCH 05/15] glsl: Add new {fr, ld}exp built-ins IR and prototypes.

Paul Berry stereotype441 at gmail.com
Fri Aug 23 08:55:45 PDT 2013


On 22 August 2013 16:08, Matt Turner <mattst88 at gmail.com> wrote:

> ---
>  src/glsl/builtins/ir/frexp.ir                   | 25
> +++++++++++++++++++++++++
>  src/glsl/builtins/ir/ldexp.ir                   | 25
> +++++++++++++++++++++++++
>  src/glsl/builtins/profiles/ARB_gpu_shader5.glsl | 10 ++++++++++
>  3 files changed, 60 insertions(+)
>  create mode 100644 src/glsl/builtins/ir/frexp.ir
>  create mode 100644 src/glsl/builtins/ir/ldexp.ir
>
> diff --git a/src/glsl/builtins/ir/frexp.ir b/src/glsl/builtins/ir/frexp.ir
> new file mode 100644
> index 0000000..a514994
> --- /dev/null
> +++ b/src/glsl/builtins/ir/frexp.ir
> @@ -0,0 +1,25 @@
> +((function frexp
> +   (signature float
> +     (parameters
> +       (declare (in) float x)
> +       (declare (out) int exp))
> +     ((return (expression float frexp (var_ref x) (var_ref exp)))))
>

Having an ir_expression that writes to one of its parameters is going to
break assumptions in a lot of our optimization passes.  For example, if
opt_tree_grafting encounters this code:

uniform float u;
void main()
{
  int exp;
  float f = frexp(u, out exp);
  float g = float(exp)/256.0;
  float h = float(exp) + 1.0;
  gl_FragColor = vec4(f, g, h, g + h);
}

it may try to optimize it to this:

uniform float u;
void main()
{
  int exp;
  float g = float(exp)/256.0;
  float h = float(exp) + 1.0;
  gl_FragColor = vec4(frexp(u, out exp), g, h, g + h);
}

I think what we need to do is either:

1. Punt on the frexp_to_arith lowering pass for now, and instead just put
the lowered code right here, or

2. In patch 7, replace ir_binop_frexp with two unary ops, one that computes
the mantissa (return value of frexp()), and one that computes the integer
exponent.  Then this code will be effectively:

float frexp(float x, out int exp)
{
   exp = ir_unop_frexp_mantissa(x);
   return ir_unop_frexp_exponent(x);
}

 I'm leaning toward option 1, because I suspect it will generate more
efficient code (option 2 is likely to cause the if test in frexp_to_arith
to be duplicated).


> +
> +   (signature vec2
> +     (parameters
> +       (declare (in) vec2 x)
> +       (declare (out) ivec2 exp))
> +     ((return (expression vec2 frexp (var_ref x) (var_ref exp)))))
> +
> +   (signature vec3
> +     (parameters
> +       (declare (in) vec3 x)
> +       (declare (out) ivec3 exp))
> +     ((return (expression vec3 frexp (var_ref x) (var_ref exp)))))
> +
> +   (signature vec4
> +     (parameters
> +       (declare (in) vec4 x)
> +       (declare (out) ivec4 exp))
> +     ((return (expression vec4 frexp (var_ref x) (var_ref exp)))))
> +))
> diff --git a/src/glsl/builtins/ir/ldexp.ir b/src/glsl/builtins/ir/ldexp.ir
> new file mode 100644
> index 0000000..dd25f5a
> --- /dev/null
> +++ b/src/glsl/builtins/ir/ldexp.ir
> @@ -0,0 +1,25 @@
> +((function ldexp
> +   (signature float
> +     (parameters
> +       (declare (in) float x)
> +       (declare (in) int exp))
> +     ((return (expression float ldexp (var_ref x) (var_ref exp)))))
>

Note: ldexp is fine as a binop, since both its parameters are inputs.


> +
> +   (signature vec2
> +     (parameters
> +       (declare (in) vec2 x)
> +       (declare (in) ivec2 exp))
> +     ((return (expression vec2 ldexp (var_ref x) (var_ref exp)))))
> +
> +   (signature vec3
> +     (parameters
> +       (declare (in) vec3 x)
> +       (declare (in) ivec3 exp))
> +     ((return (expression vec3 ldexp (var_ref x) (var_ref exp)))))
> +
> +   (signature vec4
> +     (parameters
> +       (declare (in) vec4 x)
> +       (declare (in) ivec4 exp))
> +     ((return (expression vec4 ldexp (var_ref x) (var_ref exp)))))
> +))
> diff --git a/src/glsl/builtins/profiles/ARB_gpu_shader5.glsl
> b/src/glsl/builtins/profiles/ARB_gpu_shader5.glsl
> index 3f76283..36fc0de 100644
> --- a/src/glsl/builtins/profiles/ARB_gpu_shader5.glsl
> +++ b/src/glsl/builtins/profiles/ARB_gpu_shader5.glsl
> @@ -59,3 +59,13 @@ float fma(float a, float b, float c);
>  vec2  fma(vec2  a, vec2  b, vec2  c);
>  vec3  fma(vec3  a, vec3  b, vec3  c);
>  vec4  fma(vec4  a, vec4  b, vec4  c);
> +
> +float frexp(float x, out int   exp);
> +vec2  frexp(vec2  x, out ivec2 exp);
> +vec3  frexp(vec3  x, out ivec3 exp);
> +vec4  frexp(vec4  x, out ivec4 exp);
> +
> +float ldexp(float x, int   exp);
> +vec2  ldexp(vec2  x, ivec2 exp);
> +vec3  ldexp(vec3  x, ivec3 exp);
> +vec4  ldexp(vec4  x, ivec4 exp);
> --
> 1.8.3.2
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20130823/72cf0750/attachment-0001.html>


More information about the mesa-dev mailing list