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

Reply via email to