draw: add support for later transform feedback extensions
authorDave Airlie <airlied@gmail.com>
Wed, 12 Dec 2012 11:14:58 +0000 (21:14 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 14 Dec 2012 01:34:15 +0000 (11:34 +1000)
This adds support to draw for the new features of transform feedback.

a) fix count_from_stream_output, using max_index+1 for now but it looks
like it should be valid as its derived from the vertex elements/vbo.

b) fix striding and dst offsets in output buffers - was just wrong before.

c) fix crash if tfb is suspended (so.num_targets == 0)

This also enables the new features on softpipe. It should be possible
to enable them on llvmpipe as well after this commit, but would need
to schedule piglit runs.

Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/auxiliary/draw/draw_pt.c
src/gallium/auxiliary/draw/draw_pt_so_emit.c
src/gallium/drivers/softpipe/sp_screen.c

index ddaedcdab5e4b932306ea9b605430a027ff06dd2..50b9efab7eaca0146cc74a8204ccc419970afd5f 100644 (file)
@@ -464,7 +464,7 @@ draw_vbo(struct draw_context *draw,
 {
    unsigned instance;
    unsigned index_limit;
-
+   unsigned count;
    assert(info->instance_count > 0);
    if (info->indexed)
       assert(draw->pt.user.elts);
@@ -518,6 +518,11 @@ draw_vbo(struct draw_context *draw,
 
    draw->pt.max_index = index_limit - 1;
 
+   count = info->count;
+   if (count == 0) {
+      if (info->count_from_stream_output)
+         count = draw->pt.max_index + 1;
+   }
 
    /*
     * TODO: We could use draw->pt.max_index to further narrow
@@ -531,7 +536,7 @@ draw_vbo(struct draw_context *draw,
          draw_pt_arrays_restart(draw, info);
       }
       else {
-         draw_pt_arrays(draw, info->mode, info->start, info->count);
+         draw_pt_arrays(draw, info->mode, info->start, count);
       }
    }
 }
index ecf287f9128e388207dbdea25e2a3d944fe284aa..80a164a0d7da1110cf8e4cef8c2771286dc30368 100644 (file)
@@ -118,6 +118,7 @@ static void so_emit_prim(struct pt_so_emit *so,
    for (i = 0; i < num_vertices; ++i) {
       const float (*input)[4];
       unsigned total_written_compos = 0;
+      int ob;
       /*debug_printf("%d) vertex index = %d (prim idx = %d)\n", i, indices[i], prim_idx);*/
       input = (const float (*)[4])(
          (const char *)input_ptr + (indices[i] * input_vertex_stride));
@@ -126,15 +127,17 @@ static void so_emit_prim(struct pt_so_emit *so,
          unsigned idx = state->output[slot].register_index;
          unsigned start_comp = state->output[slot].start_component;
          unsigned num_comps = state->output[slot].num_components;
-         int ob = state->output[slot].output_buffer;
+
+         ob = state->output[slot].output_buffer;
 
          buffer = (float *)((char *)draw->so.targets[ob]->mapping +
                             draw->so.targets[ob]->target.buffer_offset +
-                            draw->so.targets[ob]->internal_offset);
+                            draw->so.targets[ob]->internal_offset) + state->output[slot].dst_offset;
          memcpy(buffer, &input[idx][start_comp], num_comps * sizeof(float));
-         draw->so.targets[ob]->internal_offset += num_comps * sizeof(float);
          total_written_compos += num_comps;
       }
+      for (ob = 0; ob < draw->so.num_targets; ++ob)
+         draw->so.targets[ob]->internal_offset += state->stride[ob] * sizeof(float);
    }
    so->emitted_vertices += num_vertices;
    ++so->emitted_primitives;
@@ -193,6 +196,9 @@ void draw_pt_so_emit( struct pt_so_emit *emit,
    if (!emit->has_so)
       return;
 
+   if (!draw->so.num_targets)
+      return;
+
    emit->emitted_vertices = 0;
    emit->emitted_primitives = 0;
    emit->generated_primitives = 0;
index 564da5e1bc1f9e496a7eb3f72fc5d94820583338..840cff69e895fea0e4365c7b178a7013398012d2 100644 (file)
@@ -155,10 +155,10 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_USER_VERTEX_BUFFERS:
    case PIPE_CAP_USER_INDEX_BUFFERS:
    case PIPE_CAP_USER_CONSTANT_BUFFERS:
+   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
       return 1;
    case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
       return 16;
-   case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
    case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
    case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
    case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: