diff options
author | Dave Airlie <[email protected]> | 2012-12-12 21:14:58 +1000 |
---|---|---|
committer | Dave Airlie <[email protected]> | 2012-12-14 11:34:15 +1000 |
commit | 55d37eb40edff67fa12d1729165b292b914d8e51 (patch) | |
tree | 4db46e7ec785faa016fba7b1ae4e456e330ce72c | |
parent | 4330cfec8b5225283bccc03f53a440c20e8e5cb5 (diff) |
draw: add support for later transform feedback extensions
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 <[email protected]>
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt.c | 9 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_so_emit.c | 12 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_screen.c | 2 |
3 files changed, 17 insertions, 6 deletions
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index ddaedcdab5e..50b9efab7ea 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -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); } } } diff --git a/src/gallium/auxiliary/draw/draw_pt_so_emit.c b/src/gallium/auxiliary/draw/draw_pt_so_emit.c index ecf287f9128..80a164a0d7d 100644 --- a/src/gallium/auxiliary/draw/draw_pt_so_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_so_emit.c @@ -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; diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 564da5e1bc1..840cff69e89 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -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: |