Module: Mesa Branch: master Commit: 3a5bdd6cf77511ae8a219db6f1aa6d8e46c26fe4 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=3a5bdd6cf77511ae8a219db6f1aa6d8e46c26fe4
Author: Eric Anholt <[email protected]> Date: Thu Feb 4 14:20:16 2021 -0800 freedreno/a6xx: Add support for glDrawTransformFeedback(). It's exposed with ARB_tf2, which we claimed support for. All the KHR-GL33 TF tests pass for me locally except for no_errors, which I have some outstanding fixes for with khronos. Our CI build seems to be having some issue with exceptions inside of deqp. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8843> --- .gitlab-ci/deqp-freedreno-a630-fails.txt | 5 ++-- src/gallium/drivers/freedreno/a6xx/fd6_draw.c | 36 +++++++++++++++++++++-- src/gallium/drivers/freedreno/a6xx/fd6_emit.c | 2 ++ src/gallium/drivers/freedreno/freedreno_context.h | 2 ++ src/gallium/drivers/freedreno/freedreno_draw.c | 8 +++-- 5 files changed, 45 insertions(+), 8 deletions(-) diff --git a/.gitlab-ci/deqp-freedreno-a630-fails.txt b/.gitlab-ci/deqp-freedreno-a630-fails.txt index 0a4c87a0eb7..c40d21a118d 100644 --- a/.gitlab-ci/deqp-freedreno-a630-fails.txt +++ b/.gitlab-ci/deqp-freedreno-a630-fails.txt @@ -4,9 +4,8 @@ KHR-GL33.transform_feedback.api_errors_test,Fail KHR-GL33.transform_feedback.capture_vertex_interleaved_test,Fail KHR-GL33.transform_feedback.capture_vertex_separate_test,Fail KHR-GL33.transform_feedback.discard_vertex_test,Fail -KHR-GL33.transform_feedback.draw_xfb_feedbackk_test,Fail -KHR-GL33.transform_feedback.draw_xfb_instanced_test,Fail -KHR-GL33.transform_feedback.draw_xfb_test,Fail +KHR-GL33.transform_feedback.draw_xfb_instanced_test,Crash +KHR-GL33.transform_feedback.draw_xfb_stream_instanced_test,Crash KHR-GL33.transform_feedback.query_vertex_interleaved_test,Fail KHR-GL33.transform_feedback.query_vertex_separate_test,Fail KHR-GL33.cull_distance.coverage,Fail diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c index 5f2dfb8dcee..756234a7aab 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c @@ -43,6 +43,30 @@ #include "fd6_pack.h" +static void +draw_emit_xfb(struct fd_ringbuffer *ring, + struct CP_DRAW_INDX_OFFSET_0 *draw0, + const struct pipe_draw_info *info, + const struct pipe_draw_indirect_info *indirect) +{ + struct fd_stream_output_target *target = fd_stream_output_target(indirect->count_from_stream_output); + struct fd_resource *offset = fd_resource(target->offset_buf); + + /* All known firmware versions do not wait for WFI's with CP_DRAW_AUTO. + * Plus, for the common case where the counter buffer is written by + * vkCmdEndTransformFeedback, we need to wait for the CP_WAIT_MEM_WRITES to + * complete which means we need a WAIT_FOR_ME anyway. + */ + OUT_PKT7(ring, CP_WAIT_FOR_ME, 0); + + OUT_PKT7(ring, CP_DRAW_AUTO, 6); + OUT_RING(ring, pack_CP_DRAW_INDX_OFFSET_0(*draw0).value); + OUT_RING(ring, info->instance_count); + OUT_RELOC(ring, offset->bo, 0, 0, 0); + OUT_RING(ring, 0); /* byte counter offset subtraced from the value read from above */ + OUT_RING(ring, target->stride); +} + static void draw_emit_indirect(struct fd_ringbuffer *ring, struct CP_DRAW_INDX_OFFSET_0 *draw0, @@ -240,7 +264,9 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, .gs_enable = !!emit.key.gs, }; - if (info->index_size) { + if (indirect && indirect->count_from_stream_output) { + draw0.source_select= DI_SRC_SEL_AUTO_XFB; + } else if (info->index_size) { draw0.source_select = DI_SRC_SEL_DMA; draw0.index_size = fd4_size2indextype(info->index_size); } else { @@ -322,8 +348,12 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, */ emit_marker6(ring, 7); - if (indirect && indirect->buffer) { - draw_emit_indirect(ring, &draw0, info, indirect, index_offset); + if (indirect) { + if (indirect->count_from_stream_output) { + draw_emit_xfb(ring, &draw0, info, indirect); + } else { + draw_emit_indirect(ring, &draw0, info, indirect, index_offset); + } } else { draw_emit(ring, &draw0, info, draw, index_offset); } diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c index 6903b982bb8..ca43645cf3c 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c @@ -737,6 +737,8 @@ fd6_emit_streamout(struct fd_ringbuffer *ring, struct fd6_emit *emit, struct ir3 if (!target) continue; + target->stride = info->stride[i]; + OUT_PKT4(ring, REG_A6XX_VPC_SO_BUFFER_BASE_LO(i), 3); /* VPC_SO[i].BUFFER_BASE_LO: */ OUT_RELOC(ring, fd_resource(target->base.buffer)->bo, 0, 0, 0); diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index 214b358f8ab..aaade073c00 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -90,6 +90,8 @@ struct fd_vertex_stateobj { struct fd_stream_output_target { struct pipe_stream_output_target base; struct pipe_resource *offset_buf; + /* stride of the last stream out recorded to this target, for glDrawTransformFeedback(). */ + uint32_t stride; }; struct fd_streamout_stateobj { diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c index 25f62334c3b..bd2d4690976 100644 --- a/src/gallium/drivers/freedreno/freedreno_draw.c +++ b/src/gallium/drivers/freedreno/freedreno_draw.c @@ -213,8 +213,12 @@ batch_draw_tracking(struct fd_batch *batch, const struct pipe_draw_info *info, resource_read(batch, info->index.resource); /* Mark indirect draw buffer as being read */ - if (indirect && indirect->buffer) - resource_read(batch, indirect->buffer); + if (indirect) { + if (indirect->buffer) + resource_read(batch, indirect->buffer); + if (indirect->count_from_stream_output) + resource_read(batch, fd_stream_output_target(indirect->count_from_stream_output)->offset_buf); + } resource_written(batch, batch->query_buf); _______________________________________________ mesa-commit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-commit
