Mesa (lp-binning): llvmpipe: use new u_ringbuffer for scene queue

Keith Whitwell keithw at kemper.freedesktop.org
Sun Jan 17 00:33:37 UTC 2010


Module: Mesa
Branch: lp-binning
Commit: 591401ff05f878ff1607a1a34db1319103025d8f
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=591401ff05f878ff1607a1a34db1319103025d8f

Author: Keith Whitwell <keithw at vmware.com>
Date:   Sat Jan 16 21:12:10 2010 +0000

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(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
index d03ba17..2e2ebee 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 8d65a6a..43d74e4 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 1bd475f..fd7c65a 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 f52dce6..d4a4724 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);




More information about the mesa-commit mailing list