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;
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)
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.
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);
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;
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
* 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);
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;
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));