Browse Source

llvmpipe: rip out old mulithread support

tags/mesa_7_6_rc1
Keith Whitwell 16 years ago
parent
commit
4486012245

+ 22
- 26
src/gallium/drivers/llvmpipe/lp_context.c View File

@@ -88,19 +88,17 @@ static void llvmpipe_destroy( struct pipe_context *pipe )
if (llvmpipe->draw)
draw_destroy( llvmpipe->draw );

for (i = 0; i < LP_NUM_QUAD_THREADS; i++) {
llvmpipe->quad[i].polygon_stipple->destroy( llvmpipe->quad[i].polygon_stipple );
llvmpipe->quad[i].earlyz->destroy( llvmpipe->quad[i].earlyz );
llvmpipe->quad[i].shade->destroy( llvmpipe->quad[i].shade );
llvmpipe->quad[i].alpha_test->destroy( llvmpipe->quad[i].alpha_test );
llvmpipe->quad[i].depth_test->destroy( llvmpipe->quad[i].depth_test );
llvmpipe->quad[i].stencil_test->destroy( llvmpipe->quad[i].stencil_test );
llvmpipe->quad[i].occlusion->destroy( llvmpipe->quad[i].occlusion );
llvmpipe->quad[i].coverage->destroy( llvmpipe->quad[i].coverage );
llvmpipe->quad[i].blend->destroy( llvmpipe->quad[i].blend );
llvmpipe->quad[i].colormask->destroy( llvmpipe->quad[i].colormask );
llvmpipe->quad[i].output->destroy( llvmpipe->quad[i].output );
}
llvmpipe->quad.polygon_stipple->destroy( llvmpipe->quad.polygon_stipple );
llvmpipe->quad.earlyz->destroy( llvmpipe->quad.earlyz );
llvmpipe->quad.shade->destroy( llvmpipe->quad.shade );
llvmpipe->quad.alpha_test->destroy( llvmpipe->quad.alpha_test );
llvmpipe->quad.depth_test->destroy( llvmpipe->quad.depth_test );
llvmpipe->quad.stencil_test->destroy( llvmpipe->quad.stencil_test );
llvmpipe->quad.occlusion->destroy( llvmpipe->quad.occlusion );
llvmpipe->quad.coverage->destroy( llvmpipe->quad.coverage );
llvmpipe->quad.blend->destroy( llvmpipe->quad.blend );
llvmpipe->quad.colormask->destroy( llvmpipe->quad.colormask );
llvmpipe->quad.output->destroy( llvmpipe->quad.output );

for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
lp_destroy_tile_cache(llvmpipe->cbuf_cache[i]);
@@ -234,19 +232,17 @@ llvmpipe_create( struct pipe_screen *screen )


/* setup quad rendering stages */
for (i = 0; i < LP_NUM_QUAD_THREADS; i++) {
llvmpipe->quad[i].polygon_stipple = lp_quad_polygon_stipple_stage(llvmpipe);
llvmpipe->quad[i].earlyz = lp_quad_earlyz_stage(llvmpipe);
llvmpipe->quad[i].shade = lp_quad_shade_stage(llvmpipe);
llvmpipe->quad[i].alpha_test = lp_quad_alpha_test_stage(llvmpipe);
llvmpipe->quad[i].depth_test = lp_quad_depth_test_stage(llvmpipe);
llvmpipe->quad[i].stencil_test = lp_quad_stencil_test_stage(llvmpipe);
llvmpipe->quad[i].occlusion = lp_quad_occlusion_stage(llvmpipe);
llvmpipe->quad[i].coverage = lp_quad_coverage_stage(llvmpipe);
llvmpipe->quad[i].blend = lp_quad_blend_stage(llvmpipe);
llvmpipe->quad[i].colormask = lp_quad_colormask_stage(llvmpipe);
llvmpipe->quad[i].output = lp_quad_output_stage(llvmpipe);
}
llvmpipe->quad.polygon_stipple = lp_quad_polygon_stipple_stage(llvmpipe);
llvmpipe->quad.earlyz = lp_quad_earlyz_stage(llvmpipe);
llvmpipe->quad.shade = lp_quad_shade_stage(llvmpipe);
llvmpipe->quad.alpha_test = lp_quad_alpha_test_stage(llvmpipe);
llvmpipe->quad.depth_test = lp_quad_depth_test_stage(llvmpipe);
llvmpipe->quad.stencil_test = lp_quad_stencil_test_stage(llvmpipe);
llvmpipe->quad.occlusion = lp_quad_occlusion_stage(llvmpipe);
llvmpipe->quad.coverage = lp_quad_coverage_stage(llvmpipe);
llvmpipe->quad.blend = lp_quad_blend_stage(llvmpipe);
llvmpipe->quad.colormask = lp_quad_colormask_stage(llvmpipe);
llvmpipe->quad.output = lp_quad_output_stage(llvmpipe);

/* vertex shader samplers */
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {

+ 1
- 12
src/gallium/drivers/llvmpipe/lp_context.h View File

@@ -39,17 +39,6 @@
#include "lp_tex_sample.h"


/**
* This is a temporary variable for testing draw-stage polygon stipple.
* If zero, do stipple in lp_quad_stipple.c
*/
#define USE_DRAW_STAGE_PSTIPPLE 1

/* Number of threads working on individual quads.
* Setting to 1 disables this feature.
*/
#define LP_NUM_QUAD_THREADS 1

struct llvmpipe_vbuf_render;
struct draw_context;
struct draw_stage;
@@ -129,7 +118,7 @@ struct llvmpipe_context {
struct quad_stage *output;

struct quad_stage *first; /**< points to one of the above stages */
} quad[LP_NUM_QUAD_THREADS];
} quad;

/** TGSI exec things */
struct {

+ 17
- 31
src/gallium/drivers/llvmpipe/lp_quad_pipe.c View File

@@ -31,35 +31,29 @@
#include "pipe/p_shader_tokens.h"

static void
lp_push_quad_first(
struct llvmpipe_context *lp,
struct quad_stage *quad,
uint i )
lp_push_quad_first( struct llvmpipe_context *lp,
struct quad_stage *quad )
{
quad->next = lp->quad[i].first;
lp->quad[i].first = quad;
quad->next = lp->quad.first;
lp->quad.first = quad;
}

static void
lp_build_depth_stencil(
struct llvmpipe_context *lp,
uint i )
lp_build_depth_stencil( struct llvmpipe_context *lp )
{
if (lp->depth_stencil->stencil[0].enabled ||
lp->depth_stencil->stencil[1].enabled) {
lp_push_quad_first( lp, lp->quad[i].stencil_test, i );
lp_push_quad_first( lp, lp->quad.stencil_test );
}
else if (lp->depth_stencil->depth.enabled &&
lp->framebuffer.zsbuf) {
lp_push_quad_first( lp, lp->quad[i].depth_test, i );
lp_push_quad_first( lp, lp->quad.depth_test );
}
}

void
lp_build_quad_pipeline(struct llvmpipe_context *lp)
{
uint i;

boolean early_depth_test =
lp->depth_stencil->depth.enabled &&
lp->framebuffer.zsbuf &&
@@ -68,51 +62,43 @@ lp_build_quad_pipeline(struct llvmpipe_context *lp)
!lp->fs->info.writes_z;

/* build up the pipeline in reverse order... */
for (i = 0; i < LP_NUM_QUAD_THREADS; i++) {
lp->quad[i].first = lp->quad[i].output;
lp->quad.first = lp->quad.output;

if (lp->blend->colormask != 0xf) {
lp_push_quad_first( lp, lp->quad[i].colormask, i );
lp_push_quad_first( lp, lp->quad.colormask );
}

if (lp->blend->blend_enable ||
lp->blend->logicop_enable) {
lp_push_quad_first( lp, lp->quad[i].blend, i );
lp_push_quad_first( lp, lp->quad.blend );
}

if (lp->active_query_count) {
lp_push_quad_first( lp, lp->quad[i].occlusion, i );
lp_push_quad_first( lp, lp->quad.occlusion );
}

if (lp->rasterizer->poly_smooth ||
lp->rasterizer->line_smooth ||
lp->rasterizer->point_smooth) {
lp_push_quad_first( lp, lp->quad[i].coverage, i );
lp_push_quad_first( lp, lp->quad.coverage );
}

if (!early_depth_test) {
lp_build_depth_stencil( lp, i );
lp_build_depth_stencil( lp );
}

if (lp->depth_stencil->alpha.enabled) {
lp_push_quad_first( lp, lp->quad[i].alpha_test, i );
lp_push_quad_first( lp, lp->quad.alpha_test );
}

/* XXX always enable shader? */
if (1) {
lp_push_quad_first( lp, lp->quad[i].shade, i );
lp_push_quad_first( lp, lp->quad.shade );
}

if (early_depth_test) {
lp_build_depth_stencil( lp, i );
lp_push_quad_first( lp, lp->quad[i].earlyz, i );
}

#if !USE_DRAW_STAGE_PSTIPPLE
if (lp->rasterizer->poly_stipple_enable) {
lp_push_quad_first( lp, lp->quad[i].polygon_stipple, i );
lp_build_depth_stencil( lp );
lp_push_quad_first( lp, lp->quad.earlyz );
}
#endif
}
}


+ 17
- 236
src/gallium/drivers/llvmpipe/lp_setup.c View File

@@ -61,87 +61,7 @@ struct edge {
int lines; /**< number of lines on this edge */
};

#if LP_NUM_QUAD_THREADS > 1

/* Set to 1 if you want other threads to be instantly
* notified of pending jobs.
*/
#define INSTANT_NOTEMPTY_NOTIFY 0

struct thread_info
{
struct setup_context *setup;
uint id;
pipe_thread handle;
};

struct quad_job;

typedef void (* quad_job_routine)( struct setup_context *setup, uint thread, struct quad_job *job );

struct quad_job
{
struct quad_header_input input;
struct quad_header_inout inout;
quad_job_routine routine;
};

#define NUM_QUAD_JOBS 64

struct quad_job_que
{
struct quad_job jobs[NUM_QUAD_JOBS];
uint first;
uint last;
pipe_mutex que_mutex;
pipe_condvar que_notfull_condvar;
pipe_condvar que_notempty_condvar;
uint jobs_added;
uint jobs_done;
pipe_condvar que_done_condvar;
};

static void
add_quad_job( struct quad_job_que *que, struct quad_header *quad, quad_job_routine routine )
{
#if INSTANT_NOTEMPTY_NOTIFY
boolean empty;
#endif

/* Wait for empty slot, see if the que is empty.
*/
pipe_mutex_lock( que->que_mutex );
while ((que->last + 1) % NUM_QUAD_JOBS == que->first) {
#if !INSTANT_NOTEMPTY_NOTIFY
pipe_condvar_broadcast( que->que_notempty_condvar );
#endif
pipe_condvar_wait( que->que_notfull_condvar, que->que_mutex );
}
#if INSTANT_NOTEMPTY_NOTIFY
empty = que->last == que->first;
#endif
que->jobs_added++;
pipe_mutex_unlock( que->que_mutex );

/* Submit new job.
*/
que->jobs[que->last].input = quad->input;
que->jobs[que->last].inout = quad->inout;
que->jobs[que->last].routine = routine;
que->last = (que->last + 1) % NUM_QUAD_JOBS;

#if INSTANT_NOTEMPTY_NOTIFY
/* If the que was empty, notify consumers there's a job to be done.
*/
if (empty) {
pipe_mutex_lock( que->que_mutex );
pipe_condvar_broadcast( que->que_notempty_condvar );
pipe_mutex_unlock( que->que_mutex );
}
#endif
}

#endif

/**
* Triangle setup info (derived from draw_stage).
@@ -169,11 +89,6 @@ struct setup_context {
struct tgsi_interp_coef posCoef; /* For Z, W */
struct quad_header quad;

#if LP_NUM_QUAD_THREADS > 1
struct quad_job_que que;
struct thread_info threads[LP_NUM_QUAD_THREADS];
#endif

struct {
int left[2]; /**< [0] = row0, [1] = row1 */
int right[2];
@@ -188,67 +103,6 @@ struct setup_context {
unsigned winding; /* which winding to cull */
};

#if LP_NUM_QUAD_THREADS > 1

static PIPE_THREAD_ROUTINE( quad_thread, param )
{
struct thread_info *info = (struct thread_info *) param;
struct quad_job_que *que = &info->setup->que;

for (;;) {
struct quad_job job;
boolean full;

/* Wait for an available job.
*/
pipe_mutex_lock( que->que_mutex );
while (que->last == que->first)
pipe_condvar_wait( que->que_notempty_condvar, que->que_mutex );

/* See if the que is full.
*/
full = (que->last + 1) % NUM_QUAD_JOBS == que->first;

/* Take a job and remove it from que.
*/
job = que->jobs[que->first];
que->first = (que->first + 1) % NUM_QUAD_JOBS;

/* Notify the producer if the que is not full.
*/
if (full)
pipe_condvar_signal( que->que_notfull_condvar );
pipe_mutex_unlock( que->que_mutex );

job.routine( info->setup, info->id, &job );

/* Notify the producer if that's the last finished job.
*/
pipe_mutex_lock( que->que_mutex );
que->jobs_done++;
if (que->jobs_added == que->jobs_done)
pipe_condvar_signal( que->que_done_condvar );
pipe_mutex_unlock( que->que_mutex );
}

return NULL;
}

#define WAIT_FOR_COMPLETION(setup) \
do {\
pipe_mutex_lock( setup->que.que_mutex );\
if (!INSTANT_NOTEMPTY_NOTIFY)\
pipe_condvar_broadcast( setup->que.que_notempty_condvar );\
while (setup->que.jobs_added != setup->que.jobs_done)\
pipe_condvar_wait( setup->que.que_done_condvar, setup->que.que_mutex );\
pipe_mutex_unlock( setup->que.que_mutex );\
} while (0)

#else

#define WAIT_FOR_COMPLETION(setup) ((void) 0)

#endif



@@ -311,39 +165,17 @@ quad_clip( struct setup_context *setup, struct quad_header *quad )
* Emit a quad (pass to next stage) with clipping.
*/
static INLINE void
clip_emit_quad( struct setup_context *setup, struct quad_header *quad, uint thread )
clip_emit_quad( struct setup_context *setup, struct quad_header *quad )
{
quad_clip( setup, quad );

if (quad->inout.mask) {
struct llvmpipe_context *lp = setup->llvmpipe;

lp->quad[thread].first->run( lp->quad[thread].first, quad );
lp->quad.first->run( lp->quad.first, quad );
}
}

#if LP_NUM_QUAD_THREADS > 1

static void
clip_emit_quad_job( struct setup_context *setup, uint thread, struct quad_job *job )
{
struct quad_header quad;

quad.input = job->input;
quad.inout = job->inout;
quad.coef = setup->quad.coef;
quad.posCoef = setup->quad.posCoef;
quad.nr_attrs = setup->quad.nr_attrs;
clip_emit_quad( setup, &quad, thread );
}

#define CLIP_EMIT_QUAD(setup) add_quad_job( &setup->que, &setup->quad, clip_emit_quad_job )

#else

#define CLIP_EMIT_QUAD(setup) clip_emit_quad( setup, &setup->quad, 0 )

#endif

/**
* Emit a quad (pass to next stage). No clipping is done.
*/
@@ -361,7 +193,7 @@ emit_quad( struct setup_context *setup, struct quad_header *quad, uint thread )
if (mask & 4) setup->numFragsEmitted++;
if (mask & 8) setup->numFragsEmitted++;
#endif
lp->quad[thread].first->run( lp->quad[thread].first, quad );
lp->quad.first->run( lp->quad.first, quad );
#if DEBUG_FRAGS
mask = quad->inout.mask;
if (mask & 1) setup->numFragsWritten++;
@@ -371,38 +203,15 @@ emit_quad( struct setup_context *setup, struct quad_header *quad, uint thread )
#endif
}

#if LP_NUM_QUAD_THREADS > 1

static void
emit_quad_job( struct setup_context *setup, uint thread, struct quad_job *job )
{
struct quad_header quad;

quad.input = job->input;
quad.inout = job->inout;
quad.coef = setup->quad.coef;
quad.posCoef = setup->quad.posCoef;
quad.nr_attrs = setup->quad.nr_attrs;
emit_quad( setup, &quad, thread );
}

#define EMIT_QUAD(setup,x,y,qmask) do {\
setup->quad.input.x0 = x;\
setup->quad.input.y0 = y;\
setup->quad.inout.mask = qmask;\
add_quad_job( &setup->que, &setup->quad, emit_quad_job );\
} while (0)

#else
#define EMIT_QUAD(setup,x,y,qmask) \
do { \
setup->quad.input.x0 = x; \
setup->quad.input.y0 = y; \
setup->quad.inout.mask = qmask; \
emit_quad( setup, &setup->quad, 0 ); \
} while (0)

#define EMIT_QUAD(setup,x,y,qmask) do {\
setup->quad.input.x0 = x;\
setup->quad.input.y0 = y;\
setup->quad.inout.mask = qmask;\
emit_quad( setup, &setup->quad, 0 );\
} while (0)

#endif

/**
* Given an X or Y coordinate, return the block/quad coordinate that it
@@ -956,8 +765,6 @@ void setup_tri( struct setup_context *setup,

flush_spans( setup );

WAIT_FOR_COMPLETION(setup);

#if DEBUG_FRAGS
printf("Tri: %u frags emitted, %u written\n",
setup->numFragsEmitted,
@@ -1101,7 +908,7 @@ plot(struct setup_context *setup, int x, int y)
/* flush prev quad, start new quad */

if (setup->quad.input.x0 != -1)
CLIP_EMIT_QUAD(setup);
clip_emit_quad( setup, &setup->quad );

setup->quad.input.x0 = quadX;
setup->quad.input.y0 = quadY;
@@ -1223,10 +1030,8 @@ setup_line(struct setup_context *setup,

/* draw final quad */
if (setup->quad.inout.mask) {
CLIP_EMIT_QUAD(setup);
clip_emit_quad( setup, &setup->quad );
}

WAIT_FOR_COMPLETION(setup);
}


@@ -1334,7 +1139,7 @@ setup_point( struct setup_context *setup,
setup->quad.input.x0 = (int) x - ix;
setup->quad.input.y0 = (int) y - iy;
setup->quad.inout.mask = (1 << ix) << (2 * iy);
CLIP_EMIT_QUAD(setup);
clip_emit_quad( setup, &setup->quad );
}
else {
if (round) {
@@ -1395,7 +1200,7 @@ setup_point( struct setup_context *setup,
if (setup->quad.inout.mask) {
setup->quad.input.x0 = ix;
setup->quad.input.y0 = iy;
CLIP_EMIT_QUAD(setup);
clip_emit_quad( setup, &setup->quad );
}
}
}
@@ -1442,19 +1247,16 @@ setup_point( struct setup_context *setup,
setup->quad.inout.mask = mask;
setup->quad.input.x0 = ix;
setup->quad.input.y0 = iy;
CLIP_EMIT_QUAD(setup);
clip_emit_quad( setup, &setup->quad );
}
}
}
}

WAIT_FOR_COMPLETION(setup);
}

void setup_prepare( struct setup_context *setup )
{
struct llvmpipe_context *lp = setup->llvmpipe;
unsigned i;

if (lp->dirty) {
llvmpipe_update_derived(lp);
@@ -1463,9 +1265,7 @@ void setup_prepare( struct setup_context *setup )
/* Note: nr_attrs is only used for debugging (vertex printing) */
setup->quad.nr_attrs = draw_num_vs_outputs(lp->draw);

for (i = 0; i < LP_NUM_QUAD_THREADS; i++) {
lp->quad[i].first->begin( lp->quad[i].first );
}
lp->quad.first->begin( lp->quad.first );

if (lp->reduced_api_prim == PIPE_PRIM_TRIANGLES &&
lp->rasterizer->fill_cw == PIPE_POLYGON_MODE_FILL &&
@@ -1493,9 +1293,6 @@ void setup_destroy_context( struct setup_context *setup )
struct setup_context *setup_create_context( struct llvmpipe_context *llvmpipe )
{
struct setup_context *setup = CALLOC_STRUCT(setup_context);
#if LP_NUM_QUAD_THREADS > 1
uint i;
#endif

setup->llvmpipe = llvmpipe;

@@ -1505,22 +1302,6 @@ struct setup_context *setup_create_context( struct llvmpipe_context *llvmpipe )
setup->span.left[0] = 1000000; /* greater than right[0] */
setup->span.left[1] = 1000000; /* greater than right[1] */

#if LP_NUM_QUAD_THREADS > 1
setup->que.first = 0;
setup->que.last = 0;
pipe_mutex_init( setup->que.que_mutex );
pipe_condvar_init( setup->que.que_notfull_condvar );
pipe_condvar_init( setup->que.que_notempty_condvar );
setup->que.jobs_added = 0;
setup->que.jobs_done = 0;
pipe_condvar_init( setup->que.que_done_condvar );
for (i = 0; i < LP_NUM_QUAD_THREADS; i++) {
setup->threads[i].setup = setup;
setup->threads[i].id = i;
setup->threads[i].handle = pipe_thread_create( quad_thread, &setup->threads[i] );
}
#endif

return setup;
}


Loading…
Cancel
Save