From 591401ff05f878ff1607a1a34db1319103025d8f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 16 Jan 2010 21:12:10 +0000 Subject: llvmpipe: use new u_ringbuffer for scene queue --- src/gallium/drivers/llvmpipe/lp_rast.c | 2 +- src/gallium/drivers/llvmpipe/lp_scene_queue.c | 114 ++++++++------------------ src/gallium/drivers/llvmpipe/lp_scene_queue.h | 8 +- src/gallium/drivers/llvmpipe/lp_setup.c | 11 ++- 4 files changed, 46 insertions(+), 89 deletions(-) (limited to 'src') diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index d03ba1752d6..2e2ebee45de 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -844,7 +844,7 @@ thread_func( void *init_data ) const struct pipe_framebuffer_state *fb; boolean write_depth; - rast->curr_scene = lp_scene_dequeue( rast->full_scenes ); + rast->curr_scene = lp_scene_dequeue( rast->full_scenes, TRUE ); lp_scene_bin_iter_begin( rast->curr_scene ); diff --git a/src/gallium/drivers/llvmpipe/lp_scene_queue.c b/src/gallium/drivers/llvmpipe/lp_scene_queue.c index 8d65a6a6fa2..43d74e4d89d 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene_queue.c +++ b/src/gallium/drivers/llvmpipe/lp_scene_queue.c @@ -32,8 +32,7 @@ * which are produced by the "rast" code when it finishes rendering a scene. */ - -#include "pipe/p_thread.h" +#include "util/u_ringbuffer.h" #include "util/u_memory.h" #include "lp_scene_queue.h" @@ -41,20 +40,17 @@ #define MAX_SCENE_QUEUE 4 +struct scene_packet { + struct util_packet header; + struct lp_scene *scene; +}; /** * A queue of scenes */ struct lp_scene_queue { - /** XXX might use a linked list here somedone, but the list will - * probably always be pretty short. - */ - struct lp_scene *scenes[MAX_SCENE_QUEUE]; - unsigned count; - - pipe_condvar count_change; - pipe_mutex mutex; + struct util_ringbuffer *ring; }; @@ -64,11 +60,19 @@ struct lp_scene_queue * lp_scene_queue_create(void) { struct lp_scene_queue *queue = CALLOC_STRUCT(lp_scene_queue); - if (queue) { - pipe_condvar_init(queue->count_change); - pipe_mutex_init(queue->mutex); - } + if (queue == NULL) + return NULL; + + queue->ring = util_ringbuffer_create( MAX_SCENE_QUEUE * + sizeof( struct scene_packet ) / 4); + if (queue->ring == NULL) + goto fail; + return queue; + +fail: + FREE(queue); + return NULL; } @@ -76,41 +80,26 @@ lp_scene_queue_create(void) void lp_scene_queue_destroy(struct lp_scene_queue *queue) { - pipe_condvar_destroy(queue->count_change); - pipe_mutex_destroy(queue->mutex); + util_ringbuffer_destroy(queue->ring); + FREE(queue); } /** Remove first lp_scene from head of queue */ struct lp_scene * -lp_scene_dequeue(struct lp_scene_queue *queue) +lp_scene_dequeue(struct lp_scene_queue *queue, boolean wait) { - struct lp_scene *scene; - unsigned i; - - pipe_mutex_lock(queue->mutex); - while (queue->count == 0) { - pipe_condvar_wait(queue->count_change, queue->mutex); - } - - assert(queue->count >= 1); - - /* get head */ - scene = queue->scenes[0]; - - /* shift entries */ - for (i = 0; i < queue->count - 1; i++) { - queue->scenes[i] = queue->scenes[i + 1]; - } + struct scene_packet packet; + enum pipe_error ret; - queue->count--; + ret = util_ringbuffer_dequeue(queue->ring, + &packet.header, + sizeof packet / 4, + wait ); + if (ret != PIPE_OK) + return NULL; - /* signal size change */ - pipe_condvar_signal(queue->count_change); - - pipe_mutex_unlock(queue->mutex); - - return scene; + return packet.scene; } @@ -118,47 +107,16 @@ lp_scene_dequeue(struct lp_scene_queue *queue) void lp_scene_enqueue(struct lp_scene_queue *queue, struct lp_scene *scene) { - pipe_mutex_lock(queue->mutex); - - assert(queue->count < MAX_SCENE_QUEUE); + struct scene_packet packet; - /* debug: check that scene is not already in the queue */ - if (0) { - unsigned i; - for (i = 0; i < queue->count; i++) { - assert(queue->scenes[i] != scene); - } - } + packet.header.dwords = sizeof packet / 4; + packet.header.data24 = 0; + packet.scene = scene; - /* add to end */ - queue->scenes[queue->count++] = scene; - - /* signal size change */ - pipe_condvar_signal(queue->count_change); - - pipe_mutex_unlock(queue->mutex); + util_ringbuffer_enqueue(queue->ring, &packet.header); } -/** Return number of entries in the queue */ -unsigned -lp_scene_queue_count(struct lp_scene_queue *queue) -{ - unsigned count; - pipe_mutex_lock(queue->mutex); - count = queue->count; - pipe_mutex_unlock(queue->mutex); - return count; -} -/** Wait until the queue has exactly 'count' entries */ -void -lp_scene_queue_wait_count(struct lp_scene_queue *queue, unsigned count) -{ - pipe_mutex_lock(queue->mutex); - while (queue->count != count) { - pipe_condvar_wait(queue->count_change, queue->mutex); - } - pipe_mutex_unlock(queue->mutex); -} + diff --git a/src/gallium/drivers/llvmpipe/lp_scene_queue.h b/src/gallium/drivers/llvmpipe/lp_scene_queue.h index 1bd475fa504..fd7c65a2c8b 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene_queue.h +++ b/src/gallium/drivers/llvmpipe/lp_scene_queue.h @@ -40,16 +40,12 @@ void lp_scene_queue_destroy(struct lp_scene_queue *queue); struct lp_scene * -lp_scene_dequeue(struct lp_scene_queue *queue); +lp_scene_dequeue(struct lp_scene_queue *queue, boolean wait); void -lp_scene_enqueue(struct lp_scene_queue *queue, struct lp_scene *bins); +lp_scene_enqueue(struct lp_scene_queue *queue, struct lp_scene *scene); -unsigned -lp_scene_queue_count(struct lp_scene_queue *queue); -void -lp_scene_queue_wait_count(struct lp_scene_queue *queue, unsigned size); #endif /* LP_BIN_QUEUE */ diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index f52dce65d74..d4a4724ad1b 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -57,8 +57,11 @@ struct lp_scene * lp_setup_get_current_scene(struct setup_context *setup) { if (!setup->scene) { - /* wait for a free/empty bin */ - setup->scene = lp_scene_dequeue(setup->empty_scenes); + + /* wait for a free/empty scene + */ + setup->scene = lp_scene_dequeue(setup->empty_scenes, TRUE); + if(0)lp_scene_reset( setup->scene ); /* XXX temporary? */ lp_scene_set_framebuffer_size(setup->scene, @@ -651,8 +654,8 @@ lp_setup_destroy( struct setup_context *setup ) pipe_buffer_reference(&setup->constants.current, NULL); /* free the scenes in the 'empty' queue */ - while (lp_scene_queue_count(setup->empty_scenes) > 0) { - struct lp_scene *scene = lp_scene_dequeue(setup->empty_scenes); + while (1) { + struct lp_scene *scene = lp_scene_dequeue(setup->empty_scenes, FALSE); if (!scene) break; lp_scene_destroy(scene); -- cgit v1.2.3