drm: Branch 'master' - 4 commits

[email protected] (GitLab Mirror) Mon, 30 Jul 2018 16:19:36 +0000 (UTC)
Newsgroups gmane.comp.video.dri.patches
Message-ID <[email protected]>
 freedreno/freedreno-symbol-check |    2 
 freedreno/freedreno_priv.h       |    7 +-
 freedreno/freedreno_ringbuffer.c |   45 ++++++++++++-
 freedreno/freedreno_ringbuffer.h |    9 ++
 freedreno/kgsl/kgsl_priv.h       |    2 
 freedreno/kgsl/kgsl_ringbuffer.c |    4 -
 freedreno/msm/msm_priv.h         |   28 +++++++-
 freedreno/msm/msm_ringbuffer.c   |  133 +++++++++++++++++++++++++++------------
 8 files changed, 181 insertions(+), 49 deletions(-)

New commits:
commit 716ab859c3f250601fbeb878b0849954cc6139f0
Author: Rob Clark <[email protected]>
Date:   Mon Jul 23 10:46:12 2018 -0400

    freedreno/msm: "stateobj" support
    
    Adds support for "state object" cmdstream buffers which can be
    constructed once, and re-used many times.  This enables the use
    for CP_SET_DRAW_STATE packets on newer hardware, to lower the
    CPU overhead.
    
    Signed-off-by: Rob Clark <[email protected]>

diff --git a/freedreno/freedreno_ringbuffer.c b/freedreno/freedreno_ringbuffer.c
index a0be2dbb..eb6cd0ca 100644
--- a/freedreno/freedreno_ringbuffer.c
+++ b/freedreno/freedreno_ringbuffer.c
@@ -71,7 +71,8 @@ fd_ringbuffer_new_object(struct fd_pipe *pipe, uint32_t size)
 
 void fd_ringbuffer_del(struct fd_ringbuffer *ring)
 {
-	fd_ringbuffer_reset(ring);
+	if (!(ring->flags & FD_RINGBUFFER_OBJECT))
+		fd_ringbuffer_reset(ring);
 	ring->funcs->destroy(ring);
 }
 
diff --git a/freedreno/msm/msm_ringbuffer.c b/freedreno/msm/msm_ringbuffer.c
index 156c23c6..ec4b30fe 100644
--- a/freedreno/msm/msm_ringbuffer.c
+++ b/freedreno/msm/msm_ringbuffer.c
@@ -50,6 +50,8 @@ struct msm_cmd {
 struct msm_ringbuffer {
 	struct fd_ringbuffer base;
 
+	atomic_t refcnt;
+
 	/* submit ioctl related tables:
 	 * Note that bos and cmds are tracked by the parent ringbuffer, since
 	 * that is global to the submit ioctl call.  The reloc's table is tracked
@@ -95,6 +97,9 @@ static inline struct msm_ringbuffer * to_msm_ringbuffer(struct fd_ringbuffer *x)
 	return (struct msm_ringbuffer *)x;
 }
 
+static void msm_ringbuffer_unref(struct fd_ringbuffer *ring);
+static void msm_ringbuffer_ref(struct fd_ringbuffer *ring);
+
 #define INIT_SIZE 0x1000
 
 static pthread_mutex_t idx_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -307,6 +312,8 @@ static void flush_reset(struct fd_ringbuffer *ring)
 	/* for each of the cmd buffers, clear their reloc's: */
 	for (i = 0; i < msm_ring->submit.nr_cmds; i++) {
 		struct msm_cmd *target_cmd = msm_ring->cmds[i];
+		if (target_cmd->ring->flags & FD_RINGBUFFER_OBJECT)
+			continue;
 		target_cmd->nr_relocs = 0;
 	}
 
@@ -369,6 +376,31 @@ static void dump_submit(struct msm_ringbuffer *msm_ring)
 	}
 }
 
+static struct drm_msm_gem_submit_reloc *
+handle_stateobj_relocs(struct fd_ringbuffer *parent, struct fd_ringbuffer *stateobj,
+		struct drm_msm_gem_submit_reloc *orig_relocs, unsigned nr_relocs)
+{
+	struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(stateobj);
+	struct drm_msm_gem_submit_reloc *relocs = malloc(nr_relocs * sizeof(*relocs));
+	unsigned i;
+
+	for (i = 0; i < nr_relocs; i++) {
+		unsigned idx = orig_relocs[i].reloc_idx;
+		struct fd_bo *bo = msm_ring->bos[idx];
+		unsigned flags = 0;
+
+		if (msm_ring->submit.bos[idx].flags & MSM_SUBMIT_BO_READ)
+			flags |= FD_RELOC_READ;
+		if (msm_ring->submit.bos[idx].flags & MSM_SUBMIT_BO_WRITE)
+			flags |= FD_RELOC_WRITE;
+
+		relocs[i] = orig_relocs[i];
+		relocs[i].reloc_idx = bo2idx(parent, bo, flags);
+	}
+
+	return relocs;
+}
+
 static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start,
 		int in_fence_fd, int *out_fence_fd)
 {
@@ -380,6 +412,8 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
 	uint32_t i;
 	int ret;
 
+	assert(!ring->parent);
+
 	if (in_fence_fd != -1) {
 		req.flags |= MSM_SUBMIT_FENCE_FD_IN | MSM_SUBMIT_NO_IMPLICIT;
 		req.fence_fd = in_fence_fd;
@@ -397,8 +431,22 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
 		struct msm_cmd *msm_cmd = msm_ring->cmds[i];
 		uint32_t a = find_next_reloc_idx(msm_cmd, 0, cmd->submit_offset);
 		uint32_t b = find_next_reloc_idx(msm_cmd, a, cmd->submit_offset + cmd->size);
-		cmd->relocs = VOID2U64(&msm_cmd->relocs[a]);
-		cmd->nr_relocs = (b > a) ? b - a : 0;
+		struct drm_msm_gem_submit_reloc *relocs = &msm_cmd->relocs[a];
+		unsigned nr_relocs = (b > a) ? b - a : 0;
+
+		/* for reusable stateobjs, the reloc table has reloc_idx that
+		 * points into it's own private bos table, rather than the global
+		 * bos table used for the submit, so we need to add the stateobj's
+		 * bos to the global table and construct new relocs table with
+		 * corresponding reloc_idx
+		 */
+		if (msm_cmd->ring->flags & FD_RINGBUFFER_OBJECT) {
+			relocs = handle_stateobj_relocs(ring, msm_cmd->ring,
+					relocs, nr_relocs);
+		}
+
+		cmd->relocs = VOID2U64(relocs);
+		cmd->nr_relocs = nr_relocs;
 	}
 
 	/* needs to be after get_cmd() as that could create bos/cmds table: */
@@ -426,6 +474,16 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
 		}
 	}
 
+	/* free dynamically constructed stateobj relocs tables: */
+	for (i = 0; i < msm_ring->submit.nr_cmds; i++) {
+		struct drm_msm_gem_submit_cmd *cmd = &msm_ring->submit.cmds[i];
+		struct msm_cmd *msm_cmd = msm_ring->cmds[i];
+		if (msm_cmd->ring->flags & FD_RINGBUFFER_OBJECT) {
+			msm_ringbuffer_unref(msm_cmd->ring);
+			free(U642VOID(cmd->relocs));
+		}
+	}
+
 	flush_reset(ring);
 
 	return ret;
@@ -518,7 +576,8 @@ static uint32_t msm_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring,
 		 */
 		size = cmd->size;
 	} else {
-		get_cmd(ring, cmd, submit_offset, size, MSM_SUBMIT_CMD_IB_TARGET_BUF);
+		struct fd_ringbuffer *parent = ring->parent ? ring->parent : ring;
+		get_cmd(parent, cmd, submit_offset, size, MSM_SUBMIT_CMD_IB_TARGET_BUF);
 	}
 
 	msm_ringbuffer_emit_reloc(ring, &(struct fd_reloc){
@@ -527,6 +586,14 @@ static uint32_t msm_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring,
 		.offset = submit_offset,
 	});
 
+	/* Unlike traditional ringbuffers which are deleted as a set (after
+	 * being flushed), mesa can't really guarantee that a stateobj isn't
+	 * destroyed after emitted but before flush, so we must hold a ref:
+	 */
+	if (target->flags & FD_RINGBUFFER_OBJECT) {
+		msm_ringbuffer_ref(target);
+	}
+
 	return size;
 }
 
@@ -535,10 +602,13 @@ static uint32_t msm_ringbuffer_cmd_count(struct fd_ringbuffer *ring)
 	return to_msm_ringbuffer(ring)->cmd_count;
 }
 
-static void msm_ringbuffer_destroy(struct fd_ringbuffer *ring)
+static void msm_ringbuffer_unref(struct fd_ringbuffer *ring)
 {
 	struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
 
+	if (!atomic_dec_and_test(&msm_ring->refcnt))
+		return;
+
 	flush_reset(ring);
 	delete_cmds(msm_ring);
 
@@ -549,6 +619,12 @@ static void msm_ringbuffer_destroy(struct fd_ringbuffer *ring)
 	free(msm_ring);
 }
 
+static void msm_ringbuffer_ref(struct fd_ringbuffer *ring)
+{
+	struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
+	atomic_inc(&msm_ring->refcnt);
+}
+
 static const struct fd_ringbuffer_funcs funcs = {
 		.hostptr = msm_ringbuffer_hostptr,
 		.flush = msm_ringbuffer_flush,
@@ -557,7 +633,7 @@ static const struct fd_ringbuffer_funcs funcs = {
 		.emit_reloc = msm_ringbuffer_emit_reloc,
 		.emit_reloc_ring = msm_ringbuffer_emit_reloc_ring,
 		.cmd_count = msm_ringbuffer_cmd_count,
-		.destroy = msm_ringbuffer_destroy,
+		.destroy = msm_ringbuffer_unref,
 };
 
 drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe,
@@ -566,8 +642,6 @@ drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe,
 	struct msm_ringbuffer *msm_ring;
 	struct fd_ringbuffer *ring;
 
-	assert(!flags);
-
 	msm_ring = calloc(1, sizeof(*msm_ring));
 	if (!msm_ring) {
 		ERROR_MSG("allocation failed");
@@ -582,6 +656,7 @@ drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe,
 
 	list_inithead(&msm_ring->cmd_list);
 	msm_ring->seqno = ++to_msm_device(pipe->dev)->ring_cnt;
+	atomic_set(&msm_ring->refcnt, 1);
 
 	ring = &msm_ring->base;
 	ring->funcs = &funcs;
commit 04190a912eebdbf4ff7ca45115ee21b1e4a0edd2
Author: Rob Clark <[email protected]>
Date:   Mon Jul 23 10:23:50 2018 -0400

    freedreno: slight reordering
    
    Splitting code-motion out from next patch.  Once we add stateobj rb's
    this loop could add new entries to bos table, so it needs to be before
    we set req.bos/req.nr_bos.
    
    Signed-off-by: Rob Clark <[email protected]>

diff --git a/freedreno/msm/msm_ringbuffer.c b/freedreno/msm/msm_ringbuffer.c
index a5f9861c..156c23c6 100644
--- a/freedreno/msm/msm_ringbuffer.c
+++ b/freedreno/msm/msm_ringbuffer.c
@@ -391,12 +391,6 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
 
 	finalize_current_cmd(ring, last_start);
 
-	/* needs to be after get_cmd() as that could create bos/cmds table: */
-	req.bos = VOID2U64(msm_ring->submit.bos),
-	req.nr_bos = msm_ring->submit.nr_bos;
-	req.cmds = VOID2U64(msm_ring->submit.cmds),
-	req.nr_cmds = msm_ring->submit.nr_cmds;
-
 	/* for each of the cmd's fix up their reloc's: */
 	for (i = 0; i < msm_ring->submit.nr_cmds; i++) {
 		struct drm_msm_gem_submit_cmd *cmd = &msm_ring->submit.cmds[i];
@@ -407,6 +401,12 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
 		cmd->nr_relocs = (b > a) ? b - a : 0;
 	}
 
+	/* needs to be after get_cmd() as that could create bos/cmds table: */
+	req.bos = VOID2U64(msm_ring->submit.bos),
+	req.nr_bos = msm_ring->submit.nr_bos;
+	req.cmds = VOID2U64(msm_ring->submit.cmds),
+	req.nr_cmds = msm_ring->submit.nr_cmds;
+
 	DEBUG_MSG("nr_cmds=%u, nr_bos=%u", req.nr_cmds, req.nr_bos);
 
 	ret = drmCommandWriteRead(ring->pipe->dev->fd, DRM_MSM_GEM_SUBMIT,
commit 2932a03180b9224b9d44a83c2ee299f19107f92d
Author: Rob Clark <[email protected]>
Date:   Mon Jul 23 09:42:22 2018 -0400

    freedreno: small cleanup
    
    Make cheezy growable array thing less open-coded before adding more.
    
    Signed-off-by: Rob Clark <[email protected]>

diff --git a/freedreno/msm/msm_priv.h b/freedreno/msm/msm_priv.h
index 776859a4..ee0eecb8 100644
--- a/freedreno/msm/msm_priv.h
+++ b/freedreno/msm/msm_priv.h
@@ -101,4 +101,30 @@ static inline void get_abs_timeout(struct drm_msm_timespec *tv, uint64_t ns)
 	tv->tv_nsec = t.tv_nsec + ns - (s * 1000000000);
 }
 
+/*
+ * Stupid/simple growable array implementation:
+ */
+
+static inline void *
+grow(void *ptr, uint32_t nr, uint32_t *max, uint32_t sz)
+{
+	if ((nr + 1) > *max) {
+		if ((*max * 2) < (nr + 1))
+			*max = nr + 5;
+		else
+			*max = *max * 2;
+		ptr = realloc(ptr, *max * sz);
+	}
+	return ptr;
+}
+
+#define DECLARE_ARRAY(type, name) \
+	unsigned nr_ ## name, max_ ## name; \
+	type * name;
+
+#define APPEND(x, name) ({ \
+	(x)->name = grow((x)->name, (x)->nr_ ## name, &(x)->max_ ## name, sizeof((x)->name[0])); \
+	(x)->nr_ ## name ++; \
+})
+
 #endif /* MSM_PRIV_H_ */
diff --git a/freedreno/msm/msm_ringbuffer.c b/freedreno/msm/msm_ringbuffer.c
index 9812d58b..a5f9861c 100644
--- a/freedreno/msm/msm_ringbuffer.c
+++ b/freedreno/msm/msm_ringbuffer.c
@@ -42,8 +42,7 @@ struct msm_cmd {
 	struct fd_bo *ring_bo;
 
 	/* reloc's table: */
-	struct drm_msm_gem_submit_reloc *relocs;
-	uint32_t nr_relocs, max_relocs;
+	DECLARE_ARRAY(struct drm_msm_gem_submit_reloc, relocs);
 
 	uint32_t size;
 };
@@ -58,22 +57,18 @@ struct msm_ringbuffer {
 	 */
 	struct {
 		/* bo's table: */
-		struct drm_msm_gem_submit_bo *bos;
-		uint32_t nr_bos, max_bos;
+		DECLARE_ARRAY(struct drm_msm_gem_submit_bo, bos);
 
 		/* cmd's table: */
-		struct drm_msm_gem_submit_cmd *cmds;
-		uint32_t nr_cmds, max_cmds;
+		DECLARE_ARRAY(struct drm_msm_gem_submit_cmd, cmds);
 	} submit;
 
 	/* should have matching entries in submit.bos: */
 	/* Note, only in parent ringbuffer */
-	struct fd_bo **bos;
-	uint32_t nr_bos, max_bos;
+	DECLARE_ARRAY(struct fd_bo *, bos);
 
 	/* should have matching entries in submit.cmds: */
-	struct msm_cmd **cmds;
-	uint32_t nr_cmds, max_cmds;
+	DECLARE_ARRAY(struct msm_cmd *, cmds);
 
 	/* List of physical cmdstream buffers (msm_cmd) assocated with this
 	 * logical fd_ringbuffer.
@@ -170,23 +165,6 @@ fail:
 	return NULL;
 }
 
-static void *grow(void *ptr, uint32_t nr, uint32_t *max, uint32_t sz)
-{
-	if ((nr + 1) > *max) {
-		if ((*max * 2) < (nr + 1))
-			*max = nr + 5;
-		else
-			*max = *max * 2;
-		ptr = realloc(ptr, *max * sz);
-	}
-	return ptr;
-}
-
-#define APPEND(x, name) ({ \
-	(x)->name = grow((x)->name, (x)->nr_ ## name, &(x)->max_ ## name, sizeof((x)->name[0])); \
-	(x)->nr_ ## name ++; \
-})
-
 static struct msm_cmd *current_cmd(struct fd_ringbuffer *ring)
 {
 	struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
commit fcbf206aa293af2d478e48dc45e4e8b3af0e7737
Author: Rob Clark <[email protected]>
Date:   Sun Jul 22 11:44:15 2018 -0400

    freedreno: add fd_ringbuffer_new_object()
    
    Add new API for reusable "state objects" which can be re-used multiple
    times.  Backend implementation for msm will follow.  (Probably not
    needed to support this for any device that uses kgsl backend, since this
    is mostly useful for a5xx+.)
    
    Signed-off-by: Rob Clark <[email protected]>

diff --git a/freedreno/freedreno-symbol-check b/freedreno/freedreno-symbol-check
index e6e5719d..e732c995 100755
--- a/freedreno/freedreno-symbol-check
+++ b/freedreno/freedreno-symbol-check
@@ -46,10 +46,12 @@ fd_ringbuffer_emit_reloc_ring_full
 fd_ringbuffer_flush
 fd_ringbuffer_grow
 fd_ringbuffer_new
+fd_ringbuffer_new_object
 fd_ringbuffer_reloc
 fd_ringbuffer_reloc2
 fd_ringbuffer_reset
 fd_ringbuffer_set_parent
+fd_ringbuffer_size
 fd_ringbuffer_timestamp
 fd_ringmarker_del
 fd_ringmarker_dwords
diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h
index b0a48adf..9d51c368 100644
--- a/freedreno/freedreno_priv.h
+++ b/freedreno/freedreno_priv.h
@@ -114,8 +114,13 @@ drm_private int fd_bo_cache_free(struct fd_bo_cache *cache, struct fd_bo *bo);
 /* for where @table_lock is already held: */
 drm_private void fd_device_del_locked(struct fd_device *dev);
 
+enum fd_ringbuffer_flags {
+	FD_RINGBUFFER_OBJECT = 0x1,
+};
+
 struct fd_pipe_funcs {
-	struct fd_ringbuffer * (*ringbuffer_new)(struct fd_pipe *pipe, uint32_t size);
+	struct fd_ringbuffer * (*ringbuffer_new)(struct fd_pipe *pipe, uint32_t size,
+			enum fd_ringbuffer_flags flags);
 	int (*get_param)(struct fd_pipe *pipe, enum fd_param_id param, uint64_t *value);
 	int (*wait)(struct fd_pipe *pipe, uint32_t timestamp, uint64_t timeout);
 	void (*destroy)(struct fd_pipe *pipe);
diff --git a/freedreno/freedreno_ringbuffer.c b/freedreno/freedreno_ringbuffer.c
index 3834b51b..a0be2dbb 100644
--- a/freedreno/freedreno_ringbuffer.c
+++ b/freedreno/freedreno_ringbuffer.c
@@ -32,15 +32,17 @@
 #include "freedreno_priv.h"
 #include "freedreno_ringbuffer.h"
 
-struct fd_ringbuffer *
-fd_ringbuffer_new(struct fd_pipe *pipe, uint32_t size)
+static struct fd_ringbuffer *
+ringbuffer_new(struct fd_pipe *pipe, uint32_t size,
+		enum fd_ringbuffer_flags flags)
 {
 	struct fd_ringbuffer *ring;
 
-	ring = pipe->funcs->ringbuffer_new(pipe, size);
+	ring = pipe->funcs->ringbuffer_new(pipe, size, flags);
 	if (!ring)
 		return NULL;
 
+	ring->flags = flags;
 	ring->pipe = pipe;
 	ring->start = ring->funcs->hostptr(ring);
 	ring->end = &(ring->start[ring->size/4]);
@@ -50,6 +52,23 @@ fd_ringbuffer_new(struct fd_pipe *pipe, uint32_t size)
 	return ring;
 }
 
+struct fd_ringbuffer *
+fd_ringbuffer_new(struct fd_pipe *pipe, uint32_t size)
+{
+	return ringbuffer_new(pipe, size, 0);
+}
+
+struct fd_ringbuffer *
+fd_ringbuffer_new_object(struct fd_pipe *pipe, uint32_t size)
+{
+	/* we can't really support "growable" rb's in general for
+	 * stateobj's since we need a single gpu addr (ie. can't
+	 * do the trick of a chain of IB packets):
+	 */
+	assert(size);
+	return ringbuffer_new(pipe, size, FD_RINGBUFFER_OBJECT);
+}
+
 void fd_ringbuffer_del(struct fd_ringbuffer *ring)
 {
 	fd_ringbuffer_reset(ring);
@@ -63,6 +82,8 @@ void fd_ringbuffer_del(struct fd_ringbuffer *ring)
 void fd_ringbuffer_set_parent(struct fd_ringbuffer *ring,
 					 struct fd_ringbuffer *parent)
 {
+	/* state objects should not be parented! */
+	assert(!(ring->flags & FD_RINGBUFFER_OBJECT));
 	ring->parent = parent;
 }
 
@@ -151,6 +172,21 @@ fd_ringbuffer_emit_reloc_ring_full(struct fd_ringbuffer *ring,
 	return ring->funcs->emit_reloc_ring(ring, target, cmd_idx, 0, size);
 }
 
+uint32_t
+fd_ringbuffer_size(struct fd_ringbuffer *ring)
+{
+	/* only really needed for stateobj ringbuffers, and won't really
+	 * do what you expect for growable rb's.. so lets just restrict
+	 * this to stateobj's for now:
+	 */
+	assert(ring->flags & FD_RINGBUFFER_OBJECT);
+	return offset_bytes(ring->cur, ring->start);
+}
+
+/*
+ * Deprecated ringmarker API:
+ */
+
 struct fd_ringmarker * fd_ringmarker_new(struct fd_ringbuffer *ring)
 {
 	struct fd_ringmarker *marker = NULL;
diff --git a/freedreno/freedreno_ringbuffer.h b/freedreno/freedreno_ringbuffer.h
index 0a3d6f77..69e7ed99 100644
--- a/freedreno/freedreno_ringbuffer.h
+++ b/freedreno/freedreno_ringbuffer.h
@@ -33,8 +33,7 @@
 
 /* the ringbuffer object is not opaque so that OUT_RING() type stuff
  * can be inlined.  Note that users should not make assumptions about
- * the size of this struct.. more stuff will be added when we eventually
- * have a kernel driver that can deal w/ reloc's..
+ * the size of this struct.
  */
 
 struct fd_ringbuffer_funcs;
@@ -52,10 +51,15 @@ struct fd_ringbuffer {
 	 * ringbuffer data
 	 */
 	void *user;
+
+	uint32_t flags;
 };
 
 struct fd_ringbuffer * fd_ringbuffer_new(struct fd_pipe *pipe,
 		uint32_t size);
+struct fd_ringbuffer * fd_ringbuffer_new_object(struct fd_pipe *pipe,
+		uint32_t size);
+
 void fd_ringbuffer_del(struct fd_ringbuffer *ring);
 void fd_ringbuffer_set_parent(struct fd_ringbuffer *ring,
 		struct fd_ringbuffer *parent);
@@ -95,6 +99,7 @@ will_be_deprecated void fd_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring
 uint32_t fd_ringbuffer_cmd_count(struct fd_ringbuffer *ring);
 uint32_t fd_ringbuffer_emit_reloc_ring_full(struct fd_ringbuffer *ring,
 		struct fd_ringbuffer *target, uint32_t cmd_idx);
+uint32_t fd_ringbuffer_size(struct fd_ringbuffer *ring);
 
 will_be_deprecated struct fd_ringmarker * fd_ringmarker_new(struct fd_ringbuffer *ring);
 will_be_deprecated void fd_ringmarker_del(struct fd_ringmarker *marker);
diff --git a/freedreno/kgsl/kgsl_priv.h b/freedreno/kgsl/kgsl_priv.h
index 41b13920..a6bf2d40 100644
--- a/freedreno/kgsl/kgsl_priv.h
+++ b/freedreno/kgsl/kgsl_priv.h
@@ -106,7 +106,7 @@ drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev,
 		enum fd_pipe_id id, uint32_t prio);
 
 drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe,
-		uint32_t size);
+		uint32_t size, enum fd_ringbuffer_flags flags);
 
 drm_private int kgsl_bo_new_handle(struct fd_device *dev,
 		uint32_t size, uint32_t flags, uint32_t *handle);
diff --git a/freedreno/kgsl/kgsl_ringbuffer.c b/freedreno/kgsl/kgsl_ringbuffer.c
index a756deda..e4fdf342 100644
--- a/freedreno/kgsl/kgsl_ringbuffer.c
+++ b/freedreno/kgsl/kgsl_ringbuffer.c
@@ -202,11 +202,13 @@ static const struct fd_ringbuffer_funcs funcs = {
 };
 
 drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe,
-		uint32_t size)
+		uint32_t size, enum fd_ringbuffer_flags flags)
 {
 	struct kgsl_ringbuffer *kgsl_ring;
 	struct fd_ringbuffer *ring = NULL;
 
+	assert(!flags);
+
 	kgsl_ring = calloc(1, sizeof(*kgsl_ring));
 	if (!kgsl_ring) {
 		ERROR_MSG("allocation failed");
diff --git a/freedreno/msm/msm_priv.h b/freedreno/msm/msm_priv.h
index 88ac3aa4..776859a4 100644
--- a/freedreno/msm/msm_priv.h
+++ b/freedreno/msm/msm_priv.h
@@ -68,7 +68,7 @@ drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev,
 		enum fd_pipe_id id, uint32_t prio);
 
 drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe,
-		uint32_t size);
+		uint32_t size, enum fd_ringbuffer_flags flags);
 
 struct msm_bo {
 	struct fd_bo base;
diff --git a/freedreno/msm/msm_ringbuffer.c b/freedreno/msm/msm_ringbuffer.c
index a87e1b9a..9812d58b 100644
--- a/freedreno/msm/msm_ringbuffer.c
+++ b/freedreno/msm/msm_ringbuffer.c
@@ -583,11 +583,13 @@ static const struct fd_ringbuffer_funcs funcs = {
 };
 
 drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe,
-		uint32_t size)
+		uint32_t size, enum fd_ringbuffer_flags flags)
 {
 	struct msm_ringbuffer *msm_ring;
 	struct fd_ringbuffer *ring;
 
+	assert(!flags);
+
 	msm_ring = calloc(1, sizeof(*msm_ring));
 	if (!msm_ring) {
 		ERROR_MSG("allocation failed");

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
--