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:
@@ -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) \
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user