summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZack Rusin <zack@kde.org>2010-05-31 20:41:18 -0400
committerZack Rusin <zack@kde.org>2010-05-31 20:41:18 -0400
commit0d4faac5368e39a8a8b4aa8724abdf5458d4172c (patch)
tree0d27a6cea81515aaee72bd1f1c711c4fd7be1ffa
parent0cebe8e3cbd5385bffc283d0f74eb26cc5cfebe8 (diff)
gallium: add interface for DrawAuto and implement it in softpipe
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c1
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h6
-rw-r--r--src/gallium/drivers/softpipe/sp_draw_arrays.c51
-rw-r--r--src/gallium/drivers/softpipe/sp_state.h2
-rw-r--r--src/gallium/drivers/softpipe/sp_state_so.c11
-rw-r--r--src/gallium/include/pipe/p_context.h5
6 files changed, 75 insertions, 1 deletions
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index b1970140d5..38bc0d51f3 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 f8ffc5787d..79165fba32 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 b30036e230..8fa7f9fbde 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 dd958ebb53..4ffa2b9f59 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 49bde22e97..8bd20cd2ac 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 2fabe9e9aa..d25dfc6491 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 );
/*@}*/
/**