Ok, tested it a bit (but not to extensive). Seems to work fine, so pushed it to master.
Thanks, Christian. Am Dienstag, den 30.08.2011, 03:25 +0200 schrieb Marek Olšák: > Thanks. I wanted to do this long ago. > > Reviewed-by: Marek Olšák <mar...@gmail.com> > > On Sat, Aug 27, 2011 at 10:57 PM, Maarten Lankhorst > <m.b.lankho...@gmail.com> wrote: > > I noticed that a thread was created for every time async flush was called, > > so I moved it and used some semaphores to synch. > > > > Signed-off-by: Maarten Lankhorst <m.b.lankho...@gmail.com> > > > > --- > > diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c > > b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c > > index c309354..dd3a4a3 100644 > > --- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c > > +++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c > > @@ -130,6 +130,9 @@ static void radeon_destroy_cs_context(struct > > radeon_cs_context *csc) > > FREE(csc->relocs); > > } > > > > +DEBUG_GET_ONCE_BOOL_OPTION(thread, "RADEON_THREAD", TRUE) > > +static PIPE_THREAD_ROUTINE(radeon_drm_cs_emit_ioctl, param); > > + > > static struct radeon_winsys_cs *radeon_drm_cs_create(struct radeon_winsys > > *rws) > > { > > struct radeon_drm_winsys *ws = radeon_drm_winsys(rws); > > @@ -139,6 +142,8 @@ static struct radeon_winsys_cs > > *radeon_drm_cs_create(struct radeon_winsys *rws) > > if (!cs) { > > return NULL; > > } > > + pipe_semaphore_init(&cs->flush_queued, 0); > > + pipe_semaphore_init(&cs->flush_completed, 0); > > > > cs->ws = ws; > > > > @@ -158,6 +163,8 @@ static struct radeon_winsys_cs > > *radeon_drm_cs_create(struct radeon_winsys *rws) > > cs->base.buf = cs->csc->buf; > > > > p_atomic_inc(&ws->num_cs); > > + if (cs->ws->num_cpus > 1 && debug_get_option_thread()) > > + cs->thread = pipe_thread_create(radeon_drm_cs_emit_ioctl, cs); > > return &cs->base; > > } > > > > @@ -357,9 +364,8 @@ static void radeon_drm_cs_write_reloc(struct > > radeon_winsys_cs *rcs, > > OUT_CS(&cs->base, index * RELOC_DWORDS); > > } > > > > -static PIPE_THREAD_ROUTINE(radeon_drm_cs_emit_ioctl, param) > > +static void radeon_drm_cs_emit_ioctl_oneshot(struct radeon_cs_context *csc) > > { > > - struct radeon_cs_context *csc = (struct radeon_cs_context*)param; > > unsigned i; > > > > if (drmCommandWriteRead(csc->fd, DRM_RADEON_CS, > > @@ -381,20 +387,32 @@ static PIPE_THREAD_ROUTINE(radeon_drm_cs_emit_ioctl, > > param) > > p_atomic_dec(&csc->relocs_bo[i]->num_active_ioctls); > > > > radeon_cs_context_cleanup(csc); > > +} > > + > > +static PIPE_THREAD_ROUTINE(radeon_drm_cs_emit_ioctl, param) > > +{ > > + struct radeon_drm_cs *cs = (struct radeon_drm_cs*)param; > > + > > + while (1) { > > + pipe_semaphore_wait(&cs->flush_queued); > > + if (cs->kill_thread) > > + break; > > + radeon_drm_cs_emit_ioctl_oneshot(cs->cst); > > + pipe_semaphore_signal(&cs->flush_completed); > > + } > > + pipe_semaphore_signal(&cs->flush_completed); > > return NULL; > > } > > > > void radeon_drm_cs_sync_flush(struct radeon_drm_cs *cs) > > { > > /* Wait for any pending ioctl to complete. */ > > - if (cs->thread) { > > - pipe_thread_wait(cs->thread); > > - cs->thread = 0; > > + if (cs->thread && cs->flush_started) { > > + pipe_semaphore_wait(&cs->flush_completed); > > + cs->flush_started = 0; > > } > > } > > > > -DEBUG_GET_ONCE_BOOL_OPTION(thread, "RADEON_THREAD", TRUE) > > - > > static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs, unsigned > > flags) > > { > > struct radeon_drm_cs *cs = radeon_drm_cs(rcs); > > @@ -402,33 +420,33 @@ static void radeon_drm_cs_flush(struct > > radeon_winsys_cs *rcs, unsigned flags) > > > > radeon_drm_cs_sync_flush(cs); > > > > + /* Flip command streams. */ > > + tmp = cs->csc; > > + cs->csc = cs->cst; > > + cs->cst = tmp; > > + > > /* If the CS is not empty, emit it in a newly-spawned thread. */ > > if (cs->base.cdw) { > > - unsigned i, crelocs = cs->csc->crelocs; > > + unsigned i, crelocs = cs->cst->crelocs; > > > > - cs->csc->chunks[0].length_dw = cs->base.cdw; > > + cs->cst->chunks[0].length_dw = cs->base.cdw; > > > > for (i = 0; i < crelocs; i++) { > > /* Update the number of active asynchronous CS ioctls for the > > buffer. */ > > - p_atomic_inc(&cs->csc->relocs_bo[i]->num_active_ioctls); > > + p_atomic_inc(&cs->cst->relocs_bo[i]->num_active_ioctls); > > } > > > > - if (cs->ws->num_cpus > 1 && debug_get_option_thread() && > > + if (cs->thread && > > (flags & RADEON_FLUSH_ASYNC)) { > > - cs->thread = pipe_thread_create(radeon_drm_cs_emit_ioctl, > > cs->csc); > > - assert(cs->thread); > > + cs->flush_started = 1; > > + pipe_semaphore_signal(&cs->flush_queued); > > } else { > > - radeon_drm_cs_emit_ioctl(cs->csc); > > + radeon_drm_cs_emit_ioctl_oneshot(cs->cst); > > } > > } else { > > - radeon_cs_context_cleanup(cs->csc); > > + radeon_cs_context_cleanup(cs->cst); > > } > > > > - /* Flip command streams. */ > > - tmp = cs->csc; > > - cs->csc = cs->cst; > > - cs->cst = tmp; > > - > > /* Prepare a new CS. */ > > cs->base.buf = cs->csc->buf; > > cs->base.cdw = 0; > > @@ -438,6 +456,15 @@ static void radeon_drm_cs_destroy(struct > > radeon_winsys_cs *rcs) > > { > > struct radeon_drm_cs *cs = radeon_drm_cs(rcs); > > radeon_drm_cs_sync_flush(cs); > > + if (cs->thread) { > > + cs->kill_thread = 1; > > + pipe_semaphore_signal(&cs->flush_queued); > > + pipe_semaphore_wait(&cs->flush_completed); > > + pipe_thread_wait(cs->thread); > > + pipe_thread_destroy(cs->thread); > > + } > > + pipe_semaphore_destroy(&cs->flush_queued); > > + pipe_semaphore_destroy(&cs->flush_completed); > > radeon_cs_context_cleanup(&cs->csc1); > > radeon_cs_context_cleanup(&cs->csc2); > > p_atomic_dec(&cs->ws->num_cs); > > diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h > > b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h > > index fe28532..e8e34c2 100644 > > --- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h > > +++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h > > @@ -75,6 +75,8 @@ struct radeon_drm_cs { > > void *flush_data; > > > > pipe_thread thread; > > + int flush_started, kill_thread; > > + pipe_semaphore flush_queued, flush_completed; > > }; > > > > int radeon_get_reloc(struct radeon_cs_context *csc, struct radeon_bo *bo); > > > > > > _______________________________________________ > > mesa-dev mailing list > > mesa-dev@lists.freedesktop.org > > http://lists.freedesktop.org/mailman/listinfo/mesa-dev > > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev