[Piglit] [PATCH 3/4] arb_shader_precision: add reference implementations of complex functions

Dylan Baker baker.dylan.c at gmail.com
Fri Feb 20 16:34:29 PST 2015


On Fri, Feb 20, 2015 at 06:59:10PM -0500, Ilia Mirkin wrote:
> On Thu, Feb 19, 2015 at 1:06 AM, Micah Fedke
> <micah.fedke at collabora.co.uk> wrote:
> > ---
> >  generated_tests/gen_shader_precision_tests.py | 177
> > +++++++++++++++++++++++++-
> >  1 file changed, 176 insertions(+), 1 deletion(-)
> >
> > diff --git a/generated_tests/gen_shader_precision_tests.py
> > b/generated_tests/gen_shader_precision_tests.py
> > index 0bda05a..f1ef420 100644
> > --- a/generated_tests/gen_shader_precision_tests.py
> > +++ b/generated_tests/gen_shader_precision_tests.py
> > @@ -89,6 +89,171 @@ def _ulpsize(f):
> >      return bigfloat.next_up(f)-f if f >= 0.0 \
> >              else f-bigfloat.next_down(f)
> >  +def _to_bigfloat_any(arg):
> > +    if type(arg).__name__ == 'BigFloat':
> > +        return arg
> > +    else:
> > +        return bigfloat.BigFloat.exact('{0:1.8e}'.format(arg),
> > precision=23) if _len_any(arg) == 1 \
> > +               else map(bigfloat.BigFloat, map('{0:1.8e}'.format, arg))
> 
> This whole array vs not-array confusion has gotta go. This function
> should just do one value at a time. The caller can do the map() on its
> own.
> 
> It may be helpful to create a helper which *makes* a plain value into
> an array of size 1 to help normalize this situation. (To be called at
> function entry time, not deep inside some helper far away.)

Yes. This.

> 
> > +
> > +def _mod_ref(args):
> > +    x = _to_bigfloat_any(args[0])
> > +    y = _to_bigfloat_any(args[1])
> > +    return x - y*(bigfloat.floor(x/y))
> > +
> > +def _smoothstep_ref(args):
> > +    edge0 = _to_bigfloat_any(args[0])
> > +    edge1 = _to_bigfloat_any(args[1])
> > +    x = _to_bigfloat_any(args[2])
> > +    t = (x-edge0)/(edge1-edge0) +    return t*t*(3.0-2.0*t)
> > +
> > +def _mix_ref(args):
> > +    x = _to_bigfloat_any(args[0])
> > +    y = _to_bigfloat_any(args[1])
> > +    a = _to_bigfloat_any(args[2])
> > +    return x*(1.0-a)+y*a
> > +
> > +def _length_ref(args):
> > +    component_sum = bigfloat.BigFloat(0.0)
> > +    for i, arg in enumerate(args[0] if _len_any(args[0]) > 1 else args):
> > +        component_sum += bigfloat.pow(_to_bigfloat_any(arg), 2.0)
> > +    return bigfloat.sqrt(component_sum)
> > +
> > +def _distance_ref(args):
> > +    components = _len_any(args[0])
> > +    difference = []
> > +    for i in range(components):
> > +        p0 = _to_bigfloat_any(args[0] if components == 1 else args[0][i])
> > +        p1 = _to_bigfloat_any(args[1] if components == 1 else args[1][i])
> > +        difference.append(p0-p1)
> > +    return _length_ref(difference)
> > +
> > +def _dot_ref(args):
> > +    components = _len_any(args[0])
> > +    product = bigfloat.BigFloat(0.0)
> > +    for i in range(components):
> > +        x = _to_bigfloat_any(args[0] if components == 1 else args[0][i])
> > +        y = _to_bigfloat_any(args[1] if components == 1 else args[1][i])
> > +        product += x*y
> > +    return product
> > +
> > +def _cross_ref(args):
> > +    x0 = _to_bigfloat_any(args[0][0])
> > +    x1 = _to_bigfloat_any(args[0][1])
> > +    x2 = _to_bigfloat_any(args[0][2])
> > +    y0 = _to_bigfloat_any(args[1][0])
> > +    y1 = _to_bigfloat_any(args[1][1])
> > +    y2 = _to_bigfloat_any(args[1][2])
> > +    ret = [x1*y2-y1*x2, x2*y0-y2*x0, x0*y1-y0*x1]
> > +    return ret
> > +
> > +def _normalize_ref(args):
> > +    num_components = _len_any(args[0])
> > +    normalized_components = []
> > +    comp_len = _length_ref(args if num_components == 1 else args[0])
> > +    for i in range(num_components):
> > +        component = _to_bigfloat_any(args[0] if num_components == 1 else
> > args[0][i])
> > +        normalized_components.append(component/comp_len)
> > +    return normalized_components[0] if num_components == 1 else
> > normalized_components
> > +
> > +def _faceforward_ref(args):
> > +    N = _to_bigfloat_any(args[0])
> > +    I = _to_bigfloat_any(args[1])
> > +    Nref = _to_bigfloat_any(args[2])
> > +    components = _len_any(args[0])
> > +    if _dot_ref([Nref,I]) < 0.0:
> > +        ret = N
> > +    else:
> > +        if components == 1:
> > +            negN = N*-1.0
> > +        else:
> > +            negN = []
> > +            for i in range(components):
> > +                negN.append(N[i]*-1.0)
> > +        ret = negN
> > +    return ret
> > +
> > +def _reflect_ref(args):
> > +    I = _to_bigfloat_any(args[0])
> > +    N = _to_bigfloat_any(args[1])
> > +    components = _len_any(args[0])
> > +    dotNI = _dot_ref([N,I])
> > +    if components == 1:
> > +        ret = 2.0*dotNI*N
> > +    else:
> > +        ret = []
> > +        for i in range(components):
> > +            ret.append(2.0*dotNI*N[i])
> > +    return ret
> > +
> > +def _refract_ref(args):
> > +    I = args[0]
> > +    N = args[1]
> > +    eta = _to_bigfloat_any(args[2])
> > +    components = _len_any(args[0])
> > +    k = 1.0-eta*eta*(1.0-_dot_ref([N,I])*_dot_ref([N,I]))
> > +    if k < 0.0:
> > +        if components == 1:
> > +            ret = bigfloat.BigFloat(0.0)
> > +        else:
> > +            ret = []
> > +            for i in range(components):
> > +                ret.append(bigfloat.BigFloat(0.0))
> > +    else:
> > +        if components == 1:
> > +            ret = eta*I-(eta*_dot_ref([N,I])+bigfloat.sqrt(k))*N
> > +        else:
> > +            Ntemp = []
> > +            Itemp = []
> > +            ret = []
> > +            for i in range(components):
> > +                Ntemp = (eta*_dot_ref([N,I])+bigfloat.sqrt(k))*N[i]
> > +                Itemp = eta*I[i]
> > +                ret.append(Itemp - Ntemp)
> > +    return ret
> > +
> > +def _vec_times_mat_ref(args):
> 
> You added references to these functions in the previous commit...
> 
> > +    v = args[0]
> > +    m = args[1]
> > +    m_type = glsl_type_of(m)
> > +    num_cols = m_type.num_cols
> > +    num_rows = m_type.num_rows
> > +    components = num_cols
> > +    ret = []
> > +    for i in range(components):
> > +        m_col = []
> > +        for j in range(num_rows):
> > +            m_col.append(m[j][i])
> > +        ret.append(_dot_ref([v,m_col]))
> > +    return ret
> > +
> > +def _mat_times_vec_ref(args):
> > +    m = args[0]
> > +    v = args[1]
> > +    m_type = glsl_type_of(m)
> > +    num_rows = m_type.num_rows
> > +    components = num_rows
> > +    ret = []
> > +    for i in range(components):
> > +        m_col = m[i]
> > +        ret.append(_dot_ref([v,m_col]))
> > +    return ret
> > +
> > +def _mat_times_mat_ref(args):
> > +    mx = args[0]
> > +    my = args[1]
> > +    mx_type = glsl_type_of(mx)
> > +    my_type = glsl_type_of(my)
> > +    ret = []
> > +    for i in range(mx_type.num_rows):
> > +        for j in range(my_type.num_cols):
> > +            my_col = []
> > +            for k in range(my_type.num_rows):
> > +                my_col.append(my[k][j])
> > +            ret.append(_dot_ref([mx[i],my_col]))
> > +    return ret
> > +
> >  def _capture_error(precise, imprecise):
> >      """Perform the legwork of calculating the difference in error of the
> > high
> >      precision and low precision runs.  Decide whether this difference in
> > error
> > @@ -156,7 +321,17 @@ simple_fns = {'op-mult': 0.0,
> >                'sqrt': 3.0,
> >                'inversesqrt': 2.0}
> >   -complex_fns = {}
> > +complex_fns = {'mod': _mod_ref,
> > +             'smoothstep': _smoothstep_ref,
> > +             'mix': _mix_ref,
> > +             'length': _length_ref,
> > +             'distance': _distance_ref,
> > +             'dot': _dot_ref,
> > +             'cross': _cross_ref,
> > +             'normalize': _normalize_ref,
> > +             'faceforward': _faceforward_ref,
> > +             'reflect': _reflect_ref,
> > +             'refract': _refract_ref}
> >   componentwise_fns = ('mod', 'mix', 'smoothstep' )
> >  -- 2.2.2
> >
> > _______________________________________________
> > Piglit mailing list
> > Piglit at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/piglit
> _______________________________________________
> Piglit mailing list
> Piglit at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/piglit
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.freedesktop.org/archives/piglit/attachments/20150220/b4b57a53/attachment.sig>


More information about the Piglit mailing list