From e054fe0167ead8d788d4b53d4001bfffc8ea3cb3 Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Tue, 15 Oct 2019 08:32:47 +0200 Subject: [PATCH] v3d: support transform feedback with geometry shaders MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Reviewed-by: Alejandro Piñeiro --- src/gallium/drivers/v3d/v3d_context.h | 3 ++- src/gallium/drivers/v3d/v3dx_emit.c | 27 +++++++++++++++++++-------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/gallium/drivers/v3d/v3d_context.h b/src/gallium/drivers/v3d/v3d_context.h index bf85b42eb9d..738c1f82319 100644 --- a/src/gallium/drivers/v3d/v3d_context.h +++ b/src/gallium/drivers/v3d/v3d_context.h @@ -625,7 +625,8 @@ v3d_ioctl(int fd, unsigned long request, void *arg) static inline bool v3d_transform_feedback_enabled(struct v3d_context *v3d) { - return v3d->prog.bind_vs->num_tf_specs != 0 && + return (v3d->prog.bind_vs->num_tf_specs != 0 || + (v3d->prog.bind_gs && v3d->prog.bind_gs->num_tf_specs != 0)) && v3d->active_queries; } diff --git a/src/gallium/drivers/v3d/v3dx_emit.c b/src/gallium/drivers/v3d/v3dx_emit.c index c5726c819f5..18c2473955b 100644 --- a/src/gallium/drivers/v3d/v3dx_emit.c +++ b/src/gallium/drivers/v3d/v3dx_emit.c @@ -401,6 +401,15 @@ emit_varying_flags(struct v3d_job *job, uint32_t *flags, return emitted_any; } +static inline struct v3d_uncompiled_shader * +get_tf_shader(struct v3d_context *v3d) +{ + if (v3d->prog.bind_gs) + return v3d->prog.bind_gs; + else + return v3d->prog.bind_vs; +} + void v3dX(emit_state)(struct pipe_context *pctx) { @@ -695,13 +704,14 @@ v3dX(emit_state)(struct pipe_context *pctx) VC5_DIRTY_RASTERIZER | VC5_DIRTY_PRIM_MODE)) { struct v3d_streamout_stateobj *so = &v3d->streamout; - if (so->num_targets) { bool psiz_per_vertex = (v3d->prim_mode == PIPE_PRIM_POINTS && v3d->rasterizer->base.point_size_per_vertex); + struct v3d_uncompiled_shader *tf_shader = + get_tf_shader(v3d); uint16_t *tf_specs = (psiz_per_vertex ? - v3d->prog.bind_vs->tf_specs_psiz : - v3d->prog.bind_vs->tf_specs); + tf_shader->tf_specs_psiz : + tf_shader->tf_specs); #if V3D_VERSION >= 40 bool tf_enabled = v3d_transform_feedback_enabled(v3d); @@ -709,7 +719,7 @@ v3dX(emit_state)(struct pipe_context *pctx) cl_emit(&job->bcl, TRANSFORM_FEEDBACK_SPECS, tfe) { tfe.number_of_16_bit_output_data_specs_following = - v3d->prog.bind_vs->num_tf_specs; + tf_shader->num_tf_specs; tfe.enable = tf_enabled; }; #else /* V3D_VERSION < 40 */ @@ -717,10 +727,10 @@ v3dX(emit_state)(struct pipe_context *pctx) tfe.number_of_32_bit_output_buffer_address_following = so->num_targets; tfe.number_of_16_bit_output_data_specs_following = - v3d->prog.bind_vs->num_tf_specs; + tf_shader->num_tf_specs; }; #endif /* V3D_VERSION < 40 */ - for (int i = 0; i < v3d->prog.bind_vs->num_tf_specs; i++) { + for (int i = 0; i < tf_shader->num_tf_specs; i++) { cl_emit_prepacked(&job->bcl, &tf_specs[i]); } } else { @@ -734,14 +744,15 @@ v3dX(emit_state)(struct pipe_context *pctx) /* Set up the trasnform feedback buffers. */ if (v3d->dirty & VC5_DIRTY_STREAMOUT) { + struct v3d_uncompiled_shader *tf_shader = get_tf_shader(v3d); struct v3d_streamout_stateobj *so = &v3d->streamout; for (int i = 0; i < so->num_targets; i++) { const struct pipe_stream_output_target *target = so->targets[i]; struct v3d_resource *rsc = target ? v3d_resource(target->buffer) : NULL; - struct pipe_shader_state *vs = &v3d->prog.bind_vs->base; - struct pipe_stream_output_info *info = &vs->stream_output; + struct pipe_shader_state *ss = &tf_shader->base; + struct pipe_stream_output_info *info = &ss->stream_output; uint32_t offset = (v3d->streamout.offsets[i] * info->stride[i] * 4); -- 2.30.2