mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 04:58:05 +02:00
llvmpipe: checkpoint: more thread/queuing changes
Now mapping/unmapping the framebuffer is done by a rasteizer thread rather than the main calling thread.
This commit is contained in:
parent
24d894e557
commit
2bce5c195f
3 changed files with 84 additions and 75 deletions
|
|
@ -108,6 +108,11 @@ struct lp_bins {
|
|||
struct cmd_bin tile[TILES_X][TILES_Y];
|
||||
struct data_block_list data;
|
||||
|
||||
/** the framebuffer to render the bins into */
|
||||
struct pipe_framebuffer_state fb;
|
||||
|
||||
boolean write_depth;
|
||||
|
||||
/**
|
||||
* Number of active tiles in each dimension.
|
||||
* This basically the framebuffer size divided by tile size
|
||||
|
|
|
|||
|
|
@ -40,48 +40,6 @@
|
|||
#include "lp_bin.h"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Map the framebuffer surfaces. Initialize the 'rast' state.
|
||||
|
|
@ -525,6 +483,22 @@ lp_rast_end_tile( struct lp_rasterizer *rast,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* When all the threads are done rasterizing a bin, one thread will
|
||||
* call this function to reset the bin and put it onto the empty queue.
|
||||
*/
|
||||
static void
|
||||
release_bins( struct lp_rasterizer *rast,
|
||||
struct lp_bins *bins )
|
||||
{
|
||||
util_unreference_framebuffer_state( &bins->fb );
|
||||
|
||||
lp_reset_bins( bins );
|
||||
lp_bins_enqueue( rast->empty_bins, bins );
|
||||
rast->curr_bins = NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rasterize commands for a single bin.
|
||||
* \param x, y position of the bin's tile in the framebuffer
|
||||
|
|
@ -615,18 +589,23 @@ lp_rasterize_bins( struct lp_rasterizer *rast,
|
|||
}
|
||||
}
|
||||
|
||||
lp_rast_begin( rast, fb,
|
||||
fb->cbufs[0]!= NULL,
|
||||
fb->zsbuf != NULL && write_depth );
|
||||
/* save framebuffer state in the bin */
|
||||
util_copy_framebuffer_state(&bins->fb, fb);
|
||||
bins->write_depth = write_depth;
|
||||
|
||||
if (rast->num_threads == 0) {
|
||||
/* no threading */
|
||||
|
||||
lp_rast_begin( rast, fb,
|
||||
fb->cbufs[0]!= NULL,
|
||||
fb->zsbuf != NULL && write_depth );
|
||||
|
||||
lp_bin_iter_begin( bins );
|
||||
rasterize_bins( rast, 0, bins, write_depth );
|
||||
|
||||
/* reset bins and put into the empty queue */
|
||||
lp_reset_bins( bins );
|
||||
lp_bins_enqueue( rast->empty_bins, bins);
|
||||
release_bins( rast, bins );
|
||||
|
||||
lp_rast_end( rast );
|
||||
}
|
||||
else {
|
||||
/* threaded rendering! */
|
||||
|
|
@ -634,11 +613,6 @@ lp_rasterize_bins( struct lp_rasterizer *rast,
|
|||
|
||||
lp_bins_enqueue( rast->full_bins, bins );
|
||||
|
||||
/* XXX need to move/fix these */
|
||||
rast->write_depth = write_depth;
|
||||
|
||||
/*lp_bin_iter_begin( bins );*/
|
||||
|
||||
/* signal the threads that there's work to do */
|
||||
for (i = 0; i < rast->num_threads; i++) {
|
||||
pipe_semaphore_signal(&rast->tasks[i].work_ready);
|
||||
|
|
@ -650,8 +624,6 @@ lp_rasterize_bins( struct lp_rasterizer *rast,
|
|||
}
|
||||
}
|
||||
|
||||
lp_rast_end( rast );
|
||||
|
||||
LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
|
@ -671,23 +643,53 @@ thread_func( void *init_data )
|
|||
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);
|
||||
if (task->thread_index == 0) {
|
||||
/* thread[0]:
|
||||
* - get next set of bins to rasterize
|
||||
* - map the framebuffer surfaces
|
||||
*/
|
||||
const struct pipe_framebuffer_state *fb;
|
||||
boolean write_depth;
|
||||
|
||||
rast->curr_bins = lp_bins_dequeue( rast->full_bins );
|
||||
|
||||
lp_bin_iter_begin( rast->curr_bins );
|
||||
|
||||
fb = &rast->curr_bins->fb;
|
||||
write_depth = rast->curr_bins->write_depth;
|
||||
|
||||
lp_rast_begin( rast, fb,
|
||||
fb->cbufs[0] != NULL,
|
||||
fb->zsbuf != NULL && write_depth );
|
||||
}
|
||||
|
||||
/* Wait for all threads to get here so that threads[1+] don't
|
||||
* get a null rast->curr_bins pointer.
|
||||
*/
|
||||
pipe_barrier_wait( &rast->barrier );
|
||||
|
||||
/* do work */
|
||||
if (debug)
|
||||
debug_printf("thread %d doing work\n", task->thread_index);
|
||||
rasterize_bins(rast, task->thread_index,
|
||||
bins, rast->write_depth);
|
||||
rast->curr_bins, rast->curr_bins->write_depth);
|
||||
|
||||
release_current_bin( rast );
|
||||
/* wait for all threads to finish with this set of bins */
|
||||
pipe_barrier_wait( &rast->barrier );
|
||||
|
||||
if (task->thread_index == 0) {
|
||||
/* thread[0]:
|
||||
* - release the bins object
|
||||
* - unmap the framebuffer surfaces
|
||||
*/
|
||||
release_bins( rast, rast->curr_bins );
|
||||
lp_rast_end( rast );
|
||||
}
|
||||
|
||||
/* signal done with work */
|
||||
if (debug)
|
||||
|
|
@ -751,6 +753,9 @@ lp_rast_create( struct pipe_screen *screen, struct lp_bins_queue *empty )
|
|||
|
||||
create_rast_threads(rast);
|
||||
|
||||
/* for synchronizing rasterization threads */
|
||||
pipe_barrier_init( &rast->barrier, rast->num_threads );
|
||||
|
||||
return rast;
|
||||
}
|
||||
|
||||
|
|
@ -768,6 +773,9 @@ void lp_rast_destroy( struct lp_rasterizer *rast )
|
|||
align_free(rast->tasks[i].tile.color);
|
||||
}
|
||||
|
||||
/* for synchronizing rasterization threads */
|
||||
pipe_barrier_destroy( &rast->barrier );
|
||||
|
||||
FREE(rast);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -93,18 +93,6 @@ 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;
|
||||
|
|
@ -122,14 +110,22 @@ struct lp_rasterizer
|
|||
char clear_stencil;
|
||||
} state;
|
||||
|
||||
/** 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;
|
||||
|
||||
/** The bins currently being rasterized by the threads */
|
||||
struct lp_bins *curr_bins;
|
||||
|
||||
/** A task object for each rasterization thread */
|
||||
struct lp_rasterizer_task tasks[MAX_THREADS];
|
||||
|
||||
unsigned num_threads;
|
||||
pipe_thread threads[MAX_THREADS];
|
||||
|
||||
struct lp_bins *bins;
|
||||
boolean write_depth;
|
||||
/** For synchronizing the rasterization threads */
|
||||
pipe_barrier barrier;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue