From 270f15486072b0a2fbea2a21b7a4a9d4c76d4bfb Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 7 Dec 2009 18:04:31 -0700 Subject: 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(+) diff --git a/src/gallium/drivers/llvmpipe/lp_bin.c b/src/gallium/drivers/llvmpipe/lp_bin.c index 160a8d865ba..3e294e57994 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 fcbb975ad64..24e599ea66e 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 */ -- cgit v1.2.3