v3d: support transform feedback with geometry shaders
Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
|
Reference in New Issue
Block a user