turnip: use draw states for input attachments
authorJonathan Marek <jonathan@marek.ca>
Tue, 16 Jun 2020 16:34:57 +0000 (12:34 -0400)
committerMarge Bot <eric+marge@anholt.net>
Wed, 17 Jun 2020 15:32:30 +0000 (15:32 +0000)
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5446>

src/freedreno/vulkan/tu_clear_blit.c
src/freedreno/vulkan/tu_cmd_buffer.c
src/freedreno/vulkan/tu_private.h

index ab35bc60f1466fdf324e1a5336ab1290d40fe7b4..ba3ba5dfb8a69f01c430f26e6ed997c941c3e501 100644 (file)
@@ -2083,13 +2083,19 @@ tu_clear_sysmem_attachments(struct tu_cmd_buffer *cmd,
 
    /* 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);
index 2c8a3411dc39ff18ce70e04315d60662f7058ff8..b2712af5b84a68066998f942c3f01a8135d625f2 100644 (file)
@@ -707,6 +707,12 @@ tu_cs_emit_draw_state(struct tu_cs *cs, uint32_t id, struct tu_draw_state state)
    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 |
@@ -1258,6 +1264,7 @@ tu6_emit_binning_pass(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
 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
@@ -1322,20 +1329,36 @@ tu_emit_input_attachments(struct tu_cmd_buffer *cmd,
          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
@@ -1356,8 +1379,6 @@ tu_emit_renderpass_begin(struct tu_cmd_buffer *cmd,
    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);
@@ -1365,8 +1386,6 @@ tu_emit_renderpass_begin(struct tu_cmd_buffer *cmd,
    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);
 }
 
@@ -2780,6 +2799,8 @@ tu_CmdBeginRenderPass(VkCommandBuffer commandBuffer,
    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;
@@ -2836,16 +2857,12 @@ tu_CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents)
       }
    }
 
-   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 */
@@ -2856,6 +2873,8 @@ tu_CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents)
    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
@@ -3191,9 +3210,13 @@ tu6_bind_draw_states(struct tu_cmd_buffer *cmd,
     * 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);
index 213e4bd48437755442fd4116c54872a053d090b4..5e50b983302ea69c1d07f618f87c7ca1930ac28a 100644 (file)
@@ -438,6 +438,8 @@ enum tu_draw_state_group_id
    TU_DRAW_STATE_DESC_SETS,
    TU_DRAW_STATE_DESC_SETS_LOAD,
    TU_DRAW_STATE_VS_PARAMS,
+   TU_DRAW_STATE_INPUT_ATTACHMENTS_GMEM,
+   TU_DRAW_STATE_INPUT_ATTACHMENTS_SYSMEM,
 
    /* dynamic state related draw states */
    TU_DRAW_STATE_DYNAMIC,
@@ -816,6 +818,7 @@ struct tu_cmd_state
    struct tu_cs_entry vertex_buffers_ib;
    struct tu_cs_entry shader_const_ib[MESA_SHADER_STAGES];
    struct tu_cs_entry desc_sets_ib, desc_sets_load_ib;
+   struct tu_cs_entry ia_gmem_ib, ia_sysmem_ib;
 
    /* Stream output buffers */
    struct