From 5650a719f0c69c00954e47bd7a7b3e9433cb551d Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 8 Mar 2011 08:20:31 +0100 Subject: r300g: decide whether a flush should be asynchronous when calling it Thread offloading is not sometimes desirable, e.g. when mapping a buffer. --- src/gallium/winsys/radeon/drm/radeon_drm_bo.c | 11 +++++++---- src/gallium/winsys/radeon/drm/radeon_drm_cs.c | 17 ++++++++--------- src/gallium/winsys/radeon/drm/radeon_drm_cs.h | 5 ++--- 3 files changed, 17 insertions(+), 16 deletions(-) (limited to 'src/gallium/winsys') diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c index 3094337a3c..9eb833454d 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c @@ -172,7 +172,7 @@ static void *radeon_bo_map_internal(struct pb_buffer *_buf, /* DONTBLOCK doesn't make sense with UNSYNCHRONIZED. */ if (flags & PB_USAGE_DONTBLOCK) { if (radeon_bo_is_referenced_by_cs(cs, bo)) { - cs->flush_cs(cs->flush_data); + cs->flush_cs(cs->flush_data, R300_FLUSH_ASYNC); return NULL; } @@ -181,7 +181,11 @@ static void *radeon_bo_map_internal(struct pb_buffer *_buf, } } else { if (radeon_bo_is_referenced_by_cs(cs, bo)) { - cs->flush_cs(cs->flush_data); + cs->flush_cs(cs->flush_data, 0); + } else { + /* Try to avoid busy-waiting in radeon_bo_wait. */ + if (p_atomic_read(&bo->num_active_ioctls)) + radeon_drm_cs_sync_flush(cs); } radeon_bo_wait((struct r300_winsys_bo*)bo); @@ -406,8 +410,7 @@ static void radeon_bo_set_tiling(struct r300_winsys_bo *_buf, /* Tiling determines how DRM treats the buffer data. * We must flush CS when changing it if the buffer is referenced. */ if (cs && radeon_bo_is_referenced_by_cs(cs, bo)) { - radeon_drm_cs_flush(rcs); - radeon_drm_cs_sync_flush(rcs); + cs->flush_cs(cs->flush_data, 0); } while (p_atomic_read(&bo->num_active_ioctls)) { diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c index 9ee800f595..951791a172 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c @@ -355,10 +355,8 @@ static PIPE_THREAD_ROUTINE(radeon_drm_cs_emit_ioctl, param) return NULL; } -void radeon_drm_cs_sync_flush(struct r300_winsys_cs *rcs) +void radeon_drm_cs_sync_flush(struct radeon_drm_cs *cs) { - struct radeon_drm_cs *cs = radeon_drm_cs(rcs); - /* Wait for any pending ioctl to complete. */ if (cs->thread) { pipe_thread_wait(cs->thread); @@ -368,12 +366,12 @@ void radeon_drm_cs_sync_flush(struct r300_winsys_cs *rcs) DEBUG_GET_ONCE_BOOL_OPTION(thread, "RADEON_THREAD", TRUE) -void radeon_drm_cs_flush(struct r300_winsys_cs *rcs) +static void radeon_drm_cs_flush(struct r300_winsys_cs *rcs, unsigned flags) { struct radeon_drm_cs *cs = radeon_drm_cs(rcs); struct radeon_cs_context *tmp; - radeon_drm_cs_sync_flush(rcs); + radeon_drm_cs_sync_flush(cs); /* If the CS is not empty, emit it in a newly-spawned thread. */ if (cs->base.cdw) { @@ -384,7 +382,8 @@ void radeon_drm_cs_flush(struct r300_winsys_cs *rcs) for (i = 0; i < crelocs; i++) p_atomic_inc(&cs->csc->relocs_bo[i]->num_active_ioctls); - if (cs->ws->num_cpus > 1 && debug_get_option_thread()) { + if (cs->ws->num_cpus > 1 && debug_get_option_thread() && + (flags & R300_FLUSH_ASYNC)) { cs->thread = pipe_thread_create(radeon_drm_cs_emit_ioctl, cs->csc); assert(cs->thread); } else { @@ -407,7 +406,7 @@ void radeon_drm_cs_flush(struct r300_winsys_cs *rcs) static void radeon_drm_cs_destroy(struct r300_winsys_cs *rcs) { struct radeon_drm_cs *cs = radeon_drm_cs(rcs); - radeon_drm_cs_sync_flush(rcs); + radeon_drm_cs_sync_flush(cs); radeon_cs_context_cleanup(&cs->csc1); radeon_cs_context_cleanup(&cs->csc2); p_atomic_dec(&cs->ws->num_cs); @@ -417,7 +416,8 @@ static void radeon_drm_cs_destroy(struct r300_winsys_cs *rcs) } static void radeon_drm_cs_set_flush(struct r300_winsys_cs *rcs, - void (*flush)(void *), void *user) + void (*flush)(void *ctx, unsigned flags), + void *user) { struct radeon_drm_cs *cs = radeon_drm_cs(rcs); cs->flush_cs = flush; @@ -441,7 +441,6 @@ void radeon_drm_cs_init_functions(struct radeon_drm_winsys *ws) ws->base.cs_validate = radeon_drm_cs_validate; ws->base.cs_write_reloc = radeon_drm_cs_write_reloc; ws->base.cs_flush = radeon_drm_cs_flush; - ws->base.cs_sync_flush = radeon_drm_cs_sync_flush; ws->base.cs_set_flush = radeon_drm_cs_set_flush; ws->base.cs_is_buffer_referenced = radeon_bo_is_referenced; } diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h index 4cc97f37e0..dfaa161c31 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h +++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h @@ -70,7 +70,7 @@ struct radeon_drm_cs { struct radeon_drm_winsys *ws; /* Flush CS. */ - void (*flush_cs)(void *); + void (*flush_cs)(void *ctx, unsigned flags); void *flush_data; pipe_thread thread; @@ -96,8 +96,7 @@ static INLINE boolean radeon_bo_is_referenced_by_any_cs(struct radeon_bo *bo) return bo->num_cs_references; } -void radeon_drm_cs_flush(struct r300_winsys_cs *rcs); -void radeon_drm_cs_sync_flush(struct r300_winsys_cs *rcs); +void radeon_drm_cs_sync_flush(struct radeon_drm_cs *cs); void radeon_drm_cs_init_functions(struct radeon_drm_winsys *ws); #endif -- cgit v1.2.3