After both the main and the high priority threads have finished, check
their render timestamps to try to figure out if preemption has kicked
in.
---
 tests/egl/egl-context-preemption.c | 88 ++++++++++++++++++++++++++++++
 1 file changed, 88 insertions(+)

diff --git a/tests/egl/egl-context-preemption.c 
b/tests/egl/egl-context-preemption.c
index 8f0245e49..e9180d4ee 100644
--- a/tests/egl/egl-context-preemption.c
+++ b/tests/egl/egl-context-preemption.c
@@ -263,6 +263,36 @@ init_other_display(EGLDisplay *out_other_dpy)
        return result;
 }
 
+/* Return the time difference between t1 and t2, taking into account wrapping
+ * around 'nbits'.
+ *
+ * Note: this function only works if the time difference is up to
+ * 1 << (nbits - 1).
+ */
+static int64_t
+time_diff(int64_t t1, int64_t t2, int nbits)
+{
+       const int64_t max_delta = 1ULL << (nbits - 1);
+       const int64_t bitmask = (1ULL << nbits) - 1;
+       const int64_t diff = t1 - t2;
+       const bool wrapped = llabs(t1 - t2) > max_delta;
+
+       /* First find out which one came first
+        *  diff < 0 -- if t1 < t2
+        *  diff == 0  -- if t1 == t2
+        *  diff > 0 -- if t1 > t2
+        */
+       const int64_t diff_wrap = wrapped ? -diff : diff;
+
+       /* Then calculate the difference between them, taking overflow into
+        * account
+        */
+       if (diff_wrap > 0)
+               return (t1 - t2) & bitmask;
+       else
+               return -((t2 - t1) & bitmask);
+}
+
 static enum piglit_result
 setup_thread_context(struct test_data *d)
 {
@@ -510,6 +540,9 @@ test_preemption(void *data)
                goto cleanup;
        }
 
+       GLint nbits;
+       glGetQueryiv(GL_TIMESTAMP, GL_QUERY_COUNTER_BITS, &nbits);
+
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
 
        err = pthread_join(thread2, NULL);
@@ -519,6 +552,61 @@ test_preemption(void *data)
                goto cleanup;
        }
 
+       /* In this loop we are only looking for the first high priority render
+        * that started after the main workload. In theory the first one should
+        * already start after the main, but we run this loop just to confirm
+        * that assumption.
+        */
+       int first_run = -1;
+       for (int i = 0; i < d.nruns; i++) {
+               if (time_diff(d.tstarted[i], d.main_tstarted, nbits) > 0) {
+                       first_run = i;
+                       break;
+               }
+       }
+
+       if (first_run < 0) {
+               piglit_loge("Something went wrong, all high priority workloads"
+                           " started before the main workload.");
+               result = PIGLIT_FAIL;
+               goto cleanup;
+       }
+
+       /* If mid-command preemption is enabled, the first workload to start
+        * after the main workload should finish first.
+        */
+       if (time_diff(d.tfinished[first_run], d.main_tfinished, nbits) >= 0) {
+               piglit_loge("First preemption failed.");
+               result = PIGLIT_FAIL;
+               goto cleanup;
+       }
+
+       int second_run = first_run + 1;
+       if (second_run >= d.nruns) {
+               piglit_loge("The first run to start after the main draw was"
+                           " also the last one, so we can't check the second"
+                           " run time.");
+               piglit_loge("First run: %d, second run: %d, nruns: %d",
+                           first_run, second_run, d.nruns);
+               result = PIGLIT_WARN;
+       }
+
+       /* On i965, it looks like even if mid-command preemption is not
+        * supported/enabled, it might report that the first high priority
+        * render finished before the main render. So we check the timing of
+        * the second high priority render too, which should also finish
+        * earlier than the main render, if mid-command preemption is enabled.
+        */
+       if (time_diff(d.tfinished[second_run], d.main_tfinished, nbits) >= 0) {
+               piglit_loge("Second preemption failed.");
+               result = PIGLIT_FAIL;
+               goto cleanup;
+       }
+
+       /* TODO: Calculate the time to run each of the high priority workloads,
+        * and print the average latency.
+        */
+
 cleanup:
        free(ref_image);
        return result;
-- 
2.19.1

_______________________________________________
Piglit mailing list
Piglit@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/piglit

Reply via email to