summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2009-12-10 14:56:30 -0700
committerBrian Paul <[email protected]>2009-12-10 14:56:30 -0700
commit9509f73c2147a9e225b5ef69a646e5dd711573f5 (patch)
treef181e60199add67a95ad30f26482ca10b08f1e3a /src
parent9a6567f1ed88727545f747e8670b713f17627c94 (diff)
llvmpipe: checkpoint: use empty/full bin queues
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.c64
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast_priv.h8
2 files changed, 64 insertions, 8 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
index 5659ae2ca5a..0cd95e0ca72 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast.c
@@ -40,6 +40,46 @@
+/**
+ * Called by rasterization threads to get the next chunk of work.
+ * We use a lock to make sure that all the threads get the same bins.
+ */
+static struct lp_bins *
+get_next_full_bin( struct lp_rasterizer *rast )
+{
+ pipe_mutex_lock( rast->get_bin_mutex );
+ if (!rast->curr_bins) {
+ /* this will wait until there's something in the queue */
+ rast->curr_bins = lp_bins_dequeue( rast->full_bins );
+ rast->release_count = 0;
+
+ lp_bin_iter_begin( rast->curr_bins );
+ }
+ pipe_mutex_unlock( rast->get_bin_mutex );
+ return rast->curr_bins;
+}
+
+
+/**
+ * Called by rasterization threads after they've finished with
+ * the current bin. When all threads have called this, we reset
+ * the bin and put it into the 'empty bins' queue.
+ */
+static void
+release_current_bin( struct lp_rasterizer *rast )
+{
+ pipe_mutex_lock( rast->get_bin_mutex );
+ rast->release_count++;
+ if (rast->release_count == rast->num_threads) {
+ assert(rast->curr_bins);
+ lp_reset_bins( rast->curr_bins );
+ lp_bins_enqueue( rast->empty_bins, rast->curr_bins );
+ rast->curr_bins = NULL;
+ }
+ pipe_mutex_unlock( rast->get_bin_mutex );
+}
+
+
/**
* Begin the rasterization phase.
@@ -488,6 +528,7 @@ lp_rast_end_tile( struct lp_rasterizer *rast,
* Rasterize commands for a single bin.
* \param x, y position of the bin's tile in the framebuffer
* Must be called between lp_rast_begin() and lp_rast_end().
+ * Called per thread.
*/
static void
rasterize_bin( struct lp_rasterizer *rast,
@@ -514,6 +555,7 @@ rasterize_bin( struct lp_rasterizer *rast,
/**
* Rasterize/execute all bins.
+ * Called per thread.
*/
static void
rasterize_bins( struct lp_rasterizer *rast,
@@ -539,6 +581,7 @@ rasterize_bins( struct lp_rasterizer *rast,
struct cmd_bin *bin;
int x, y;
+ assert(bins);
while ((bin = lp_bin_iter_next(bins, &x, &y))) {
rasterize_bin( rast, thread_index, bin, x * TILE_SIZE, y * TILE_SIZE);
}
@@ -593,11 +636,13 @@ lp_rasterize_bins( struct lp_rasterizer *rast,
/* threaded rendering! */
unsigned i;
- rast->bins = bins;
+ lp_bins_enqueue( rast->full_bins, bins );
+
+ /* XXX need to move/fix these */
rast->fb = fb;
rast->write_depth = write_depth;
- lp_bin_iter_begin( bins );
+ /*lp_bin_iter_begin( bins );*/
/* signal the threads that there's work to do */
for (i = 0; i < rast->num_threads; i++) {
@@ -608,10 +653,6 @@ lp_rasterize_bins( struct lp_rasterizer *rast,
for (i = 0; i < rast->num_threads; i++) {
pipe_semaphore_wait(&rast->tasks[i].work_done);
}
-
- /* reset bins and put into the empty queue */
- lp_reset_bins( bins );
- lp_bins_enqueue( rast->empty_bins, bins);
}
lp_rast_end( rast );
@@ -632,19 +673,26 @@ thread_func( void *init_data )
{
struct lp_rasterizer_task *task = (struct lp_rasterizer_task *) init_data;
struct lp_rasterizer *rast = task->rast;
- int debug = 0;
+ boolean debug = false;
while (1) {
+ struct lp_bins *bins;
+
/* wait for work */
if (debug)
debug_printf("thread %d waiting for work\n", task->thread_index);
pipe_semaphore_wait(&task->work_ready);
+ bins = get_next_full_bin( rast );
+ assert(bins);
+
/* do work */
if (debug)
debug_printf("thread %d doing work\n", task->thread_index);
rasterize_bins(rast, task->thread_index,
- rast->bins, rast->fb, rast->write_depth);
+ bins, rast->fb, rast->write_depth);
+
+ release_current_bin( rast );
/* signal done with work */
if (debug)
diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
index 4e4f8b36a7a..f174aa15052 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
@@ -95,10 +95,18 @@ struct lp_rasterizer
boolean clipped_tile;
boolean check_for_clipped_tiles;
+ /** The incoming queue of filled bins to rasterize */
struct lp_bins_queue *full_bins;
+ /** The outgoing queue of emptied bins to return to setup modulee */
struct lp_bins_queue *empty_bins;
+
pipe_mutex get_bin_mutex;
+ /** The bins currently being rasterized by the threads */
+ struct lp_bins *curr_bins;
+ /** Counter to determine when all threads are done with current bin */
+ unsigned release_count;
+
/* Framebuffer stuff
*/
struct pipe_screen *screen;