lowlevel-blt-bench: horizontal/vertical variants of bilinear scaling

Submitted by Siarhei Siamashka on April 5, 2016, 10:20 a.m.

Details

Message ID 1459851652-5933-1-git-send-email-siarhei.siamashka@gmail.com
State New
Series "lowlevel-blt-bench: horizontal/vertical variants of bilinear scaling"
Headers show

Commit Message

Siarhei Siamashka April 5, 2016, 10:20 a.m.
This patch adds the 'v' and 'h' modifiers to the command line
parsing logic, which can be used together with the '-b' option.
They enforce vertical-only or horizontal-only special cases of
interpolation when running the bilinear scaling benchmark.

The optimized implementations may have special shortcuts for
doing only vertical or only horizontal scaling. This change
allows to do benchmarking for these code paths.

Also instead of just a minimal nudge to the x-axis scaling
coefficient, apply a more sizeable nudge to the x- or y-axis
translation coefficients. With the older matrix variant, a
clever hack in the optimized code could be able to deduct
that the matrix is in fact indistinguishable from the
identity tranformation. Which would be an undesired effect
and an opportunity to 'rig' benchmark scores.

Signed-off-by: Siarhei Siamashka <siarhei.siamashka@gmail.com>
---
 test/lowlevel-blt-bench.c | 67 ++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 57 insertions(+), 10 deletions(-)

Patch hide | download patch | download mbox

diff --git a/test/lowlevel-blt-bench.c b/test/lowlevel-blt-bench.c
index 28ff669..380937b 100644
--- a/test/lowlevel-blt-bench.c
+++ b/test/lowlevel-blt-bench.c
@@ -89,19 +89,49 @@  bench_memcpy ()
 }
 
 static pixman_bool_t use_scaling = FALSE;
+static const char *scaling_descr = "unknown";
 static pixman_filter_t filter = PIXMAN_FILTER_NEAREST;
 static pixman_bool_t use_csv_output = FALSE;
 
-/* nearly 1x scale factor */
-static pixman_transform_t m =
+/*
+ * Some small constant, which is still significant enough to make
+ * the transformation matrix look sufficiently distinct from the
+ * identity matrix even with 4-bit bilinear interpolation accuracy.
+ */
+#define MATRIX_NUDGE_CONST (pixman_fixed_1 / 13)
+
+/* nearly identity matrix (interpolate in both directions) */
+static pixman_transform_t m_vh =
+{
+    {
+        { pixman_fixed_1, 0,              MATRIX_NUDGE_CONST },
+        { 0,              pixman_fixed_1, MATRIX_NUDGE_CONST },
+        { 0,              0,              pixman_fixed_1 }
+    }
+};
+
+/* nearly identity matrix (only interpolate in horizontal direction) */
+static pixman_transform_t m_h =
 {
     {
-        { pixman_fixed_1 + 1, 0,              0              },
-        { 0,                  pixman_fixed_1, 0              },
-        { 0,                  0,              pixman_fixed_1 }
+        { pixman_fixed_1, 0,              MATRIX_NUDGE_CONST },
+        { 0,              pixman_fixed_1, 0                  },
+        { 0,              0,              pixman_fixed_1     }
     }
 };
 
+/* nearly identity matrix (only interpolate in vertical direction) */
+static pixman_transform_t m_v =
+{
+    {
+        { pixman_fixed_1, 0,              0                  },
+        { 0,              pixman_fixed_1, MATRIX_NUDGE_CONST },
+        { 0,              0,              pixman_fixed_1 }
+    }
+};
+
+static pixman_transform_t m;
+
 static void
 pixman_image_composite_wrapper (pixman_implementation_t *impl,
 				pixman_composite_info_t *info)
@@ -1073,7 +1103,7 @@  print_speed_scaling (double bw)
     {
 	printf ("---\n");
 	if (filter == PIXMAN_FILTER_BILINEAR)
-	    printf ("BILINEAR scaling\n");
+	    printf ("BILINEAR scaling (%s)\n", scaling_descr);
 	else if (filter == PIXMAN_FILTER_NEAREST)
 	    printf ("NEAREST scaling\n");
 	else
@@ -1086,10 +1116,12 @@  print_speed_scaling (double bw)
 static void
 usage (const char *progname)
 {
-    printf ("Usage: %s [-b] [-n] [-c] [-m M] pattern\n", progname);
-    printf ("  -n : benchmark nearest scaling\n");
-    printf ("  -b : benchmark bilinear scaling\n");
-    printf ("  -c : print output as CSV data\n");
+    printf ("Usage: %s [-b|-bv|-bh] [-n] [-c] [-m M] pattern\n", progname);
+    printf ("  -n   : benchmark nearest scaling\n");
+    printf ("  -b   : benchmark bilinear scaling\n");
+    printf ("  -bv  : only vertical interpolation (a modifier for bilinear scaling)\n");
+    printf ("  -bh  : only horizontal interpolation (a modifier for bilinear scaling)\n");
+    printf ("  -c   : print output as CSV data\n");
     printf ("  -m M : set reference memcpy speed to M MB/s instead of measuring it\n");
 }
 
@@ -1107,11 +1139,26 @@  main (int argc, char *argv[])
 	    {
 		use_scaling = TRUE;
 		filter = PIXMAN_FILTER_BILINEAR;
+		m = m_vh;
+		scaling_descr = "both horizontal and vertical";
+		if (strchr (argv[i] + 1, 'v') &&
+		    !strchr (argv[i] + 1, 'h'))
+		{
+			m = m_v;
+			scaling_descr = "vertical only";
+		}
+		else if (strchr (argv[i] + 1, 'h') &&
+		         !strchr (argv[i] + 1, 'v'))
+		{
+			m = m_h;
+			scaling_descr = "horizontal only";
+		}
 	    }
 	    else if (strchr (argv[i] + 1, 'n'))
 	    {
 		use_scaling = TRUE;
 		filter = PIXMAN_FILTER_NEAREST;
+		m = m_vh;
 	    }
 
 	    if (strchr (argv[i] + 1, 'c'))