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: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33500>
This commit is contained in:
Connor Abbott 2025-02-11 10:49:38 -05:00 committed by Marge Bot
parent df0c17f76e
commit 7351f8d587
4 changed files with 28 additions and 12 deletions

View file

@ -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<CHIP>(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<CHIP>(cmd, cs, src_iview, dst_iview, src->samples, false, src_format,

View file

@ -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++) {

View file

@ -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);

View file

@ -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[] = {