[Piglit] [PATCH v2 4/7] egl-context-preemption: check that preemption actually happened.
Rafael Antognolli
rafael.antognolli at intel.com
Mon Oct 29 17:16:32 UTC 2018
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
More information about the Piglit
mailing list