Add tests to catch rounding bug of IntrinsicConvolve

 -For MR1, relax the constraint for NEON.

bug 18121051

Change-Id: I7e79600673c7fff06b1ea0398ac12aad0d240222
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicConvolve3x3.java b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicConvolve3x3.java
index 1880132..8faeb22 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicConvolve3x3.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicConvolve3x3.java
@@ -24,11 +24,17 @@
         float cf1[] = {0.f, 0.f, 0.f,  0.f, 1.f, 0.f,  0.f, 0.f, 0.f};
         float cf2[] = {0.f, -1.f, 0.f,  -1.f, 5.f, -1.f,  0.f, -1.f, 0.f};
 
+        float irCoeff1 = 3.1415927f;
+        float irCoeff2 = -irCoeff1;
+        float cf3[] = {0.f, irCoeff1, 0.f,  irCoeff2, 1.f, irCoeff2,  0.f, irCoeff1, 0.f};
+
         Element e = makeElement(dt, vecSize);
 
         System.gc();
         makeBuffers(w, h, e);
 
+        mVerify.set_gAllowedIntError(1);
+
         ScriptIntrinsicConvolve3x3 si = ScriptIntrinsicConvolve3x3.create(mRS, e);
         si.setCoefficients(cf1);
         si.setInput(mAllocSrc);
@@ -116,6 +122,44 @@
         }
         //android.util.Log.e("RSI test", "test convolve U8_" + vecSize + " 2 " + w + ", " + h);
         mVerify.invoke_verify(mAllocRef, mAllocDst, mAllocSrc);
+
+        si.setCoefficients(cf3);
+        sr.set_gCoeffs(cf3);
+        si.forEach(mAllocRef, sc);
+        if (dt == Element.DataType.UNSIGNED_8) {
+            switch(vecSize) {
+            case 4:
+                sr.forEach_convolve_U4(mAllocDst, sc);
+                break;
+            case 3:
+                sr.forEach_convolve_U3(mAllocDst, sc);
+                break;
+            case 2:
+                sr.forEach_convolve_U2(mAllocDst, sc);
+                break;
+            case 1:
+                sr.forEach_convolve_U1(mAllocDst, sc);
+                break;
+            }
+        } else {
+            switch(vecSize) {
+            case 4:
+                sr.forEach_convolve_F4(mAllocDst, sc);
+                break;
+            case 3:
+                sr.forEach_convolve_F3(mAllocDst, sc);
+                break;
+            case 2:
+                sr.forEach_convolve_F2(mAllocDst, sc);
+                break;
+            case 1:
+                sr.forEach_convolve_F1(mAllocDst, sc);
+                break;
+            }
+        }
+        //android.util.Log.e("RSI test", "test convolve U8_" + vecSize + " 2 " + w + ", " + h);
+        mVerify.invoke_verify(mAllocRef, mAllocDst, mAllocSrc);
+
         mRS.finish();
     }
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicConvolve5x5.java b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicConvolve5x5.java
index ee92651..0753c62 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicConvolve5x5.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicConvolve5x5.java
@@ -85,13 +85,24 @@
                        -1.f,  0.f,  0.f,  0.f, -1.f,
                        -1.f, -1.f, -1.f, -1.f, -1.f};
 
+        float irCoeff1 = 3.1415927f;
+        float irCoeff2 = -irCoeff1;
+        float cf3[] = {irCoeff1, -1.f, -1.f, -1.f, irCoeff2,
+                       irCoeff1,  0.f,  0.f,  0.f, irCoeff2,
+                       irCoeff1,  0.f,  7.f,  0.f, irCoeff2,
+                       irCoeff1,  0.f,  0.f,  0.f, irCoeff2,
+                       irCoeff1, -1.f, -1.f, -1.f, irCoeff2};
+
         Element e = makeElement(dt, vecSize);
         makeBuffers(w, h, e);
 
+        mVerify.set_gAllowedIntError(1);
+
         ScriptIntrinsicConvolve5x5 si = ScriptIntrinsicConvolve5x5.create(mRS, e);
         ScriptC_intrinsic_convolve5x5 sr = new ScriptC_intrinsic_convolve5x5(mRS);
         test5(sr, si, e, cf1, "test convolve", 1, w, h, sc);
         test5(sr, si, e, cf2, "test convolve", 2, w, h, sc);
+        test5(sr, si, e, cf3, "test convolve", 3, w, h, sc);
     }
 
     public void test_U8_4() {
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/intrinsic_convolve5x5.rs b/tests/tests/renderscript/src/android/renderscript/cts/intrinsic_convolve5x5.rs
index 9f9aa2b..966dbdd 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/intrinsic_convolve5x5.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/intrinsic_convolve5x5.rs
@@ -66,7 +66,7 @@
               + convert_float4(rsGetElementAt_uchar4(gIn, x3, y4)) * gCoeffs[23]
               + convert_float4(rsGetElementAt_uchar4(gIn, x4, y4)) * gCoeffs[24];
 
-    p0 = clamp(p0 + p1 + p2 + p3 + p4, 0.f, 255.f);
+    p0 = clamp(p0 + p1 + p2 + p3 + p4 + 0.5f, 0.f, 255.f);
     return convert_uchar4(p0);
 }
 
@@ -113,7 +113,7 @@
               + convert_float3(rsGetElementAt_uchar3(gIn, x3, y4)) * gCoeffs[23]
               + convert_float3(rsGetElementAt_uchar3(gIn, x4, y4)) * gCoeffs[24];
 
-    p0 = clamp(p0 + p1 + p2 + p3 + p4, 0.f, 255.f);
+    p0 = clamp(p0 + p1 + p2 + p3 + p4 + 0.5f, 0.f, 255.f);
     return convert_uchar3(p0);
 }
 
@@ -160,7 +160,7 @@
               + convert_float2(rsGetElementAt_uchar2(gIn, x3, y4)) * gCoeffs[23]
               + convert_float2(rsGetElementAt_uchar2(gIn, x4, y4)) * gCoeffs[24];
 
-    p0 = clamp(p0 + p1 + p2 + p3 + p4, 0.f, 255.f);
+    p0 = clamp(p0 + p1 + p2 + p3 + p4 + 0.5f, 0.f, 255.f);
     return convert_uchar2(p0);
 }
 
@@ -207,7 +207,7 @@
              + (float)(rsGetElementAt_uchar(gIn, x3, y4)) * gCoeffs[23]
              + (float)(rsGetElementAt_uchar(gIn, x4, y4)) * gCoeffs[24];
 
-    return clamp(p0 + p1 + p2 + p3 + p4, 0.f, 255.f);
+    return clamp(p0 + p1 + p2 + p3 + p4 + 0.5f, 0.f, 255.f);
 }
 
 float4 __attribute__((kernel)) convolve_F4(uint32_t x, uint32_t y) {