[Intel-gfx] Wait-for-submit on future syncobj

Chris Wilson chris at chris-wilson.co.uk
Mon May 4 13:50:24 UTC 2020


This series extends the I915_EXEC_FENCE_SUBMIT to syncobj; with the
primary motivation for this to allow userspace to schedule between
individual clients coordinating with semaphores. The advantage syncobj
have over sync-file is that since the syncobj is known a priori, it can
be used to pass the location of a not-yet-submitted fence. This is used
by iris in its deferred flush implementations where a fence is acquired
for an incomplete batch, and that future-fence may be used to
serlisation execution in another context. Since we already handle
'bonded execution' for media submission, we need only extend support to
syncobjs.

A simplified example of out-of-order execution that is required by iris:

        struct drm_i915_gem_exec_object2 obj = {
                .offset = 24 << 20,
                .handle = future_submit_batch(i915, 24 << 20),
                .flags = EXEC_OBJECT_PINNED,
        };
        struct drm_i915_gem_exec_fence fence = {
                .handle = syncobj_create(i915, 0),
        };
        struct drm_i915_gem_execbuffer2 execbuf  = {
                .buffers_ptr = to_user_pointer(&obj),
                .buffer_count = 1,
                .cliprects_ptr = to_user_pointer(&fence),
                .num_cliprects = 1,
                .flags = engine | I915_EXEC_FENCE_ARRAY,
        };
        uint32_t result;
        int out;

        /*
         * Here we submit client A waiting on client B, but internally client
         * B has a semaphore that waits on client A. This relies on timeslicing
         * to reorder B before A, even though userspace has asked to submit
         * A & B simultaneously (and due to the sequence we will submit B
         * then A).
         */
        igt_require(gem_scheduler_has_timeslicing(i915));

        execbuf.rsvd1 = gem_context_create(i915);
        fence.flags = I915_EXEC_FENCE_WAIT | I915_EXEC_FENCE_WAIT_SUBMIT;
        execbuf.batch_start_offset = 0;
        execbuf.flags |= I915_EXEC_FENCE_OUT;
        igt_require(__gem_execbuf_wr(i915, &execbuf) == 0); /* writes 1 */
        execbuf.flags &= ~I915_EXEC_FENCE_OUT;
        gem_context_destroy(i915, execbuf.rsvd1);

        execbuf.rsvd1 = gem_context_create(i915);
        fence.flags = I915_EXEC_FENCE_SIGNAL;
        execbuf.batch_start_offset = 64;
        gem_execbuf(i915, &execbuf); /* writes 2 */
        gem_context_destroy(i915, execbuf.rsvd1);

        gem_sync(i915, obj.handle); /* write hazard lies */
        gem_read(i915, obj.handle, 4000, &result, sizeof(result));
        igt_assert_eq(result, 2);

        /* check we didn't autotimeout */
        out = execbuf.rsvd2 >> 32;
        igt_assert_eq(sync_fence_status(out), 1);
        close(out);

        gem_close(i915, obj.handle);
        syncobj_destroy(i915, fence.handle);


Link: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3802
Link: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4854





More information about the Intel-gfx mailing list