Add more allowed 'dot' alternatives
authorAlexander Galazin <alexander.galazin@arm.com>
Tue, 22 Aug 2017 13:59:49 +0000 (15:59 +0200)
committerAlexander Galazin <alexander.galazin@arm.com>
Sun, 3 Sep 2017 09:13:50 +0000 (11:13 +0200)
Expanded dot may be re-associated in multiple ways.
Add all possible alternatives to prevent precision failures.

Components: AOSP

VK-GL-CTS issue: 634
Google issue: 28767510

Affects:
dEQP-GLES3.functional.shaders.builtin_functions.precision.dot.*
dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.*
dEQP-GLES31.functional.shaders.builtin_functions.precision.dot.*
dEQP-GLES31.functional.shaders.builtin_functions.precision.reflect.*

Change-Id: I2a91add1b92363acab2172179320cd880da779ec

modules/glshared/glsBuiltinPrecisionTests.cpp

index da69f89..afe990b 100644 (file)
@@ -2924,12 +2924,32 @@ public:
 protected:
        ExprP<float>    doExpand        (ExpandContext&, const ArgExprs& args) const
        {
-               ExprP<float> val = args.a[0] * args.b[0];
+               ExprP<float> op[Size];
+               // Precompute all products.
+               for (int ndx = 0; ndx < Size; ++ndx)
+                       op[ndx] = args.a[ndx] * args.b[ndx];
 
-               for (int ndx = 1; ndx < Size; ++ndx)
-                       val = val + args.a[ndx] * args.b[ndx];
+               int idx[Size];
+               //Prepare an array of indices.
+               for (int ndx = 0; ndx < Size; ++ndx)
+                       idx[ndx] = ndx;
 
-               return val;
+               ExprP<float> res = op[0];
+               // Compute the first dot alternative: SUM(a[i]*b[i]), i = 0 .. Size-1
+               for (int ndx = 1; ndx < Size; ++ndx)
+                       res = res + op[ndx];
+
+               // Generate all permutations of indices and
+               // using a permutation compute a dot alternative.
+               // Generates all possible variants fo summation of products in the dot product expansion expression.
+               do {
+                       ExprP<float> alt = constant(0.0f);
+                       for (int ndx = 0; ndx < Size; ++ndx)
+                               alt = alt + op[idx[ndx]];
+                       res = alternatives(res, alt);
+               } while (std::next_permutation(idx, idx + Size));
+
+               return res;
        }
 };