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@ext_texture_snorm@fbo-blending-formats,Fail spec@ext_transform_feedback2@draw-auto,Fail spec@ext_transform_feedback@change-size base-shrink,Fail spec@ext_transform_feedback@change-size offset-shrink,Fail -spec@ext_transform_feedback@change-size range-grow,Fail spec@ext_transform_feedback@change-size range-shrink,Fail spec@ext_transform_feedback@discard-copypixels,Fail spec@ext_transform_feedback@generatemipmap prims_generated,Fail spec@ext_transform_feedback@immediate-reuse,Fail spec@ext_transform_feedback@immediate-reuse-index-buffer,Fail spec@ext_transform_feedback@immediate-reuse-uniform-buffer,Fail -spec@ext_transform_feedback@intervening-read prims_written,Fail spec@ext_transform_feedback@overflow-edge-cases,Fail -spec@ext_transform_feedback@query-primitives_written-bufferrange,Fail spec@ext_transform_feedback@query-primitives_written-bufferrange-discard,Fail spec@ext_transform_feedback@tessellation line_loop flat_first,Fail spec@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. - */ - if (ctx->streamout.num_targets > 0) { - assert(ctx->active_queries); - ctx->stats.prims_emitted += prims; - } ctx->stats.prims_generated += prims; + + if (ctx->streamout.num_targets > 0) { + /* 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); + } } } 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]); }