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 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx