[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