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

Micah Fedke micah.fedke at collabora.co.uk
Wed Feb 18 22:06:46 PST 2015


---
  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))
+
+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):
+    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



More information about the Piglit mailing list