Mesa (lp-binning): llvmpipe: introduce mutex and bin iteration functions

Brian Paul brianp at kemper.freedesktop.org
Mon Dec 7 17:16:04 PST 2009


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

Author: Brian Paul <brianp at vmware.com>
Date:   Mon Dec  7 18:04:31 2009 -0700

llvmpipe: introduce mutex and bin iteration functions

---

 src/gallium/drivers/llvmpipe/lp_bin.c |   68 +++++++++++++++++++++++++++++++++
 src/gallium/drivers/llvmpipe/lp_bin.h |   11 +++++
 2 files changed, 79 insertions(+), 0 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_bin.c b/src/gallium/drivers/llvmpipe/lp_bin.c
index 160a8d8..3e294e5 100644
--- a/src/gallium/drivers/llvmpipe/lp_bin.c
+++ b/src/gallium/drivers/llvmpipe/lp_bin.c
@@ -41,9 +41,14 @@ lp_init_bins(struct lp_bins *bins)
 
    bins->data.head =
       bins->data.tail = CALLOC_STRUCT(data_block);
+
+   pipe_mutex_init(bins->mutex);
 }
 
 
+/**
+ * Set bins to empty state.
+ */
 void
 lp_reset_bins(struct lp_bins *bins )
 {
@@ -87,6 +92,9 @@ lp_reset_bins(struct lp_bins *bins )
 }
 
 
+/**
+ * Free all data associated with the given bin, but don't free(bins).
+ */
 void
 lp_free_bin_data(struct lp_bins *bins)
 {
@@ -104,6 +112,8 @@ lp_free_bin_data(struct lp_bins *bins)
 
    FREE(bins->data.head);
    bins->data.head = NULL;
+
+   pipe_mutex_destroy(bins->mutex);
 }
 
 
@@ -191,3 +201,61 @@ lp_bin_state_command( struct lp_bins *bins,
       }
    }
 }
+
+
+/** advance curr_x,y to the next bin */
+static boolean
+next_bin(struct lp_bins *bins)
+{
+   bins->curr_x++;
+   if (bins->curr_x >= bins->tiles_x) {
+      bins->curr_x = 0;
+      bins->curr_y++;
+   }
+   if (bins->curr_y >= bins->tiles_y) {
+      /* no more bins */
+      return FALSE;
+   }
+   return TRUE;
+}
+
+
+void
+lp_bin_iter_begin( struct lp_bins *bins )
+{
+   bins->curr_x = bins->curr_y = -1;
+}
+
+
+/**
+ * Return point to next bin to be rendered.
+ * The lp_bins::curr_x and ::curr_y fields will be advanced.
+ * Multiple rendering threads will call this function to get a chunk
+ * of work (a bin) to work on.
+ */
+struct cmd_bin *
+lp_bin_iter_next( struct lp_bins *bins, int *bin_x, int *bin_y )
+{
+   struct cmd_bin *bin = NULL;
+
+   pipe_mutex_lock(bins->mutex);
+
+   if (bins->curr_x < 0) {
+      /* first bin */
+      bins->curr_x = 0;
+      bins->curr_y = 0;
+   }
+   else if (!next_bin(bins)) {
+      /* no more bins left */
+      goto end;
+   }
+
+   bin = lp_get_bin(bins, bins->curr_x, bins->curr_y);
+   *bin_x = bins->curr_x;
+   *bin_y = bins->curr_y;
+
+end:
+   /*printf("return bin %p at %d, %d\n", (void *) bin, *bin_x, *bin_y);*/
+   pipe_mutex_unlock(bins->mutex);
+   return bin;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_bin.h b/src/gallium/drivers/llvmpipe/lp_bin.h
index fcbb975..24e599e 100644
--- a/src/gallium/drivers/llvmpipe/lp_bin.h
+++ b/src/gallium/drivers/llvmpipe/lp_bin.h
@@ -35,6 +35,7 @@
 #ifndef LP_BIN_H
 #define LP_BIN_H
 
+#include "pipe/p_thread.h"
 #include "lp_tile_soa.h"
 #include "lp_rast.h"
 
@@ -110,6 +111,9 @@ struct lp_bins {
     * This basically the framebuffer size divided by tile size
     */
    unsigned tiles_x, tiles_y;
+
+   int curr_x, curr_y;  /**< for iterating over bins */
+   pipe_mutex mutex;
 };
 
 
@@ -239,4 +243,11 @@ lp_bin_state_command( struct lp_bins *bins,
                       const union lp_rast_cmd_arg arg );
 
 
+void
+lp_bin_iter_begin( struct lp_bins *bins );
+
+struct cmd_bin *
+lp_bin_iter_next( struct lp_bins *bins, int *bin_x, int *bin_y );
+
+
 #endif /* LP_BIN_H */



More information about the mesa-commit mailing list