v3d: support transform feedback with geometry shaders

Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
This commit is contained in:
Iago Toral Quiroga
2019-10-15 08:32:47 +02:00
parent e54cf64939
commit e054fe0167
2 changed files with 21 additions and 9 deletions

View File

@@ -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;
}

View File

@@ -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);