/* disable all draw states so they don't interfere
* TODO: use and re-use draw states for this path
+ * we have to disable draw states individually to preserve
+ * input attachment states, because a secondary command buffer
+ * won't be able to restore them
*/
- tu_cs_emit_pkt7(cs, CP_SET_DRAW_STATE, 3);
- tu_cs_emit(cs, CP_SET_DRAW_STATE__0_COUNT(0) |
- CP_SET_DRAW_STATE__0_DISABLE_ALL_GROUPS |
- CP_SET_DRAW_STATE__0_GROUP_ID(0));
- tu_cs_emit(cs, CP_SET_DRAW_STATE__1_ADDR_LO(0));
- tu_cs_emit(cs, CP_SET_DRAW_STATE__2_ADDR_HI(0));
+ tu_cs_emit_pkt7(cs, CP_SET_DRAW_STATE, 3 * (TU_DRAW_STATE_COUNT - 2));
+ for (uint32_t i = 0; i < TU_DRAW_STATE_COUNT; i++) {
+ if (i == TU_DRAW_STATE_INPUT_ATTACHMENTS_GMEM ||
+ i == TU_DRAW_STATE_INPUT_ATTACHMENTS_SYSMEM)
+ continue;
+ tu_cs_emit(cs, CP_SET_DRAW_STATE__0_GROUP_ID(i) |
+ CP_SET_DRAW_STATE__0_DISABLE);
+ tu_cs_emit_qw(cs, 0);
+ }
cmd->state.dirty |= TU_CMD_DIRTY_DRAW_STATE;
tu_cs_emit_pkt4(cs, REG_A6XX_SP_FS_OUTPUT_CNTL0, 2);
case TU_DRAW_STATE_VI_BINNING:
enable_mask = CP_SET_DRAW_STATE__0_BINNING;
break;
+ case TU_DRAW_STATE_INPUT_ATTACHMENTS_GMEM:
+ enable_mask = CP_SET_DRAW_STATE__0_GMEM;
+ break;
+ case TU_DRAW_STATE_INPUT_ATTACHMENTS_SYSMEM:
+ enable_mask = CP_SET_DRAW_STATE__0_SYSMEM;
+ break;
default:
enable_mask = CP_SET_DRAW_STATE__0_GMEM |
CP_SET_DRAW_STATE__0_SYSMEM |
static void
tu_emit_input_attachments(struct tu_cmd_buffer *cmd,
const struct tu_subpass *subpass,
+ struct tu_cs_entry *ib,
bool gmem)
{
/* note: we can probably emit input attachments just once for the whole
dst[i] = 0;
}
- struct tu_cs *cs = &cmd->draw_cs;
+ struct tu_cs cs;
+ tu_cs_begin_sub_stream(&cmd->sub_cs, 9, &cs);
- tu_cs_emit_pkt7(cs, CP_LOAD_STATE6_FRAG, 3);
- tu_cs_emit(cs, CP_LOAD_STATE6_0_DST_OFF(0) |
+ tu_cs_emit_pkt7(&cs, CP_LOAD_STATE6_FRAG, 3);
+ tu_cs_emit(&cs, CP_LOAD_STATE6_0_DST_OFF(0) |
CP_LOAD_STATE6_0_STATE_TYPE(ST6_CONSTANTS) |
CP_LOAD_STATE6_0_STATE_SRC(SS6_INDIRECT) |
CP_LOAD_STATE6_0_STATE_BLOCK(SB6_FS_TEX) |
CP_LOAD_STATE6_0_NUM_UNIT(subpass->input_count * 2));
- tu_cs_emit_qw(cs, texture.iova);
+ tu_cs_emit_qw(&cs, texture.iova);
+
+ tu_cs_emit_pkt4(&cs, REG_A6XX_SP_FS_TEX_CONST_LO, 2);
+ tu_cs_emit_qw(&cs, texture.iova);
- tu_cs_emit_pkt4(cs, REG_A6XX_SP_FS_TEX_CONST_LO, 2);
- tu_cs_emit_qw(cs, texture.iova);
+ tu_cs_emit_regs(&cs, A6XX_SP_FS_TEX_COUNT(subpass->input_count * 2));
- tu_cs_emit_regs(cs, A6XX_SP_FS_TEX_COUNT(subpass->input_count * 2));
+ *ib = tu_cs_end_sub_stream(&cmd->sub_cs, &cs);
+}
+
+static void
+tu_set_input_attachments(struct tu_cmd_buffer *cmd, const struct tu_subpass *subpass)
+{
+ struct tu_cs *cs = &cmd->draw_cs;
+
+ tu_emit_input_attachments(cmd, subpass, &cmd->state.ia_gmem_ib, true);
+ tu_emit_input_attachments(cmd, subpass, &cmd->state.ia_sysmem_ib, false);
+
+ tu_cs_emit_pkt7(cs, CP_SET_DRAW_STATE, 6);
+ tu_cs_emit_sds_ib(cs, TU_DRAW_STATE_INPUT_ATTACHMENTS_GMEM, cmd->state.ia_gmem_ib);
+ tu_cs_emit_sds_ib(cs, TU_DRAW_STATE_INPUT_ATTACHMENTS_SYSMEM, cmd->state.ia_sysmem_ib);
}
static void
for (uint32_t i = 0; i < cmd->state.pass->attachment_count; ++i)
tu_clear_gmem_attachment(cmd, cs, i, info);
- tu_emit_input_attachments(cmd, cmd->state.subpass, true);
-
tu_cond_exec_end(cs);
tu_cond_exec_start(cs, CP_COND_EXEC_0_RENDER_MODE_SYSMEM);
for (uint32_t i = 0; i < cmd->state.pass->attachment_count; ++i)
tu_clear_sysmem_attachment(cmd, cs, i, info);
- tu_emit_input_attachments(cmd, cmd->state.subpass, false);
-
tu_cond_exec_end(cs);
}
tu6_emit_msaa(&cmd->draw_cs, cmd->state.subpass->samples);
tu6_emit_render_cntl(cmd, cmd->state.subpass, &cmd->draw_cs, false);
+ tu_set_input_attachments(cmd, cmd->state.subpass);
+
/* note: use_hw_binning only checks tiling config */
if (use_hw_binning(cmd))
cmd->use_vsc_data = true;
}
}
- tu_emit_input_attachments(cmd, cmd->state.subpass, true);
-
tu_cond_exec_end(cs);
tu_cond_exec_start(cs, CP_COND_EXEC_0_RENDER_MODE_SYSMEM);
tu6_emit_sysmem_resolves(cmd, cs, subpass);
- tu_emit_input_attachments(cmd, cmd->state.subpass, false);
-
tu_cond_exec_end(cs);
/* Handle dependencies for the next subpass */
tu6_emit_mrt(cmd, cmd->state.subpass, cs);
tu6_emit_msaa(cs, cmd->state.subpass->samples);
tu6_emit_render_cntl(cmd, cmd->state.subpass, cs, false);
+
+ tu_set_input_attachments(cmd, cmd->state.subpass);
}
void
* and if a draw-state disabling path (CmdClearAttachments 3D fallback) was
* used, then draw states must be re-emitted. note however this only happens
* in the sysmem path, so this can be skipped this for the gmem path (TODO)
+ *
+ * the two input attachment states are excluded because secondary command
+ * buffer doesn't have a state ib to restore it, and not re-emitting them
+ * is OK since CmdClearAttachments won't disable/overwrite them
*/
if (cmd->state.dirty & TU_CMD_DIRTY_DRAW_STATE) {
- tu_cs_emit_pkt7(cs, CP_SET_DRAW_STATE, 3 * TU_DRAW_STATE_COUNT);
+ tu_cs_emit_pkt7(cs, CP_SET_DRAW_STATE, 3 * (TU_DRAW_STATE_COUNT - 2));
tu_cs_emit_sds_ib(cs, TU_DRAW_STATE_PROGRAM, pipeline->program.state_ib);
tu_cs_emit_sds_ib(cs, TU_DRAW_STATE_PROGRAM_BINNING, pipeline->program.binning_state_ib);