[PATCH libdrm 2/2] etnaviv: add fence fd support

Philipp Zabel p.zabel at pengutronix.de
Wed Apr 5 12:34:56 UTC 2017


Add etna_cmd_stream_flush_explicit with in-fence fd and out-fence fd
support for explicit fencing.

Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>
---
 etnaviv/etnaviv_cmd_stream.c | 33 +++++++++++++++++++++++++++++----
 etnaviv/etnaviv_drmif.h      |  2 ++
 2 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/etnaviv/etnaviv_cmd_stream.c b/etnaviv/etnaviv_cmd_stream.c
index 9ce3f363..93c46e25 100644
--- a/etnaviv/etnaviv_cmd_stream.c
+++ b/etnaviv/etnaviv_cmd_stream.c
@@ -177,7 +177,8 @@ static uint32_t bo2idx(struct etna_cmd_stream *stream, struct etna_bo *bo,
 	return idx;
 }
 
-static void flush(struct etna_cmd_stream *stream)
+static void flush(struct etna_cmd_stream *stream, int in_fence_fd,
+		  int *out_fence_fd)
 {
 	struct etna_cmd_stream_priv *priv = etna_cmd_stream_priv(stream);
 	int ret, id = priv->pipe->id;
@@ -194,8 +195,22 @@ static void flush(struct etna_cmd_stream *stream)
 		.stream_size = stream->offset * 4, /* in bytes */
 	};
 
+	if (in_fence_fd != -1) {
+		req.flags |= ETNA_SUBMIT_FENCE_FD_IN | ETNA_SUBMIT_NO_IMPLICIT;
+		req.fence_fd = in_fence_fd;
+	}
+
+	if (out_fence_fd)
+		req.flags |= ETNA_SUBMIT_FENCE_FD_OUT;
+
+	/*
+	 * Pass the complete submit structure only if flags are set. Otherwise,
+	 * only pass the fields up to, but not including the flags field for
+	 * backwards compatiblity with older kernels.
+	 */
 	ret = drmCommandWriteRead(gpu->dev->fd, DRM_ETNAVIV_GEM_SUBMIT,
-			&req, sizeof(req));
+			&req, req.flags ? sizeof(req) :
+			offsetof(struct drm_etnaviv_gem_submit, flags));
 
 	if (ret)
 		ERROR_MSG("submit failed: %d (%s)", ret, strerror(errno));
@@ -208,11 +223,21 @@ static void flush(struct etna_cmd_stream *stream)
 		bo->current_stream = NULL;
 		etna_bo_del(bo);
 	}
+
+	if (out_fence_fd)
+		*out_fence_fd = req.fence_fd;
 }
 
 void etna_cmd_stream_flush(struct etna_cmd_stream *stream)
 {
-	flush(stream);
+	flush(stream, -1, NULL);
+	reset_buffer(stream);
+}
+
+void etna_cmd_stream_flush_explicit(struct etna_cmd_stream *stream,
+				    int in_fence_fd, int *out_fence_fd)
+{
+	flush(stream, in_fence_fd, out_fence_fd);
 	reset_buffer(stream);
 }
 
@@ -220,7 +245,7 @@ void etna_cmd_stream_finish(struct etna_cmd_stream *stream)
 {
 	struct etna_cmd_stream_priv *priv = etna_cmd_stream_priv(stream);
 
-	flush(stream);
+	flush(stream, -1, NULL);
 	etna_pipe_wait(priv->pipe, priv->last_timestamp, 5000);
 	reset_buffer(stream);
 }
diff --git a/etnaviv/etnaviv_drmif.h b/etnaviv/etnaviv_drmif.h
index 8119baad..e6dbb1d5 100644
--- a/etnaviv/etnaviv_drmif.h
+++ b/etnaviv/etnaviv_drmif.h
@@ -142,6 +142,8 @@ struct etna_cmd_stream *etna_cmd_stream_new(struct etna_pipe *pipe, uint32_t siz
 void etna_cmd_stream_del(struct etna_cmd_stream *stream);
 uint32_t etna_cmd_stream_timestamp(struct etna_cmd_stream *stream);
 void etna_cmd_stream_flush(struct etna_cmd_stream *stream);
+void etna_cmd_stream_flush_explicit(struct etna_cmd_stream *stream,
+				    int in_fence_fd, int *out_fence_fd);
 void etna_cmd_stream_finish(struct etna_cmd_stream *stream);
 
 static inline uint32_t etna_cmd_stream_avail(struct etna_cmd_stream *stream)
-- 
2.11.0



More information about the dri-devel mailing list