aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/v3d
diff options
context:
space:
mode:
authorIago Toral Quiroga <[email protected]>2019-10-15 08:32:47 +0200
committerIago Toral Quiroga <[email protected]>2019-12-16 08:42:37 +0100
commite054fe0167ead8d788d4b53d4001bfffc8ea3cb3 (patch)
treef545bcc3c205dc585a5029f8f6b17609c926724e /src/gallium/drivers/v3d
parente54cf649397d57ff99c495ba5821e31b6d4a0068 (diff)
v3d: support transform feedback with geometry shaders
Reviewed-by: Alejandro PiƱeiro <[email protected]>
Diffstat (limited to 'src/gallium/drivers/v3d')
-rw-r--r--src/gallium/drivers/v3d/v3d_context.h3
-rw-r--r--src/gallium/drivers/v3d/v3dx_emit.c27
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);