freedreno+turnip: Add has_cp_reg_write
Newer a6xx devices drop this packet from the sqe firmware, and use direct (pkt4) register writes instead for the few cases that previously used CP_REG_WRITE. The turnip part was adapted from Jonathans patch on !10892 Signed-off-by: Rob Clark <robdclark@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11790>
This commit is contained in:
parent
f74d0bf05e
commit
e552784e68
|
@ -89,6 +89,11 @@ struct fd_dev_info {
|
|||
|
||||
bool has_sample_locations;
|
||||
|
||||
/* The firmware on newer a6xx drops CP_REG_WRITE support as we
|
||||
* can now use direct register writes for these regs.
|
||||
*/
|
||||
bool has_cp_reg_write;
|
||||
|
||||
struct {
|
||||
uint32_t RB_UNKNOWN_8E04_blit;
|
||||
uint32_t PC_UNKNOWN_9805;
|
||||
|
|
|
@ -112,6 +112,10 @@ class A6xxGPUInfo(GPUInfo):
|
|||
self.a6xx.magic.PC_UNKNOWN_9805 = PC_UNKNOWN_9805
|
||||
self.a6xx.magic.SP_UNKNOWN_A0F8 = SP_UNKNOWN_A0F8
|
||||
|
||||
# Things that earlier gens have and later gens remove, provide
|
||||
# defaults here and let them be overridden by sub-gen template:
|
||||
self.a6xx.has_cp_reg_write = True
|
||||
|
||||
for name, val in template.items():
|
||||
setattr(self.a6xx, name, val)
|
||||
|
||||
|
|
|
@ -482,6 +482,7 @@ r3d_common(struct tu_cmd_buffer *cmd, struct tu_cs *cs, bool blit, uint32_t num_
|
|||
tu_cs_emit_regs(cs, A6XX_PC_PRIMITIVE_CNTL_0());
|
||||
tu_cs_emit_regs(cs, A6XX_VFD_CONTROL_0());
|
||||
|
||||
if (cmd->device->physical_device->info->a6xx.has_cp_reg_write) {
|
||||
/* Copy what the blob does here. This will emit an extra 0x3f
|
||||
* CP_EVENT_WRITE when multiview is disabled. I'm not exactly sure what
|
||||
* this is working around yet.
|
||||
|
@ -490,6 +491,9 @@ r3d_common(struct tu_cmd_buffer *cmd, struct tu_cs *cs, bool blit, uint32_t num_
|
|||
tu_cs_emit(cs, CP_REG_WRITE_0_TRACKER(UNK_EVENT_WRITE));
|
||||
tu_cs_emit(cs, REG_A6XX_PC_MULTIVIEW_CNTL);
|
||||
tu_cs_emit(cs, 0);
|
||||
} else {
|
||||
tu_cs_emit_regs(cs, A6XX_PC_MULTIVIEW_CNTL());
|
||||
}
|
||||
tu_cs_emit_regs(cs, A6XX_VFD_MULTIVIEW_CNTL());
|
||||
|
||||
tu6_emit_vpc(cs, &vs, NULL, NULL, NULL, &fs, 0);
|
||||
|
|
|
@ -324,9 +324,13 @@ tu6_emit_render_cntl(struct tu_cmd_buffer *cmd,
|
|||
bool binning)
|
||||
{
|
||||
const struct tu_framebuffer *fb = cmd->state.framebuffer;
|
||||
/* doesn't RB_RENDER_CNTL set differently for binning pass: */
|
||||
bool no_track = !cmd->device->physical_device->info->a6xx.has_cp_reg_write;
|
||||
uint32_t cntl = 0;
|
||||
cntl |= A6XX_RB_RENDER_CNTL_UNK4;
|
||||
if (binning) {
|
||||
if (no_track)
|
||||
return;
|
||||
cntl |= A6XX_RB_RENDER_CNTL_BINNING;
|
||||
} else {
|
||||
uint32_t mrts_ubwc_enable = 0;
|
||||
|
@ -349,6 +353,12 @@ tu6_emit_render_cntl(struct tu_cmd_buffer *cmd,
|
|||
cntl |= A6XX_RB_RENDER_CNTL_FLAG_DEPTH;
|
||||
}
|
||||
|
||||
if (no_track) {
|
||||
tu_cs_emit_pkt4(cs, REG_A6XX_RB_RENDER_CNTL, 1);
|
||||
tu_cs_emit(cs, cntl);
|
||||
return;
|
||||
}
|
||||
|
||||
/* In the !binning case, we need to set RB_RENDER_CNTL in the draw_cs
|
||||
* in order to set it correctly for the different subpasses. However,
|
||||
* that means the packets we're emitting also happen during binning. So
|
||||
|
|
|
@ -1612,9 +1612,13 @@ tu6_emit_program(struct tu_cs *cs,
|
|||
* CP_EVENT_WRITE when multiview is disabled. I'm not exactly sure what
|
||||
* this is working around yet.
|
||||
*/
|
||||
tu_cs_emit_pkt7(cs, CP_REG_WRITE, 3);
|
||||
tu_cs_emit(cs, CP_REG_WRITE_0_TRACKER(UNK_EVENT_WRITE));
|
||||
tu_cs_emit(cs, REG_A6XX_PC_MULTIVIEW_CNTL);
|
||||
if (builder->device->physical_device->info->a6xx.has_cp_reg_write) {
|
||||
tu_cs_emit_pkt7(cs, CP_REG_WRITE, 3);
|
||||
tu_cs_emit(cs, CP_REG_WRITE_0_TRACKER(UNK_EVENT_WRITE));
|
||||
tu_cs_emit(cs, REG_A6XX_PC_MULTIVIEW_CNTL);
|
||||
} else {
|
||||
tu_cs_emit_pkt4(cs, REG_A6XX_PC_MULTIVIEW_CNTL, 1);
|
||||
}
|
||||
tu_cs_emit(cs, multiview_cntl);
|
||||
|
||||
tu_cs_emit_pkt4(cs, REG_A6XX_VFD_MULTIVIEW_CNTL, 1);
|
||||
|
|
|
@ -335,6 +335,7 @@ update_render_cntl(struct fd_batch *batch, struct pipe_framebuffer_state *pfb,
|
|||
bool binning)
|
||||
{
|
||||
struct fd_ringbuffer *ring = batch->gmem;
|
||||
struct fd_screen *screen = batch->ctx->screen;
|
||||
uint32_t cntl = 0;
|
||||
bool depth_ubwc_enable = false;
|
||||
uint32_t mrts_ubwc_enable = 0;
|
||||
|
@ -363,9 +364,13 @@ update_render_cntl(struct fd_batch *batch, struct pipe_framebuffer_state *pfb,
|
|||
if (binning)
|
||||
cntl |= A6XX_RB_RENDER_CNTL_BINNING;
|
||||
|
||||
OUT_PKT7(ring, CP_REG_WRITE, 3);
|
||||
OUT_RING(ring, CP_REG_WRITE_0_TRACKER(TRACK_RENDER_CNTL));
|
||||
OUT_RING(ring, REG_A6XX_RB_RENDER_CNTL);
|
||||
if (screen->info->a6xx.has_cp_reg_write) {
|
||||
OUT_PKT7(ring, CP_REG_WRITE, 3);
|
||||
OUT_RING(ring, CP_REG_WRITE_0_TRACKER(TRACK_RENDER_CNTL));
|
||||
OUT_RING(ring, REG_A6XX_RB_RENDER_CNTL);
|
||||
} else {
|
||||
OUT_PKT4(ring, REG_A6XX_RB_RENDER_CNTL, 1);
|
||||
}
|
||||
OUT_RING(ring, cntl |
|
||||
COND(depth_ubwc_enable, A6XX_RB_RENDER_CNTL_FLAG_DEPTH) |
|
||||
A6XX_RB_RENDER_CNTL_FLAG_MRTS(mrts_ubwc_enable));
|
||||
|
|
Loading…
Reference in New Issue