From c05fafa4a0fd93d4264c46578e23a83ecf2b481e Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Fri, 9 Dec 2011 18:33:58 +0100 Subject: st/mesa: implement EXT_transform_feedback and ARB_transform_feedback2 --- src/gallium/auxiliary/cso_cache/cso_context.c | 101 ++++++++++++++++++++++++++ src/gallium/auxiliary/cso_cache/cso_context.h | 8 ++ src/gallium/auxiliary/util/u_blit.c | 6 ++ src/gallium/auxiliary/util/u_gen_mipmap.c | 3 + 4 files changed, 118 insertions(+) (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index b2a2b79b09a..49318e7d105 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -79,6 +79,7 @@ struct cso_context { struct cso_cache *cache; boolean has_geometry_shader; + boolean has_streamout; struct sampler_info fragment_samplers; struct sampler_info vertex_samplers; @@ -89,6 +90,12 @@ struct cso_context { uint nr_vertex_buffers_saved; struct pipe_vertex_buffer vertex_buffers_saved[PIPE_MAX_ATTRIBS]; + unsigned nr_so_targets; + struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS]; + + unsigned nr_so_targets_saved; + struct pipe_stream_output_target *so_targets_saved[PIPE_MAX_SO_BUFFERS]; + /** Current and saved state. * The saved state is used as a 1-deep stack. */ @@ -276,6 +283,10 @@ struct cso_context *cso_create_context( struct pipe_context *pipe ) PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0) { ctx->has_geometry_shader = TRUE; } + if (pipe->screen->get_param(pipe->screen, + PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0) { + ctx->has_streamout = TRUE; + } return ctx; @@ -306,6 +317,7 @@ void cso_release_all( struct cso_context *ctx ) ctx->pipe->set_fragment_sampler_views(ctx->pipe, 0, NULL); if (ctx->pipe->set_vertex_sampler_views) ctx->pipe->set_vertex_sampler_views(ctx->pipe, 0, NULL); + ctx->pipe->set_stream_output_targets(ctx->pipe, 0, NULL, 0); } /* free fragment samplers, views */ @@ -332,6 +344,11 @@ void cso_release_all( struct cso_context *ctx ) &ctx->nr_vertex_buffers_saved, NULL, 0); + for (i = 0; i < PIPE_MAX_SO_BUFFERS; i++) { + pipe_so_target_reference(&ctx->so_targets[i], NULL); + pipe_so_target_reference(&ctx->so_targets_saved[i], NULL); + } + if (ctx->cache) { cso_cache_delete( ctx->cache ); ctx->cache = NULL; @@ -1311,3 +1328,87 @@ cso_restore_vertex_sampler_views(struct cso_context *ctx) restore_sampler_views(ctx, &ctx->vertex_samplers, ctx->pipe->set_vertex_sampler_views); } + + +void +cso_set_stream_outputs(struct cso_context *ctx, + unsigned num_targets, + struct pipe_stream_output_target **targets, + unsigned append_bitmask) +{ + struct pipe_context *pipe = ctx->pipe; + uint i; + + if (!ctx->has_streamout) { + assert(num_targets == 0); + return; + } + + if (ctx->nr_so_targets == 0 && num_targets == 0) { + /* Nothing to do. */ + return; + } + + /* reference new targets */ + for (i = 0; i < num_targets; i++) { + pipe_so_target_reference(&ctx->so_targets[i], targets[i]); + } + /* unref extra old targets, if any */ + for (; i < ctx->nr_so_targets; i++) { + pipe_so_target_reference(&ctx->so_targets[i], NULL); + } + + pipe->set_stream_output_targets(pipe, num_targets, targets, + append_bitmask); + ctx->nr_so_targets = num_targets; +} + +void +cso_save_stream_outputs(struct cso_context *ctx) +{ + uint i; + + if (!ctx->has_streamout) { + return; + } + + ctx->nr_so_targets_saved = ctx->nr_so_targets; + + for (i = 0; i < ctx->nr_so_targets; i++) { + assert(!ctx->so_targets_saved[i]); + pipe_so_target_reference(&ctx->so_targets_saved[i], ctx->so_targets[i]); + } +} + +void +cso_restore_stream_outputs(struct cso_context *ctx) +{ + struct pipe_context *pipe = ctx->pipe; + uint i; + + if (!ctx->has_streamout) { + return; + } + + if (ctx->nr_so_targets == 0 && ctx->nr_so_targets_saved == 0) { + /* Nothing to do. */ + return; + } + + for (i = 0; i < ctx->nr_so_targets_saved; i++) { + pipe_so_target_reference(&ctx->so_targets[i], NULL); + /* move the reference from one pointer to another */ + ctx->so_targets[i] = ctx->so_targets_saved[i]; + ctx->so_targets_saved[i] = NULL; + } + for (; i < ctx->nr_so_targets; i++) { + pipe_so_target_reference(&ctx->so_targets[i], NULL); + } + + /* ~0 means append */ + pipe->set_stream_output_targets(pipe, ctx->nr_so_targets_saved, + ctx->so_targets, ~0); + + ctx->nr_so_targets = ctx->nr_so_targets_saved; + ctx->nr_so_targets_saved = 0; +} diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index 00edc9f8dd4..5102d706e33 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -117,6 +117,14 @@ void cso_save_vertex_buffers(struct cso_context *ctx); void cso_restore_vertex_buffers(struct cso_context *ctx); +void cso_set_stream_outputs(struct cso_context *ctx, + unsigned num_targets, + struct pipe_stream_output_target **targets, + unsigned append_bitmask); +void cso_save_stream_outputs(struct cso_context *ctx); +void cso_restore_stream_outputs(struct cso_context *ctx); + + /* These aren't really sensible -- most of the time the api provides * object semantics for shaders anyway, and the cases where it doesn't * (eg mesa's internall-generated texenv programs), it will be up to diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 3a0d7d42406..bba0031d772 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -529,6 +529,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, cso_save_rasterizer(ctx->cso); cso_save_samplers(ctx->cso); cso_save_fragment_sampler_views(ctx->cso); + cso_save_stream_outputs(ctx->cso); cso_save_viewport(ctx->cso); cso_save_framebuffer(ctx->cso); cso_save_fragment_shader(ctx->cso); @@ -546,6 +547,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, cso_set_rasterizer(ctx->cso, &ctx->rasterizer); cso_set_clip(ctx->cso, &ctx->clip); cso_set_vertex_elements(ctx->cso, 2, ctx->velem); + cso_set_stream_outputs(ctx->cso, 0, NULL, 0); /* sampler */ ctx->sampler.normalized_coords = normalized; @@ -622,6 +624,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, cso_restore_clip(ctx->cso); cso_restore_vertex_elements(ctx->cso); cso_restore_vertex_buffers(ctx->cso); + cso_restore_stream_outputs(ctx->cso); pipe_sampler_view_reference(&sampler_view, NULL); if (dst_surface != dst) @@ -722,6 +725,7 @@ util_blit_pixels_tex(struct blit_state *ctx, cso_save_rasterizer(ctx->cso); cso_save_samplers(ctx->cso); cso_save_fragment_sampler_views(ctx->cso); + cso_save_stream_outputs(ctx->cso); cso_save_viewport(ctx->cso); cso_save_framebuffer(ctx->cso); cso_save_fragment_shader(ctx->cso); @@ -737,6 +741,7 @@ util_blit_pixels_tex(struct blit_state *ctx, cso_set_rasterizer(ctx->cso, &ctx->rasterizer); cso_set_clip(ctx->cso, &ctx->clip); cso_set_vertex_elements(ctx->cso, 2, ctx->velem); + cso_set_stream_outputs(ctx->cso, 0, NULL, 0); /* sampler */ ctx->sampler.normalized_coords = normalized; @@ -801,4 +806,5 @@ util_blit_pixels_tex(struct blit_state *ctx, cso_restore_clip(ctx->cso); cso_restore_vertex_elements(ctx->cso); cso_restore_vertex_buffers(ctx->cso); + cso_restore_stream_outputs(ctx->cso); } diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 436a0e42456..7cce815beba 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -1558,6 +1558,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_save_rasterizer(ctx->cso); cso_save_samplers(ctx->cso); cso_save_fragment_sampler_views(ctx->cso); + cso_save_stream_outputs(ctx->cso); cso_save_framebuffer(ctx->cso); cso_save_fragment_shader(ctx->cso); cso_save_vertex_shader(ctx->cso); @@ -1572,6 +1573,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_set_rasterizer(ctx->cso, &ctx->rasterizer); cso_set_clip(ctx->cso, &ctx->clip); cso_set_vertex_elements(ctx->cso, 2, ctx->velem); + cso_set_stream_outputs(ctx->cso, 0, NULL, 0); set_fragment_shader(ctx, type); set_vertex_shader(ctx); @@ -1688,4 +1690,5 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_restore_viewport(ctx->cso); cso_restore_clip(ctx->cso); cso_restore_vertex_elements(ctx->cso); + cso_restore_stream_outputs(ctx->cso); } -- cgit v1.2.3