From ba5975dd3274a3cc760e79dabaf9c11b96673f4a Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Mon, 31 May 2010 20:41:18 -0400 Subject: [PATCH] gallium: add interface for DrawAuto and implement it in softpipe --- src/gallium/drivers/softpipe/sp_context.c | 1 + src/gallium/drivers/softpipe/sp_context.h | 6 +++ src/gallium/drivers/softpipe/sp_draw_arrays.c | 51 +++++++++++++++++++ src/gallium/drivers/softpipe/sp_state.h | 2 + src/gallium/drivers/softpipe/sp_state_so.c | 11 +++- src/gallium/include/pipe/p_context.h | 5 ++ 6 files changed, 75 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index b1970140d50..38bc0d51f34 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -276,6 +276,7 @@ softpipe_create_context( struct pipe_screen *screen, softpipe->pipe.draw_range_elements = softpipe_draw_range_elements; softpipe->pipe.draw_arrays_instanced = softpipe_draw_arrays_instanced; softpipe->pipe.draw_elements_instanced = softpipe_draw_elements_instanced; + softpipe->pipe.draw_auto = softpipe_draw_auto; softpipe->pipe.clear = softpipe_clear; softpipe->pipe.flush = softpipe_flush; diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index f8ffc5787d3..79165fba32c 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -80,6 +80,12 @@ struct softpipe_context { struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + struct { + struct softpipe_resource *buffer[PIPE_MAX_SO_BUFFERS]; + int offset[PIPE_MAX_SO_BUFFERS]; + int so_count[PIPE_MAX_SO_BUFFERS]; + int num_buffers; + } so_target; unsigned num_samplers; unsigned num_sampler_views; diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index b30036e2303..8fa7f9fbdec 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -84,6 +84,57 @@ softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, 1); } +void +softpipe_draw_auto(struct pipe_context *pipe, unsigned mode) +{ + struct softpipe_context *sp = softpipe_context(pipe); + struct draw_context *draw = sp->draw; + const unsigned start = 0; + const unsigned count = sp->so_target.so_count[0]; + void *buf = sp->so_target.buffer[0]->data; + int offset = sp->so_target.offset[0]; + + if (!softpipe_check_render_cond(sp) || + sp->so_target.num_buffers != 1) + return; + + sp->reduced_api_prim = u_reduced_prim(mode); + + if (sp->dirty) { + softpipe_update_derived(sp); + } + + softpipe_map_transfers(sp); + + /* Map so buffers */ + if (offset < 0) /* we were appending so start from beginning */ + offset = 0; + buf = (void*)((int32_t*)buf + offset); + draw_set_mapped_vertex_buffer(draw, 0, buf); + + draw_set_mapped_element_buffer_range(draw, + 0, 0, + start, + start + count - 1, + NULL); + + /* draw! */ + draw_arrays_instanced(draw, mode, start, count, 0, 1); + + /* unmap vertex/index buffers - will cause draw module to flush */ + draw_set_mapped_vertex_buffer(draw, 0, NULL); + + /* + * TODO: Flush only when a user vertex/index buffer is present + * (or even better, modify draw module to do this + * internally when this condition is seen?) + */ + draw_flush(draw); + + /* Note: leave drawing surfaces mapped */ + sp->dirty_render_cache = TRUE; +} + void softpipe_draw_range_elements(struct pipe_context *pipe, diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index dd958ebb53e..4ffa2b9f598 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -250,6 +250,8 @@ softpipe_draw_elements_instanced(struct pipe_context *pipe, unsigned startInstance, unsigned instanceCount); +void softpipe_draw_auto(struct pipe_context *pipe, unsigned mode); + void softpipe_map_transfers(struct softpipe_context *sp); diff --git a/src/gallium/drivers/softpipe/sp_state_so.c b/src/gallium/drivers/softpipe/sp_state_so.c index 49bde22e979..8bd20cd2aca 100644 --- a/src/gallium/drivers/softpipe/sp_state_so.c +++ b/src/gallium/drivers/softpipe/sp_state_so.c @@ -93,7 +93,14 @@ softpipe_set_stream_output_buffers(struct pipe_context *pipe, softpipe->dirty |= SP_NEW_SO_BUFFERS; for (i = 0; i < num_buffers; ++i) { - void *mapped = softpipe_resource(buffers[i])->data; + void *mapped; + struct softpipe_resource *res = softpipe_resource(buffers[i]); + + softpipe->so_target.buffer[i] = res; + softpipe->so_target.offset[i] = offsets[i]; + softpipe->so_target.so_count[i] = 0; + + mapped = res->data; if (offsets[i] >= 0) map_buffers[i] = ((char*)mapped) + offsets[i]; else { @@ -102,5 +109,7 @@ softpipe_set_stream_output_buffers(struct pipe_context *pipe, map_buffers[i] = mapped; } } + softpipe->so_target.num_buffers = num_buffers; + draw_set_mapped_so_buffers(softpipe->draw, map_buffers, num_buffers); } diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 0267ed8fa4a..3a792b0fe0f 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -101,6 +101,11 @@ struct pipe_context { unsigned mode, unsigned start, unsigned count); + + /** + * Draw the stream output buffer at index 0 + */ + void (*draw_auto)( struct pipe_context *pipe, unsigned mode ); /*@}*/ /** -- 2.30.2