diff options
-rw-r--r-- | src/gallium/auxiliary/draw/draw_context.c | 6 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pipe.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_private.h | 7 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt.c | 14 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt.h | 7 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c | 10 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c | 43 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_vsplit.c | 2 |
8 files changed, 68 insertions, 23 deletions
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index c231aba1963..bc2f0e1d03f 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -289,7 +289,7 @@ void draw_set_rasterize_stage( struct draw_context *draw, void draw_set_clip_state( struct draw_context *draw, const struct pipe_clip_state *clip ) { - draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + draw_do_flush(draw, DRAW_FLUSH_PARAMETER_CHANGE); memcpy(&draw->plane[6], clip->ucp, sizeof(clip->ucp)); } @@ -301,7 +301,7 @@ void draw_set_clip_state( struct draw_context *draw, void draw_set_viewport_state( struct draw_context *draw, const struct pipe_viewport_state *viewport ) { - draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); + draw_do_flush(draw, DRAW_FLUSH_PARAMETER_CHANGE); draw->viewport = *viewport; /* struct copy */ draw->identity_viewport = (viewport->scale[0] == 1.0f && viewport->scale[1] == 1.0f && @@ -368,6 +368,8 @@ draw_set_mapped_constant_buffer(struct draw_context *draw, shader_type == PIPE_SHADER_GEOMETRY); debug_assert(slot < PIPE_MAX_CONSTANT_BUFFERS); + draw_do_flush(draw, DRAW_FLUSH_PARAMETER_CHANGE); + switch (shader_type) { case PIPE_SHADER_VERTEX: draw->pt.user.vs_constants[slot] = buffer; diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index ac449b75f00..f1ee6cb1b0a 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -347,6 +347,6 @@ void draw_pipeline_flush( struct draw_context *draw, unsigned flags ) { draw->pipeline.first->flush( draw->pipeline.first, flags ); - if (!(flags & DRAW_FLUSH_BACKEND)) + if (flags & DRAW_FLUSH_STATE_CHANGE) draw->pipeline.first = draw->pipeline.validate; } diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index e52b3fda0ec..2223fcb3f40 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -144,6 +144,8 @@ struct draw_context unsigned opt; /**< bitmask of PT_x flags */ unsigned eltSize; /* saved eltSize for flushing */ + boolean rebind_parameters; + struct { struct draw_pt_middle_end *fetch_emit; struct draw_pt_middle_end *fetch_shade_emit; @@ -434,8 +436,9 @@ void draw_pipeline_flush( struct draw_context *draw, * Flushing */ -#define DRAW_FLUSH_STATE_CHANGE 0x8 -#define DRAW_FLUSH_BACKEND 0x10 +#define DRAW_FLUSH_PARAMETER_CHANGE 0x1 /**< Constants, viewport, etc */ +#define DRAW_FLUSH_STATE_CHANGE 0x2 /**< Other/heavy state changes */ +#define DRAW_FLUSH_BACKEND 0x4 /**< Flush the output buffer */ void draw_do_flush( struct draw_context *draw, unsigned flags ); diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 7113b9e0f2d..ddaedcdab5e 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -139,6 +139,12 @@ draw_pt_arrays(struct draw_context *draw, draw->pt.opt = opt; } + if (draw->pt.rebind_parameters) { + /* update constants, viewport dims, clip planes, etc */ + middle->bind_parameters(middle); + draw->pt.rebind_parameters = FALSE; + } + frontend->run( frontend, start, count ); return TRUE; @@ -146,13 +152,19 @@ draw_pt_arrays(struct draw_context *draw, void draw_pt_flush( struct draw_context *draw, unsigned flags ) { + assert(flags); + if (draw->pt.frontend) { draw->pt.frontend->flush( draw->pt.frontend, flags ); /* don't prepare if we only are flushing the backend */ - if (!(flags & DRAW_FLUSH_BACKEND)) + if (flags & DRAW_FLUSH_STATE_CHANGE) draw->pt.frontend = NULL; } + + if (flags & DRAW_FLUSH_PARAMETER_CHANGE) { + draw->pt.rebind_parameters = TRUE; + } } diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h index 2c2efdc1c59..7d07363068e 100644 --- a/src/gallium/auxiliary/draw/draw_pt.h +++ b/src/gallium/auxiliary/draw/draw_pt.h @@ -93,6 +93,13 @@ struct draw_pt_middle_end { unsigned opt, unsigned *max_vertices ); + /** + * Bind/update parameter state such as constants, viewport dims + * and clip planes. Basically, stuff which isn't "baked" into the + * shader or pipeline state. + */ + void (*bind_parameters)(struct draw_pt_middle_end *); + void (*run)( struct draw_pt_middle_end *, const unsigned *fetch_elts, unsigned fetch_count, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index a6f5484fcf4..d1b76b12b02 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -137,6 +137,15 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle, } +static void +fetch_pipeline_bind_parameters(struct draw_pt_middle_end *middle) +{ + /* No-op since the vertex shader executor and drawing pipeline + * just grab the constants, viewport, etc. from the draw context state. + */ +} + + static void fetch( struct pt_fetch *fetch, const struct draw_fetch_info *fetch_info, char *output) @@ -421,6 +430,7 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit( struct draw_context * goto fail; fpme->base.prepare = fetch_pipeline_prepare; + fpme->base.bind_parameters = fetch_pipeline_bind_parameters; fpme->base.run = fetch_pipeline_run; fpme->base.run_linear = fetch_pipeline_linear_run; fpme->base.run_linear_elts = fetch_pipeline_linear_run_elts; diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c index 2230a7e5fa3..bfad54bb36e 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c @@ -180,24 +180,34 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle, fpme->current_variant = variant; } +} - /* Bind the VS and GS input constants, clip planes and viewport */ - { - unsigned i; - for (i = 0; i < Elements(fpme->llvm->jit_context.vs_constants); ++i) { - fpme->llvm->jit_context.vs_constants[i] = - draw->pt.user.vs_constants[i]; - } - for (i = 0; i < Elements(fpme->llvm->jit_context.gs_constants); ++i) { - fpme->llvm->jit_context.gs_constants[i] = - draw->pt.user.gs_constants[i]; - } - fpme->llvm->jit_context.planes = - (float (*) [DRAW_TOTAL_CLIP_PLANES][4]) draw->pt.user.planes[0]; - fpme->llvm->jit_context.viewport = - (float *) draw->viewport.scale; - } +/** + * Bind/update constant buffer pointers, clip planes and viewport dims. + * These are "light weight" parameters which aren't baked into the + * generated code. Updating these items is much cheaper than revalidating + * and rebuilding the generated pipeline code. + */ +static void +llvm_middle_end_bind_parameters(struct draw_pt_middle_end *middle) +{ + struct llvm_middle_end *fpme = (struct llvm_middle_end *)middle; + struct draw_context *draw = fpme->draw; + unsigned i; + + for (i = 0; i < Elements(fpme->llvm->jit_context.vs_constants); ++i) { + fpme->llvm->jit_context.vs_constants[i] = draw->pt.user.vs_constants[i]; + } + + for (i = 0; i < Elements(fpme->llvm->jit_context.gs_constants); ++i) { + fpme->llvm->jit_context.gs_constants[i] = draw->pt.user.gs_constants[i]; + } + + fpme->llvm->jit_context.planes = + (float (*)[DRAW_TOTAL_CLIP_PLANES][4]) draw->pt.user.planes[0]; + + fpme->llvm->jit_context.viewport = (float *) draw->viewport.scale; } @@ -448,6 +458,7 @@ draw_pt_fetch_pipeline_or_emit_llvm(struct draw_context *draw) goto fail; fpme->base.prepare = llvm_middle_end_prepare; + fpme->base.bind_parameters = llvm_middle_end_bind_parameters; fpme->base.run = llvm_middle_end_run; fpme->base.run_linear = llvm_middle_end_linear_run; fpme->base.run_linear_elts = llvm_middle_end_linear_run_elts; diff --git a/src/gallium/auxiliary/draw/draw_pt_vsplit.c b/src/gallium/auxiliary/draw/draw_pt_vsplit.c index 0fed057efbe..c2d2a8fd555 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vsplit.c +++ b/src/gallium/auxiliary/draw/draw_pt_vsplit.c @@ -182,7 +182,7 @@ static void vsplit_flush(struct draw_pt_front_end *frontend, unsigned flags) { struct vsplit_frontend *vsplit = (struct vsplit_frontend *) frontend; - if (!(flags & DRAW_FLUSH_BACKEND)) { + if (flags & DRAW_FLUSH_STATE_CHANGE) { vsplit->middle->finish(vsplit->middle); vsplit->middle = NULL; } |