+ struct st_context *st = st_context(ctx);
+ struct pipe_context *pipe = st->pipe;
+ struct st_transform_feedback_object *sobj =
+ st_transform_feedback_object(obj);
+ unsigned i, max_num_targets;
+ unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
+
+ max_num_targets = MIN2(ARRAY_SIZE(sobj->base.Buffers),
+ ARRAY_SIZE(sobj->targets));
+
+ /* Convert the transform feedback state into the gallium representation. */
+ for (i = 0; i < max_num_targets; i++) {
+ struct st_buffer_object *bo = st_buffer_object(sobj->base.Buffers[i]);
+
+ if (bo && bo->buffer) {
+ unsigned stream =
+ obj->shader_program->LinkedTransformFeedback.BufferStream[i];
+
+ /* Check whether we need to recreate the target. */
+ if (!sobj->targets[i] ||
+ sobj->targets[i] == sobj->draw_count[stream] ||
+ sobj->targets[i]->buffer != bo->buffer ||
+ sobj->targets[i]->buffer_offset != sobj->base.Offset[i] ||
+ sobj->targets[i]->buffer_size != sobj->base.Size[i]) {
+ /* Create a new target. */
+ struct pipe_stream_output_target *so_target =
+ pipe->create_stream_output_target(pipe, bo->buffer,
+ sobj->base.Offset[i],
+ sobj->base.Size[i]);
+
+ pipe_so_target_reference(&sobj->targets[i], NULL);
+ sobj->targets[i] = so_target;
+ }
+
+ sobj->num_targets = i+1;
+ } else {
+ pipe_so_target_reference(&sobj->targets[i], NULL);
+ }
+ }
+
+ /* Start writing at the beginning of each target. */
+ cso_set_stream_outputs(st->cso_context, sobj->num_targets,
+ sobj->targets, offsets);