Quoting Jason Ekstrand (2017-08-10 06:35:43) > This adds both trivial error-checking tests as well as more complex > tests which actually test whether or not waits do what they're supposed > to do. They only currently work on i915 but it should be simple to hook > them up for other drivers by simply implementing the little function > pointer hook provided at the top for triggering a syncobj. > > v2: > - Actually add the reset tests. > v3: > - Only do one execbuf for trigger > - Use do_ioctl and do_ioctl_err > - Better check for syncobj support > - Add local_/LOCAL_ defines of things > - Use a timer instead of a pthread > v4: > - Use ioctl wrappers > - Use VGEM instead of i915 > - Combine a bunch of the simple tests into one function > v5: > - Combinatorially generate basic tests > - Use sw_sync instead of using vgem directly Aye, sw_sync looks to be quite useful here - a completely driver agnostic method for signaling syncobj. Nice. > +static int > +syncobj_attach_sw_sync(int fd, uint32_t handle) > +{ > + struct drm_syncobj_handle; > + int timeline, fence; > + > + timeline = sw_sync_timeline_create(); > + fence = sw_sync_timeline_create_fence(timeline, 1); > + syncobj_import_sync_file(fd, handle, fence); > + close(fence); > + > + return timeline; > +} > + > +static void > +syncobj_trigger(int fd, uint32_t handle) > +{ > + int timeline = syncobj_attach_sw_sync(fd, handle); > + sw_sync_timeline_inc(timeline, 1); > +} > + > +struct delayed_trigger { > + int fd; > + uint32_t *syncobjs; > + int count; > + uint64_t nsec; > +}; > + > +static void > +trigger_syncobj_delayed_func(union sigval sigval) > +{ > + struct delayed_trigger *trigger = sigval.sival_ptr; > + int i; > + > + for (i = 0; i < trigger->count; i++) > + syncobj_trigger(trigger->fd, trigger->syncobjs[i]); > + free(trigger); > +} > + > +static timer_t > +trigger_syncobj_delayed(int fd, uint32_t *syncobjs, int count, uint64_t nsec) > +{ > + struct delayed_trigger *trigger; > + timer_t timer; > + struct sigevent sev; > + struct itimerspec its; > + > + trigger = malloc(sizeof(*trigger)); > + trigger->fd = fd; > + trigger->syncobjs = syncobjs; > + trigger->count = count; > + trigger->nsec = nsec; > + > + memset(&sev, 0, sizeof(sev)); > + sev.sigev_notify = SIGEV_THREAD; > + sev.sigev_value.sival_ptr = trigger; > + sev.sigev_notify_function = trigger_syncobj_delayed_func; > + igt_assert(timer_create(CLOCK_MONOTONIC, &sev, &timer) == 0); > + > + memset(&its, 0, sizeof(its)); > + its.it_value.tv_sec = nsec / NSEC_PER_SEC; > + its.it_value.tv_nsec = nsec % NSEC_PER_SEC; > + igt_assert(timer_settime(timer, 0, &its, NULL) == 0); > + > + return timer; > +} static void trigger_syncobj_delayed_func(union sigval sigval) { int timeline = (intptr_t)sigval.sival_ptr; sw_sync_timeline_inc(timeline, 1); close(timeline); } static timer_t trigger_syncobj_delayed(int fd, uint32_t *syncobjs, int count, uint64_t nsec) { struct itimerspec its; struct sigevent sev; int timeline, fence; timer_t timer; timeline = sw_sync_timeline_create(); fence = sw_sync_timeline_create_fence(timeline, 1); for (int i = 0; i < count; i++) syncobj_import_sync_file(fd, syncobjs[i], fence); close(fence); memset(&sev, 0, sizeof(sev)); sev.sigev_notify = SIGEV_THREAD; sev.sigev_value.sival_ptr = (intptr_t)timeline; sev.sigev_notify_function = trigger_syncobj_delayed_func; igt_assert(timer_create(CLOCK_MONOTONIC, &sev, &timer) == 0); memset(&its, 0, sizeof(its)); its.it_value.tv_sec = nsec / NSEC_PER_SEC; its.it_value.tv_nsec = nsec % NSEC_PER_SEC; igt_assert(timer_settime(timer, 0, &its, NULL) == 0); return timer; } _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx