tu: Group pipeline state based on VkPipeline*StateCreateInfo
authorConnor Abbott <cwabbott0@gmail.com>
Thu, 18 Aug 2022 09:54:41 +0000 (11:54 +0200)
committerMarge Bot <emma+marge@anholt.net>
Wed, 21 Sep 2022 11:20:15 +0000 (11:20 +0000)
This will help us to merge state when combining pipelines.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18554>

src/freedreno/vulkan/tu_cmd_buffer.c
src/freedreno/vulkan/tu_lrz.c
src/freedreno/vulkan/tu_pipeline.c
src/freedreno/vulkan/tu_pipeline.h

index 9766747..68af847 100644 (file)
@@ -2501,7 +2501,7 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer,
    cmd->state.dirty |= TU_CMD_DIRTY_DESC_SETS_LOAD | TU_CMD_DIRTY_SHADER_CONSTS |
                        TU_CMD_DIRTY_LRZ | TU_CMD_DIRTY_VS_PARAMS;
 
-   if (pipeline->feedback_loop_may_involve_textures) {
+   if (pipeline->output.feedback_loop_may_involve_textures) {
       /* VK_EXT_attachment_feedback_loop_layout allows feedback loop to involve
        * not only input attachments but also sampled images or image resources.
        * But we cannot just patch gmem for image in the descriptors.
@@ -2519,7 +2519,7 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer,
        */
       cmd->state.rp.disable_gmem = true;
    }
-   cmd->state.rp.sysmem_single_prim_mode |= pipeline->sysmem_single_prim_mode;
+   cmd->state.rp.sysmem_single_prim_mode |= pipeline->prim_order.sysmem_single_prim_mode;
 
    struct tu_cs *cs = &cmd->draw_cs;
 
@@ -2533,9 +2533,9 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer,
       tu_cs_emit_draw_state(cs, TU_DRAW_STATE_PROGRAM_CONFIG, pipeline->program.config_state);
       tu_cs_emit_draw_state(cs, TU_DRAW_STATE_PROGRAM, pipeline->program.state);
       tu_cs_emit_draw_state(cs, TU_DRAW_STATE_PROGRAM_BINNING, pipeline->program.binning_state);
-      tu_cs_emit_draw_state(cs, TU_DRAW_STATE_RAST, pipeline->rast_state);
-      tu_cs_emit_draw_state(cs, TU_DRAW_STATE_PRIM_MODE_SYSMEM, pipeline->prim_order_state_sysmem);
-      tu_cs_emit_draw_state(cs, TU_DRAW_STATE_PRIM_MODE_GMEM, pipeline->prim_order_state_gmem);
+      tu_cs_emit_draw_state(cs, TU_DRAW_STATE_RAST, pipeline->rast.state);
+      tu_cs_emit_draw_state(cs, TU_DRAW_STATE_PRIM_MODE_SYSMEM, pipeline->prim_order.state_sysmem);
+      tu_cs_emit_draw_state(cs, TU_DRAW_STATE_PRIM_MODE_GMEM, pipeline->prim_order.state_gmem);
 
       u_foreach_bit(i, mask)
          tu_cs_emit_draw_state(cs, TU_DRAW_STATE_DYNAMIC + i, pipeline->dynamic_state[i]);
@@ -2555,8 +2555,8 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer,
       tu_cs_emit(cs, subdraw_size);
    }
 
-   if (cmd->state.line_mode != pipeline->line_mode) {
-      cmd->state.line_mode = pipeline->line_mode;
+   if (cmd->state.line_mode != pipeline->rast.line_mode) {
+      cmd->state.line_mode = pipeline->rast.line_mode;
 
       /* We have to disable MSAA when bresenham lines are used, this is
        * a hardware limitation and spec allows it:
@@ -2571,19 +2571,19 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer,
    }
 
    if ((pipeline->dynamic_state_mask & BIT(VK_DYNAMIC_STATE_VIEWPORT)) &&
-       (pipeline->z_negative_one_to_one != cmd->state.z_negative_one_to_one)) {
-      cmd->state.z_negative_one_to_one = pipeline->z_negative_one_to_one;
+       (pipeline->viewport.z_negative_one_to_one != cmd->state.z_negative_one_to_one)) {
+      cmd->state.z_negative_one_to_one = pipeline->viewport.z_negative_one_to_one;
       cmd->state.dirty |= TU_CMD_DIRTY_VIEWPORTS;
    }
 
    if (!(pipeline->dynamic_state_mask & BIT(TU_DYNAMIC_STATE_VERTEX_INPUT)))
-      tu_update_num_vbs(cmd, pipeline->num_vbs);
+      tu_update_num_vbs(cmd, pipeline->vi.num_vbs);
 
-#define UPDATE_REG(X, Y) {                                           \
+#define UPDATE_REG(group, X, Y) {                                    \
    /* note: would be better to have pipeline bits already masked */  \
-   uint32_t pipeline_bits = pipeline->X & pipeline->X##_mask;        \
-   if ((cmd->state.X & pipeline->X##_mask) != pipeline_bits) {       \
-      cmd->state.X &= ~pipeline->X##_mask;                           \
+   uint32_t pipeline_bits = pipeline->group.X & pipeline->group.X##_mask; \
+   if ((cmd->state.X & pipeline->group.X##_mask) != pipeline_bits) { \
+      cmd->state.X &= ~pipeline->group.X##_mask;                     \
       cmd->state.X |= pipeline_bits;                                 \
       cmd->state.dirty |= TU_CMD_DIRTY_##Y;                          \
    }                                                                 \
@@ -2597,54 +2597,54 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer,
     * the relevant dirty bit is cleared to avoid overriding the non-dynamic
     * state with a dynamic state the next draw.
     */
-   UPDATE_REG(gras_su_cntl, GRAS_SU_CNTL);
-   UPDATE_REG(rb_depth_cntl, RB_DEPTH_CNTL);
-   UPDATE_REG(rb_stencil_cntl, RB_STENCIL_CNTL);
-   UPDATE_REG(pc_raster_cntl, RASTERIZER_DISCARD);
-   UPDATE_REG(vpc_unknown_9107, RASTERIZER_DISCARD);
-   UPDATE_REG(sp_blend_cntl, BLEND);
-   UPDATE_REG(rb_blend_cntl, BLEND);
-
-   for (unsigned i = 0; i < pipeline->num_rts; i++) {
-      if ((cmd->state.rb_mrt_control[i] & pipeline->rb_mrt_control_mask) !=
-          pipeline->rb_mrt_control[i]) {
-         cmd->state.rb_mrt_control[i] &= ~pipeline->rb_mrt_control_mask;
-         cmd->state.rb_mrt_control[i] |= pipeline->rb_mrt_control[i];
+   UPDATE_REG(rast, gras_su_cntl, GRAS_SU_CNTL);
+   UPDATE_REG(ds, rb_depth_cntl, RB_DEPTH_CNTL);
+   UPDATE_REG(ds, rb_stencil_cntl, RB_STENCIL_CNTL);
+   UPDATE_REG(rast, pc_raster_cntl, RASTERIZER_DISCARD);
+   UPDATE_REG(rast, vpc_unknown_9107, RASTERIZER_DISCARD);
+   UPDATE_REG(blend, sp_blend_cntl, BLEND);
+   UPDATE_REG(blend, rb_blend_cntl, BLEND);
+
+   for (unsigned i = 0; i < pipeline->blend.num_rts; i++) {
+      if ((cmd->state.rb_mrt_control[i] & pipeline->blend.rb_mrt_control_mask) !=
+          pipeline->blend.rb_mrt_control[i]) {
+         cmd->state.rb_mrt_control[i] &= ~pipeline->blend.rb_mrt_control_mask;
+         cmd->state.rb_mrt_control[i] |= pipeline->blend.rb_mrt_control[i];
          cmd->state.dirty |= TU_CMD_DIRTY_BLEND;
       }
 
-      if (cmd->state.rb_mrt_blend_control[i] != pipeline->rb_mrt_blend_control[i]) {
-         cmd->state.rb_mrt_blend_control[i] = pipeline->rb_mrt_blend_control[i];
+      if (cmd->state.rb_mrt_blend_control[i] != pipeline->blend.rb_mrt_blend_control[i]) {
+         cmd->state.rb_mrt_blend_control[i] = pipeline->blend.rb_mrt_blend_control[i];
          cmd->state.dirty |= TU_CMD_DIRTY_BLEND;
       }
    }
 #undef UPDATE_REG
 
-   if (cmd->state.pipeline_color_write_enable != pipeline->color_write_enable) {
-      cmd->state.pipeline_color_write_enable = pipeline->color_write_enable;
+   if (cmd->state.pipeline_color_write_enable != pipeline->blend.color_write_enable) {
+      cmd->state.pipeline_color_write_enable = pipeline->blend.color_write_enable;
       cmd->state.dirty |= TU_CMD_DIRTY_BLEND;
    }
-   if (cmd->state.pipeline_blend_enable != pipeline->blend_enable) {
-      cmd->state.pipeline_blend_enable = pipeline->blend_enable;
+   if (cmd->state.pipeline_blend_enable != pipeline->blend.blend_enable) {
+      cmd->state.pipeline_blend_enable = pipeline->blend.blend_enable;
       cmd->state.dirty |= TU_CMD_DIRTY_BLEND;
    }
-   if (cmd->state.logic_op_enabled != pipeline->logic_op_enabled) {
-      cmd->state.logic_op_enabled = pipeline->logic_op_enabled;
+   if (cmd->state.logic_op_enabled != pipeline->blend.logic_op_enabled) {
+      cmd->state.logic_op_enabled = pipeline->blend.logic_op_enabled;
       cmd->state.dirty |= TU_CMD_DIRTY_BLEND;
    }
    if (!(pipeline->dynamic_state_mask & BIT(TU_DYNAMIC_STATE_LOGIC_OP)) &&
-       cmd->state.rop_reads_dst != pipeline->rop_reads_dst) {
-      cmd->state.rop_reads_dst = pipeline->rop_reads_dst;
+       cmd->state.rop_reads_dst != pipeline->blend.rop_reads_dst) {
+      cmd->state.rop_reads_dst = pipeline->blend.rop_reads_dst;
       cmd->state.dirty |= TU_CMD_DIRTY_BLEND;
    }
-   if (cmd->state.dynamic_state[TU_DYNAMIC_STATE_BLEND].size != pipeline->num_rts * 3 + 4) {
+   if (cmd->state.dynamic_state[TU_DYNAMIC_STATE_BLEND].size != pipeline->blend.num_rts * 3 + 4) {
       cmd->state.dirty |= TU_CMD_DIRTY_BLEND;
    }
    if (!(pipeline->dynamic_state_mask & BIT(TU_DYNAMIC_STATE_BLEND))) {
       cmd->state.dirty &= ~TU_CMD_DIRTY_BLEND;
    }
 
-   if (pipeline->rb_depth_cntl_disable)
+   if (pipeline->output.rb_depth_cntl_disable)
       cmd->state.dirty |= TU_CMD_DIRTY_RB_DEPTH_CNTL;
 }
 
@@ -4218,12 +4218,12 @@ tu6_writes_stencil(struct tu_cmd_buffer *cmd)
    bool stencil_front_writemask =
       (cmd->state.pipeline->dynamic_state_mask & BIT(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK)) ?
       (cmd->state.dynamic_stencil_wrmask & 0xff) :
-      (cmd->state.pipeline->stencil_wrmask & 0xff);
+      (cmd->state.pipeline->ds.stencil_wrmask & 0xff);
 
    bool stencil_back_writemask =
       (cmd->state.pipeline->dynamic_state_mask & BIT(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK)) ?
       ((cmd->state.dynamic_stencil_wrmask & 0xff00) >> 8) :
-      (cmd->state.pipeline->stencil_wrmask & 0xff00) >> 8;
+      (cmd->state.pipeline->ds.stencil_wrmask & 0xff00) >> 8;
 
    VkStencilOp front_fail_op =
       (cmd->state.rb_stencil_cntl & A6XX_RB_STENCIL_CONTROL_FAIL__MASK) >> A6XX_RB_STENCIL_CONTROL_FAIL__SHIFT;
@@ -4261,19 +4261,19 @@ tu6_build_depth_plane_z_mode(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
    bool depth_write = tu6_writes_depth(cmd, depth_test_enable);
    bool stencil_write = tu6_writes_stencil(cmd);
 
-   if ((cmd->state.pipeline->lrz.fs_has_kill ||
-        cmd->state.pipeline->subpass_feedback_loop_ds) &&
+   if ((cmd->state.pipeline->lrz.fs.has_kill ||
+        cmd->state.pipeline->output.subpass_feedback_loop_ds) &&
        (depth_write || stencil_write)) {
       zmode = (cmd->state.lrz.valid && cmd->state.lrz.enabled)
                  ? A6XX_EARLY_LRZ_LATE_Z
                  : A6XX_LATE_Z;
    }
 
-   if (cmd->state.pipeline->lrz.force_late_z || !depth_test_enable)
+   if (cmd->state.pipeline->lrz.fs.force_late_z || !depth_test_enable)
       zmode = A6XX_LATE_Z;
 
    /* User defined early tests take precedence above all else */
-   if (cmd->state.pipeline->lrz.early_fragment_tests)
+   if (cmd->state.pipeline->lrz.fs.early_fragment_tests)
       zmode = A6XX_EARLY_Z;
 
    tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_SU_DEPTH_PLANE_CNTL, 1);
@@ -4293,13 +4293,13 @@ tu6_emit_blend(struct tu_cs *cs, struct tu_cmd_buffer *cmd)
        BIT(TU_DYNAMIC_STATE_COLOR_WRITE_ENABLE))
       color_write_enable &= cmd->state.color_write_enable;
 
-   for (unsigned i = 0; i < pipeline->num_rts; i++) {
+   for (unsigned i = 0; i < pipeline->blend.num_rts; i++) {
       tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_CONTROL(i), 2);
       if (color_write_enable & BIT(i)) {
          tu_cs_emit(cs, cmd->state.rb_mrt_control[i] |
                         ((cmd->state.logic_op_enabled ?
                           cmd->state.rb_mrt_control_rop : 0) &
-                         ~pipeline->rb_mrt_control_mask));
+                         ~pipeline->blend.rb_mrt_control_mask));
          tu_cs_emit(cs, cmd->state.rb_mrt_blend_control[i]);
       } else {
          tu_cs_emit(cs, 0);
@@ -4315,12 +4315,12 @@ tu6_emit_blend(struct tu_cs *cs, struct tu_cmd_buffer *cmd)
    tu_cs_emit_pkt4(cs, REG_A6XX_SP_BLEND_CNTL, 1);
    tu_cs_emit(cs, cmd->state.sp_blend_cntl |
                   (A6XX_SP_BLEND_CNTL_ENABLE_BLEND(blend_enable_mask) &
-                   ~pipeline->sp_blend_cntl_mask));
+                   ~pipeline->blend.sp_blend_cntl_mask));
 
    tu_cs_emit_pkt4(cs, REG_A6XX_RB_BLEND_CNTL, 1);
    tu_cs_emit(cs, cmd->state.rb_blend_cntl |
                   (A6XX_RB_BLEND_CNTL_ENABLE_BLEND(blend_enable_mask) &
-                   ~pipeline->rb_blend_cntl_mask));
+                   ~pipeline->blend.rb_blend_cntl_mask));
 }
 
 static VkResult
@@ -4336,10 +4336,10 @@ tu6_draw_common(struct tu_cmd_buffer *cmd,
    cmd->state.rp.drawcall_count++;
 
    cmd->state.rp.drawcall_bandwidth_per_sample_sum +=
-      cmd->state.pipeline->color_bandwidth_per_sample;
+      cmd->state.pipeline->output.color_bandwidth_per_sample;
 
    /* add depth memory bandwidth cost */
-   const uint32_t depth_bandwidth = cmd->state.pipeline->depth_cpp_per_sample;
+   const uint32_t depth_bandwidth = cmd->state.pipeline->output.depth_cpp_per_sample;
    if (cmd->state.rb_depth_cntl & A6XX_RB_DEPTH_CNTL_Z_WRITE_ENABLE)
       cmd->state.rp.drawcall_bandwidth_per_sample_sum += depth_bandwidth;
    if (cmd->state.rb_depth_cntl & A6XX_RB_DEPTH_CNTL_Z_TEST_ENABLE)
@@ -4347,7 +4347,7 @@ tu6_draw_common(struct tu_cmd_buffer *cmd,
 
    /* add stencil memory bandwidth cost */
    const uint32_t stencil_bandwidth =
-      cmd->state.pipeline->stencil_cpp_per_sample;
+      cmd->state.pipeline->output.stencil_cpp_per_sample;
    if (cmd->state.rb_stencil_cntl & A6XX_RB_STENCIL_CONTROL_STENCIL_ENABLE)
       cmd->state.rp.drawcall_bandwidth_per_sample_sum += stencil_bandwidth * 2;
 
@@ -4360,7 +4360,7 @@ tu6_draw_common(struct tu_cmd_buffer *cmd,
    tu_cs_emit_regs(cs, A6XX_PC_PRIMITIVE_CNTL_0(
          .primitive_restart =
                primitive_restart_enabled && indexed,
-         .provoking_vtx_last = pipeline->provoking_vertex_last,
+         .provoking_vtx_last = pipeline->rast.provoking_vertex_last,
          .tess_upper_left_domain_origin =
                pipeline->tess.upper_left_domain_origin));
 
@@ -4405,7 +4405,7 @@ tu6_draw_common(struct tu_cmd_buffer *cmd,
           !(rb_depth_cntl & A6XX_RB_DEPTH_CNTL_Z_TEST_ENABLE))
          tu6_apply_depth_bounds_workaround(cmd->device, &rb_depth_cntl);
 
-      if (pipeline->rb_depth_cntl_disable)
+      if (pipeline->output.rb_depth_cntl_disable)
          rb_depth_cntl = 0;
 
       tu_cs_emit_regs(&cs, A6XX_RB_DEPTH_CNTL(.dword = rb_depth_cntl));
@@ -4422,12 +4422,12 @@ tu6_draw_common(struct tu_cmd_buffer *cmd,
    if (cmd->state.dirty & TU_CMD_DIRTY_VIEWPORTS) {
       struct tu_cs cs = tu_cmd_dynamic_state(cmd, VK_DYNAMIC_STATE_VIEWPORT, 8 + 10 * cmd->state.max_viewport);
       tu6_emit_viewport(&cs, cmd->state.viewport, cmd->state.max_viewport,
-                        pipeline->z_negative_one_to_one);
+                        pipeline->viewport.z_negative_one_to_one);
    }
 
    if (cmd->state.dirty & TU_CMD_DIRTY_BLEND) {
       struct tu_cs cs = tu_cmd_dynamic_state(cmd, TU_DYNAMIC_STATE_BLEND,
-                                             4 + 3 * cmd->state.pipeline->num_rts);
+                                             4 + 3 * cmd->state.pipeline->blend.num_rts);
       tu6_emit_blend(&cs, cmd);
    }
 
@@ -4447,9 +4447,9 @@ tu6_draw_common(struct tu_cmd_buffer *cmd,
       tu_cs_emit_draw_state(cs, TU_DRAW_STATE_PROGRAM_CONFIG, pipeline->program.config_state);
       tu_cs_emit_draw_state(cs, TU_DRAW_STATE_PROGRAM, pipeline->program.state);
       tu_cs_emit_draw_state(cs, TU_DRAW_STATE_PROGRAM_BINNING, pipeline->program.binning_state);
-      tu_cs_emit_draw_state(cs, TU_DRAW_STATE_RAST, pipeline->rast_state);
-      tu_cs_emit_draw_state(cs, TU_DRAW_STATE_PRIM_MODE_SYSMEM, pipeline->prim_order_state_sysmem);
-      tu_cs_emit_draw_state(cs, TU_DRAW_STATE_PRIM_MODE_GMEM, pipeline->prim_order_state_gmem);
+      tu_cs_emit_draw_state(cs, TU_DRAW_STATE_RAST, pipeline->rast.state);
+      tu_cs_emit_draw_state(cs, TU_DRAW_STATE_PRIM_MODE_SYSMEM, pipeline->prim_order.state_sysmem);
+      tu_cs_emit_draw_state(cs, TU_DRAW_STATE_PRIM_MODE_GMEM, pipeline->prim_order.state_gmem);
       tu_cs_emit_draw_state(cs, TU_DRAW_STATE_CONST, cmd->state.shader_const);
       tu_cs_emit_draw_state(cs, TU_DRAW_STATE_DESC_SETS, cmd->state.desc_sets);
       tu_cs_emit_draw_state(cs, TU_DRAW_STATE_DESC_SETS_LOAD, pipeline->load_state);
index 514c428..e6cdced 100644 (file)
@@ -685,13 +685,13 @@ tu6_calculate_lrz_state(struct tu_cmd_buffer *cmd,
         BIT(TU_DYNAMIC_STATE_COLOR_WRITE_ENABLE)) &&
        (cmd->state.color_write_enable &
         MASK(cmd->state.subpass->color_count)) !=
-          MASK(cmd->state.pipeline->num_rts)) {
+          MASK(cmd->state.pipeline->blend.num_rts)) {
       if (gras_lrz_cntl.lrz_write) {
          perf_debug(
             cmd->device,
             "disabling lrz write due to dynamic color write enables (%x/%x)",
             cmd->state.color_write_enable,
-            MASK(cmd->state.pipeline->num_rts));
+            MASK(cmd->state.pipeline->blend.num_rts));
       }
       gras_lrz_cntl.lrz_write = false;
    }
@@ -805,12 +805,12 @@ tu6_calculate_lrz_state(struct tu_cmd_buffer *cmd,
       bool stencil_front_writemask =
          (pipeline->dynamic_state_mask & BIT(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK)) ?
          (cmd->state.dynamic_stencil_wrmask & 0xff) :
-         (pipeline->stencil_wrmask & 0xff);
+         (pipeline->ds.stencil_wrmask & 0xff);
 
       bool stencil_back_writemask =
          (pipeline->dynamic_state_mask & BIT(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK)) ?
          ((cmd->state.dynamic_stencil_wrmask & 0xff00) >> 8) :
-         (pipeline->stencil_wrmask & 0xff00) >> 8;
+         (pipeline->ds.stencil_wrmask & 0xff00) >> 8;
 
       VkCompareOp stencil_front_compare_op =
          (cmd->state.rb_stencil_cntl & A6XX_RB_STENCIL_CONTROL_FUNC__MASK) >> A6XX_RB_STENCIL_CONTROL_FUNC__SHIFT;
index 72f5d79..5c4a386 100644 (file)
@@ -1667,12 +1667,12 @@ tu6_emit_fs_outputs(struct tu_cs *cs,
                    A6XX_RB_RENDER_COMPONENTS(.dword = fs_render_components));
 
    if (pipeline) {
-      pipeline->lrz.fs_has_kill = fs->has_kill;
-      pipeline->lrz.early_fragment_tests = fs->fs.early_fragment_tests;
+      pipeline->lrz.fs.has_kill = fs->has_kill;
+      pipeline->lrz.fs.early_fragment_tests = fs->fs.early_fragment_tests;
 
       if (!fs->fs.early_fragment_tests &&
           (fs->no_earlyz || fs->has_kill || fs->writes_pos || fs->writes_stencilref || no_earlyz || fs->writes_smask)) {
-         pipeline->lrz.force_late_z = true;
+         pipeline->lrz.fs.force_late_z = true;
       }
    }
 }
@@ -2233,13 +2233,13 @@ tu6_emit_rb_mrt_controls(struct tu_pipeline *pipeline,
 
    uint32_t rb_mrt_control_rop = 0;
    if (blend_info->logicOpEnable) {
-      pipeline->logic_op_enabled = true;
+      pipeline->blend.logic_op_enabled = true;
       rb_mrt_control_rop = tu6_rb_mrt_control_rop(blend_info->logicOp,
                                                   rop_reads_dst);
    }
 
    uint32_t total_bpp = 0;
-   pipeline->num_rts = blend_info->attachmentCount;
+   pipeline->blend.num_rts = blend_info->attachmentCount;
    for (uint32_t i = 0; i < blend_info->attachmentCount; i++) {
       const VkPipelineColorBlendAttachmentState *att =
          &blend_info->pAttachments[i];
@@ -2270,17 +2270,17 @@ tu6_emit_rb_mrt_controls(struct tu_pipeline *pipeline,
          }
          total_bpp += write_bpp;
 
-         pipeline->color_write_enable |= BIT(i);
+         pipeline->blend.color_write_enable |= BIT(i);
          if (att->blendEnable)
-            pipeline->blend_enable |= BIT(i);
+            pipeline->blend.blend_enable |= BIT(i);
 
          if (att->blendEnable || *rop_reads_dst) {
             total_bpp += write_bpp;
          }
       }
 
-      pipeline->rb_mrt_control[i] = rb_mrt_control & pipeline->rb_mrt_control_mask;
-      pipeline->rb_mrt_blend_control[i] = rb_mrt_blend_control;
+      pipeline->blend.rb_mrt_control[i] = rb_mrt_control & pipeline->blend.rb_mrt_control_mask;
+      pipeline->blend.rb_mrt_blend_control[i] = rb_mrt_blend_control;
    }
 
    *color_bandwidth_per_sample = total_bpp / 8;
@@ -2297,34 +2297,34 @@ tu6_emit_blend_control(struct tu_pipeline *pipeline,
                              : ((1 << msaa_info->rasterizationSamples) - 1);
 
 
-   pipeline->sp_blend_cntl =
+   pipeline->blend.sp_blend_cntl =
        A6XX_SP_BLEND_CNTL(.enable_blend = blend_enable_mask,
                           .dual_color_in_enable = dual_src_blend,
                           .alpha_to_coverage = msaa_info->alphaToCoverageEnable,
-                          .unk8 = true).value & pipeline->sp_blend_cntl_mask;
+                          .unk8 = true).value & pipeline->blend.sp_blend_cntl_mask;
 
    /* set A6XX_RB_BLEND_CNTL_INDEPENDENT_BLEND only when enabled? */
-   pipeline->rb_blend_cntl =
+   pipeline->blend.rb_blend_cntl =
        A6XX_RB_BLEND_CNTL(.enable_blend = blend_enable_mask,
                           .independent_blend = true,
                           .sample_mask = sample_mask,
                           .dual_color_in_enable = dual_src_blend,
                           .alpha_to_coverage = msaa_info->alphaToCoverageEnable,
                           .alpha_to_one = msaa_info->alphaToOneEnable).value &
-      pipeline->rb_blend_cntl_mask;
+      pipeline->blend.rb_blend_cntl_mask;
 }
 
 static void
 tu6_emit_blend(struct tu_cs *cs,
                struct tu_pipeline *pipeline)
 {
-   tu_cs_emit_regs(cs, A6XX_SP_BLEND_CNTL(.dword = pipeline->sp_blend_cntl));
-   tu_cs_emit_regs(cs, A6XX_RB_BLEND_CNTL(.dword = pipeline->rb_blend_cntl));
+   tu_cs_emit_regs(cs, A6XX_SP_BLEND_CNTL(.dword = pipeline->blend.sp_blend_cntl));
+   tu_cs_emit_regs(cs, A6XX_RB_BLEND_CNTL(.dword = pipeline->blend.rb_blend_cntl));
 
-   for (unsigned i = 0; i < pipeline->num_rts; i++) {
+   for (unsigned i = 0; i < pipeline->blend.num_rts; i++) {
       tu_cs_emit_regs(cs,
-                      A6XX_RB_MRT_CONTROL(i, .dword = pipeline->rb_mrt_control[i]),
-                      A6XX_RB_MRT_BLEND_CONTROL(i, .dword = pipeline->rb_mrt_blend_control[i]));
+                      A6XX_RB_MRT_CONTROL(i, .dword = pipeline->blend.rb_mrt_control[i]),
+                      A6XX_RB_MRT_BLEND_CONTROL(i, .dword = pipeline->blend.rb_mrt_blend_control[i]));
    }
 }
 
@@ -3149,14 +3149,14 @@ tu_pipeline_builder_parse_dynamic(struct tu_pipeline_builder *builder,
    const VkPipelineDynamicStateCreateInfo *dynamic_info =
       builder->create_info->pDynamicState;
 
-   pipeline->gras_su_cntl_mask = ~0u;
-   pipeline->rb_depth_cntl_mask = ~0u;
-   pipeline->rb_stencil_cntl_mask = ~0u;
-   pipeline->pc_raster_cntl_mask = ~0u;
-   pipeline->vpc_unknown_9107_mask = ~0u;
-   pipeline->sp_blend_cntl_mask = ~0u;
-   pipeline->rb_blend_cntl_mask = ~0u;
-   pipeline->rb_mrt_control_mask = ~0u;
+   pipeline->rast.gras_su_cntl_mask = ~0u;
+   pipeline->rast.pc_raster_cntl_mask = ~0u;
+   pipeline->rast.vpc_unknown_9107_mask = ~0u;
+   pipeline->ds.rb_depth_cntl_mask = ~0u;
+   pipeline->ds.rb_stencil_cntl_mask = ~0u;
+   pipeline->blend.sp_blend_cntl_mask = ~0u;
+   pipeline->blend.rb_blend_cntl_mask = ~0u;
+   pipeline->blend.rb_mrt_control_mask = ~0u;
 
    if (!dynamic_info)
       return;
@@ -3166,19 +3166,19 @@ tu_pipeline_builder_parse_dynamic(struct tu_pipeline_builder *builder,
       switch (state) {
       case VK_DYNAMIC_STATE_VIEWPORT ... VK_DYNAMIC_STATE_STENCIL_REFERENCE:
          if (state == VK_DYNAMIC_STATE_LINE_WIDTH)
-            pipeline->gras_su_cntl_mask &= ~A6XX_GRAS_SU_CNTL_LINEHALFWIDTH__MASK;
+            pipeline->rast.gras_su_cntl_mask &= ~A6XX_GRAS_SU_CNTL_LINEHALFWIDTH__MASK;
          pipeline->dynamic_state_mask |= BIT(state);
          break;
       case VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT:
          pipeline->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_SAMPLE_LOCATIONS);
          break;
       case VK_DYNAMIC_STATE_CULL_MODE:
-         pipeline->gras_su_cntl_mask &=
+         pipeline->rast.gras_su_cntl_mask &=
             ~(A6XX_GRAS_SU_CNTL_CULL_BACK | A6XX_GRAS_SU_CNTL_CULL_FRONT);
          pipeline->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_GRAS_SU_CNTL);
          break;
       case VK_DYNAMIC_STATE_FRONT_FACE:
-         pipeline->gras_su_cntl_mask &= ~A6XX_GRAS_SU_CNTL_FRONT_CW;
+         pipeline->rast.gras_su_cntl_mask &= ~A6XX_GRAS_SU_CNTL_FRONT_CW;
          pipeline->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_GRAS_SU_CNTL);
          break;
       case VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY:
@@ -3194,62 +3194,62 @@ tu_pipeline_builder_parse_dynamic(struct tu_pipeline_builder *builder,
          pipeline->dynamic_state_mask |= BIT(VK_DYNAMIC_STATE_SCISSOR);
          break;
       case VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE:
-         pipeline->rb_depth_cntl_mask &=
+         pipeline->ds.rb_depth_cntl_mask &=
             ~(A6XX_RB_DEPTH_CNTL_Z_TEST_ENABLE | A6XX_RB_DEPTH_CNTL_Z_READ_ENABLE);
          pipeline->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_RB_DEPTH_CNTL);
          break;
       case VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE:
-         pipeline->rb_depth_cntl_mask &= ~A6XX_RB_DEPTH_CNTL_Z_WRITE_ENABLE;
+         pipeline->ds.rb_depth_cntl_mask &= ~A6XX_RB_DEPTH_CNTL_Z_WRITE_ENABLE;
          pipeline->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_RB_DEPTH_CNTL);
          break;
       case VK_DYNAMIC_STATE_DEPTH_COMPARE_OP:
-         pipeline->rb_depth_cntl_mask &= ~A6XX_RB_DEPTH_CNTL_ZFUNC__MASK;
+         pipeline->ds.rb_depth_cntl_mask &= ~A6XX_RB_DEPTH_CNTL_ZFUNC__MASK;
          pipeline->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_RB_DEPTH_CNTL);
          break;
       case VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE:
-         pipeline->rb_depth_cntl_mask &=
+         pipeline->ds.rb_depth_cntl_mask &=
             ~(A6XX_RB_DEPTH_CNTL_Z_BOUNDS_ENABLE | A6XX_RB_DEPTH_CNTL_Z_READ_ENABLE);
          pipeline->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_RB_DEPTH_CNTL);
          break;
       case VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE:
-         pipeline->rb_stencil_cntl_mask &= ~(A6XX_RB_STENCIL_CONTROL_STENCIL_ENABLE |
-                                             A6XX_RB_STENCIL_CONTROL_STENCIL_ENABLE_BF |
-                                             A6XX_RB_STENCIL_CONTROL_STENCIL_READ);
+         pipeline->ds.rb_stencil_cntl_mask &= ~(A6XX_RB_STENCIL_CONTROL_STENCIL_ENABLE |
+                                                A6XX_RB_STENCIL_CONTROL_STENCIL_ENABLE_BF |
+                                                A6XX_RB_STENCIL_CONTROL_STENCIL_READ);
          pipeline->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_RB_STENCIL_CNTL);
          break;
       case VK_DYNAMIC_STATE_STENCIL_OP:
-         pipeline->rb_stencil_cntl_mask &= ~(A6XX_RB_STENCIL_CONTROL_FUNC__MASK |
-                                             A6XX_RB_STENCIL_CONTROL_FAIL__MASK |
-                                             A6XX_RB_STENCIL_CONTROL_ZPASS__MASK |
-                                             A6XX_RB_STENCIL_CONTROL_ZFAIL__MASK |
-                                             A6XX_RB_STENCIL_CONTROL_FUNC_BF__MASK |
-                                             A6XX_RB_STENCIL_CONTROL_FAIL_BF__MASK |
-                                             A6XX_RB_STENCIL_CONTROL_ZPASS_BF__MASK |
-                                             A6XX_RB_STENCIL_CONTROL_ZFAIL_BF__MASK);
+         pipeline->ds.rb_stencil_cntl_mask &= ~(A6XX_RB_STENCIL_CONTROL_FUNC__MASK |
+                                                A6XX_RB_STENCIL_CONTROL_FAIL__MASK |
+                                                A6XX_RB_STENCIL_CONTROL_ZPASS__MASK |
+                                                A6XX_RB_STENCIL_CONTROL_ZFAIL__MASK |
+                                                A6XX_RB_STENCIL_CONTROL_FUNC_BF__MASK |
+                                                A6XX_RB_STENCIL_CONTROL_FAIL_BF__MASK |
+                                                A6XX_RB_STENCIL_CONTROL_ZPASS_BF__MASK |
+                                                A6XX_RB_STENCIL_CONTROL_ZFAIL_BF__MASK);
          pipeline->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_RB_STENCIL_CNTL);
          break;
       case VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE:
-         pipeline->gras_su_cntl_mask &= ~A6XX_GRAS_SU_CNTL_POLY_OFFSET;
+         pipeline->rast.gras_su_cntl_mask &= ~A6XX_GRAS_SU_CNTL_POLY_OFFSET;
          pipeline->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_GRAS_SU_CNTL);
          break;
       case VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE:
          pipeline->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE);
          break;
       case VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE:
-         pipeline->pc_raster_cntl_mask &= ~A6XX_PC_RASTER_CNTL_DISCARD;
-         pipeline->vpc_unknown_9107_mask &= ~A6XX_VPC_UNKNOWN_9107_RASTER_DISCARD;
+         pipeline->rast.pc_raster_cntl_mask &= ~A6XX_PC_RASTER_CNTL_DISCARD;
+         pipeline->rast.vpc_unknown_9107_mask &= ~A6XX_VPC_UNKNOWN_9107_RASTER_DISCARD;
          pipeline->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_RASTERIZER_DISCARD);
          break;
       case VK_DYNAMIC_STATE_LOGIC_OP_EXT:
-         pipeline->sp_blend_cntl_mask &= ~A6XX_SP_BLEND_CNTL_ENABLE_BLEND__MASK;
-         pipeline->rb_blend_cntl_mask &= ~A6XX_RB_BLEND_CNTL_ENABLE_BLEND__MASK;
-         pipeline->rb_mrt_control_mask &= ~A6XX_RB_MRT_CONTROL_ROP_CODE__MASK;
+         pipeline->blend.sp_blend_cntl_mask &= ~A6XX_SP_BLEND_CNTL_ENABLE_BLEND__MASK;
+         pipeline->blend.rb_blend_cntl_mask &= ~A6XX_RB_BLEND_CNTL_ENABLE_BLEND__MASK;
+         pipeline->blend.rb_mrt_control_mask &= ~A6XX_RB_MRT_CONTROL_ROP_CODE__MASK;
          pipeline->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_BLEND);
          pipeline->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_LOGIC_OP);
          break;
       case VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT:
-         pipeline->sp_blend_cntl_mask &= ~A6XX_SP_BLEND_CNTL_ENABLE_BLEND__MASK;
-         pipeline->rb_blend_cntl_mask &= ~A6XX_RB_BLEND_CNTL_ENABLE_BLEND__MASK;
+         pipeline->blend.sp_blend_cntl_mask &= ~A6XX_SP_BLEND_CNTL_ENABLE_BLEND__MASK;
+         pipeline->blend.rb_blend_cntl_mask &= ~A6XX_RB_BLEND_CNTL_ENABLE_BLEND__MASK;
          pipeline->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_BLEND);
 
          /* Dynamic color write enable doesn't directly change any of the
@@ -3369,7 +3369,7 @@ tu_pipeline_builder_parse_vertex_input(struct tu_pipeline_builder *builder,
       };
 
       /* Bindings may contain holes */
-      pipeline->num_vbs = MAX2(pipeline->num_vbs, binding->binding + 1);
+      pipeline->vi.num_vbs = MAX2(pipeline->vi.num_vbs, binding->binding + 1);
    }
 
    const VkPipelineVertexInputDivisorStateCreateInfoEXT *div_state =
@@ -3456,12 +3456,12 @@ tu_pipeline_builder_parse_viewport(struct tu_pipeline_builder *builder,
       builder->create_info->pViewportState;
    const VkPipelineViewportDepthClipControlCreateInfoEXT *depth_clip_info =
          vk_find_struct_const(vp_info->pNext, PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT);
-   pipeline->z_negative_one_to_one = depth_clip_info ? depth_clip_info->negativeOneToOne : false;
+   pipeline->viewport.z_negative_one_to_one = depth_clip_info ? depth_clip_info->negativeOneToOne : false;
 
    struct tu_cs cs;
 
    if (tu_pipeline_static_state(pipeline, &cs, VK_DYNAMIC_STATE_VIEWPORT, 8 + 10 * vp_info->viewportCount))
-      tu6_emit_viewport(&cs, vp_info->pViewports, vp_info->viewportCount, pipeline->z_negative_one_to_one);
+      tu6_emit_viewport(&cs, vp_info->pViewports, vp_info->viewportCount, pipeline->viewport.z_negative_one_to_one);
 
    if (tu_pipeline_static_state(pipeline, &cs, VK_DYNAMIC_STATE_SCISSOR, 1 + 2 * vp_info->scissorCount))
       tu6_emit_scissor(&cs, vp_info->pScissors, vp_info->scissorCount);
@@ -3474,7 +3474,7 @@ tu_pipeline_builder_parse_rasterization(struct tu_pipeline_builder *builder,
    const VkPipelineRasterizationStateCreateInfo *rast_info =
       builder->create_info->pRasterizationState;
 
-   pipeline->feedback_loop_may_involve_textures =
+   pipeline->output.feedback_loop_may_involve_textures =
       builder->feedback_loop_may_involve_textures;
 
    enum a6xx_polygon_mode mode = tu6_polygon_mode(rast_info->polygonMode);
@@ -3486,7 +3486,7 @@ tu_pipeline_builder_parse_rasterization(struct tu_pipeline_builder *builder,
    if (depth_clip_state)
       builder->depth_clip_disable = !depth_clip_state->depthClipEnable;
 
-   pipeline->line_mode = RECTANGULAR;
+   pipeline->rast.line_mode = RECTANGULAR;
 
    if (tu6_primtype_line(pipeline->ia.primtype) ||
        (tu6_primtype_patches(pipeline->ia.primtype) &&
@@ -3497,7 +3497,7 @@ tu_pipeline_builder_parse_rasterization(struct tu_pipeline_builder *builder,
 
       if (rast_line_state && rast_line_state->lineRasterizationMode ==
                VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT) {
-         pipeline->line_mode = BRESENHAM;
+         pipeline->rast.line_mode = BRESENHAM;
       }
    }
 
@@ -3505,7 +3505,7 @@ tu_pipeline_builder_parse_rasterization(struct tu_pipeline_builder *builder,
    uint32_t cs_size = 9 +
       (builder->device->physical_device->info->a6xx.has_shading_rate ? 8 : 0) +
       (builder->emit_msaa_state ? 11 : 0);
-   pipeline->rast_state = tu_cs_draw_state(&pipeline->cs, &cs, cs_size);
+   pipeline->rast.state = tu_cs_draw_state(&pipeline->cs, &cs, cs_size);
 
    tu_cs_emit_regs(&cs,
                    A6XX_GRAS_CL_CNTL(
@@ -3513,7 +3513,7 @@ tu_pipeline_builder_parse_rasterization(struct tu_pipeline_builder *builder,
                      .zfar_clip_disable = builder->depth_clip_disable,
                      /* TODO should this be depth_clip_disable instead? */
                      .unk5 = rast_info->depthClampEnable,
-                     .zero_gb_scale_z = pipeline->z_negative_one_to_one ? 0 : 1,
+                     .zero_gb_scale_z = pipeline->viewport.z_negative_one_to_one ? 0 : 1,
                      .vp_clip_code_ignore = 1));
 
    tu_cs_emit_regs(&cs,
@@ -3538,30 +3538,30 @@ tu_pipeline_builder_parse_rasterization(struct tu_pipeline_builder *builder,
     * It happens when subpass doesn't use any color/depth attachment.
     */
    if (builder->emit_msaa_state)
-      tu6_emit_msaa(&cs, builder->samples, pipeline->line_mode);
+      tu6_emit_msaa(&cs, builder->samples, pipeline->rast.line_mode);
 
    const VkPipelineRasterizationStateStreamCreateInfoEXT *stream_info =
       vk_find_struct_const(rast_info->pNext,
                            PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT);
    unsigned stream = stream_info ? stream_info->rasterizationStream : 0;
 
-   pipeline->pc_raster_cntl = A6XX_PC_RASTER_CNTL_STREAM(stream);
-   pipeline->vpc_unknown_9107 = 0;
+   pipeline->rast.pc_raster_cntl = A6XX_PC_RASTER_CNTL_STREAM(stream);
+   pipeline->rast.vpc_unknown_9107 = 0;
    if (rast_info->rasterizerDiscardEnable) {
-      pipeline->pc_raster_cntl |= A6XX_PC_RASTER_CNTL_DISCARD;
-      pipeline->vpc_unknown_9107 |= A6XX_VPC_UNKNOWN_9107_RASTER_DISCARD;
+      pipeline->rast.pc_raster_cntl |= A6XX_PC_RASTER_CNTL_DISCARD;
+      pipeline->rast.vpc_unknown_9107 |= A6XX_VPC_UNKNOWN_9107_RASTER_DISCARD;
    }
 
    if (tu_pipeline_static_state(pipeline, &cs, TU_DYNAMIC_STATE_RASTERIZER_DISCARD, 4)) {
-      tu_cs_emit_regs(&cs, A6XX_PC_RASTER_CNTL(.dword = pipeline->pc_raster_cntl));
-      tu_cs_emit_regs(&cs, A6XX_VPC_UNKNOWN_9107(.dword = pipeline->vpc_unknown_9107));
+      tu_cs_emit_regs(&cs, A6XX_PC_RASTER_CNTL(.dword = pipeline->rast.pc_raster_cntl));
+      tu_cs_emit_regs(&cs, A6XX_VPC_UNKNOWN_9107(.dword = pipeline->rast.vpc_unknown_9107));
    }
 
-   pipeline->gras_su_cntl =
-      tu6_gras_su_cntl(rast_info, pipeline->line_mode, builder->multiview_mask != 0);
+   pipeline->rast.gras_su_cntl =
+      tu6_gras_su_cntl(rast_info, pipeline->rast.line_mode, builder->multiview_mask != 0);
 
    if (tu_pipeline_static_state(pipeline, &cs, TU_DYNAMIC_STATE_GRAS_SU_CNTL, 2))
-      tu_cs_emit_regs(&cs, A6XX_GRAS_SU_CNTL(.dword = pipeline->gras_su_cntl));
+      tu_cs_emit_regs(&cs, A6XX_GRAS_SU_CNTL(.dword = pipeline->rast.gras_su_cntl));
 
    if (tu_pipeline_static_state(pipeline, &cs, VK_DYNAMIC_STATE_DEPTH_BIAS, 4)) {
       tu6_emit_depth_bias(&cs, rast_info->depthBiasConstantFactor,
@@ -3571,7 +3571,7 @@ tu_pipeline_builder_parse_rasterization(struct tu_pipeline_builder *builder,
 
    const struct VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *provoking_vtx_state =
       vk_find_struct_const(rast_info->pNext, PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT);
-   pipeline->provoking_vertex_last = provoking_vtx_state &&
+   pipeline->rast.provoking_vertex_last = provoking_vtx_state &&
       provoking_vtx_state->provokingVertexMode == VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT;
 }
 
@@ -3615,7 +3615,7 @@ tu_pipeline_builder_parse_depth_stencil(struct tu_pipeline_builder *builder,
       if (ds_info->depthBoundsTestEnable && !ds_info->depthTestEnable)
          tu6_apply_depth_bounds_workaround(builder->device, &rb_depth_cntl);
 
-      pipeline->depth_cpp_per_sample = util_format_get_component_bits(
+      pipeline->output.depth_cpp_per_sample = util_format_get_component_bits(
             pipe_format, UTIL_FORMAT_COLORSPACE_ZS, 0) / 8;
    } else {
       /* if RB_DEPTH_CNTL is set dynamically, we need to make sure it is set
@@ -3623,7 +3623,7 @@ tu_pipeline_builder_parse_depth_stencil(struct tu_pipeline_builder *builder,
        * is no depth attachment is a problem (at least for the S8_UINT case)
        */
       if (pipeline->dynamic_state_mask & BIT(TU_DYNAMIC_STATE_RB_DEPTH_CNTL))
-         pipeline->rb_depth_cntl_disable = true;
+         pipeline->output.rb_depth_cntl_disable = true;
    }
 
    if (builder->depth_attachment_format != VK_FORMAT_UNDEFINED) {
@@ -3647,7 +3647,7 @@ tu_pipeline_builder_parse_depth_stencil(struct tu_pipeline_builder *builder,
             A6XX_RB_STENCIL_CONTROL_STENCIL_READ;
       }
 
-      pipeline->stencil_cpp_per_sample = util_format_get_component_bits(
+      pipeline->output.stencil_cpp_per_sample = util_format_get_component_bits(
             pipe_format, UTIL_FORMAT_COLORSPACE_ZS, 1) / 8;
    }
 
@@ -3655,13 +3655,13 @@ tu_pipeline_builder_parse_depth_stencil(struct tu_pipeline_builder *builder,
       tu_cs_emit_pkt4(&cs, REG_A6XX_RB_DEPTH_CNTL, 1);
       tu_cs_emit(&cs, rb_depth_cntl);
    }
-   pipeline->rb_depth_cntl = rb_depth_cntl;
+   pipeline->ds.rb_depth_cntl = rb_depth_cntl;
 
    if (tu_pipeline_static_state(pipeline, &cs, TU_DYNAMIC_STATE_RB_STENCIL_CNTL, 2)) {
       tu_cs_emit_pkt4(&cs, REG_A6XX_RB_STENCIL_CONTROL, 1);
       tu_cs_emit(&cs, rb_stencil_cntl);
    }
-   pipeline->rb_stencil_cntl = rb_stencil_cntl;
+   pipeline->ds.rb_stencil_cntl = rb_stencil_cntl;
 
    /* the remaining draw states arent used if there is no d/s, leave them empty */
    if (builder->depth_attachment_format == VK_FORMAT_UNDEFINED)
@@ -3679,9 +3679,9 @@ tu_pipeline_builder_parse_depth_stencil(struct tu_pipeline_builder *builder,
    }
 
    if (tu_pipeline_static_state(pipeline, &cs, VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, 2)) {
-      update_stencil_mask(&pipeline->stencil_wrmask,  VK_STENCIL_FACE_FRONT_BIT, ds_info->front.writeMask);
-      update_stencil_mask(&pipeline->stencil_wrmask,  VK_STENCIL_FACE_BACK_BIT, ds_info->back.writeMask);
-      tu_cs_emit_regs(&cs, A6XX_RB_STENCILWRMASK(.dword = pipeline->stencil_wrmask));
+      update_stencil_mask(&pipeline->ds.stencil_wrmask,  VK_STENCIL_FACE_FRONT_BIT, ds_info->front.writeMask);
+      update_stencil_mask(&pipeline->ds.stencil_wrmask,  VK_STENCIL_FACE_BACK_BIT, ds_info->back.writeMask);
+      tu_cs_emit_regs(&cs, A6XX_RB_STENCILWRMASK(.dword = pipeline->ds.stencil_wrmask));
    }
 
    if (tu_pipeline_static_state(pipeline, &cs, VK_DYNAMIC_STATE_STENCIL_REFERENCE, 2)) {
@@ -3733,11 +3733,13 @@ tu_pipeline_builder_parse_multisample_and_color_blend(
    struct tu_cs cs;
    tu6_emit_rb_mrt_controls(pipeline, blend_info,
                             builder->color_attachment_formats,
-                            &pipeline->rop_reads_dst,
-                            &pipeline->color_bandwidth_per_sample);
+                            &pipeline->blend.rop_reads_dst,
+                            &pipeline->output.color_bandwidth_per_sample);
 
    uint32_t blend_enable_mask =
-      pipeline->rop_reads_dst ? pipeline->color_write_enable : pipeline->blend_enable;
+      pipeline->blend.rop_reads_dst ? 
+      pipeline->blend.color_write_enable :
+      pipeline->blend.blend_enable;
    tu6_emit_blend_control(pipeline, blend_enable_mask,
                           builder->use_dual_src_blend, msaa_info);
 
@@ -3769,7 +3771,7 @@ tu_pipeline_builder_parse_multisample_and_color_blend(
       unsigned mask = MASK(vk_format_get_nr_components(format));
       if (format != VK_FORMAT_UNDEFINED &&
           ((blendAttachment.colorWriteMask & mask) != mask ||
-           !(pipeline->color_write_enable & BIT(i)))) {
+           !(pipeline->blend.color_write_enable & BIT(i)))) {
          pipeline->lrz.force_disable_mask |= TU_LRZ_FORCE_DISABLE_WRITE;
       }
    }
@@ -3799,7 +3801,7 @@ tu_pipeline_builder_parse_rasterization_order(
    if (builder->rasterizer_discard)
       return;
 
-   pipeline->subpass_feedback_loop_ds = builder->subpass_feedback_loop_ds;
+   pipeline->output.subpass_feedback_loop_ds = builder->subpass_feedback_loop_ds;
 
    const VkPipelineColorBlendStateCreateInfo *blend_info =
       builder->create_info->pColorBlendState;
@@ -3808,20 +3810,20 @@ tu_pipeline_builder_parse_rasterization_order(
       builder->create_info->pDepthStencilState;
 
    if (builder->use_color_attachments) {
-      pipeline->raster_order_attachment_access =
+      pipeline->output.raster_order_attachment_access =
          blend_info->flags &
          VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT;
    }
 
    if (builder->depth_attachment_format != VK_FORMAT_UNDEFINED) {
-      pipeline->raster_order_attachment_access |=
+      pipeline->output.raster_order_attachment_access |=
          ds_info->flags &
          (VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT |
           VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT);
    }
 
    if (unlikely(builder->device->physical_device->instance->debug_flags & TU_DEBUG_RAST_ORDER))
-      pipeline->raster_order_attachment_access = true;
+      pipeline->output.raster_order_attachment_access = true;
 
    /* VK_EXT_blend_operation_advanced would also require ordered access
     * when implemented in the future.
@@ -3830,7 +3832,7 @@ tu_pipeline_builder_parse_rasterization_order(
    uint32_t sysmem_prim_mode = NO_FLUSH;
    uint32_t gmem_prim_mode = NO_FLUSH;
 
-   if (pipeline->raster_order_attachment_access) {
+   if (pipeline->output.raster_order_attachment_access) {
       /* VK_EXT_rasterization_order_attachment_access:
        *
        * This extension allow access to framebuffer attachments when used as
@@ -3839,7 +3841,7 @@ tu_pipeline_builder_parse_rasterization_order(
        */
       sysmem_prim_mode = FLUSH_PER_OVERLAP_AND_OVERWRITE;
       gmem_prim_mode = FLUSH_PER_OVERLAP;
-      pipeline->sysmem_single_prim_mode = true;
+      pipeline->prim_order.sysmem_single_prim_mode = true;
    } else {
       /* If there is a feedback loop, then the shader can read the previous value
        * of a pixel being written out. It can also write some components and then
@@ -3853,18 +3855,18 @@ tu_pipeline_builder_parse_rasterization_order(
           (builder->subpass_feedback_loop_ds &&
            (ds_info->depthWriteEnable || ds_info->stencilTestEnable))) {
          sysmem_prim_mode = FLUSH_PER_OVERLAP_AND_OVERWRITE;
-         pipeline->sysmem_single_prim_mode = true;
+         pipeline->prim_order.sysmem_single_prim_mode = true;
       }
    }
 
    struct tu_cs cs;
 
-   pipeline->prim_order_state_gmem = tu_cs_draw_state(&pipeline->cs, &cs, 2);
+   pipeline->prim_order.state_gmem = tu_cs_draw_state(&pipeline->cs, &cs, 2);
    tu_cs_emit_write_reg(&cs, REG_A6XX_GRAS_SC_CNTL,
                         A6XX_GRAS_SC_CNTL_CCUSINGLECACHELINESIZE(2) |
                         A6XX_GRAS_SC_CNTL_SINGLE_PRIM_MODE(gmem_prim_mode));
 
-   pipeline->prim_order_state_sysmem = tu_cs_draw_state(&pipeline->cs, &cs, 2);
+   pipeline->prim_order.state_sysmem = tu_cs_draw_state(&pipeline->cs, &cs, 2);
    tu_cs_emit_write_reg(&cs, REG_A6XX_GRAS_SC_CNTL,
                         A6XX_GRAS_SC_CNTL_CCUSINGLECACHELINESIZE(2) |
                         A6XX_GRAS_SC_CNTL_SINGLE_PRIM_MODE(sysmem_prim_mode));
index c420100..f68bfe6 100644 (file)
@@ -60,9 +60,12 @@ VK_DEFINE_NONDISP_HANDLE_CASTS(tu_pipeline_cache, base, VkPipelineCache,
 struct tu_lrz_pipeline
 {
    uint32_t force_disable_mask;
-   bool fs_has_kill;
-   bool force_late_z;
-   bool early_fragment_tests;
+
+   struct {
+      bool has_kill;
+      bool force_late_z;
+      bool early_fragment_tests;
+   } fs;
 };
 
 struct tu_compiled_shaders
@@ -126,32 +129,62 @@ struct tu_pipeline
    struct tu_draw_state dynamic_state[TU_DYNAMIC_STATE_COUNT];
 
    /* for dynamic states which use the same register: */
-   uint32_t gras_su_cntl, gras_su_cntl_mask;
-   uint32_t rb_depth_cntl, rb_depth_cntl_mask;
-   uint32_t rb_stencil_cntl, rb_stencil_cntl_mask;
-   uint32_t pc_raster_cntl, pc_raster_cntl_mask;
-   uint32_t vpc_unknown_9107, vpc_unknown_9107_mask;
-   uint32_t stencil_wrmask;
-
-   unsigned num_rts;
-   uint32_t rb_mrt_control[MAX_RTS], rb_mrt_control_mask;
-   uint32_t rb_mrt_blend_control[MAX_RTS];
-   uint32_t sp_blend_cntl, sp_blend_cntl_mask;
-   uint32_t rb_blend_cntl, rb_blend_cntl_mask;
-   uint32_t color_write_enable, blend_enable;
-   bool logic_op_enabled, rop_reads_dst;
-   bool rasterizer_discard;
-
-   bool rb_depth_cntl_disable;
-
-   enum a5xx_line_mode line_mode;
+   struct {
+      uint32_t gras_su_cntl, gras_su_cntl_mask;
+      uint32_t pc_raster_cntl, pc_raster_cntl_mask;
+      uint32_t vpc_unknown_9107, vpc_unknown_9107_mask;
+      enum a5xx_line_mode line_mode;
+      bool provoking_vertex_last;
+
+      struct tu_draw_state state;
+   } rast;
+
+   struct {
+      uint32_t rb_depth_cntl, rb_depth_cntl_mask;
+      uint32_t rb_stencil_cntl, rb_stencil_cntl_mask;
+      uint32_t stencil_wrmask;
+   } ds;
+
+   struct {
+      unsigned num_rts;
+      uint32_t rb_mrt_control[MAX_RTS], rb_mrt_control_mask;
+      uint32_t rb_mrt_blend_control[MAX_RTS];
+      uint32_t sp_blend_cntl, sp_blend_cntl_mask;
+      uint32_t rb_blend_cntl, rb_blend_cntl_mask;
+      uint32_t color_write_enable, blend_enable;
+      bool logic_op_enabled, rop_reads_dst;
+
+   } blend;
+
+   /* Misc. info from the fragment output interface state that is used
+    * elsewhere.
+    */
+   struct {
+      /* memory bandwidth cost (in bytes) for color attachments */
+      uint32_t color_bandwidth_per_sample;
+      uint32_t depth_cpp_per_sample;
+      uint32_t stencil_cpp_per_sample;
+
+      bool rb_depth_cntl_disable;
+
+      bool raster_order_attachment_access;
+      bool subpass_feedback_loop_ds;
+      bool feedback_loop_may_involve_textures;
+   } output;
+
+   /* In other words - framebuffer fetch support */
+   struct {
+      /* If the pipeline sets SINGLE_PRIM_MODE for sysmem. */
+      bool sysmem_single_prim_mode;
+      struct tu_draw_state state_sysmem, state_gmem;
+   } prim_order;
 
    /* draw states for the pipeline */
-   struct tu_draw_state load_state, rast_state;
-   struct tu_draw_state prim_order_state_sysmem, prim_order_state_gmem;
+   struct tu_draw_state load_state;
 
-   /* for vertex buffers state */
-   uint32_t num_vbs;
+   struct {
+      uint32_t num_vbs;
+   } vi;
 
    struct tu_push_constant_range shared_consts;
 
@@ -183,24 +216,11 @@ struct tu_pipeline
       uint32_t subgroup_size;
    } compute;
 
-   bool provoking_vertex_last;
-
    struct tu_lrz_pipeline lrz;
 
-   /* In other words - framebuffer fetch support */
-   bool raster_order_attachment_access;
-   bool subpass_feedback_loop_ds;
-   bool feedback_loop_may_involve_textures;
-   /* If the pipeline sets SINGLE_PRIM_MODE for sysmem. */
-   bool sysmem_single_prim_mode;
-
-   bool z_negative_one_to_one;
-
-   /* memory bandwidth cost (in bytes) for color attachments */
-   uint32_t color_bandwidth_per_sample;
-
-   uint32_t depth_cpp_per_sample;
-   uint32_t stencil_cpp_per_sample;
+   struct {
+      bool z_negative_one_to_one;
+   } viewport;
 
    void *executables_mem_ctx;
    /* tu_pipeline_executable */