From f677f64e80c453f21fbfa81855c88ba97c03b062 Mon Sep 17 00:00:00 2001 From: Amber Date: Tue, 28 Feb 2023 14:19:19 +0100 Subject: [PATCH] freedreno: implement GL_ARB_indirect_parameters Part-of: --- docs/features.txt | 4 +-- src/freedreno/ci/freedreno-a618-fails.txt | 5 ++++ src/freedreno/ci/freedreno-a630-fails.txt | 5 ++++ src/gallium/drivers/freedreno/a6xx/fd6_draw.cc | 33 +++++++++++++++++++++++- src/gallium/drivers/freedreno/freedreno_screen.c | 1 + 5 files changed, 45 insertions(+), 3 deletions(-) diff --git a/docs/features.txt b/docs/features.txt index e241143..571e0c5 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -228,11 +228,11 @@ GL 4.5, GLSL 4.50 -- all DONE: freedreno/a6xx, nvc0, r600, radeonsi, llvmpipe, z GL 4.6, GLSL 4.60 -- all DONE: radeonsi, zink GL_ARB_gl_spirv DONE (freedreno, i965/gen7+, llvmpipe) - GL_ARB_indirect_parameters DONE (i965/gen7+, nvc0, llvmpipe, virgl, d3d12) + GL_ARB_indirect_parameters DONE (freedreno/a6xx+, i965/gen7+, nvc0, llvmpipe, virgl, d3d12) GL_ARB_pipeline_statistics_query DONE (i965, nvc0, r600, llvmpipe, softpipe, ) GL_ARB_polygon_offset_clamp DONE (freedreno, i965, nv50, nvc0, r600, llvmpipe, v3d, virgl) GL_ARB_shader_atomic_counter_ops DONE (freedreno/a5xx+, i965/gen7+, nvc0, r600, llvmpipe, softpipe, virgl, v3d) - GL_ARB_shader_draw_parameters DONE (i965, llvmpipe, nvc0, d3d12) + GL_ARB_shader_draw_parameters DONE (freedreno/a6xx+, i965, llvmpipe, nvc0, d3d12) GL_ARB_shader_group_vote DONE (freedreno/a6xx, i965, nvc0, llvmpipe) GL_ARB_spirv_extensions DONE (freedreno, i965/gen7+, llvmpipe) GL_ARB_texture_filter_anisotropic DONE (etnaviv/HALTI0, freedreno, i965, nv50, nvc0, r600, softpipe, llvmpipe, d3d12, virgl, v3d, panfrost/g72+, asahi) diff --git a/src/freedreno/ci/freedreno-a618-fails.txt b/src/freedreno/ci/freedreno-a618-fails.txt index 46b1858..791c8cb 100644 --- a/src/freedreno/ci/freedreno-a618-fails.txt +++ b/src/freedreno/ci/freedreno-a618-fails.txt @@ -125,6 +125,11 @@ spec@arb_vertex_type_2_10_10_10_rev@attrib-p-type-size-match,Fail spec@arb_enhanced_layouts@execution@component-layout@vs-fs-array-dvec3,Crash spec@arb_enhanced_layouts@gs-stream-location-aliasing,Fail +# fails on gen1 (a618/a630) with both fd and zink, but passes on gen4.. +# maybe gen1 sqe doesn't handle the count==0 case? +spec@arb_indirect_parameters@tf-count-arrays,Fail +spec@arb_indirect_parameters@tf-count-elements,Fail + spec@egl 1.4@eglterminate then unbind context,Fail spec@egl_chromium_sync_control@conformance@eglGetSyncValuesCHROMIUM_msc_and_sbc_test,Fail spec@egl_chromium_sync_control@conformance,Fail diff --git a/src/freedreno/ci/freedreno-a630-fails.txt b/src/freedreno/ci/freedreno-a630-fails.txt index f16788a..f312e17 100644 --- a/src/freedreno/ci/freedreno-a630-fails.txt +++ b/src/freedreno/ci/freedreno-a630-fails.txt @@ -131,6 +131,11 @@ spec@arb_vertex_type_2_10_10_10_rev@attrib-p-type-size-match,Fail spec@arb_enhanced_layouts@execution@component-layout@vs-fs-array-dvec3,Crash spec@arb_enhanced_layouts@gs-stream-location-aliasing,Fail +# fails on gen1 (a618/a630) with both fd and zink, but passes on gen4.. +# maybe gen1 sqe doesn't handle the count==0 case? +spec@arb_indirect_parameters@tf-count-arrays,Fail +spec@arb_indirect_parameters@tf-count-elements,Fail + spec@egl 1.4@eglterminate then unbind context,Fail spec@egl_chromium_sync_control@conformance@eglGetSyncValuesCHROMIUM_msc_and_sbc_test,Fail spec@egl_chromium_sync_control@conformance,Fail diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_draw.cc b/src/gallium/drivers/freedreno/a6xx/fd6_draw.cc index 015cde6..aefd347 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_draw.cc +++ b/src/gallium/drivers/freedreno/a6xx/fd6_draw.cc @@ -83,7 +83,26 @@ draw_emit_indirect(struct fd_context *ctx, { struct fd_resource *ind = fd_resource(indirect->buffer); - if (info->index_size) { + if (indirect->indirect_draw_count && info->index_size) { + //On some firmwares CP_DRAW_INDIRECT_MULTI waits for WFIs before + //reading the draw parameters but after reading the count, so commands + //that use indirect draw count need a WFM anyway. + OUT_PKT7(ring, CP_WAIT_FOR_ME, 0); + OUT_PKT7(ring, CP_DRAW_INDIRECT_MULTI, 11); + OUT_RING(ring, pack_CP_DRAW_INDX_OFFSET_0(*draw0).value); + OUT_RING(ring, + (A6XX_CP_DRAW_INDIRECT_MULTI_1_OPCODE(INDIRECT_OP_INDIRECT_COUNT_INDEXED) + | A6XX_CP_DRAW_INDIRECT_MULTI_1_DST_OFF(driver_param))); + struct fd_resource *count_buf = fd_resource(indirect->indirect_draw_count); + struct pipe_resource *idx = info->index.resource; + unsigned max_indices = (idx->width0 - index_offset) / info->index_size; + OUT_RING(ring, indirect->draw_count); + OUT_RELOC(ring, fd_resource(idx)->bo, index_offset, 0, 0); + OUT_RING(ring, max_indices); + OUT_RELOC(ring, ind->bo, indirect->offset, 0, 0); + OUT_RELOC(ring, count_buf->bo, indirect->indirect_draw_count_offset, 0, 0); + OUT_RING(ring, indirect->stride); + } else if (info->index_size) { OUT_PKT7(ring, CP_DRAW_INDIRECT_MULTI, 9); OUT_RING(ring, pack_CP_DRAW_INDX_OFFSET_0(*draw0).value); OUT_RING(ring, @@ -98,6 +117,18 @@ draw_emit_indirect(struct fd_context *ctx, OUT_RING(ring, max_indices); OUT_RELOC(ring, ind->bo, indirect->offset, 0, 0); OUT_RING(ring, indirect->stride); + } else if(indirect->indirect_draw_count) { + OUT_PKT7(ring, CP_WAIT_FOR_ME, 0); + OUT_PKT7(ring, CP_DRAW_INDIRECT_MULTI, 8); + OUT_RING(ring, pack_CP_DRAW_INDX_OFFSET_0(*draw0).value); + OUT_RING(ring, + (A6XX_CP_DRAW_INDIRECT_MULTI_1_OPCODE(INDIRECT_OP_INDIRECT_COUNT) + | A6XX_CP_DRAW_INDIRECT_MULTI_1_DST_OFF(driver_param))); + struct fd_resource *count_buf = fd_resource(indirect->indirect_draw_count); + OUT_RING(ring, indirect->draw_count); + OUT_RELOC(ring, ind->bo, indirect->offset, 0, 0); + OUT_RELOC(ring, count_buf->bo, indirect->indirect_draw_count_offset, 0, 0); + OUT_RING(ring, indirect->stride); } else { OUT_PKT7(ring, CP_DRAW_INDIRECT_MULTI, 6); OUT_RING(ring, pack_CP_DRAW_INDX_OFFSET_0(*draw0).value); diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index f5081a3..bf2b37b 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -215,6 +215,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_CLEAR_TEXTURE: case PIPE_CAP_MULTI_DRAW_INDIRECT: case PIPE_CAP_DRAW_PARAMETERS: + case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS: return is_a6xx(screen); case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: -- 2.7.4