/** * Called by setup module when it has something for us to render. */ void lp_rast_queue_scene( struct lp_rasterizer *rast, struct lp_scene *scene) { LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); if (rast->num_threads == 0) { /* no threading */ lp_rast_begin( rast, scene ); rasterize_scene( &rast->tasks[0], scene ); lp_rast_end( rast ); rast->curr_scene = NULL; } else { /* threaded rendering! */ unsigned i; lp_scene_enqueue( rast->full_scenes, scene ); /* 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); } } LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__); }
/** * This is the thread's main entrypoint. * It's a simple loop: * 1. wait for work * 2. do work * 3. signal that we're done */ static PIPE_THREAD_ROUTINE( thread_function, init_data ) { struct lp_rasterizer_task *task = (struct lp_rasterizer_task *) init_data; struct lp_rasterizer *rast = task->rast; boolean debug = false; unsigned fpstate = util_fpstate_get(); /* Make sure that denorms are treated like zeros. This is * the behavior required by D3D10. OpenGL doesn't care. */ util_fpstate_set_denorms_to_zero(fpstate); while (1) { /* wait for work */ if (debug) 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 */ lp_rast_begin( rast, lp_scene_dequeue( rast->full_scenes, TRUE ) ); } /* Wait for all threads to get here so that threads[1+] don't * get a null rast->curr_scene pointer. */ pipe_barrier_wait( &rast->barrier ); /* do work */ if (debug) debug_printf("thread %d doing work\n", task->thread_index); 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) { 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); } return 0; }
/** * This is the thread's main entrypoint. * It's a simple loop: * 1. wait for work * 2. do work * 3. signal that we're done */ static PIPE_THREAD_ROUTINE( thread_func, init_data ) { struct lp_rasterizer_task *task = (struct lp_rasterizer_task *) init_data; struct lp_rasterizer *rast = task->rast; boolean debug = false; while (1) { /* wait for work */ if (debug) 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 */ lp_rast_begin( rast, lp_scene_dequeue( rast->full_scenes, TRUE ) ); } /* Wait for all threads to get here so that threads[1+] don't * get a null rast->curr_scene pointer. */ pipe_barrier_wait( &rast->barrier ); /* do work */ if (debug) debug_printf("thread %d doing work\n", task->thread_index); 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) { 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); } return NULL; }
/** * Called by setup module when it has something for us to render. */ void lp_rast_queue_scene( struct lp_rasterizer *rast, struct lp_scene *scene) { LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__); if (rast->num_threads == 0) { /* no threading */ unsigned fpstate = util_fpstate_get(); /* Make sure that denorms are treated like zeros. This is * the behavior required by D3D10. OpenGL doesn't care. */ util_fpstate_set_denorms_to_zero(fpstate); lp_rast_begin( rast, scene ); rasterize_scene( &rast->tasks[0], scene ); lp_rast_end( rast ); util_fpstate_set(fpstate); rast->curr_scene = NULL; } else { /* threaded rendering! */ unsigned i; lp_scene_enqueue( rast->full_scenes, scene ); /* 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); } } LP_DBG(DEBUG_SETUP, "%s done \n", __FUNCTION__); }