From 7351f8d5875f4a7772e5ba251fd66060100b762e Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Tue, 11 Feb 2025 10:49:38 -0500 Subject: [PATCH] tu/fdm: Skip some patchpoints when binning In order to implement FDM offset, we will have to offset the viewport and scissor in the binning pass. In order to do this, we have to pass a bin with nonsensical negative offsets to the patchpoint function, which would result in asserts when patching the load/store sequences. But we don't really need to patch these anyways as they are unused during binning, so add the ability to skip them when binning. FS params and some implementations of CmdClearAttachments (that don't contribute to visibility) can similarly be skipped. Part-of: --- src/freedreno/vulkan/tu_clear_blit.cc | 17 +++++++++-------- src/freedreno/vulkan/tu_cmd_buffer.cc | 3 +++ src/freedreno/vulkan/tu_cmd_buffer.h | 14 ++++++++++++-- src/freedreno/vulkan/tu_pipeline.cc | 6 ++++-- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/freedreno/vulkan/tu_clear_blit.cc b/src/freedreno/vulkan/tu_clear_blit.cc index 2e58fd58ca9..a3c94f570aa 100644 --- a/src/freedreno/vulkan/tu_clear_blit.cc +++ b/src/freedreno/vulkan/tu_clear_blit.cc @@ -4105,7 +4105,7 @@ tu_clear_sysmem_attachments(struct tu_cmd_buffer *cmd, .z_clear_val = z_clear_val, .rect = rects[i].rect, }; - tu_create_fdm_bin_patchpoint(cmd, cs, 4, + tu_create_fdm_bin_patchpoint(cmd, cs, 4, TU_FDM_NONE, fdm_apply_sysmem_clear_coords, state); } else { @@ -4237,7 +4237,7 @@ tu_emit_clear_gmem_attachment(struct tu_cmd_buffer *cmd, .view = layer, .rect = *fdm_rect, }; - tu_create_fdm_bin_patchpoint(cmd, cs, 3, + tu_create_fdm_bin_patchpoint(cmd, cs, 3, TU_FDM_SKIP_BINNING, fdm_apply_gmem_clear_coords, state); } if (att->format == VK_FORMAT_D32_SFLOAT_S8_UINT) { @@ -4295,7 +4295,7 @@ tu_clear_gmem_attachments(struct tu_cmd_buffer *cmd, .view = 0, .rect = rects[i].rect, }; - tu_create_fdm_bin_patchpoint(cmd, cs, 3, + tu_create_fdm_bin_patchpoint(cmd, cs, 3, TU_FDM_SKIP_BINNING, fdm_apply_gmem_clear_coords, state); } else { /* We need to patch the clear rectangle for each view. */ @@ -4413,7 +4413,7 @@ tu7_clear_attachment_generic_single_rect( .view = 0, .rect = rect->rect, }; - tu_create_fdm_bin_patchpoint(cmd, cs, 3, + tu_create_fdm_bin_patchpoint(cmd, cs, 3, TU_FDM_SKIP_BINNING, fdm_apply_gmem_clear_coords, state); } } else { @@ -4441,7 +4441,7 @@ tu7_clear_attachment_generic_single_rect( .view = layer, .rect = rect->rect, }; - tu_create_fdm_bin_patchpoint(cmd, cs, 3, + tu_create_fdm_bin_patchpoint(cmd, cs, 3, TU_FDM_SKIP_BINNING, fdm_apply_gmem_clear_coords, state); } @@ -4877,7 +4877,8 @@ load_3d_blit(struct tu_cmd_buffer *cmd, struct apply_load_coords_state state = { .view = att->clear_views ? i : 0, }; - tu_create_fdm_bin_patchpoint(cmd, cs, 4, fdm_apply_load_coords, state); + tu_create_fdm_bin_patchpoint(cmd, cs, 4, TU_FDM_SKIP_BINNING, + fdm_apply_load_coords, state); } r3d_dst_gmem(cmd, cs, iview, att, separate_stencil, i); @@ -5436,8 +5437,8 @@ tu_store_gmem_attachment(struct tu_cmd_buffer *cmd, struct apply_store_coords_state state = { .view = view, }; - tu_create_fdm_bin_patchpoint(cmd, cs, 8, fdm_apply_store_coords, - state); + tu_create_fdm_bin_patchpoint(cmd, cs, 8, TU_FDM_SKIP_BINNING, + fdm_apply_store_coords, state); } if (store_common) { store_cp_blit(cmd, cs, src_iview, dst_iview, src->samples, false, src_format, diff --git a/src/freedreno/vulkan/tu_cmd_buffer.cc b/src/freedreno/vulkan/tu_cmd_buffer.cc index 110c714ef32..573475d558a 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.cc +++ b/src/freedreno/vulkan/tu_cmd_buffer.cc @@ -1729,6 +1729,8 @@ tu6_emit_binning_pass(struct tu_cmd_buffer *cmd, struct tu_cs *cs) VkRect2D bin = { { 0, 0 }, { fb->width, fb->height } }; util_dynarray_foreach (&cmd->fdm_bin_patchpoints, struct tu_fdm_bin_patchpoint, patch) { + if (patch->flags & TU_FDM_SKIP_BINNING) + continue; tu_cs_emit_pkt7(cs, CP_MEM_WRITE, 2 + patch->size); tu_cs_emit_qw(cs, patch->iova); patch->apply(cmd, cs, patch->data, bin, num_views, unscaled_frag_areas); @@ -5946,6 +5948,7 @@ tu_emit_fdm_params(struct tu_cmd_buffer *cmd, .num_consts = num_units - 1, }; tu_create_fdm_bin_patchpoint(cmd, cs, 4 * (num_units - 1), + TU_FDM_SKIP_BINNING, fdm_apply_fs_params, state); } else { for (unsigned i = 1; i < num_units; i++) { diff --git a/src/freedreno/vulkan/tu_cmd_buffer.h b/src/freedreno/vulkan/tu_cmd_buffer.h index 52727be352a..5afad09f62a 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.h +++ b/src/freedreno/vulkan/tu_cmd_buffer.h @@ -755,9 +755,17 @@ typedef void (*tu_fdm_bin_apply_t)(struct tu_cmd_buffer *cmd, unsigned views, const VkExtent2D *frag_areas); +enum tu_fdm_flags { + TU_FDM_NONE = 0, + + /* Skip applying this patchpoint when binning */ + TU_FDM_SKIP_BINNING = 1, +}; + struct tu_fdm_bin_patchpoint { uint64_t iova; uint32_t size; + enum tu_fdm_flags flags; void *data; tu_fdm_bin_apply_t apply; }; @@ -777,6 +785,7 @@ static inline void _tu_create_fdm_bin_patchpoint(struct tu_cmd_buffer *cmd, struct tu_cs *cs, unsigned size, + enum tu_fdm_flags flags, tu_fdm_bin_apply_t apply, void *state, unsigned state_size) @@ -788,6 +797,7 @@ _tu_create_fdm_bin_patchpoint(struct tu_cmd_buffer *cmd, struct tu_fdm_bin_patchpoint patch = { .iova = tu_cs_get_cur_iova(cs), .size = size, + .flags = flags, .data = data, .apply = apply, }; @@ -811,8 +821,8 @@ _tu_create_fdm_bin_patchpoint(struct tu_cmd_buffer *cmd, patch); } -#define tu_create_fdm_bin_patchpoint(cmd, cs, size, apply, state) \ - _tu_create_fdm_bin_patchpoint(cmd, cs, size, apply, &state, sizeof(state)) +#define tu_create_fdm_bin_patchpoint(cmd, cs, size, flags, apply, state) \ + _tu_create_fdm_bin_patchpoint(cmd, cs, size, flags, apply, &state, sizeof(state)) VkResult tu_init_bin_preamble(struct tu_device *device); diff --git a/src/freedreno/vulkan/tu_pipeline.cc b/src/freedreno/vulkan/tu_pipeline.cc index 7eec3f560e9..47ac853229f 100644 --- a/src/freedreno/vulkan/tu_pipeline.cc +++ b/src/freedreno/vulkan/tu_pipeline.cc @@ -2642,7 +2642,8 @@ tu6_emit_viewport_fdm(struct tu_cs *cs, struct tu_cmd_buffer *cmd, state.vp.viewport_count = num_views; unsigned size = TU_CALLX(cmd->device, tu6_viewport_size)(cmd->device, &state.vp, &state.rs); tu_cs_begin_sub_stream(&cmd->sub_cs, size, cs); - tu_create_fdm_bin_patchpoint(cmd, cs, size, fdm_apply_viewports, state); + tu_create_fdm_bin_patchpoint(cmd, cs, size, TU_FDM_NONE, + fdm_apply_viewports, state); cmd->state.rp.shared_viewport |= !cmd->state.per_view_viewport; } @@ -2754,7 +2755,8 @@ tu6_emit_scissor_fdm(struct tu_cs *cs, struct tu_cmd_buffer *cmd, state.vp.scissor_count = num_views; unsigned size = TU_CALLX(cmd->device, tu6_scissor_size)(cmd->device, &state.vp); tu_cs_begin_sub_stream(&cmd->sub_cs, size, cs); - tu_create_fdm_bin_patchpoint(cmd, cs, size, fdm_apply_scissors, state); + tu_create_fdm_bin_patchpoint(cmd, cs, size, TU_FDM_NONE, fdm_apply_scissors, + state); } static const enum mesa_vk_dynamic_graphics_state tu_sample_locations_state[] = {