u_blitter: restore stream output targets
authorMarek Olšák <maraeo@gmail.com>
Sat, 19 Nov 2011 20:44:28 +0000 (21:44 +0100)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Thu, 15 Dec 2011 17:51:48 +0000 (18:51 +0100)
src/gallium/auxiliary/util/u_blitter.c
src/gallium/auxiliary/util/u_blitter.h

index f5cc5cb3b07a3b0e3de04bb829fa25a5b3a1ccfd..c0c477b6a189356275b8c653a6c0d641eaab117a 100644 (file)
@@ -109,6 +109,7 @@ struct blitter_context_priv
 
    boolean has_geometry_shader;
    boolean vertex_has_integers;
+   boolean has_stream_out;
 };
 
 static void blitter_draw_rectangle(struct blitter_context *blitter,
@@ -148,6 +149,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
    ctx->base.saved_num_sampler_views = ~0;
    ctx->base.saved_num_sampler_states = ~0;
    ctx->base.saved_num_vertex_buffers = ~0;
+   ctx->base.saved_num_so_targets = ~0;
 
    ctx->has_geometry_shader =
       pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY,
@@ -155,6 +157,9 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
    ctx->vertex_has_integers =
       pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_VERTEX,
                                      PIPE_SHADER_CAP_INTEGERS);
+   ctx->has_stream_out =
+      pipe->screen->get_param(pipe->screen,
+                              PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0;
 
    /* blend state objects */
    memset(&blend, 0, sizeof(blend));
@@ -319,6 +324,7 @@ static void blitter_check_saved_vertex_states(struct blitter_context_priv *ctx)
           ctx->base.saved_velem_state != INVALID_PTR &&
           ctx->base.saved_vs != INVALID_PTR &&
           (!ctx->has_geometry_shader || ctx->base.saved_gs != INVALID_PTR) &&
+          (!ctx->has_stream_out || ctx->base.saved_num_so_targets != ~0) &&
           ctx->base.saved_rs_state != INVALID_PTR);
 }
 
@@ -354,6 +360,18 @@ static void blitter_restore_vertex_states(struct blitter_context_priv *ctx)
       ctx->base.saved_gs = INVALID_PTR;
    }
 
+   /* Stream outputs. */
+   if (ctx->has_stream_out) {
+      pipe->set_stream_output_targets(pipe,
+                                      ctx->base.saved_num_so_targets,
+                                      ctx->base.saved_so_targets, ~0);
+
+      for (i = 0; i < ctx->base.saved_num_so_targets; i++)
+         pipe_so_target_reference(&ctx->base.saved_so_targets[i], NULL);
+
+      ctx->base.saved_num_so_targets = ~0;
+   }
+
    /* Rasterizer. */
    pipe->bind_rasterizer_state(pipe, ctx->base.saved_rs_state);
    ctx->base.saved_rs_state = INVALID_PTR;
index 3e1457ae0dda2a6bf1863a5b97a1c57bdfb7ce67..d02cfafc17f8676dc3fc8cc952e14d80d380b5bf 100644 (file)
@@ -104,6 +104,9 @@ struct blitter_context
 
    int saved_num_vertex_buffers;
    struct pipe_vertex_buffer saved_vertex_buffers[PIPE_MAX_ATTRIBS];
+
+   int saved_num_so_targets;
+   struct pipe_stream_output_target *saved_so_targets[PIPE_MAX_SO_BUFFERS];
 };
 
 /**
@@ -131,6 +134,7 @@ struct pipe_context *util_blitter_get_pipe(struct blitter_context *blitter)
  * - vertex elements
  * - vertex shader
  * - geometry shader (if supported)
+ * - stream output targets (if supported)
  * - rasterizer state
  */
 
@@ -379,6 +383,20 @@ util_blitter_save_vertex_buffers(struct blitter_context *blitter,
                             num_vertex_buffers);
 }
 
+static INLINE void
+util_blitter_save_so_targets(struct blitter_context *blitter,
+                             int num_targets,
+                             struct pipe_stream_output_target **targets)
+{
+   unsigned i;
+   assert(num_targets <= Elements(blitter->saved_so_targets));
+
+   blitter->saved_num_so_targets = num_targets;
+   for (i = 0; i < num_targets; i++)
+      pipe_so_target_reference(&blitter->saved_so_targets[i],
+                               targets[i]);
+}
+
 #ifdef __cplusplus
 }
 #endif