Verify that the rendering done by the high priority thread was also correct by rendering a reference image at the beginning. --- tests/egl/egl-context-preemption.c | 75 +++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-)
diff --git a/tests/egl/egl-context-preemption.c b/tests/egl/egl-context-preemption.c index 26ead9d58..b5be67677 100644 --- a/tests/egl/egl-context-preemption.c +++ b/tests/egl/egl-context-preemption.c @@ -52,6 +52,7 @@ struct test_data { EGLDisplay dpy; EGLContext ctx; const struct test_profile *p; + float *ref_image; }; struct test_profile { @@ -448,6 +449,16 @@ thread2_create_high_priority_context(void *data) draw_high_priority(d, program, i); } + /* check that the rendering was correct */ + bool pass = true; + for (int i = 0; i < d->nruns; i++) { + glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[i]); + pass = pass && piglit_probe_image_rgba(0, 0, hp_width, hp_height, + d->ref_image); + } + + *result = pass ? PIGLIT_PASS : PIGLIT_FAIL; + if (d->ctx != EGL_NO_CONTEXT) eglDestroyContext(d->dpy, d->ctx); if (!d->p->same_display) @@ -484,6 +495,39 @@ read_pixels_float(GLint x, GLint y, GLsizei width, GLsizei height, return pixels; } +static void* +thread_create_ref_image(void *data) +{ + enum piglit_result *result = malloc(sizeof(*result)); + struct test_data *d = data; + + *result = setup_thread_context(d); + if (*result != PIGLIT_PASS) + return result; + + GLuint fbo; + GLuint texColorBuffer; + setup_render_target(&fbo, &texColorBuffer, 1, hp_width, hp_height); + + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + unsigned int program = setup_shaders(); + + draw_objects(program, GL_TRIANGLES, triangle_vertices, + sizeof(triangle_vertices), 1); + glFinish(); + + d->ref_image = read_pixels_float(0, 0, hp_width, hp_height, + GL_RGBA, NULL); + + if (d->ctx != EGL_NO_CONTEXT) + eglDestroyContext(d->dpy, d->ctx); + if (!d->p->same_display) + eglTerminate(d->dpy); + + return result; +} + static enum piglit_result test_preemption(void *data) { @@ -496,6 +540,29 @@ test_preemption(void *data) }; d.dpy = eglGetCurrentDisplay(); + pthread_t thread1; + int err = pthread_create( + &thread1, NULL, + thread_create_ref_image, + &d); + if (err) { + piglit_loge("failed to create ref image thread"); + result = PIGLIT_FAIL; + goto cleanup; + } + + void *retval = NULL; + err = pthread_join(thread1, &retval); + if (err) { + piglit_loge("failed to join thread %"PRIuMAX, (uintmax_t) thread1); + result = PIGLIT_FAIL; + goto cleanup; + } + + result = *((enum piglit_result *)retval); + if (result != PIGLIT_PASS) + goto cleanup; + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, piglit_winsys_fbo); if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) @@ -533,7 +600,7 @@ test_preemption(void *data) /* Start second thread with high priority */ pthread_t thread2; - int err = pthread_create( + err = pthread_create( &thread2, NULL, thread2_create_high_priority_context, &d); @@ -559,12 +626,16 @@ test_preemption(void *data) glBindFramebuffer(GL_FRAMEBUFFER, 0); - err = pthread_join(thread2, NULL); + err = pthread_join(thread2, &retval); if (err) { piglit_loge("failed to join thread %"PRIuMAX, (uintmax_t) thread2); result = PIGLIT_FAIL; goto cleanup; } + result = *((enum piglit_result *)retval); + if (result != PIGLIT_PASS) + 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 -- 2.19.0 _______________________________________________ Piglit mailing list Piglit@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/piglit