diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_rast.c | 64 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_rast_priv.h | 8 | 
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 5659ae2ca5..0cd95e0ca7 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 4e4f8b36a7..f174aa1505 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; | 
