v3d: Set the SO offsets correctly if we have to re-emit.
authorEric Anholt <eric@anholt.net>
Sat, 16 Jun 2018 00:08:29 +0000 (17:08 -0700)
committerEric Anholt <eric@anholt.net>
Mon, 18 Jun 2018 21:54:16 +0000 (14:54 -0700)
This should fix TF across a glFlush() or TF pause/restart.  Fixes
dEQP-GLES3.functional.transform_feedback.array.interleaved.lines.highp_float
and many, many others.

src/gallium/drivers/v3d/v3d_context.h
src/gallium/drivers/v3d/v3d_program.c
src/gallium/drivers/v3d/v3dx_draw.c
src/gallium/drivers/v3d/v3dx_emit.c
src/gallium/drivers/v3d/v3dx_state.c

index c0de05d36304ba897077ce9e3d0eaac7002c1803..7c920dbc3db380683d37bc3064c82efda172b65d 100644 (file)
@@ -189,6 +189,8 @@ struct v3d_vertex_stateobj {
 
 struct v3d_streamout_stateobj {
         struct pipe_stream_output_target *targets[PIPE_MAX_SO_BUFFERS];
+        /* Number of vertices we've written into the buffer so far. */
+        uint32_t offsets[PIPE_MAX_SO_BUFFERS];
         unsigned num_targets;
 };
 
index 036f7c6e6728d03ed7efce96ba0437cfb57195b4..ef7dd375bf72659b3045be60b3f96798c6ca1916 100644 (file)
@@ -152,6 +152,8 @@ v3d_set_transform_feedback_outputs(struct v3d_uncompiled_shader *so,
                         vpm_start_offset += write_size;
                         vpm_size -= write_size;
                 }
+                so->base.stream_output.stride[buffer] =
+                        stream_output->stride[buffer];
         }
 
         so->num_tf_outputs = slot_count;
index 1771973805610b30863c921f77cab4c17dc1a01c..eb3afaa026d38f307dcc66392d414864243e9c9c 100644 (file)
@@ -557,6 +557,12 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
         }
         job->draw_calls_queued++;
 
+        /* Increment the TF offsets by how many verts we wrote.  XXX: This
+         * needs some clamping to the buffer size.
+         */
+        for (int i = 0; i < v3d->streamout.num_targets; i++)
+                v3d->streamout.offsets[i] += info->count;
+
         if (v3d->zsa && job->zsbuf &&
             (v3d->zsa->base.depth.enabled ||
              v3d->zsa->base.stencil[0].enabled)) {
index 344f9e464f2d9e092a82a0f95ba3f178aa378699..e0bb95efb219054110c0245b09cd7aef4e19a04e 100644 (file)
@@ -694,6 +694,10 @@ v3dX(emit_state)(struct pipe_context *pctx)
                                 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;
+                        uint32_t offset = (v3d->streamout.offsets[i] *
+                                           info->stride[i] * 4);
 
 #if V3D_VERSION >= 40
                         if (!target)
@@ -702,9 +706,10 @@ v3dX(emit_state)(struct pipe_context *pctx)
                         cl_emit(&job->bcl, TRANSFORM_FEEDBACK_BUFFER, output) {
                                 output.buffer_address =
                                         cl_address(rsc->bo,
-                                                   target->buffer_offset);
+                                                   target->buffer_offset +
+                                                   offset);
                                 output.buffer_size_in_32_bit_words =
-                                        target->buffer_size >> 2;
+                                        (target->buffer_size - offset) >> 2;
                                 output.buffer_number = i;
                         }
 #else /* V3D_VERSION < 40 */
@@ -712,7 +717,8 @@ v3dX(emit_state)(struct pipe_context *pctx)
                                 if (target) {
                                         output.address =
                                                 cl_address(rsc->bo,
-                                                           target->buffer_offset);
+                                                           target->buffer_offset +
+                                                           offset);
                                 }
                         };
 #endif /* V3D_VERSION < 40 */
index ec6e8ebfef9a1134fda924f3660145f519d5bd29..70c596855f9b7ac419547471b4e38f41f55268a2 100644 (file)
@@ -902,8 +902,12 @@ v3d_set_stream_output_targets(struct pipe_context *pctx,
 
         assert(num_targets <= ARRAY_SIZE(so->targets));
 
-        for (i = 0; i < num_targets; i++)
+        for (i = 0; i < num_targets; i++) {
+                if (offsets[i] != -1)
+                        so->offsets[i] = offsets[i];
+
                 pipe_so_target_reference(&so->targets[i], targets[i]);
+        }
 
         for (; i < so->num_targets; i++)
                 pipe_so_target_reference(&so->targets[i], NULL);