freedreno/a6xx: Move static regs to preamble IB

We can re-use this for preemption.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30544>
This commit is contained in:
Rob Clark
2024-09-24 14:33:23 -07:00
committed by Marge Bot
parent 0c36ca7446
commit 270e595811
6 changed files with 135 additions and 58 deletions
@@ -44,6 +44,12 @@ fd6_context_destroy(struct pipe_context *pctx) in_dt
if (fd6_ctx->sample_locations_disable_stateobj)
fd_ringbuffer_del(fd6_ctx->sample_locations_disable_stateobj);
if (fd6_ctx->preamble)
fd_ringbuffer_del(fd6_ctx->preamble);
if (fd6_ctx->restore)
fd_ringbuffer_del(fd6_ctx->restore);
fd_context_destroy(pctx);
if (fd6_ctx->vsc_draw_strm)
@@ -311,6 +317,12 @@ fd6_context_create(struct pipe_screen *pscreen, void *priv,
fd6_ctx->sample_locations_disable_stateobj = ring;
fd6_ctx->preamble = fd6_build_preemption_preamble<CHIP>(&fd6_ctx->base);
ring = fd_ringbuffer_new_object(fd6_ctx->base.pipe, 0x1000);
fd6_emit_static_regs<CHIP>(&fd6_ctx->base, ring);
fd6_ctx->restore = ring;
return fd_context_init_tc(pctx, flags);
}
FD_GENX(fd6_context_create);
@@ -92,6 +92,9 @@ struct fd6_context {
/* pre-baked stateobj for sample-locations disable: */
struct fd_ringbuffer *sample_locations_disable_stateobj;
/* pre-baked stateobj for preamble: */
struct fd_ringbuffer *preamble, *restore;
/* storage for ctx->last.key: */
struct ir3_shader_key last_key;
@@ -154,6 +157,8 @@ struct fd6_control {
uint32_t offset;
uint32_t pad[7];
} flush_base[4];
uint32_t vsc_state[32];
};
#define control_ptr(fd6_ctx, member) \
+60 -51
View File
@@ -856,60 +856,12 @@ fd6_emit_stomp(struct fd_ringbuffer *ring, const uint16_t *regs, size_t count)
}
}
/* emit setup at begin of new cmdstream buffer (don't rely on previous
* state, there could have been a context switch between ioctls):
*/
template <chip CHIP>
void
fd6_emit_restore(struct fd_batch *batch, struct fd_ringbuffer *ring)
fd6_emit_static_regs(struct fd_context *ctx, struct fd_ringbuffer *ring)
{
struct fd_context *ctx = batch->ctx;
struct fd_screen *screen = ctx->screen;
if (!batch->nondraw) {
trace_start_state_restore(&batch->trace, ring);
}
if (FD_DBG(STOMP)) {
fd6_emit_stomp<CHIP>(ring, &RP_BLIT_REGS<CHIP>[0], ARRAY_SIZE(RP_BLIT_REGS<CHIP>));
fd6_emit_stomp<CHIP>(ring, &CMD_REGS<CHIP>[0], ARRAY_SIZE(CMD_REGS<CHIP>));
}
OUT_PKT7(ring, CP_SET_MODE, 1);
OUT_RING(ring, 0);
if (CHIP == A6XX) {
fd6_cache_inv<CHIP>(ctx, ring);
} else {
OUT_PKT7(ring, CP_THREAD_CONTROL, 1);
OUT_RING(ring, CP_THREAD_CONTROL_0_THREAD(CP_SET_THREAD_BR) |
CP_THREAD_CONTROL_0_CONCURRENT_BIN_DISABLE);
fd6_event_write<CHIP>(ctx, ring, FD_CCU_INVALIDATE_COLOR);
fd6_event_write<CHIP>(ctx, ring, FD_CCU_INVALIDATE_DEPTH);
OUT_PKT7(ring, CP_EVENT_WRITE, 1);
OUT_RING(ring, UNK_40);
fd6_event_write<CHIP>(ctx, ring, FD_CACHE_INVALIDATE);
OUT_WFI5(ring);
}
OUT_REG(ring,
HLSQ_INVALIDATE_CMD(CHIP,
.vs_state = true, .hs_state = true,
.ds_state = true, .gs_state = true,
.fs_state = true, .cs_state = true,
.cs_ibo = true, .gfx_ibo = true,
.cs_shared_const = true,
.gfx_shared_const = true,
.cs_bindless = CHIP == A6XX ? 0x1f : 0xff,
.gfx_bindless = CHIP == A6XX ? 0x1f : 0xff,
)
);
OUT_WFI5(ring);
if (CHIP >= A7XX) {
/* On A7XX, RB_CCU_CNTL was broken into two registers, RB_CCU_CNTL which has
* static properties that can be set once, this requires a WFI to take effect.
@@ -926,8 +878,6 @@ fd6_emit_restore(struct fd_batch *batch, struct fd_ringbuffer *ring)
);
}
fd6_emit_ccu_cntl<CHIP>(ring, screen, false);
for (size_t i = 0; i < ARRAY_SIZE(screen->info->a6xx.magic_raw); i++) {
auto magic_reg = screen->info->a6xx.magic_raw[i];
if (!magic_reg.reg)
@@ -1126,6 +1076,65 @@ fd6_emit_restore(struct fd_batch *batch, struct fd_ringbuffer *ring)
if (screen->info->a6xx.has_early_preamble) {
WRITE(REG_A6XX_SP_FS_CTRL_REG0, 0);
}
}
FD_GENX(fd6_emit_static_regs);
/* emit setup at begin of new cmdstream buffer (don't rely on previous
* state, there could have been a context switch between ioctls):
*/
template <chip CHIP>
void
fd6_emit_restore(struct fd_batch *batch, struct fd_ringbuffer *ring)
{
struct fd_context *ctx = batch->ctx;
struct fd_screen *screen = ctx->screen;
if (!batch->nondraw) {
trace_start_state_restore(&batch->trace, ring);
}
if (FD_DBG(STOMP)) {
fd6_emit_stomp<CHIP>(ring, &RP_BLIT_REGS<CHIP>[0], ARRAY_SIZE(RP_BLIT_REGS<CHIP>));
fd6_emit_stomp<CHIP>(ring, &CMD_REGS<CHIP>[0], ARRAY_SIZE(CMD_REGS<CHIP>));
}
OUT_PKT7(ring, CP_SET_MODE, 1);
OUT_RING(ring, 0);
if (CHIP == A6XX) {
fd6_cache_inv<CHIP>(ctx, ring);
} else {
OUT_PKT7(ring, CP_THREAD_CONTROL, 1);
OUT_RING(ring, CP_THREAD_CONTROL_0_THREAD(CP_SET_THREAD_BR) |
CP_THREAD_CONTROL_0_CONCURRENT_BIN_DISABLE);
fd6_event_write<CHIP>(ctx, ring, FD_CCU_INVALIDATE_COLOR);
fd6_event_write<CHIP>(ctx, ring, FD_CCU_INVALIDATE_DEPTH);
OUT_PKT7(ring, CP_EVENT_WRITE, 1);
OUT_RING(ring, UNK_40);
fd6_event_write<CHIP>(ctx, ring, FD_CACHE_INVALIDATE);
OUT_WFI5(ring);
}
OUT_REG(ring,
HLSQ_INVALIDATE_CMD(CHIP,
.vs_state = true, .hs_state = true,
.ds_state = true, .gs_state = true,
.fs_state = true, .cs_state = true,
.cs_ibo = true, .gfx_ibo = true,
.cs_shared_const = true,
.gfx_shared_const = true,
.cs_bindless = CHIP == A6XX ? 0x1f : 0xff,
.gfx_bindless = CHIP == A6XX ? 0x1f : 0xff,
)
);
OUT_WFI5(ring);
fd6_emit_ib(ring, fd6_context(ctx)->restore);
fd6_emit_ccu_cntl<CHIP>(ring, screen, false);
if (!batch->nondraw) {
trace_end_state_restore(&batch->trace, ring);
@@ -384,6 +384,9 @@ void fd6_emit_cs_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
template <chip CHIP>
void fd6_emit_ccu_cntl(struct fd_ringbuffer *ring, struct fd_screen *screen, bool gmem);
template <chip CHIP>
void fd6_emit_static_regs(struct fd_context *ctx, struct fd_ringbuffer *ring);
template <chip CHIP>
void fd6_emit_restore(struct fd_batch *batch, struct fd_ringbuffer *ring);
+52 -7
View File
@@ -1068,6 +1068,48 @@ static void prepare_tile_setup(struct fd_batch *batch);
template <chip CHIP>
static void prepare_tile_fini(struct fd_batch *batch);
static void
fd7_emit_static_binning_regs(struct fd_ringbuffer *ring)
{
OUT_REG(ring, A7XX_RB_UNKNOWN_8812(0x0));
OUT_REG(ring, A7XX_RB_UNKNOWN_8E06(0x0));
OUT_REG(ring, A7XX_GRAS_UNKNOWN_8007(0x0));
OUT_REG(ring, A6XX_GRAS_UNKNOWN_8110(0x2));
OUT_REG(ring, A7XX_RB_UNKNOWN_8E09(0x4));
OUT_REG(ring, A7XX_RB_BLIT_CLEAR_MODE(.clear_mode = CLEAR_MODE_GMEM));
}
template <chip CHIP>
struct fd_ringbuffer *
fd6_build_preemption_preamble(struct fd_context *ctx)
{
struct fd_screen *screen = ctx->screen;
struct fd_ringbuffer *ring;
ring = fd_ringbuffer_new_object(ctx->pipe, 0x1000);
fd6_emit_static_regs<CHIP>(ctx, ring);
fd6_emit_ccu_cntl<CHIP>(ring, screen, false);
if (CHIP == A6XX) {
OUT_REG(ring, A6XX_PC_POWER_CNTL(screen->info->a6xx.magic.PC_POWER_CNTL));
OUT_REG(ring, A6XX_VFD_POWER_CNTL(screen->info->a6xx.magic.PC_POWER_CNTL));
} else if (CHIP >= A7XX) {
fd7_emit_static_binning_regs(ring);
}
/* TODO use CP_MEM_TO_SCRATCH_MEM on a7xx. The VSC scratch mem should be
* automatically saved, unlike GPU registers, so we wouldn't have to
* manually restore this state.
*/
OUT_PKT7(ring, CP_MEM_TO_REG, 3);
OUT_RING(ring, CP_MEM_TO_REG_0_REG(REG_A6XX_VSC_STATE(0)) |
CP_MEM_TO_REG_0_CNT(32));
OUT_RELOC(ring, control_ptr(fd6_context(ctx), vsc_state));
return ring;
}
FD_GENX(fd6_build_preemption_preamble);
/* before first tile */
template <chip CHIP>
static void
@@ -1109,13 +1151,8 @@ fd6_emit_tile_init(struct fd_batch *batch) assert_dt
emit_msaa(ring, pfb->samples);
patch_fb_read_gmem(batch);
if (CHIP >= A7XX) {
OUT_REG(ring, A7XX_RB_UNKNOWN_8812(0x0));
OUT_REG(ring, A7XX_RB_UNKNOWN_8E06(0x0));
OUT_REG(ring, A7XX_GRAS_UNKNOWN_8007(0x0));
OUT_REG(ring, A6XX_GRAS_UNKNOWN_8110(0x2));
OUT_REG(ring, A7XX_RB_UNKNOWN_8E09(0x4));
}
if (CHIP >= A7XX)
fd7_emit_static_binning_regs(ring);
if (use_hw_binning(batch)) {
/* enable stream-out during binning pass: */
@@ -1156,6 +1193,14 @@ fd6_emit_tile_init(struct fd_batch *batch) assert_dt
OUT_PKT7(ring, CP_SKIP_IB2_ENABLE_GLOBAL, 1);
OUT_RING(ring, 0x1);
/* Upload state regs to memory to be restored on skipsaverestore
* preemption.
*/
OUT_PKT7(ring, CP_REG_TO_MEM, 3);
OUT_RING(ring, CP_REG_TO_MEM_0_REG(REG_A6XX_VSC_STATE_REG(0)) |
CP_REG_TO_MEM_0_CNT(32));
OUT_RELOC(ring, control_ptr(fd6_context(batch->ctx), vsc_state));
} else {
/* no binning pass, so enable stream-out for draw pass:: */
OUT_REG(ring, A6XX_VPC_SO_DISABLE(false));
@@ -12,6 +12,9 @@
#include "pipe/p_context.h"
template <chip CHIP>
struct fd_ringbuffer *fd6_build_preemption_preamble(struct fd_context *ctx);
template <chip CHIP>
void fd6_gmem_init(struct pipe_context *pctx);