summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h7
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c14
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.h7
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c10
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c43
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_vsplit.c2
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;
}