Commit 3a5bdd6c authored by Emma Anholt's avatar Emma Anholt
Browse files

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: <!8843>
parent 59f047e6
Pipeline #266481 passed with stage
in 7 minutes and 10 seconds
......@@ -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
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -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 {
......
......@@ -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);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment