X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fllvmpipe%2Flp_state_so.c;h=b2afd6fbf702ba202b031cf0aed830af0654762c;hb=e94d034a38b9993d0ea898dec550cf52541da8f1;hp=35de52c6c996c2e43935ade4296d190d48a41b68;hpb=4f4a1be2009863ea34a69b22f58aa1ca08cd710f;p=mesa.git diff --git a/src/gallium/drivers/llvmpipe/lp_state_so.c b/src/gallium/drivers/llvmpipe/lp_state_so.c index 35de52c6c99..b2afd6fbf70 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_so.c +++ b/src/gallium/drivers/llvmpipe/lp_state_so.c @@ -32,113 +32,71 @@ #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_state *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; - so->base.stride = templ->stride; - memcpy(so->base.output_buffer, - templ->output_buffer, - sizeof(int) * templ->num_outputs); - memcpy(so->base.register_index, - templ->register_index, - sizeof(int) * templ->num_outputs); - memcpy(so->base.register_mask, - templ->register_mask, - sizeof(ubyte) * templ->num_outputs); - } - 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, + const unsigned *offsets) { - 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; + for (i = 0; i < num_targets; i++) { + const boolean append = (offsets[i] == (unsigned)-1); + /* + * Warn if the so target was created in another context. + * XXX Not entirely sure if mesa/st may rely on this? + * Otherwise should just assert. + */ + if (targets[i] && targets[i]->context != pipe) { + debug_printf("Illegal setting of so target with target %d created in " + "another context\n", i); } - - 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; + pipe_so_target_reference((struct pipe_stream_output_target **)&llvmpipe->so_targets[i], targets[i]); + /* If we're not appending then lets set the internal + offset to what was requested */ + if (!append && llvmpipe->so_targets[i]) { + llvmpipe->so_targets[i]->internal_offset = offsets[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; }