115/130 sounds great. Just one minor comment. Otherwise looks good
Reviewed-by: Jose Fonseca <[email protected]> Jose ----- Original Message ----- > 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. > > Signed-off-by: Dave Airlie <[email protected]> > --- > src/gallium/drivers/llvmpipe/lp_context.h | 11 +- > src/gallium/drivers/llvmpipe/lp_draw_arrays.c | 9 ++ > src/gallium/drivers/llvmpipe/lp_query.c | 24 ++++ > src/gallium/drivers/llvmpipe/lp_query.h | 2 + > src/gallium/drivers/llvmpipe/lp_rast.c | 8 +- > src/gallium/drivers/llvmpipe/lp_scene.c | 3 +- > src/gallium/drivers/llvmpipe/lp_scene.h | 5 +- > src/gallium/drivers/llvmpipe/lp_screen.c | 3 +- > src/gallium/drivers/llvmpipe/lp_setup.c | 12 +- > src/gallium/drivers/llvmpipe/lp_setup.h | 4 + > src/gallium/drivers/llvmpipe/lp_setup_context.h | 1 + > src/gallium/drivers/llvmpipe/lp_setup_vbuf.c | 14 +++ > src/gallium/drivers/llvmpipe/lp_state_rasterizer.c | 2 + > src/gallium/drivers/llvmpipe/lp_state_so.c | 121 > ++++++--------------- > src/gallium/drivers/llvmpipe/lp_surface.c | 4 +- > 15 files changed, 122 insertions(+), 101 deletions(-) > > diff --git a/src/gallium/drivers/llvmpipe/lp_context.h > b/src/gallium/drivers/llvmpipe/lp_context.h > index fe6fa3f..25cdff9 100644 > --- a/src/gallium/drivers/llvmpipe/lp_context.h > +++ b/src/gallium/drivers/llvmpipe/lp_context.h > @@ -81,12 +81,6 @@ struct llvmpipe_context { > struct pipe_viewport_state viewport; > struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; > struct pipe_index_buffer index_buffer; > - struct { > - struct llvmpipe_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 pipe_resource *mapped_vs_tex[PIPE_MAX_SAMPLERS]; > > unsigned num_samplers[PIPE_SHADER_TYPES]; > @@ -94,6 +88,11 @@ struct llvmpipe_context { > > unsigned num_vertex_buffers; > > + 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 dirty; /**< Mask of LP_NEW_x flags */ > > unsigned active_occlusion_query; > diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c > b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c > index 3497edf..eaa9ba3 100644 > --- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c > +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c > @@ -88,6 +88,13 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const > struct pipe_draw_info *info) > lp->index_buffer.index_size); > } > > + for (i = 0; i < lp->num_so_targets; i++) { > + void *buf = > llvmpipe_resource(lp->so_targets[i]->target.buffer)->data; > + lp->so_targets[i]->mapping = buf; > + } > + draw_set_mapped_so_targets(draw, lp->num_so_targets, > + lp->so_targets); > + > llvmpipe_prepare_vertex_sampling(lp, > > lp->num_sampler_views[PIPE_SHADER_VERTEX], > lp->sampler_views[PIPE_SHADER_VERTEX]); > @@ -104,6 +111,8 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, > const struct pipe_draw_info *info) > if (mapped_indices) { > draw_set_indexes(draw, NULL, 0); > } > + draw_set_mapped_so_targets(draw, 0, NULL); > + > llvmpipe_cleanup_vertex_sampling(lp); > > /* > diff --git a/src/gallium/drivers/llvmpipe/lp_query.c > b/src/gallium/drivers/llvmpipe/lp_query.c > index e302197..7a62a80 100644 > --- a/src/gallium/drivers/llvmpipe/lp_query.c > +++ b/src/gallium/drivers/llvmpipe/lp_query.c > @@ -138,6 +138,12 @@ llvmpipe_get_query_result(struct pipe_context > *pipe, > *result = os_time_get_nano(); > } > break; > + case PIPE_QUERY_PRIMITIVES_GENERATED: > + *result = pq->num_primitives_generated; > + break; > + case PIPE_QUERY_PRIMITIVES_EMITTED: > + *result = pq->num_primitives_written; > + break; > default: > assert(0); > break; > @@ -165,6 +171,16 @@ llvmpipe_begin_query(struct pipe_context *pipe, > struct pipe_query *q) > memset(pq->count, 0, sizeof(pq->count)); > lp_setup_begin_query(llvmpipe->setup, pq); > > + if (pq->type == PIPE_QUERY_PRIMITIVES_EMITTED) { > + pq->num_primitives_written = 0; > + llvmpipe->so_stats.num_primitives_written = 0; > + } > + > + if (pq->type == PIPE_QUERY_PRIMITIVES_GENERATED) { > + pq->num_primitives_generated = 0; > + llvmpipe->num_primitives_generated = 0; > + } > + > if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER) { > llvmpipe->active_occlusion_query = TRUE; > llvmpipe->dirty |= LP_NEW_OCCLUSION_QUERY; > @@ -180,6 +196,14 @@ llvmpipe_end_query(struct pipe_context *pipe, > struct pipe_query *q) > > lp_setup_end_query(llvmpipe->setup, pq); > > + if (pq->type == PIPE_QUERY_PRIMITIVES_EMITTED) { > + pq->num_primitives_written = > llvmpipe->so_stats.num_primitives_written; > + } > + > + if (pq->type == PIPE_QUERY_PRIMITIVES_GENERATED) { > + pq->num_primitives_generated = > llvmpipe->num_primitives_generated; > + } > + > if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER) { > assert(llvmpipe->active_occlusion_query); > llvmpipe->active_occlusion_query = FALSE; > diff --git a/src/gallium/drivers/llvmpipe/lp_query.h > b/src/gallium/drivers/llvmpipe/lp_query.h > index cacbd9d..19d977f 100644 > --- a/src/gallium/drivers/llvmpipe/lp_query.h > +++ b/src/gallium/drivers/llvmpipe/lp_query.h > @@ -45,6 +45,8 @@ struct llvmpipe_query { > uint64_t count[LP_MAX_THREADS]; /* a counter for each thread */ > struct lp_fence *fence; /* fence from last scene this > was binned in */ > unsigned type; /* PIPE_QUERY_* */ > + unsigned num_primitives_generated; > + unsigned num_primitives_written; > }; > > > diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c > b/src/gallium/drivers/llvmpipe/lp_rast.c > index 40a8591..37be6ad 100644 > --- a/src/gallium/drivers/llvmpipe/lp_rast.c > +++ b/src/gallium/drivers/llvmpipe/lp_rast.c > @@ -440,6 +440,9 @@ lp_rast_begin_query(struct lp_rasterizer_task > *task, > case PIPE_QUERY_TIME_ELAPSED: > task->query_start = os_time_get_nano(); > break; > + case PIPE_QUERY_PRIMITIVES_GENERATED: > + case PIPE_QUERY_PRIMITIVES_EMITTED: > + break; > default: > assert(0); > break; > @@ -471,6 +474,9 @@ lp_rast_end_query(struct lp_rasterizer_task > *task, > case PIPE_QUERY_TIMESTAMP: > pq->count[task->thread_index] = os_time_get_nano(); > break; > + case PIPE_QUERY_PRIMITIVES_GENERATED: > + case PIPE_QUERY_PRIMITIVES_EMITTED: > + break; > default: > assert(0); > break; > @@ -606,7 +612,7 @@ rasterize_scene(struct lp_rasterizer_task *task, > { > task->scene = scene; > > - if (!task->rast->no_rast) { > + if (!task->rast->no_rast && !scene->discard) { > /* loop over scene bins, rasterize each */ > #if 0 > { > diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c > b/src/gallium/drivers/llvmpipe/lp_scene.c > index ed99824..328c0f7 100644 > --- a/src/gallium/drivers/llvmpipe/lp_scene.c > +++ b/src/gallium/drivers/llvmpipe/lp_scene.c > @@ -472,10 +472,11 @@ end: > > > void lp_scene_begin_binning( struct lp_scene *scene, > - struct pipe_framebuffer_state *fb ) > + struct pipe_framebuffer_state *fb, > boolean discard ) > { > assert(lp_scene_is_empty(scene)); > > + scene->discard = discard; > util_copy_framebuffer_state(&scene->fb, fb); > > scene->tiles_x = align(fb->width, TILE_SIZE) / TILE_SIZE; > diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h > b/src/gallium/drivers/llvmpipe/lp_scene.h > index 31a5ae7..b1db61b 100644 > --- a/src/gallium/drivers/llvmpipe/lp_scene.h > +++ b/src/gallium/drivers/llvmpipe/lp_scene.h > @@ -157,7 +157,7 @@ struct lp_scene { > > boolean alloc_failed; > boolean has_depthstencil_clear; > - > + boolean discard; > /** > * Number of active tiles in each dimension. > * This basically the framebuffer size divided by tile size > @@ -381,7 +381,8 @@ lp_scene_bin_iter_next( struct lp_scene *scene ); > */ > void > lp_scene_begin_binning( struct lp_scene *scene, > - struct pipe_framebuffer_state *fb ); > + struct pipe_framebuffer_state *fb, > + boolean discard ); > > void > lp_scene_end_binning( struct lp_scene *scene ); > diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c > b/src/gallium/drivers/llvmpipe/lp_screen.c > index acbde9d..61228f6 100644 > --- a/src/gallium/drivers/llvmpipe/lp_screen.c > +++ b/src/gallium/drivers/llvmpipe/lp_screen.c > @@ -117,7 +117,7 @@ llvmpipe_get_param(struct pipe_screen *screen, > enum pipe_cap param) > case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: > return 0; > case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: > - return 0; > + return PIPE_MAX_SO_BUFFERS; > case PIPE_CAP_ANISOTROPIC_FILTER: > return 0; > case PIPE_CAP_POINT_SPRITE: > @@ -186,6 +186,7 @@ llvmpipe_get_param(struct pipe_screen *screen, > enum pipe_cap param) > return 0; > case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: > case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: > + return 16*4; > case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: > return 0; > case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS: > diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c > b/src/gallium/drivers/llvmpipe/lp_setup.c > index 1d71a87..25e5da8 100644 > --- a/src/gallium/drivers/llvmpipe/lp_setup.c > +++ b/src/gallium/drivers/llvmpipe/lp_setup.c > @@ -65,7 +65,9 @@ static boolean try_update_scene_state( struct > lp_setup_context *setup ); > static void > lp_setup_get_empty_scene(struct lp_setup_context *setup) > { > + struct llvmpipe_context *lp = llvmpipe_context(setup->pipe); > assert(setup->scene == NULL); > + boolean discard = lp->rasterizer ? > lp->rasterizer->rasterizer_discard : FALSE; > > setup->scene_idx++; > setup->scene_idx %= Elements(setup->scenes); > @@ -80,7 +82,7 @@ lp_setup_get_empty_scene(struct lp_setup_context > *setup) > lp_fence_wait(setup->scene->fence); > } > > - lp_scene_begin_binning(setup->scene, &setup->fb); > + lp_scene_begin_binning(setup->scene, &setup->fb, discard); > > } > > @@ -620,6 +622,13 @@ lp_setup_set_flatshade_first( struct > lp_setup_context *setup, > setup->flatshade_first = flatshade_first; > } > > +void > +lp_setup_set_rasterizer_discard( struct lp_setup_context *setup, > + boolean rasterizer_discard ) > +{ > + setup->rasterizer_discard = rasterizer_discard; > + set_scene_state( setup, SETUP_FLUSHED, __FUNCTION__ ); > +} > > void > lp_setup_set_vertex_info( struct lp_setup_context *setup, > @@ -1057,6 +1066,7 @@ lp_setup_create( struct pipe_context *pipe, > struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen); > struct lp_setup_context *setup; > unsigned i; > + struct llvmpipe_context *lp = llvmpipe_context(pipe); > > setup = CALLOC_STRUCT(lp_setup_context); > if (!setup) { > diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h > b/src/gallium/drivers/llvmpipe/lp_setup.h > index 78b4145..c3dde80 100644 > --- a/src/gallium/drivers/llvmpipe/lp_setup.h > +++ b/src/gallium/drivers/llvmpipe/lp_setup.h > @@ -138,6 +138,10 @@ lp_setup_set_flatshade_first( struct > lp_setup_context *setup, > boolean flatshade_first ); > > void > +lp_setup_set_rasterizer_discard( struct lp_setup_context *setup, > + boolean rasterizer_discard ); > + > +void > lp_setup_set_vertex_info( struct lp_setup_context *setup, > struct vertex_info *info ); > > diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h > b/src/gallium/drivers/llvmpipe/lp_setup_context.h > index 6c86b4b..f810700 100644 > --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h > +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h > @@ -95,6 +95,7 @@ struct lp_setup_context > boolean ccw_is_frontface; > boolean scissor_test; > boolean point_size_per_vertex; > + boolean rasterizer_discard; > unsigned cullmode; > float pixel_offset; > float line_width; > diff --git a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c > b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c > index b287ef4..9e0a5b3 100644 > --- a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c > +++ b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c > @@ -37,6 +37,7 @@ > > > #include "lp_setup_context.h" > +#include "lp_context.h" > #include "draw/draw_vbuf.h" > #include "draw/draw_vertex.h" > #include "util/u_memory.h" > @@ -533,6 +534,18 @@ lp_setup_vbuf_destroy(struct vbuf_render *vbr) > lp_setup_destroy(setup); > } > > +static void > +lp_setup_so_info(struct vbuf_render *vbr, uint primitives, uint > vertices, > + uint prim_generated) > +{ > + struct lp_setup_context *setup = lp_setup_context(vbr); > + struct llvmpipe_context *lp = llvmpipe_context(setup->pipe); > + > + lp->so_stats.num_primitives_written += primitives; > + lp->so_stats.primitives_storage_needed = > + vertices * 4 /*sizeof(float|int32)*/ * 4 /*x,y,z,w*/; > + lp->num_primitives_generated += prim_generated; > +} > > /** > * Create the post-transform vertex handler for the given context. > @@ -552,4 +565,5 @@ lp_setup_init_vbuf(struct lp_setup_context > *setup) > setup->base.draw_arrays = lp_setup_draw_arrays; > setup->base.release_vertices = lp_setup_release_vertices; > setup->base.destroy = lp_setup_vbuf_destroy; > + setup->base.set_stream_output_info = lp_setup_so_info; > } > diff --git a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c > b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c > index 574f9e9..40ccaf6 100644 > --- a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c > +++ b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c > @@ -114,6 +114,8 @@ llvmpipe_bind_rasterizer_state(struct > pipe_context *pipe, void *handle) > state->lp_state.gl_rasterization_rules); > lp_setup_set_flatshade_first( llvmpipe->setup, > state->lp_state.flatshade_first); > + lp_setup_set_rasterizer_discard( llvmpipe->setup, > + state->lp_state.rasterizer_discard); > lp_setup_set_line_state( llvmpipe->setup, > state->lp_state.line_width); > lp_setup_set_point_state( llvmpipe->setup, > diff --git a/src/gallium/drivers/llvmpipe/lp_state_so.c > b/src/gallium/drivers/llvmpipe/lp_state_so.c > index ed2272d..b937bcf 100644 > --- a/src/gallium/drivers/llvmpipe/lp_state_so.c > +++ b/src/gallium/drivers/llvmpipe/lp_state_so.c > @@ -32,106 +32,53 @@ > #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); Lets catch NULL t here: 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; > } > diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c > b/src/gallium/drivers/llvmpipe/lp_surface.c > index e42f4c8..11475fd 100644 > --- a/src/gallium/drivers/llvmpipe/lp_surface.c > +++ b/src/gallium/drivers/llvmpipe/lp_surface.c > @@ -208,8 +208,8 @@ static void lp_blit(struct pipe_context *pipe, > util_blitter_save_vertex_elements(lp->blitter, > (void*)lp->velems); > util_blitter_save_vertex_shader(lp->blitter, (void*)lp->vs); > util_blitter_save_geometry_shader(lp->blitter, (void*)lp->gs); > - /*util_blitter_save_so_targets(lp->blitter, lp->num_so_targets, > - (struct > pipe_stream_output_target**)lp->so_targets);*/ > + util_blitter_save_so_targets(lp->blitter, lp->num_so_targets, > + (struct > pipe_stream_output_target**)lp->so_targets); > util_blitter_save_rasterizer(lp->blitter, (void*)lp->rasterizer); > util_blitter_save_viewport(lp->blitter, &lp->viewport); > util_blitter_save_scissor(lp->blitter, &lp->scissor); > -- > 1.7.11.7 > > _______________________________________________ > mesa-dev mailing list > [email protected] > http://lists.freedesktop.org/mailman/listinfo/mesa-dev > _______________________________________________ mesa-dev mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-dev
