v3d: include offset as part of streamout target
authorJuan A. Suarez Romero <jasuarez@igalia.com>
Tue, 7 Mar 2023 09:49:58 +0000 (10:49 +0100)
committerMarge Bot <emma+marge@anholt.net>
Tue, 21 Mar 2023 12:31:24 +0000 (12:31 +0000)
When dealing with multiple Transform Feedback buffers, each of them
needs to have their own offset, so when resuming from one to another we
know exactly were to continue adding primitives.

Fixes "spec@arb_transform_feedback2@change objects while paused (gles3)"
piglit test.

Signed-off-by: Juan A. Suarez Romero <jasuarez@igalia.com>
Reviewed-by: Eric Engestrom <eric@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17373>

src/broadcom/ci/broadcom-rpi4-fails.txt
src/gallium/drivers/v3d/v3d_context.h
src/gallium/drivers/v3d/v3dx_draw.c
src/gallium/drivers/v3d/v3dx_emit.c
src/gallium/drivers/v3d/v3dx_state.c

index 99f0f0f..8e05345 100644 (file)
@@ -183,7 +183,6 @@ spec@arb_texture_rg@texwrap formats-float bordercolor-swizzled@GL_RG32F- swizzle
 spec@arb_texture_rg@texwrap formats-float,Fail
 spec@arb_texture_rg@texwrap formats-float@GL_R32F- NPOT,Fail
 spec@arb_texture_rg@texwrap formats-float@GL_RG32F- NPOT,Fail
-spec@arb_transform_feedback2@change objects while paused (gles3),Fail
 spec@egl 1.4@eglterminate then unbind context,Fail
 spec@egl_ext_protected_content@conformance,Fail
 spec@egl_khr_gl_image@egl_khr_gl_renderbuffer_image-clear-shared-image gl_depth_component24,Fail
index b7f3790..56157b4 100644 (file)
@@ -273,12 +273,12 @@ struct v3d_stream_output_target {
         struct pipe_stream_output_target base;
         /* Number of transform feedback vertices written to this target */
         uint32_t recorded_vertex_count;
+        /* Number of vertices we've written into the buffer so far */
+        uint32_t offset;
 };
 
 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 c3ed1da..f18a60c 100644 (file)
@@ -1261,7 +1261,8 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
          * needs some clamping to the buffer size.
          */
         for (int i = 0; i < v3d->streamout.num_targets; i++)
-                v3d->streamout.offsets[i] += draws[0].count;
+                v3d_stream_output_target(v3d->streamout.targets[i])->offset +=
+                        draws[0].count;
 
         if (v3d->zsa && job->zsbuf && v3d->zsa->base.depth_enabled) {
                 struct v3d_resource *rsc = v3d_resource(job->zsbuf->texture);
index e47753d..a35031e 100644 (file)
@@ -780,14 +780,14 @@ v3dX(emit_state)(struct pipe_context *pctx)
                 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 =
+                        struct pipe_stream_output_target *target =
                                 so->targets[i];
                         struct v3d_resource *rsc = target ?
                                 v3d_resource(target->buffer) : NULL;
                         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);
+                        uint32_t offset = target ?
+                                v3d_stream_output_target(target)->offset * info->stride[i] * 4 : 0;
 
 #if V3D_VERSION >= 40
                         if (!target)
index b7651de..b740b21 100644 (file)
@@ -1296,9 +1296,12 @@ v3d_set_stream_output_targets(struct pipe_context *pctx,
         if (num_targets == 0 && so->num_targets > 0)
                 v3d_update_primitive_counters(ctx);
 
+        /* If offset is (unsigned) -1, it means continue appending to the
+         * buffer at the existing offset.
+         */
         for (i = 0; i < num_targets; i++) {
-                if (offsets[i] != -1)
-                        so->offsets[i] = offsets[i];
+                if (offsets[i] != (unsigned)-1)
+                        v3d_stream_output_target(targets[i])->offset = offsets[i];
 
                 pipe_so_target_reference(&so->targets[i], targets[i]);
         }