summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZack Rusin <[email protected]>2013-03-30 06:21:41 -0700
committerZack Rusin <[email protected]>2013-04-03 10:16:25 -0700
commit302df7cc85b0e2ce47c40048f30bd116b0d692fc (patch)
tree4af50d5db1d99dda7a1c90659c79425e00f9c0f0
parent246e68735fe22b4d9f510f8fb1bb8b7bb448b068 (diff)
draw/llvmpipe: allow independent so attachments to the vs
When geometry shaders are present, one needs to be able to create an empty geometry shader with stream output that needs to be resolved later and attached to the currently bound vertex shader. Lets add support for it to llvmpipe and draw. draw allows attaching independent stream output info to any vertex shader and llvmpipe resolves at draw time which vertex shader the given empty geometry shader should be linked to. Signed-off-by: Zack Rusin <[email protected]> Reviewed-by: Brian Paul <[email protected]> Reviewed-by: José Fonseca <[email protected]>
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c9
-rw-r--r--src/gallium/auxiliary/draw/draw_context.h7
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h1
-rw-r--r--src/gallium/auxiliary/draw/draw_vs.c13
-rw-r--r--src/gallium/drivers/llvmpipe/lp_draw_arrays.c15
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_gs.c21
6 files changed, 43 insertions, 23 deletions
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index bb56f1bdee5..2fb9bacf4c6 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -735,15 +735,6 @@ draw_set_mapped_so_targets(struct draw_context *draw,
}
void
-draw_set_so_state(struct draw_context *draw,
- struct pipe_stream_output_info *state)
-{
- memcpy(&draw->so.state,
- state,
- sizeof(struct pipe_stream_output_info));
-}
-
-void
draw_set_sampler_views(struct draw_context *draw,
unsigned shader_stage,
struct pipe_sampler_view **views,
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index 426fd44f5eb..1d25b7f255e 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -171,6 +171,9 @@ void draw_bind_vertex_shader(struct draw_context *draw,
struct draw_vertex_shader *dvs);
void draw_delete_vertex_shader(struct draw_context *draw,
struct draw_vertex_shader *dvs);
+void draw_vs_attach_so(struct draw_vertex_shader *dvs,
+ const struct pipe_stream_output_info *info);
+void draw_vs_reset_so(struct draw_vertex_shader *dvs);
/*
@@ -226,10 +229,6 @@ draw_set_mapped_so_targets(struct draw_context *draw,
int num_targets,
struct draw_so_target *targets[PIPE_MAX_SO_BUFFERS]);
-void
-draw_set_so_state(struct draw_context *draw,
- struct pipe_stream_output_info *state);
-
/***********************************************************************
* draw_pt.c
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index 5063c3c8f64..757ed2645ef 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -279,7 +279,6 @@ struct draw_context
/** Stream output (vertex feedback) state */
struct {
- struct pipe_stream_output_info state;
struct draw_so_target *targets[PIPE_MAX_SO_BUFFERS];
uint num_targets;
} so;
diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c
index 266cca713e1..afec3760e77 100644
--- a/src/gallium/auxiliary/draw/draw_vs.c
+++ b/src/gallium/auxiliary/draw/draw_vs.c
@@ -245,3 +245,16 @@ draw_vs_get_emit( struct draw_context *draw,
return draw->vs.emit;
}
+
+void
+draw_vs_attach_so(struct draw_vertex_shader *dvs,
+ const struct pipe_stream_output_info *info)
+{
+ dvs->state.stream_output = *info;
+}
+
+void
+draw_vs_reset_so(struct draw_vertex_shader *dvs)
+{
+ memset(&dvs->state.stream_output, 0, sizeof(dvs->state.stream_output));
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
index ae00c49d490..efeca255755 100644
--- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
+++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
@@ -101,6 +101,13 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
llvmpipe_prepare_geometry_sampling(lp,
lp->num_sampler_views[PIPE_SHADER_GEOMETRY],
lp->sampler_views[PIPE_SHADER_GEOMETRY]);
+ if (lp->gs && !lp->gs->shader.tokens) {
+ /* we have an empty geometry shader with stream output, so
+ attach the stream output info to the current vertex shader */
+ if (lp->vs) {
+ draw_vs_attach_so(lp->vs->draw_data, &lp->gs->shader.stream_output);
+ }
+ }
/* draw! */
draw_vbo(draw, info);
@@ -116,6 +123,14 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
}
draw_set_mapped_so_targets(draw, 0, NULL);
+ if (lp->gs && !lp->gs->shader.tokens) {
+ /* we have attached stream output to the vs for rendering,
+ now lets reset it */
+ if (lp->vs) {
+ draw_vs_reset_so(lp->vs->draw_data);
+ }
+ }
+
llvmpipe_cleanup_vertex_sampling(lp);
llvmpipe_cleanup_geometry_sampling(lp);
diff --git a/src/gallium/drivers/llvmpipe/lp_state_gs.c b/src/gallium/drivers/llvmpipe/lp_state_gs.c
index fd6f5f7d0da..b18795cdc4f 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_gs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_gs.c
@@ -53,15 +53,18 @@ llvmpipe_create_gs_state(struct pipe_context *pipe,
if (0)
tgsi_dump(templ->tokens, 0);
- /* copy shader tokens, the ones passed in will go away.
- */
- state->shader.tokens = tgsi_dup_tokens(templ->tokens);
- if (state->shader.tokens == NULL)
- goto fail;
-
- state->draw_data = draw_create_geometry_shader(llvmpipe->draw, templ);
- if (state->draw_data == NULL)
- goto fail;
+ /* copy stream output info */
+ state->shader = *templ;
+ if (templ->tokens) {
+ /* copy shader tokens, the ones passed in will go away. */
+ state->shader.tokens = tgsi_dup_tokens(templ->tokens);
+ if (state->shader.tokens == NULL)
+ goto fail;
+
+ state->draw_data = draw_create_geometry_shader(llvmpipe->draw, templ);
+ if (state->draw_data == NULL)
+ goto fail;
+ }
return state;