iris: Tag each submitted batch with a syncobj
authorChris Wilson <chris@chris-wilson.co.uk>
Fri, 9 Nov 2018 15:02:12 +0000 (15:02 +0000)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 21 Feb 2019 18:26:10 +0000 (10:26 -0800)
(adjusted by Ken to make the signalling sync object immediately on
batch reset, rather than batch finish time.  this will work better
with deferred flushes...)

src/gallium/drivers/iris/iris_batch.c
src/gallium/drivers/iris/iris_batch.h
src/gallium/drivers/iris/iris_fence.c [new file with mode: 0644]
src/gallium/drivers/iris/iris_fence.h [new file with mode: 0644]
src/gallium/drivers/iris/iris_screen.c
src/gallium/drivers/iris/meson.build

index 7367e6136e871bc68f4e08276048136824c458c8..04d71c0bff0a01761a40f4142b36d08f2fc39f91 100644 (file)
@@ -40,6 +40,7 @@
 #include "iris_batch.h"
 #include "iris_bufmgr.h"
 #include "iris_context.h"
+#include "iris_fence.h"
 
 #include "drm-uapi/i915_drm.h"
 
@@ -183,6 +184,7 @@ iris_init_batch(struct iris_batch *batch,
    assert(batch->hw_ctx_id);
 
    util_dynarray_init(&batch->exec_fences, ralloc_context(NULL));
+   util_dynarray_init(&batch->syncpts, ralloc_context(NULL));
 
    batch->exec_count = 0;
    batch->exec_array_size = 100;
@@ -345,6 +347,8 @@ create_batch(struct iris_batch *batch)
 static void
 iris_batch_reset(struct iris_batch *batch)
 {
+   struct iris_screen *screen = batch->screen;
+
    iris_bo_unreference(batch->bo);
    batch->primary_batch_size = 0;
    batch->contains_draw = false;
@@ -352,6 +356,10 @@ iris_batch_reset(struct iris_batch *batch)
    create_batch(batch);
    assert(batch->bo->index == 0);
 
+   struct iris_syncpt *syncpt = iris_create_syncpt(screen);
+   iris_batch_add_syncpt(batch, syncpt, I915_EXEC_FENCE_SIGNAL);
+   iris_syncpt_reference(screen, &syncpt, NULL);
+
    if (batch->state_sizes)
       _mesa_hash_table_clear(batch->state_sizes, NULL);
 
@@ -372,6 +380,10 @@ iris_batch_free(struct iris_batch *batch)
 
    ralloc_free(batch->exec_fences.mem_ctx);
 
+   util_dynarray_foreach(&batch->syncpts, struct iris_syncpt *, s)
+      iris_syncpt_reference(screen, s, NULL);
+   ralloc_free(batch->syncpts.mem_ctx);
+
    iris_bo_unreference(batch->bo);
    batch->bo = NULL;
    batch->map = NULL;
@@ -517,6 +529,8 @@ submit_batch(struct iris_batch *batch)
 void
 _iris_batch_flush(struct iris_batch *batch, const char *file, int line)
 {
+   struct iris_screen *screen = batch->screen;
+
    if (iris_batch_bytes_used(batch) == 0)
       return;
 
@@ -566,6 +580,10 @@ _iris_batch_flush(struct iris_batch *batch, const char *file, int line)
    batch->exec_count = 0;
    batch->aperture_space = 0;
 
+   util_dynarray_foreach(&batch->syncpts, struct iris_syncpt *, s)
+      iris_syncpt_reference(screen, s, NULL);
+   util_dynarray_clear(&batch->syncpts);
+
    util_dynarray_clear(&batch->exec_fences);
 
    /* Start a new batch buffer. */
index 73d02b573a40711c8ee53c86b3d51640fffe223a..daa57fce6b5376a9f6e33c0443128c050fada5ea 100644 (file)
@@ -76,6 +76,15 @@ struct iris_batch {
    int exec_count;
    int exec_array_size;
 
+   /**
+    * A list of iris_syncpts associated with this batch.
+    *
+    * The first list entry will always be a signalling sync-point, indicating
+    * that this batch has completed.  The others are likely to be sync-points
+    * to wait on before executing the batch.
+    */
+   struct util_dynarray syncpts;
+
    /** A list of drm_i915_exec_fences to have execbuf signal or wait on */
    struct util_dynarray exec_fences;
 
diff --git a/src/gallium/drivers/iris/iris_fence.c b/src/gallium/drivers/iris/iris_fence.c
new file mode 100644 (file)
index 0000000..b39c597
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright © 2018 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file iris_fence.c
+ *
+ * Fences for driver and IPC serialisation, scheduling and synchronisation.
+ */
+
+#include "util/u_inlines.h"
+
+#include "iris_batch.h"
+#include "iris_bufmgr.h"
+#include "iris_fence.h"
+#include "iris_screen.h"
+
+static uint32_t
+gem_syncobj_create(int fd, uint32_t flags)
+{
+   struct drm_syncobj_create args = {
+      .flags = flags,
+   };
+
+   drm_ioctl(fd, DRM_IOCTL_SYNCOBJ_CREATE, &args);
+
+   return args.handle;
+}
+
+static void
+gem_syncobj_destroy(int fd, uint32_t handle)
+{
+   struct drm_syncobj_destroy args = {
+      .handle = handle,
+   };
+
+   drm_ioctl(fd, DRM_IOCTL_SYNCOBJ_DESTROY, &args);
+}
+
+/**
+ * Make a new sync-point.
+ */
+struct iris_syncpt *
+iris_create_syncpt(struct iris_screen *screen)
+{
+   struct iris_syncpt *syncpt = malloc(sizeof(*syncpt));
+
+   if (!syncpt)
+      return NULL;
+
+   syncpt->handle = gem_syncobj_create(screen->fd, 0);
+   assert(syncpt->handle);
+
+   pipe_reference_init(&syncpt->ref, 1);
+
+   return syncpt;
+}
+
+void
+iris_syncpt_destroy(struct iris_screen *screen, struct iris_syncpt *syncpt)
+{
+   gem_syncobj_destroy(screen->fd, syncpt->handle);
+   free(syncpt);
+}
+
+/**
+ * Add a sync-point to the batch, with the given flags.
+ *
+ * \p flags   One of I915_EXEC_FENCE_WAIT or I915_EXEC_FENCE_SIGNAL.
+ */
+void
+iris_batch_add_syncpt(struct iris_batch *batch,
+                      struct iris_syncpt *syncpt,
+                      unsigned flags)
+{
+   struct drm_i915_gem_exec_fence *fence =
+      util_dynarray_grow(&batch->exec_fences, sizeof(*fence));
+
+   *fence = (struct drm_i915_gem_exec_fence) {
+      .handle = syncpt->handle,
+      .flags = flags,
+   };
+
+   struct iris_syncpt **store =
+      util_dynarray_grow(&batch->syncpts, sizeof(*store));
+
+   *store = NULL;
+   iris_syncpt_reference(batch->screen, store, syncpt);
+}
diff --git a/src/gallium/drivers/iris/iris_fence.h b/src/gallium/drivers/iris/iris_fence.h
new file mode 100644 (file)
index 0000000..0101ce0
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright © 2018 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef IRIS_FENCE_H
+#define IRIS_FENCE_H
+
+#include "util/u_inlines.h"
+
+struct pipe_screen;
+
+struct iris_syncpt {
+   struct pipe_reference ref;
+   uint32_t handle;
+};
+
+struct iris_syncpt *iris_create_syncpt(struct iris_screen *screen);
+void iris_syncpt_destroy(struct iris_screen *, struct iris_syncpt *);
+void iris_batch_add_syncpt(struct iris_batch *batch,
+                           struct iris_syncpt *syncpt,
+                           unsigned flags);
+
+static inline void
+iris_syncpt_reference(struct iris_screen *screen,
+                      struct iris_syncpt **dst,
+                      struct iris_syncpt *src)
+{
+   if (pipe_reference(&(*dst)->ref, &src->ref))
+      iris_syncpt_destroy(screen, *dst);
+
+   *dst = src;
+}
+
+#endif
index 48d08c6f33d2c075c327b263199991d44eafe0c5..f85b66ce50f522296efde208d6f5f5be1f1a6c5a 100644 (file)
@@ -44,6 +44,7 @@
 #include "drm-uapi/i915_drm.h"
 #include "iris_context.h"
 #include "iris_defines.h"
+#include "iris_fence.h"
 #include "iris_pipe.h"
 #include "iris_resource.h"
 #include "iris_screen.h"
index cb5e5eee04328b0de786cf714041c725195b5c35..62fda80d669c47903960f53ced053bf359788126 100644 (file)
@@ -31,6 +31,8 @@ files_libiris = files(
   'iris_context.c',
   'iris_context.h',
   'iris_draw.c',
+  'iris_fence.c',
+  'iris_fence.h',
   'iris_formats.c',
   'iris_pipe.h',
   'iris_pipe_control.c',