Mesa (master): freedreno: Clamp TF prims written to buffer size pre-a6xx.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Mar 24 21:46:24 UTC 2021


Module: Mesa
Branch: master
Commit: 9be24c89c8c298069eaa3ff600ba556b9a4557e9
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=9be24c89c8c298069eaa3ff600ba556b9a4557e9

Author: Eric Anholt <eric at anholt.net>
Date:   Wed Mar 17 16:13:41 2021 -0700

freedreno: Clamp TF prims written to buffer size pre-a6xx.

I thought based on some previous debug this was going to fix a pile of
dEQPs, but no luck.  Still, one less TODO in the driver.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9687>

---

 .../freedreno/ci/piglit-freedreno-a530-fails.txt   |  3 ---
 src/gallium/drivers/freedreno/freedreno_context.h  |  5 +++++
 src/gallium/drivers/freedreno/freedreno_draw.c     | 22 +++++++++++++---------
 src/gallium/drivers/freedreno/freedreno_state.c    |  7 ++++++-
 4 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/src/gallium/drivers/freedreno/ci/piglit-freedreno-a530-fails.txt b/src/gallium/drivers/freedreno/ci/piglit-freedreno-a530-fails.txt
index 09a26449cc4..e14d02da737 100644
--- a/src/gallium/drivers/freedreno/ci/piglit-freedreno-a530-fails.txt
+++ b/src/gallium/drivers/freedreno/ci/piglit-freedreno-a530-fails.txt
@@ -255,16 +255,13 @@ spec at ext_texture_snorm@fbo-blending-formats,Fail
 spec at ext_transform_feedback2@draw-auto,Fail
 spec at ext_transform_feedback@change-size base-shrink,Fail
 spec at ext_transform_feedback@change-size offset-shrink,Fail
-spec at ext_transform_feedback@change-size range-grow,Fail
 spec at ext_transform_feedback@change-size range-shrink,Fail
 spec at ext_transform_feedback@discard-copypixels,Fail
 spec at ext_transform_feedback@generatemipmap prims_generated,Fail
 spec at ext_transform_feedback@immediate-reuse,Fail
 spec at ext_transform_feedback@immediate-reuse-index-buffer,Fail
 spec at ext_transform_feedback@immediate-reuse-uniform-buffer,Fail
-spec at ext_transform_feedback@intervening-read prims_written,Fail
 spec at ext_transform_feedback@overflow-edge-cases,Fail
-spec at ext_transform_feedback@query-primitives_written-bufferrange,Fail
 spec at ext_transform_feedback@query-primitives_written-bufferrange-discard,Fail
 spec at ext_transform_feedback@tessellation line_loop flat_first,Fail
 spec at ext_transform_feedback@tessellation line_loop flat_last,Fail
diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h
index 04fb04fcade..87ac9107529 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.h
+++ b/src/gallium/drivers/freedreno/freedreno_context.h
@@ -117,6 +117,11 @@ struct fd_streamout_stateobj {
 	 * queries are used.
 	 */
 	unsigned max_tf_vtx;
+
+	/* Pre-a6xx, the number of verts written to the buffers since the last
+	 * Begin.  Used for overflow checking for SW queries.
+	 */
+	unsigned verts_written;
 };
 
 #define MAX_GLOBAL_BUFFERS 16
diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c
index 2c091656080..77473ec8462 100644
--- a/src/gallium/drivers/freedreno/freedreno_draw.c
+++ b/src/gallium/drivers/freedreno/freedreno_draw.c
@@ -245,17 +245,21 @@ update_draw_stats(struct fd_context *ctx, const struct pipe_draw_info *info,
 			}
 		}
 
-		/* TODO prims_emitted should be clipped when the stream-out buffer is
-		 * not large enough.  See max_tf_vtx().. probably need to move that
-		 * into common code.  Although a bit more annoying since a2xx doesn't
-		 * use ir3 so no common way to get at the pipe_stream_output_info
-		 * which is needed for this calculation.
-		 */
+		ctx->stats.prims_generated += prims;
+
 		if (ctx->streamout.num_targets > 0) {
-			assert(ctx->active_queries);
-			ctx->stats.prims_emitted += prims;
+			/* Clip the prims we're writing to the size of the SO buffers. */
+			enum pipe_prim_type tf_prim = u_decomposed_prim(info->mode);
+			unsigned verts_written = u_vertices_for_prims(tf_prim, prims);
+			unsigned remaining_vert_space = ctx->streamout.max_tf_vtx - ctx->streamout.verts_written;
+			if (verts_written > remaining_vert_space) {
+				verts_written = remaining_vert_space;
+				u_trim_pipe_prim(tf_prim, &remaining_vert_space);
+			}
+			ctx->streamout.verts_written += verts_written;
+
+			ctx->stats.prims_emitted += u_reduced_prims_for_vertices(tf_prim, verts_written);
 		}
-		ctx->stats.prims_generated += prims;
 	}
 }
 
diff --git a/src/gallium/drivers/freedreno/freedreno_state.c b/src/gallium/drivers/freedreno/freedreno_state.c
index 63637ad9a8f..ab008cf9711 100644
--- a/src/gallium/drivers/freedreno/freedreno_state.c
+++ b/src/gallium/drivers/freedreno/freedreno_state.c
@@ -600,8 +600,13 @@ fd_set_stream_output_targets(struct pipe_context *pctx,
 		if (!changed && !reset)
 			continue;
 
-		if (reset)
+		/* Note that all SO targets will be reset at once at a
+		 * BeginTransformFeedback().
+		 */
+		if (reset) {
 			so->offsets[i] = offsets[i];
+			ctx->streamout.verts_written = 0;
+		}
 
 		pipe_so_target_reference(&so->targets[i], targets[i]);
 	}



More information about the mesa-commit mailing list