freedreno: some msm-ring reset/flush fixes

Need to update timestamp on all ring's associated with a submit (ie.
both the binning pass and main ring).  Also, make sure nr_reloc's
in particular gets cleared if the rb is reset.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
main
Rob Clark 2014-02-19 11:01:23 -05:00
parent 128e74cf64
commit c5de5abbd9
3 changed files with 35 additions and 9 deletions

View File

@ -114,6 +114,7 @@ struct fd_ringmarker {
struct fd_ringbuffer_funcs {
void * (*hostptr)(struct fd_ringbuffer *ring);
int (*flush)(struct fd_ringbuffer *ring, uint32_t *last_start);
void (*reset)(struct fd_ringbuffer *ring);
void (*emit_reloc)(struct fd_ringbuffer *ring,
const struct fd_reloc *reloc);
void (*emit_reloc_ring)(struct fd_ringbuffer *ring,

View File

@ -72,6 +72,8 @@ void fd_ringbuffer_reset(struct fd_ringbuffer *ring)
if (ring->pipe->id == FD_PIPE_2D)
start = &ring->start[0x140];
ring->cur = ring->last_start = start;
if (ring->funcs->reset)
ring->funcs->reset(ring);
}
/* maybe get rid of this and use fd_ringmarker_flush() from DDX too? */

View File

@ -169,6 +169,22 @@ static uint32_t find_next_reloc_idx(struct msm_ringbuffer *msm_ring,
return i;
}
static void flush_reset(struct fd_ringbuffer *ring)
{
struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
unsigned i;
/* for each of the cmd buffers, clear their reloc's: */
for (i = 0; i < msm_ring->nr_cmds; i++) {
struct msm_ringbuffer *target_ring = to_msm_ringbuffer(msm_ring->rings[i]);
target_ring->nr_relocs = 0;
}
msm_ring->nr_relocs = 0;
msm_ring->nr_cmds = 0;
msm_ring->nr_bos = 0;
}
static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start)
{
struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
@ -205,8 +221,16 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
ret = drmCommandWriteRead(ring->pipe->dev->fd, DRM_MSM_GEM_SUBMIT,
&req, sizeof(req));
if (ret)
if (ret) {
ERROR_MSG("submit failed: %d (%s)", ret, strerror(errno));
} else {
/* update timestamp on all rings associated with submit: */
for (i = 0; i < msm_ring->nr_cmds; i++) {
struct fd_ringbuffer *target_ring = msm_ring->rings[i];
if (!ret)
target_ring->last_timestamp = req.fence;
}
}
LIST_FOR_EACH_ENTRY_SAFE(msm_bo, tmp, &msm_ring->submit_list, list[id]) {
struct list_head *list = &msm_bo->list[id];
@ -215,18 +239,16 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
fd_bo_del(&msm_bo->base);
}
/* for each of the cmd buffers, clear their reloc's: */
for (i = 0; i < msm_ring->nr_cmds; i++) {
struct msm_ringbuffer *target_ring = to_msm_ringbuffer(msm_ring->rings[i]);
target_ring->nr_relocs = 0;
}
msm_ring->nr_cmds = 0;
msm_ring->nr_bos = 0;
flush_reset(ring);
return ret;
}
static void msm_ringbuffer_reset(struct fd_ringbuffer *ring)
{
flush_reset(ring);
}
static void msm_ringbuffer_emit_reloc(struct fd_ringbuffer *ring,
const struct fd_reloc *r)
{
@ -285,6 +307,7 @@ static void msm_ringbuffer_destroy(struct fd_ringbuffer *ring)
static struct fd_ringbuffer_funcs funcs = {
.hostptr = msm_ringbuffer_hostptr,
.flush = msm_ringbuffer_flush,
.reset = msm_ringbuffer_reset,
.emit_reloc = msm_ringbuffer_emit_reloc,
.emit_reloc_ring = msm_ringbuffer_emit_reloc_ring,
.destroy = msm_ringbuffer_destroy,