summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/llvmpipe/lp_state_so.c
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2012-12-05 06:50:07 +1000
committerDave Airlie <[email protected]>2012-12-06 14:48:10 +1000
commit77b26564c3f0395bf3e744abbf6d0e7aa9d2c8da (patch)
treeb592e6ecfdfad109ee33e1de801f144033175ea1 /src/gallium/drivers/llvmpipe/lp_state_so.c
parent71f06344a0d72a6bd27750ceca571fc016b8de85 (diff)
llvmpipe: EXT_transform_feedback support (v1.1)
I'd written most of this ages ago, but never finished it off. This passes 115/130 piglit tests so far. I'll look into the others as time permits. v1.1: fix calloc return check as suggested by Jose. Reviewed-by: Jose Fonseca <[email protected]> Signed-off-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_state_so.c')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_so.c124
1 files changed, 37 insertions, 87 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_state_so.c b/src/gallium/drivers/llvmpipe/lp_state_so.c
index ed2272d05ee..58bab396435 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_so.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_so.c
@@ -32,106 +32,56 @@
#include "util/u_memory.h"
#include "draw/draw_context.h"
-
-static void *
-llvmpipe_create_stream_output_state(struct pipe_context *pipe,
- const struct pipe_stream_output_info *templ)
+static struct pipe_stream_output_target *
+llvmpipe_create_so_target(struct pipe_context *pipe,
+ struct pipe_resource *buffer,
+ unsigned buffer_offset,
+ unsigned buffer_size)
{
- struct lp_so_state *so;
- so = (struct lp_so_state *) CALLOC_STRUCT(lp_so_state);
-
- if (so) {
- so->base.num_outputs = templ->num_outputs;
- memcpy(so->base.stride, templ->stride, sizeof(templ->stride));
- memcpy(so->base.output, templ->output,
- templ->num_outputs * sizeof(templ->output[0]));
- }
- return so;
+ struct draw_so_target *t;
+
+ t = CALLOC_STRUCT(draw_so_target);
+ if (!t)
+ return NULL;
+
+ t->target.context = pipe;
+ t->target.reference.count = 1;
+ pipe_resource_reference(&t->target.buffer, buffer);
+ t->target.buffer_offset = buffer_offset;
+ t->target.buffer_size = buffer_size;
+ return &t->target;
}
-
+
static void
-llvmpipe_bind_stream_output_state(struct pipe_context *pipe,
- void *so)
+llvmpipe_so_target_destroy(struct pipe_context *pipe,
+ struct pipe_stream_output_target *target)
{
- struct llvmpipe_context *lp = llvmpipe_context(pipe);
- struct lp_so_state *lp_so = (struct lp_so_state *) so;
-
- lp->so = lp_so;
-
- lp->dirty |= LP_NEW_SO;
-
- if (lp_so)
- draw_set_so_state(lp->draw, &lp_so->base);
+ pipe_resource_reference(&target->buffer, NULL);
+ FREE(target);
}
static void
-llvmpipe_delete_stream_output_state(struct pipe_context *pipe, void *so)
+llvmpipe_set_so_targets(struct pipe_context *pipe,
+ unsigned num_targets,
+ struct pipe_stream_output_target **targets,
+ unsigned append_bitmask)
{
- FREE( so );
-}
-
-static void
-llvmpipe_set_stream_output_buffers(struct pipe_context *pipe,
- struct pipe_resource **buffers,
- int *offsets,
- int num_buffers)
-{
- struct llvmpipe_context *lp = llvmpipe_context(pipe);
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
int i;
- void *map_buffers[PIPE_MAX_SO_BUFFERS];
-
- assert(num_buffers <= PIPE_MAX_SO_BUFFERS);
- if (num_buffers > PIPE_MAX_SO_BUFFERS)
- num_buffers = PIPE_MAX_SO_BUFFERS;
-
- lp->dirty |= LP_NEW_SO_BUFFERS;
-
- for (i = 0; i < num_buffers; ++i) {
- void *mapped;
- struct llvmpipe_resource *res = llvmpipe_resource(buffers[i]);
-
- if (!res) {
- /* the whole call is invalid, bail out */
- lp->so_target.num_buffers = 0;
- draw_set_mapped_so_buffers(lp->draw, 0, 0);
- return;
- }
-
- lp->so_target.buffer[i] = res;
- lp->so_target.offset[i] = offsets[i];
- lp->so_target.so_count[i] = 0;
-
- mapped = res->data;
- if (offsets[i] >= 0)
- map_buffers[i] = ((char*)mapped) + offsets[i];
- else {
- /* this is a buffer append */
- assert(!"appending not implemented");
- map_buffers[i] = mapped;
- }
+ for (i = 0; i < num_targets; i++) {
+ pipe_so_target_reference((struct pipe_stream_output_target **)&llvmpipe->so_targets[i], targets[i]);
}
- lp->so_target.num_buffers = num_buffers;
- draw_set_mapped_so_buffers(lp->draw, map_buffers, num_buffers);
+ for (; i < llvmpipe->num_so_targets; i++) {
+ pipe_so_target_reference((struct pipe_stream_output_target **)&llvmpipe->so_targets[i], NULL);
+ }
+ llvmpipe->num_so_targets = num_targets;
}
void
-llvmpipe_init_so_funcs(struct llvmpipe_context *llvmpipe)
+llvmpipe_init_so_funcs(struct llvmpipe_context *pipe)
{
-#if 0
- llvmpipe->pipe.create_stream_output_state =
- llvmpipe_create_stream_output_state;
- llvmpipe->pipe.bind_stream_output_state =
- llvmpipe_bind_stream_output_state;
- llvmpipe->pipe.delete_stream_output_state =
- llvmpipe_delete_stream_output_state;
-
- llvmpipe->pipe.set_stream_output_buffers =
- llvmpipe_set_stream_output_buffers;
-#else
- (void) llvmpipe_create_stream_output_state;
- (void) llvmpipe_bind_stream_output_state;
- (void) llvmpipe_delete_stream_output_state;
- (void) llvmpipe_set_stream_output_buffers;
-#endif
+ pipe->pipe.create_stream_output_target = llvmpipe_create_so_target;
+ pipe->pipe.stream_output_target_destroy = llvmpipe_so_target_destroy;
+ pipe->pipe.set_stream_output_targets = llvmpipe_set_so_targets;
}