diff options
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r-- | src/gallium/drivers/softpipe/sp_context.c | 1 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_context.h | 12 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_draw_arrays.c | 62 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_prim_vbuf.c | 11 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_query.c | 25 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_screen.c | 5 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_setup.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_state.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_state_so.c | 115 |
9 files changed, 80 insertions, 160 deletions
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 324d9fd67c6..e533e5a8243 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -257,7 +257,6 @@ softpipe_create_context( struct pipe_screen *screen, softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; softpipe->pipe.draw_vbo = softpipe_draw_vbo; - /* XXX softpipe->pipe.draw_stream_output = softpipe_draw_stream_output; */ softpipe->pipe.clear = softpipe_clear; softpipe->pipe.flush = softpipe_flush_wrapped; diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 5442aba9019..c657bd61fcf 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -55,7 +55,6 @@ struct sp_vertex_shader; struct sp_velems_state; struct sp_so_state; - struct softpipe_context { struct pipe_context pipe; /**< base class */ @@ -88,13 +87,12 @@ struct softpipe_context { struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; struct pipe_index_buffer index_buffer; - 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; + + struct draw_so_target *so_targets[PIPE_MAX_SO_BUFFERS]; + int num_so_targets; + struct pipe_query_data_so_statistics so_stats; + unsigned num_primitives_generated; unsigned num_fragment_samplers; unsigned num_fragment_sampler_views; diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index 69b5b96b4fd..27004071f02 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -43,58 +43,6 @@ #include "draw/draw_context.h" - - - - -void -softpipe_draw_stream_output(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, sp->reduced_api_prim); - } - - 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_index_buffer(draw, NULL); - - /* draw! */ - draw_arrays(draw, mode, start, count); - - /* 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; -} - - /** * This function handles drawing indexed and non-indexed prims, * instanced and non-instanced drawing, with or without min/max element @@ -139,6 +87,14 @@ softpipe_draw_vbo(struct pipe_context *pipe, draw_set_mapped_index_buffer(draw, mapped_indices); + for (i = 0; i < sp->num_so_targets; i++) { + void *buf = softpipe_resource(sp->so_targets[i]->target.buffer)->data; + sp->so_targets[i]->mapping = buf; + } + + draw_set_mapped_so_targets(draw, sp->num_so_targets, + sp->so_targets); + /* draw! */ draw_vbo(draw, info); @@ -150,6 +106,8 @@ softpipe_draw_vbo(struct pipe_context *pipe, draw_set_mapped_index_buffer(draw, NULL); } + draw_set_mapped_so_targets(draw, 0, NULL); + /* * TODO: Flush only when a user vertex/index buffer is present * (or even better, modify draw module to do this diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c index 54a6542bdcd..a142118f31e 100644 --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c @@ -542,19 +542,16 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) } static void -sp_vbuf_so_info(struct vbuf_render *vbr, uint primitives, uint vertices) +sp_vbuf_so_info(struct vbuf_render *vbr, uint primitives, uint vertices, + uint prim_generated) { struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr); struct softpipe_context *softpipe = cvbr->softpipe; - unsigned i; - - for (i = 0; i < softpipe->so_target.num_buffers; ++i) { - softpipe->so_target.so_count[i] += vertices; - } - softpipe->so_stats.num_primitives_written = primitives; + softpipe->so_stats.num_primitives_written += primitives; softpipe->so_stats.primitives_storage_needed = vertices * 4 /*sizeof(float|int32)*/ * 4 /*x,y,z,w*/; + softpipe->num_primitives_generated += prim_generated; } diff --git a/src/gallium/drivers/softpipe/sp_query.c b/src/gallium/drivers/softpipe/sp_query.c index c2c48e8ecb3..2e54e023091 100644 --- a/src/gallium/drivers/softpipe/sp_query.c +++ b/src/gallium/drivers/softpipe/sp_query.c @@ -42,6 +42,7 @@ struct softpipe_query { uint64_t start; uint64_t end; struct pipe_query_data_so_statistics so; + unsigned num_primitives_generated; }; @@ -59,6 +60,8 @@ softpipe_create_query(struct pipe_context *pipe, assert(type == PIPE_QUERY_OCCLUSION_COUNTER || type == PIPE_QUERY_TIME_ELAPSED || type == PIPE_QUERY_SO_STATISTICS || + type == PIPE_QUERY_PRIMITIVES_EMITTED || + type == PIPE_QUERY_PRIMITIVES_GENERATED || type == PIPE_QUERY_GPU_FINISHED || type == PIPE_QUERY_TIMESTAMP || type == PIPE_QUERY_TIMESTAMP_DISJOINT); @@ -91,8 +94,14 @@ softpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q) sq->start = 1000*os_time_get(); break; case PIPE_QUERY_SO_STATISTICS: - sq->so.num_primitives_written = 0; sq->so.primitives_storage_needed = 0; + case PIPE_QUERY_PRIMITIVES_EMITTED: + sq->so.num_primitives_written = 0; + softpipe->so_stats.num_primitives_written = 0; + break; + case PIPE_QUERY_PRIMITIVES_GENERATED: + sq->num_primitives_generated = 0; + softpipe->num_primitives_generated = 0; break; case PIPE_QUERY_TIMESTAMP: case PIPE_QUERY_GPU_FINISHED: @@ -125,10 +134,14 @@ softpipe_end_query(struct pipe_context *pipe, struct pipe_query *q) sq->end = 1000*os_time_get(); break; case PIPE_QUERY_SO_STATISTICS: - sq->so.num_primitives_written = - softpipe->so_stats.num_primitives_written; sq->so.primitives_storage_needed = softpipe->so_stats.primitives_storage_needed; + case PIPE_QUERY_PRIMITIVES_EMITTED: + sq->so.num_primitives_written = + softpipe->so_stats.num_primitives_written; + break; + case PIPE_QUERY_PRIMITIVES_GENERATED: + sq->num_primitives_generated = softpipe->num_primitives_generated; break; case PIPE_QUERY_GPU_FINISHED: break; @@ -166,6 +179,12 @@ softpipe_get_query_result(struct pipe_context *pipe, sizeof(struct pipe_query_data_timestamp_disjoint)); } break; + case PIPE_QUERY_PRIMITIVES_EMITTED: + *result = sq->so.num_primitives_written; + break; + case PIPE_QUERY_PRIMITIVES_GENERATED: + *result = sq->num_primitives_generated; + break; default: *result = sq->end - sq->start; break; diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 07f1970b385..982af6b3808 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -106,7 +106,10 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: return 1; case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: - return 0; + return PIPE_MAX_SO_BUFFERS; + case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: + case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: + return 16*4; case PIPE_CAP_PRIMITIVE_RESTART: return 1; case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c index 656d001809f..0d67af3eb74 100644 --- a/src/gallium/drivers/softpipe/sp_setup.c +++ b/src/gallium/drivers/softpipe/sp_setup.c @@ -807,7 +807,7 @@ sp_setup_tri(struct setup_context *setup, print_vertex(setup, v2); #endif - if (setup->softpipe->no_rast) + if (setup->softpipe->no_rast || setup->softpipe->rasterizer->rasterizer_discard) return; det = calc_det(v0, v1, v2); @@ -1073,7 +1073,7 @@ sp_setup_line(struct setup_context *setup, print_vertex(setup, v1); #endif - if (setup->softpipe->no_rast) + if (setup->softpipe->no_rast || setup->softpipe->rasterizer->rasterizer_discard) return; if (dx == 0 && dy == 0) @@ -1206,7 +1206,7 @@ sp_setup_point(struct setup_context *setup, print_vertex(setup, v0); #endif - if (softpipe->no_rast) + if (setup->softpipe->no_rast || setup->softpipe->rasterizer->rasterizer_discard) return; assert(setup->softpipe->reduced_prim == PIPE_PRIM_POINTS); diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index bdda29495b2..6df40c66394 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -159,9 +159,6 @@ softpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info); void -softpipe_draw_stream_output(struct pipe_context *pipe, unsigned mode); - -void softpipe_map_transfers(struct softpipe_context *sp); void diff --git a/src/gallium/drivers/softpipe/sp_state_so.c b/src/gallium/drivers/softpipe/sp_state_so.c index 31ef3841294..2b5893906c8 100644 --- a/src/gallium/drivers/softpipe/sp_state_so.c +++ b/src/gallium/drivers/softpipe/sp_state_so.c @@ -32,109 +32,58 @@ #include "util/u_format.h" #include "util/u_memory.h" #include "draw/draw_context.h" +#include "pipebuffer/pb_buffer.h" - -static void * -softpipe_create_stream_output_state(struct pipe_context *pipe, - const struct pipe_stream_output_info *templ) +static struct pipe_stream_output_target * +softpipe_create_so_target(struct pipe_context *pipe, + struct pipe_resource *buffer, + unsigned buffer_offset, + unsigned buffer_size) { - struct sp_so_state *so; - so = (struct sp_so_state *) CALLOC_STRUCT(sp_so_state); - - if (so) { - so->base.num_outputs = templ->num_outputs; - so->base.stride = templ->stride; - memcpy(so->base.output, templ->output, - templ->num_outputs * sizeof(templ->output[0])); - } - return so; -} - - -static void -softpipe_bind_stream_output_state(struct pipe_context *pipe, - void *so) -{ - struct softpipe_context *softpipe = softpipe_context(pipe); - struct sp_so_state *sp_so = (struct sp_so_state *) so; - - softpipe->so = sp_so; - - softpipe->dirty |= SP_NEW_SO; - - if (sp_so) - draw_set_so_state(softpipe->draw, &sp_so->base); + struct draw_so_target *t; + + t = CALLOC_STRUCT(draw_so_target); + 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 -softpipe_delete_stream_output_state(struct pipe_context *pipe, void *so) +softpipe_so_target_destroy(struct pipe_context *pipe, + struct pipe_stream_output_target *target) { - FREE( so ); + pipe_resource_reference(&target->buffer, NULL); + FREE(target); } - static void -softpipe_set_stream_output_buffers(struct pipe_context *pipe, - struct pipe_resource **buffers, - int *offsets, - int num_buffers) +softpipe_set_so_targets(struct pipe_context *pipe, + unsigned num_targets, + struct pipe_stream_output_target **targets, + unsigned append_bitmask) { struct softpipe_context *softpipe = softpipe_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; - - softpipe->dirty |= SP_NEW_SO_BUFFERS; - - for (i = 0; i < num_buffers; ++i) { - void *mapped; - struct softpipe_resource *res = softpipe_resource(buffers[i]); - if (!res) { - /* the whole call is invalid, bail out */ - softpipe->so_target.num_buffers = 0; - draw_set_mapped_so_buffers(softpipe->draw, 0, 0); - return; - } - - softpipe->so_target.buffer[i] = res; - softpipe->so_target.offset[i] = offsets[i]; - softpipe->so_target.so_count[i] = 0; + for (i = 0; i < num_targets; i++) { + pipe_so_target_reference((struct pipe_stream_output_target **)&softpipe->so_targets[i], targets[i]); + } - 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 < softpipe->num_so_targets; i++) { + pipe_so_target_reference((struct pipe_stream_output_target **)&softpipe->so_targets[i], NULL); } - softpipe->so_target.num_buffers = num_buffers; - draw_set_mapped_so_buffers(softpipe->draw, map_buffers, num_buffers); + softpipe->num_so_targets = num_targets; } - - void softpipe_init_streamout_funcs(struct pipe_context *pipe) { -#if 0 - pipe->create_stream_output_state = softpipe_create_stream_output_state; - pipe->bind_stream_output_state = softpipe_bind_stream_output_state; - pipe->delete_stream_output_state = softpipe_delete_stream_output_state; - - pipe->set_stream_output_buffers = softpipe_set_stream_output_buffers; -#else - (void) softpipe_create_stream_output_state; - (void) softpipe_bind_stream_output_state; - (void) softpipe_delete_stream_output_state; - (void) softpipe_set_stream_output_buffers; -#endif + pipe->create_stream_output_target = softpipe_create_so_target; + pipe->stream_output_target_destroy = softpipe_so_target_destroy; + pipe->set_stream_output_targets = softpipe_set_so_targets; } |