enum fd_version {
FD_VERSION_MADVISE = 1, /* kernel supports madvise */
FD_VERSION_UNLIMITED_CMDS = 1, /* submits w/ >4 cmd buffers (growable ringbuffer) */
+ FD_VERSION_FENCE_FD = 2, /* submit command supports in/out fences */
};
enum fd_version fd_device_version(struct fd_device *dev);
struct fd_ringbuffer_funcs {
void * (*hostptr)(struct fd_ringbuffer *ring);
- int (*flush)(struct fd_ringbuffer *ring, uint32_t *last_start);
+ int (*flush)(struct fd_ringbuffer *ring, uint32_t *last_start,
+ int in_fence_fd, int *out_fence_fd);
void (*grow)(struct fd_ringbuffer *ring, uint32_t size);
void (*reset)(struct fd_ringbuffer *ring);
void (*emit_reloc)(struct fd_ringbuffer *ring,
ring->funcs->reset(ring);
}
-/* maybe get rid of this and use fd_ringmarker_flush() from DDX too? */
int fd_ringbuffer_flush(struct fd_ringbuffer *ring)
{
- return ring->funcs->flush(ring, ring->last_start);
+ return ring->funcs->flush(ring, ring->last_start, -1, NULL);
+}
+
+int fd_ringbuffer_flush2(struct fd_ringbuffer *ring, int in_fence_fd,
+ int *out_fence_fd)
+{
+ return ring->funcs->flush(ring, ring->last_start, in_fence_fd, out_fence_fd);
}
void fd_ringbuffer_grow(struct fd_ringbuffer *ring, uint32_t ndwords)
int fd_ringmarker_flush(struct fd_ringmarker *marker)
{
struct fd_ringbuffer *ring = marker->ring;
- return ring->funcs->flush(ring, marker->cur);
+ return ring->funcs->flush(ring, marker->cur, -1, NULL);
}
struct fd_ringbuffer *parent);
void fd_ringbuffer_reset(struct fd_ringbuffer *ring);
int fd_ringbuffer_flush(struct fd_ringbuffer *ring);
+/* in_fence_fd: -1 for no in-fence, else fence fd
+ * out_fence_fd: NULL for no output-fence requested, else ptr to return out-fence
+ */
+int fd_ringbuffer_flush2(struct fd_ringbuffer *ring, int in_fence_fd,
+ int *out_fence_fd);
void fd_ringbuffer_grow(struct fd_ringbuffer *ring, uint32_t ndwords);
uint32_t fd_ringbuffer_timestamp(struct fd_ringbuffer *ring);
return kgsl_ring->bo->hostptr;
}
-static int kgsl_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start)
+static int kgsl_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start,
+ int in_fence_fd, int *out_fence_fd)
{
struct kgsl_ringbuffer *kgsl_ring = to_kgsl_ringbuffer(ring);
struct kgsl_pipe *kgsl_pipe = to_kgsl_pipe(ring->pipe);
};
int ret;
+ assert(in_fence_fd == -1);
+ assert(out_fence_fd == NULL);
+
kgsl_pipe_pre_submit(kgsl_pipe);
/* z180_cmdstream_issueibcmds() is made of fail: */
}
}
-static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start)
+static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start,
+ int in_fence_fd, int *out_fence_fd)
{
struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
struct drm_msm_gem_submit req = {
uint32_t i;
int ret;
+ if (in_fence_fd != -1) {
+ req.flags |= MSM_SUBMIT_FENCE_FD_IN | MSM_SUBMIT_NO_IMPLICIT;
+ req.fence_fd = in_fence_fd;
+ }
+
+ if (out_fence_fd) {
+ req.flags |= MSM_SUBMIT_FENCE_FD_OUT;
+ }
+
finalize_current_cmd(ring, last_start);
/* needs to be after get_cmd() as that could create bos/cmds table: */
struct msm_cmd *msm_cmd = msm_ring->cmds[i];
msm_cmd->ring->last_timestamp = req.fence;
}
+
+ if (out_fence_fd) {
+ *out_fence_fd = req.fence_fd;
+ }
}
flush_reset(ring);