diff options
author | Michal Krol <[email protected]> | 2010-03-10 15:49:30 +0100 |
---|---|---|
committer | Michal Krol <[email protected]> | 2010-03-10 15:49:30 +0100 |
commit | 3ce4375912c8ea488460e593e07c5bb15b92dca9 (patch) | |
tree | 1011fa439bd829fd46a44fd99478135848800e73 /src/gallium/drivers/llvmpipe/lp_rast.c | |
parent | f59f28093ea827bd234d8e1a36bdd56a9fce5f09 (diff) | |
parent | 9b348d0ed125a22be3f318ac60cef6f201edfdab (diff) |
Merge branch 'master' into gallium-sampler-view
Conflicts:
src/gallium/auxiliary/Makefile
src/gallium/auxiliary/SConscript
src/gallium/auxiliary/tgsi/tgsi_exec.c
src/gallium/auxiliary/util/u_blitter.c
src/gallium/drivers/i915/i915_context.h
src/gallium/drivers/i965/brw_context.h
src/gallium/drivers/llvmpipe/lp_context.h
src/gallium/drivers/nv50/nv50_context.h
src/gallium/drivers/nv50/nv50_state_validate.c
src/gallium/drivers/nv50/nv50_tex.c
src/gallium/drivers/r300/r300_blit.c
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_emit.c
src/gallium/drivers/r300/r300_state.c
src/gallium/drivers/softpipe/sp_context.h
src/gallium/drivers/svga/svga_context.h
src/gallium/drivers/svga/svga_pipe_sampler.c
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c')
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_rast.c | 431 |
1 files changed, 160 insertions, 271 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 6dbcb3c9b31..dd9a8e8856f 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -42,128 +42,73 @@ #include "lp_scene.h" -/** - * Begin the rasterization phase. - * Map the framebuffer surfaces. Initialize the 'rast' state. +/* Begin rasterizing a scene: */ static boolean lp_rast_begin( struct lp_rasterizer *rast, - const struct pipe_framebuffer_state *fb, - boolean write_color, - boolean write_zstencil ) + struct lp_scene *scene ) { - struct pipe_screen *screen = rast->screen; - struct pipe_surface *cbuf, *zsbuf; + const struct pipe_framebuffer_state *fb = &scene->fb; + boolean write_color = fb->nr_cbufs != 0; + boolean write_zstencil = fb->zsbuf != NULL; int i; - LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); + rast->curr_scene = scene; - util_copy_framebuffer_state(&rast->state.fb, fb); + LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); + rast->state.nr_cbufs = scene->fb.nr_cbufs; rast->state.write_zstencil = write_zstencil; rast->state.write_color = write_color; - - rast->check_for_clipped_tiles = (fb->width % TILE_SIZE != 0 || - fb->height % TILE_SIZE != 0); - - for (i = 0; i < rast->state.fb.nr_cbufs; i++) { - cbuf = rast->state.fb.cbufs[i]; - if (cbuf) { - rast->cbuf_transfer[i] = screen->get_tex_transfer(rast->screen, - cbuf->texture, - cbuf->face, - cbuf->level, - cbuf->zslice, - PIPE_TRANSFER_READ_WRITE, - 0, 0, - cbuf->width, - cbuf->height); - if (!rast->cbuf_transfer[i]) - goto fail; - - rast->cbuf_map[i] = screen->transfer_map(rast->screen, - rast->cbuf_transfer[i]); - if (!rast->cbuf_map[i]) - goto fail; - } + for (i = 0; i < rast->state.nr_cbufs; i++) { + rast->cbuf[i].map = scene->cbuf_map[i]; + rast->cbuf[i].format = scene->cbuf_transfer[i]->texture->format; + rast->cbuf[i].width = scene->cbuf_transfer[i]->width; + rast->cbuf[i].height = scene->cbuf_transfer[i]->height; + rast->cbuf[i].stride = scene->cbuf_transfer[i]->stride; } - zsbuf = rast->state.fb.zsbuf; - if (zsbuf) { - rast->zsbuf_transfer = screen->get_tex_transfer(rast->screen, - zsbuf->texture, - zsbuf->face, - zsbuf->level, - zsbuf->zslice, - PIPE_TRANSFER_READ_WRITE, - 0, 0, - zsbuf->width, - zsbuf->height); - if (!rast->zsbuf_transfer) - goto fail; - - rast->zsbuf_map = screen->transfer_map(rast->screen, - rast->zsbuf_transfer); - if (!rast->zsbuf_map) - goto fail; + if (write_zstencil) { + rast->zsbuf.map = scene->zsbuf_map; + rast->zsbuf.stride = scene->zsbuf_transfer->stride; + rast->zsbuf.blocksize = + util_format_get_blocksize(scene->zsbuf_transfer->texture->format); } + lp_scene_bin_iter_begin( scene ); + return TRUE; - -fail: - /* Unmap and release transfers? - */ - return FALSE; } -/** - * Finish the rasterization phase. - * Unmap framebuffer surfaces. - */ static void lp_rast_end( struct lp_rasterizer *rast ) { - struct pipe_screen *screen = rast->screen; - unsigned i; - - for (i = 0; i < rast->state.fb.nr_cbufs; i++) { - if (rast->cbuf_map[i]) - screen->transfer_unmap(screen, rast->cbuf_transfer[i]); - - if (rast->cbuf_transfer[i]) - screen->tex_transfer_destroy(rast->cbuf_transfer[i]); - - rast->cbuf_transfer[i] = NULL; - rast->cbuf_map[i] = NULL; - } + int i; - if (rast->zsbuf_map) - screen->transfer_unmap(screen, rast->zsbuf_transfer); + lp_scene_reset( rast->curr_scene ); - if (rast->zsbuf_transfer) - screen->tex_transfer_destroy(rast->zsbuf_transfer); + for (i = 0; i < rast->state.nr_cbufs; i++) + rast->cbuf[i].map = NULL; - rast->zsbuf_transfer = NULL; - rast->zsbuf_map = NULL; + rast->zsbuf.map = NULL; + rast->curr_scene = NULL; } - /** * Begining rasterization of a tile. * \param x window X position of the tile, in pixels * \param y window Y position of the tile, in pixels */ static void -lp_rast_start_tile( struct lp_rasterizer *rast, - unsigned thread_index, - unsigned x, unsigned y ) +lp_rast_start_tile(struct lp_rasterizer_task *task, + unsigned x, unsigned y) { LP_DBG(DEBUG_RAST, "%s %d,%d\n", __FUNCTION__, x, y); - rast->tasks[thread_index].x = x; - rast->tasks[thread_index].y = y; + task->x = x; + task->y = y; } @@ -171,12 +116,13 @@ lp_rast_start_tile( struct lp_rasterizer *rast, * Clear the rasterizer's current color tile. * This is a bin command called during bin processing. */ -void lp_rast_clear_color( struct lp_rasterizer *rast, - unsigned thread_index, - const union lp_rast_cmd_arg arg ) +void +lp_rast_clear_color(struct lp_rasterizer_task *task, + const union lp_rast_cmd_arg arg) { + struct lp_rasterizer *rast = task->rast; const uint8_t *clear_color = arg.clear_color; - uint8_t **color_tile = rast->tasks[thread_index].tile.color; + uint8_t **color_tile = task->tile.color; unsigned i; LP_DBG(DEBUG_RAST, "%s 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__, @@ -189,7 +135,7 @@ void lp_rast_clear_color( struct lp_rasterizer *rast, clear_color[1] == clear_color[2] && clear_color[2] == clear_color[3]) { /* clear to grayscale value {x, x, x, x} */ - for (i = 0; i < rast->state.fb.nr_cbufs; i++) { + for (i = 0; i < rast->state.nr_cbufs; i++) { memset(color_tile[i], clear_color[0], TILE_SIZE * TILE_SIZE * 4); } } @@ -200,7 +146,7 @@ void lp_rast_clear_color( struct lp_rasterizer *rast, * works. */ const unsigned chunk = TILE_SIZE / 4; - for (i = 0; i < rast->state.fb.nr_cbufs; i++) { + for (i = 0; i < rast->state.nr_cbufs; i++) { uint8_t *c = color_tile[i]; unsigned j; for (j = 0; j < 4 * TILE_SIZE; j++) { @@ -225,24 +171,24 @@ void lp_rast_clear_color( struct lp_rasterizer *rast, * Clear the rasterizer's current z/stencil tile. * This is a bin command called during bin processing. */ -void lp_rast_clear_zstencil( struct lp_rasterizer *rast, - unsigned thread_index, - const union lp_rast_cmd_arg arg) +void +lp_rast_clear_zstencil(struct lp_rasterizer_task *task, + const union lp_rast_cmd_arg arg) { - struct lp_rasterizer_task *task = &rast->tasks[thread_index]; + struct lp_rasterizer *rast = task->rast; const unsigned tile_x = task->x; const unsigned tile_y = task->y; - const unsigned height = TILE_SIZE/TILE_VECTOR_HEIGHT; - const unsigned width = TILE_SIZE*TILE_VECTOR_HEIGHT; - unsigned block_size = util_format_get_blocksize(rast->zsbuf_transfer->texture->format); + const unsigned height = TILE_SIZE / TILE_VECTOR_HEIGHT; + const unsigned width = TILE_SIZE * TILE_VECTOR_HEIGHT; + unsigned block_size = rast->zsbuf.blocksize; uint8_t *dst; - unsigned dst_stride = rast->zsbuf_transfer->stride*TILE_VECTOR_HEIGHT; + unsigned dst_stride = rast->zsbuf.stride * TILE_VECTOR_HEIGHT; unsigned i, j; LP_DBG(DEBUG_RAST, "%s 0x%x\n", __FUNCTION__, arg.clear_zstencil); - assert(rast->zsbuf_map); - if (!rast->zsbuf_map) + assert(rast->zsbuf.map); + if (!rast->zsbuf.map) return; LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); @@ -278,8 +224,8 @@ void lp_rast_clear_zstencil( struct lp_rasterizer *rast, } break; default: - assert(0); - break; + assert(0); + break; } } @@ -288,55 +234,42 @@ void lp_rast_clear_zstencil( struct lp_rasterizer *rast, * Load tile color from the framebuffer surface. * This is a bin command called during bin processing. */ -void lp_rast_load_color( struct lp_rasterizer *rast, - unsigned thread_index, - const union lp_rast_cmd_arg arg) +void +lp_rast_load_color(struct lp_rasterizer_task *task, + const union lp_rast_cmd_arg arg) { - struct lp_rasterizer_task *task = &rast->tasks[thread_index]; - const unsigned x = task->x; - const unsigned y = task->y; + struct lp_rasterizer *rast = task->rast; + const unsigned x = task->x, y = task->y; unsigned i; LP_DBG(DEBUG_RAST, "%s at %u, %u\n", __FUNCTION__, x, y); - for (i = 0; i < rast->state.fb.nr_cbufs; i++) { - struct pipe_transfer *transfer = rast->cbuf_transfer[i]; - int w = TILE_SIZE; - int h = TILE_SIZE; - - if (x >= transfer->width) - continue; - - if (y >= transfer->height) + for (i = 0; i < rast->state.nr_cbufs; i++) { + if (x >= rast->cbuf[i].width || y >= rast->cbuf[i].height) continue; - assert(w >= 0); - assert(h >= 0); - assert(w <= TILE_SIZE); - assert(h <= TILE_SIZE); - - lp_tile_read_4ub(transfer->texture->format, + lp_tile_read_4ub(rast->cbuf[i].format, task->tile.color[i], - rast->cbuf_map[i], - transfer->stride, + rast->cbuf[i].map, + rast->cbuf[i].stride, x, y, - w, h); + TILE_SIZE, TILE_SIZE); LP_COUNT(nr_color_tile_load); } } -void lp_rast_set_state( struct lp_rasterizer *rast, - unsigned thread_index, - const union lp_rast_cmd_arg arg ) +void +lp_rast_set_state(struct lp_rasterizer_task *task, + const union lp_rast_cmd_arg arg) { const struct lp_rast_state *state = arg.set_state; LP_DBG(DEBUG_RAST, "%s %p\n", __FUNCTION__, (void *) state); /* just set the current state pointer for this rasterizer */ - rast->tasks[thread_index].current_state = state; + task->current_state = state; } @@ -346,16 +279,15 @@ void lp_rast_set_state( struct lp_rasterizer *rast, * completely contained inside a triangle. * This is a bin command called during bin processing. */ -void lp_rast_shade_tile( struct lp_rasterizer *rast, - unsigned thread_index, - const union lp_rast_cmd_arg arg ) +void +lp_rast_shade_tile(struct lp_rasterizer_task *task, + const union lp_rast_cmd_arg arg) { - struct lp_rasterizer_task *task = &rast->tasks[thread_index]; + struct lp_rasterizer *rast = task->rast; const struct lp_rast_state *state = task->current_state; struct lp_rast_tile *tile = &task->tile; const struct lp_rast_shader_inputs *inputs = arg.shade_tile; - const unsigned tile_x = task->x; - const unsigned tile_y = task->y; + const unsigned tile_x = task->x, tile_y = task->y; unsigned x, y; LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); @@ -371,7 +303,7 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, block_offset = ((y / 4) * (16 * 16) + (x / 4) * 16); /* color buffer */ - for (i = 0; i < rast->state.fb.nr_cbufs; i++) + for (i = 0; i < rast->state.nr_cbufs; i++) color[i] = tile->color[i] + 4 * block_offset; /* depth buffer */ @@ -396,14 +328,13 @@ void lp_rast_shade_tile( struct lp_rasterizer *rast, * Compute shading for a 4x4 block of pixels. * This is a bin command called during bin processing. */ -void lp_rast_shade_quads( struct lp_rasterizer *rast, - unsigned thread_index, +void lp_rast_shade_quads( struct lp_rasterizer_task *task, const struct lp_rast_shader_inputs *inputs, unsigned x, unsigned y, int32_t c1, int32_t c2, int32_t c3) { - struct lp_rasterizer_task *task = &rast->tasks[thread_index]; const struct lp_rast_state *state = task->current_state; + struct lp_rasterizer *rast = task->rast; struct lp_rast_tile *tile = &task->tile; uint8_t *color[PIPE_MAX_COLOR_BUFS]; void *depth; @@ -411,7 +342,6 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, unsigned ix, iy; int block_offset; -#ifdef DEBUG assert(state); /* Sanity checks */ @@ -420,7 +350,6 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, assert((x % 4) == 0); assert((y % 4) == 0); -#endif ix = x % TILE_SIZE; iy = y % TILE_SIZE; @@ -429,22 +358,19 @@ void lp_rast_shade_quads( struct lp_rasterizer *rast, block_offset = ((iy / 4) * (16 * 16) + (ix / 4) * 16); /* color buffer */ - for (i = 0; i < rast->state.fb.nr_cbufs; i++) + for (i = 0; i < rast->state.nr_cbufs; i++) color[i] = tile->color[i] + 4 * block_offset; /* depth buffer */ depth = lp_rast_depth_pointer(rast, x, y); - -#ifdef DEBUG assert(lp_check_alignment(tile->color[0], 16)); assert(lp_check_alignment(state->jit_context.blend_color, 16)); assert(lp_check_alignment(inputs->step[0], 16)); assert(lp_check_alignment(inputs->step[1], 16)); assert(lp_check_alignment(inputs->step[2], 16)); -#endif /* run shader */ state->jit_function[1]( &state->jit_context, @@ -515,66 +441,48 @@ outline_subtiles(uint8_t *tile) /** * Write the rasterizer's color tile to the framebuffer. */ -static void lp_rast_store_color( struct lp_rasterizer *rast, - unsigned thread_index) +static void +lp_rast_store_color(struct lp_rasterizer_task *task) { - struct lp_rasterizer_task *task = &rast->tasks[thread_index]; - const unsigned x = task->x; - const unsigned y = task->y; + struct lp_rasterizer *rast = task->rast; + const unsigned x = task->x, y = task->y; unsigned i; - for (i = 0; i < rast->state.fb.nr_cbufs; i++) { - struct pipe_transfer *transfer = rast->cbuf_transfer[i]; - int w = TILE_SIZE; - int h = TILE_SIZE; - - if (x >= transfer->width) + for (i = 0; i < rast->state.nr_cbufs; i++) { + if (x >= rast->cbuf[i].width) continue; - if (y >= transfer->height) + if (y >= rast->cbuf[i].height) continue; - LP_DBG(DEBUG_RAST, "%s [%u] %d,%d %dx%d\n", __FUNCTION__, - thread_index, x, y, w, h); + LP_DBG(DEBUG_RAST, "%s [%u] %d,%d\n", __FUNCTION__, + task->thread_index, x, y); if (LP_DEBUG & DEBUG_SHOW_SUBTILES) outline_subtiles(task->tile.color[i]); else if (LP_DEBUG & DEBUG_SHOW_TILES) outline_tile(task->tile.color[i]); - lp_tile_write_4ub(transfer->texture->format, + lp_tile_write_4ub(rast->cbuf[i].format, task->tile.color[i], - rast->cbuf_map[i], - transfer->stride, + rast->cbuf[i].map, + rast->cbuf[i].stride, x, y, - w, h); + TILE_SIZE, TILE_SIZE); LP_COUNT(nr_color_tile_store); } } -/** - * Write the rasterizer's tiles to the framebuffer. - */ -static void -lp_rast_end_tile( struct lp_rasterizer *rast, - unsigned thread_index ) -{ - LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); - - if (rast->state.write_color) - lp_rast_store_color(rast, thread_index); -} - /** * Signal on a fence. This is called during bin execution/rasterization. * Called per thread. */ -void lp_rast_fence( struct lp_rasterizer *rast, - unsigned thread_index, - const union lp_rast_cmd_arg arg ) +void +lp_rast_fence(struct lp_rasterizer_task *task, + const union lp_rast_cmd_arg arg) { struct lp_fence *fence = arg.fence; @@ -592,20 +500,6 @@ void lp_rast_fence( struct lp_rasterizer *rast, } -/** - * When all the threads are done rasterizing a scene, one thread will - * call this function to reset the scene and put it onto the empty queue. - */ -static void -release_scene( struct lp_rasterizer *rast, - struct lp_scene *scene ) -{ - util_unreference_framebuffer_state( &scene->fb ); - - lp_scene_reset( scene ); - lp_scene_enqueue( rast->empty_scenes, scene ); - rast->curr_scene = NULL; -} /** @@ -615,25 +509,31 @@ release_scene( struct lp_rasterizer *rast, * Called per thread. */ static void -rasterize_bin( struct lp_rasterizer *rast, - unsigned thread_index, - const struct cmd_bin *bin, - int x, int y) +rasterize_bin(struct lp_rasterizer_task *task, + const struct cmd_bin *bin, + int x, int y) { const struct cmd_block_list *commands = &bin->commands; struct cmd_block *block; unsigned k; - lp_rast_start_tile( rast, thread_index, x, y ); + lp_rast_start_tile( task, x * TILE_SIZE, y * TILE_SIZE ); /* simply execute each of the commands in the block list */ for (block = commands->head; block; block = block->next) { for (k = 0; k < block->count; k++) { - block->cmd[k]( rast, thread_index, block->arg[k] ); + block->cmd[k]( task, block->arg[k] ); } } - lp_rast_end_tile( rast, thread_index ); + /* Write the rasterizer's tiles to the framebuffer. + */ + if (task->rast->state.write_color) + lp_rast_store_color(task); + + /* Free data for this bin. + */ + lp_scene_bin_reset( task->rast->curr_scene, x, y); } @@ -717,10 +617,8 @@ is_empty_bin( const struct cmd_bin *bin ) * Called per thread. */ static void -rasterize_scene( struct lp_rasterizer *rast, - unsigned thread_index, - struct lp_scene *scene, - bool write_depth ) +rasterize_scene(struct lp_rasterizer_task *task, + struct lp_scene *scene) { /* loop over scene bins, rasterize each */ #if 0 @@ -728,9 +626,8 @@ rasterize_scene( struct lp_rasterizer *rast, unsigned i, j; for (i = 0; i < scene->tiles_x; i++) { for (j = 0; j < scene->tiles_y; j++) { - struct cmd_bin *bin = lp_get_bin(scene, i, j); - rasterize_bin( rast, thread_index, - bin, i * TILE_SIZE, j * TILE_SIZE ); + struct cmd_bin *bin = lp_scene_get_bin(scene, i, j); + rasterize_bin(task, bin, i, j); } } } @@ -742,7 +639,7 @@ rasterize_scene( struct lp_rasterizer *rast, assert(scene); while ((bin = lp_scene_bin_iter_next(scene, &x, &y))) { if (!is_empty_bin( bin )) - rasterize_bin( rast, thread_index, bin, x * TILE_SIZE, y * TILE_SIZE); + rasterize_bin(task, bin, x, y); } } #endif @@ -753,44 +650,20 @@ rasterize_scene( struct lp_rasterizer *rast, * Called by setup module when it has something for us to render. */ void -lp_rasterize_scene( struct lp_rasterizer *rast, - struct lp_scene *scene, - const struct pipe_framebuffer_state *fb, - bool write_depth ) +lp_rast_queue_scene( struct lp_rasterizer *rast, + struct lp_scene *scene) { - boolean debug = false; - LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); - if (debug) { - unsigned x, y; - debug_printf("rasterize scene:\n"); - debug_printf(" data size: %u\n", lp_scene_data_size(scene)); - for (y = 0; y < scene->tiles_y; y++) { - for (x = 0; x < scene->tiles_x; x++) { - debug_printf(" bin %u, %u size: %u\n", x, y, - lp_scene_bin_size(scene, x, y)); - } - } - } - - /* save framebuffer state in the bin */ - util_copy_framebuffer_state(&scene->fb, fb); - scene->write_depth = write_depth; - if (rast->num_threads == 0) { /* no threading */ - lp_rast_begin( rast, fb, - fb->nr_cbufs != 0, /* always write color if cbufs present */ - fb->zsbuf != NULL && write_depth ); + lp_rast_begin( rast, scene ); - lp_scene_bin_iter_begin( scene ); - rasterize_scene( rast, 0, scene, write_depth ); + rasterize_scene( &rast->tasks[0], scene ); - release_scene( rast, scene ); - - lp_rast_end( rast ); + lp_scene_reset( scene ); + rast->curr_scene = NULL; } else { /* threaded rendering! */ @@ -802,14 +675,26 @@ lp_rasterize_scene( struct lp_rasterizer *rast, for (i = 0; i < rast->num_threads; i++) { pipe_semaphore_signal(&rast->tasks[i].work_ready); } + } + + LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__); +} + + +void +lp_rast_finish( struct lp_rasterizer *rast ) +{ + if (rast->num_threads == 0) { + /* nothing to do */ + } + else { + int i; /* wait for work to complete */ for (i = 0; i < rast->num_threads; i++) { pipe_semaphore_wait(&rast->tasks[i].work_done); } } - - LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__); } @@ -832,24 +717,16 @@ static PIPE_THREAD_ROUTINE( thread_func, init_data ) debug_printf("thread %d waiting for work\n", task->thread_index); pipe_semaphore_wait(&task->work_ready); + if (rast->exit_flag) + break; + if (task->thread_index == 0) { /* thread[0]: * - get next scene to rasterize * - map the framebuffer surfaces */ - const struct pipe_framebuffer_state *fb; - boolean write_depth; - - rast->curr_scene = lp_scene_dequeue( rast->full_scenes, TRUE ); - - lp_scene_bin_iter_begin( rast->curr_scene ); - - fb = &rast->curr_scene->fb; - write_depth = rast->curr_scene->write_depth; - - lp_rast_begin( rast, fb, - fb->nr_cbufs != 0, - fb->zsbuf != NULL && write_depth ); + lp_rast_begin( rast, + lp_scene_dequeue( rast->full_scenes, TRUE ) ); } /* Wait for all threads to get here so that threads[1+] don't @@ -860,26 +737,23 @@ static PIPE_THREAD_ROUTINE( thread_func, init_data ) /* do work */ if (debug) debug_printf("thread %d doing work\n", task->thread_index); - rasterize_scene(rast, - task->thread_index, - rast->curr_scene, - rast->curr_scene->write_depth); + + rasterize_scene(task, + rast->curr_scene); /* wait for all threads to finish with this scene */ pipe_barrier_wait( &rast->barrier ); + /* XXX: shouldn't be necessary: + */ if (task->thread_index == 0) { - /* thread[0]: - * - release the scene object - * - unmap the framebuffer surfaces - */ - release_scene( rast, rast->curr_scene ); lp_rast_end( rast ); } /* signal done with work */ if (debug) debug_printf("thread %d done working\n", task->thread_index); + pipe_semaphore_signal(&task->work_done); } @@ -922,7 +796,7 @@ create_rast_threads(struct lp_rasterizer *rast) * processing them. */ struct lp_rasterizer * -lp_rast_create( struct pipe_screen *screen, struct lp_scene_queue *empty ) +lp_rast_create( void ) { struct lp_rasterizer *rast; unsigned i, cbuf; @@ -931,9 +805,6 @@ lp_rast_create( struct pipe_screen *screen, struct lp_scene_queue *empty ) if(!rast) return NULL; - rast->screen = screen; - - rast->empty_scenes = empty; rast->full_scenes = lp_scene_queue_create(); for (i = 0; i < Elements(rast->tasks); i++) { @@ -961,13 +832,31 @@ void lp_rast_destroy( struct lp_rasterizer *rast ) { unsigned i, cbuf; - util_unreference_framebuffer_state(&rast->state.fb); - for (i = 0; i < Elements(rast->tasks); i++) { for (cbuf = 0; cbuf < PIPE_MAX_COLOR_BUFS; cbuf++ ) align_free(rast->tasks[i].tile.color[cbuf]); } + /* Set exit_flag and signal each thread's work_ready semaphore. + * Each thread will be woken up, notice that the exit_flag is set and + * break out of its main loop. The thread will then exit. + */ + rast->exit_flag = TRUE; + for (i = 0; i < rast->num_threads; i++) { + pipe_semaphore_signal(&rast->tasks[i].work_ready); + } + + /* Wait for threads to terminate before cleaning up per-thread data */ + for (i = 0; i < rast->num_threads; i++) { + pipe_thread_wait(rast->threads[i]); + } + + /* Clean up per-thread data */ + for (i = 0; i < rast->num_threads; i++) { + pipe_semaphore_destroy(&rast->tasks[i].work_ready); + pipe_semaphore_destroy(&rast->tasks[i].work_done); + } + /* for synchronizing rasterization threads */ pipe_barrier_destroy( &rast->barrier ); |