From 94be0dd0b86cf7dcedd94e732d8ee91bd16d091d Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Tue, 7 Jun 2022 01:48:44 +0200 Subject: [PATCH] tu: Implement extendedDynamicState2LogicOp Because this impacts most of the registers in the BLEND draw state, we make the entire draw state dynamic so that it all gets re-emitted when the logicOp changes. This also lays the groundwork for VK_EXT_color_write_enable. Part-of: --- src/freedreno/vulkan/tu_cmd_buffer.c | 113 +++++++++++++++++++++++++-- src/freedreno/vulkan/tu_device.c | 2 +- src/freedreno/vulkan/tu_pipeline.c | 103 ++++++++++++++++-------- src/freedreno/vulkan/tu_private.h | 25 +++++- 4 files changed, 200 insertions(+), 43 deletions(-) diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c index 59dab17bf4d..0818c46e62b 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.c +++ b/src/freedreno/vulkan/tu_cmd_buffer.c @@ -2334,14 +2334,13 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer, if (!(cmd->state.dirty & TU_CMD_DIRTY_DRAW_STATE)) { uint32_t mask = ~pipeline->dynamic_state_mask & BITFIELD_MASK(TU_DYNAMIC_STATE_COUNT); - tu_cs_emit_pkt7(cs, CP_SET_DRAW_STATE, 3 * (9 + util_bitcount(mask))); + tu_cs_emit_pkt7(cs, CP_SET_DRAW_STATE, 3 * (8 + util_bitcount(mask))); 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_VI, pipeline->vi.state); tu_cs_emit_draw_state(cs, TU_DRAW_STATE_VI_BINNING, pipeline->vi.binning_state); tu_cs_emit_draw_state(cs, TU_DRAW_STATE_RAST, pipeline->rast_state); - tu_cs_emit_draw_state(cs, TU_DRAW_STATE_BLEND, pipeline->blend_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); @@ -2430,8 +2429,48 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer, 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]; + 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]; + 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; + cmd->state.dirty |= TU_CMD_DIRTY_BLEND; + } + if (cmd->state.pipeline_blend_enable != pipeline->blend_enable) { + cmd->state.pipeline_blend_enable = pipeline->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; + 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.dirty |= TU_CMD_DIRTY_BLEND; + } + if (cmd->state.dynamic_state[TU_DYNAMIC_STATE_BLEND].size != pipeline->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) cmd->state.dirty |= TU_CMD_DIRTY_RB_DEPTH_CNTL; } @@ -2793,7 +2832,12 @@ VKAPI_ATTR void VKAPI_CALL tu_CmdSetLogicOpEXT(VkCommandBuffer commandBuffer, VkLogicOp logicOp) { - tu_stub(); + TU_FROM_HANDLE(tu_cmd_buffer, cmd, commandBuffer); + + cmd->state.rb_mrt_control_rop = + tu6_rb_mrt_control_rop(logicOp, &cmd->state.rop_reads_dst); + + cmd->state.dirty |= TU_CMD_DIRTY_BLEND; } VKAPI_ATTR void VKAPI_CALL @@ -3770,6 +3814,11 @@ tu6_calculate_lrz_state(struct tu_cmd_buffer *cmd, gras_lrz_cntl.z_test_enable = z_read_enable; gras_lrz_cntl.z_bounds_enable = z_bounds_enable; + /* See comment in tu_pipeline about disabling LRZ write for blending. */ + if ((cmd->state.pipeline->dynamic_state_mask & BIT(TU_DYNAMIC_STATE_LOGIC_OP)) && + cmd->state.logic_op_enabled && cmd->state.rop_reads_dst) + gras_lrz_cntl.lrz_write = false; + /* LRZ is disabled until it is cleared, which means that one "wrong" * depth test or shader could disable LRZ until depth buffer is cleared. */ @@ -3998,6 +4047,41 @@ tu6_build_depth_plane_z_mode(struct tu_cmd_buffer *cmd, struct tu_cs *cs) tu_cs_emit(cs, A6XX_RB_DEPTH_PLANE_CNTL_Z_MODE(zmode)); } +static void +tu6_emit_blend(struct tu_cs *cs, struct tu_cmd_buffer *cmd) +{ + struct tu_pipeline *pipeline = cmd->state.pipeline; + uint32_t color_write_enable = cmd->state.pipeline_color_write_enable; + + for (unsigned i = 0; i < pipeline->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)); + tu_cs_emit(cs, cmd->state.rb_mrt_blend_control[i]); + } else { + tu_cs_emit(cs, 0); + tu_cs_emit(cs, 0); + } + } + + uint32_t blend_enable_mask = + (cmd->state.logic_op_enabled && cmd->state.rop_reads_dst) ? + color_write_enable : cmd->state.pipeline_blend_enable; + + 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)); + + 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)); +} + static VkResult tu6_draw_common(struct tu_cmd_buffer *cmd, struct tu_cs *cs, @@ -4043,7 +4127,9 @@ tu6_draw_common(struct tu_cmd_buffer *cmd, if (!(cmd->state.dirty & ~TU_CMD_DIRTY_COMPUTE_DESC_SETS_LOAD)) return VK_SUCCESS; - bool dirty_lrz = cmd->state.dirty & (TU_CMD_DIRTY_LRZ | TU_CMD_DIRTY_RB_DEPTH_CNTL | TU_CMD_DIRTY_RB_STENCIL_CNTL); + bool dirty_lrz = + cmd->state.dirty & (TU_CMD_DIRTY_LRZ | TU_CMD_DIRTY_RB_DEPTH_CNTL | + TU_CMD_DIRTY_RB_STENCIL_CNTL | TU_CMD_DIRTY_BLEND); struct tu_descriptor_state *descriptors_state = &cmd->descriptors[VK_PIPELINE_BIND_POINT_GRAPHICS]; @@ -4103,6 +4189,12 @@ tu6_draw_common(struct tu_cmd_buffer *cmd, pipeline->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); + tu6_emit_blend(&cs, cmd); + } + /* for the first draw in a renderpass, re-emit all the draw states * * and if a draw-state disabling path (CmdClearAttachments 3D fallback) was @@ -4122,7 +4214,6 @@ tu6_draw_common(struct tu_cmd_buffer *cmd, tu_cs_emit_draw_state(cs, TU_DRAW_STATE_VI, pipeline->vi.state); tu_cs_emit_draw_state(cs, TU_DRAW_STATE_VI_BINNING, pipeline->vi.binning_state); tu_cs_emit_draw_state(cs, TU_DRAW_STATE_RAST, pipeline->rast_state); - tu_cs_emit_draw_state(cs, TU_DRAW_STATE_BLEND, pipeline->blend_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_SHADER_GEOM_CONST, cmd->state.shader_const[0]); @@ -4143,7 +4234,7 @@ tu6_draw_common(struct tu_cmd_buffer *cmd, /* emit draw states that were just updated * note we eventually don't want to have to emit anything here */ - bool emit_binding_stride = false; + bool emit_binding_stride = false, emit_blend = false; uint32_t draw_state_count = ((cmd->state.dirty & TU_CMD_DIRTY_SHADER_CONSTS) ? 2 : 0) + ((cmd->state.dirty & TU_CMD_DIRTY_DESC_SETS_LOAD) ? 1 : 0) + @@ -4157,6 +4248,12 @@ tu6_draw_common(struct tu_cmd_buffer *cmd, draw_state_count += 1; } + if ((cmd->state.dirty & TU_CMD_DIRTY_BLEND) && + (pipeline->dynamic_state_mask & BIT(TU_DYNAMIC_STATE_BLEND))) { + emit_blend = true; + draw_state_count += 1; + } + if (draw_state_count > 0) tu_cs_emit_pkt7(cs, CP_SET_DRAW_STATE, 3 * draw_state_count); @@ -4172,6 +4269,10 @@ tu6_draw_common(struct tu_cmd_buffer *cmd, tu_cs_emit_draw_state(cs, TU_DRAW_STATE_DYNAMIC + TU_DYNAMIC_STATE_VB_STRIDE, cmd->state.dynamic_state[TU_DYNAMIC_STATE_VB_STRIDE]); } + if (emit_blend) { + tu_cs_emit_draw_state(cs, TU_DRAW_STATE_DYNAMIC + TU_DYNAMIC_STATE_BLEND, + cmd->state.dynamic_state[TU_DYNAMIC_STATE_BLEND]); + } if (cmd->state.dirty & TU_CMD_DIRTY_VS_PARAMS) tu_cs_emit_draw_state(cs, TU_DRAW_STATE_VS_PARAMS, cmd->state.vs_params); diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c index 9be4d7b25a0..9b15768b992 100644 --- a/src/freedreno/vulkan/tu_device.c +++ b/src/freedreno/vulkan/tu_device.c @@ -772,7 +772,7 @@ tu_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *features = (VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *)ext; features->extendedDynamicState2 = true; - features->extendedDynamicState2LogicOp = false; + features->extendedDynamicState2LogicOp = true; features->extendedDynamicState2PatchControlPoints = false; break; } diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c index 51d3bd94958..29449ca4427 100644 --- a/src/freedreno/vulkan/tu_pipeline.c +++ b/src/freedreno/vulkan/tu_pipeline.c @@ -2140,26 +2140,33 @@ tu6_rb_mrt_control(const VkPipelineColorBlendAttachmentState *att, return rb_mrt_control; } +uint32_t +tu6_rb_mrt_control_rop(VkLogicOp op, bool *rop_reads_dst) +{ + *rop_reads_dst = tu_logic_op_reads_dst(op); + return A6XX_RB_MRT_CONTROL_ROP_ENABLE | + A6XX_RB_MRT_CONTROL_ROP_CODE(tu6_rop(op)); +} + static void -tu6_emit_rb_mrt_controls(struct tu_cs *cs, +tu6_emit_rb_mrt_controls(struct tu_pipeline *pipeline, const VkPipelineColorBlendStateCreateInfo *blend_info, const VkFormat attachment_formats[MAX_RTS], - uint32_t *blend_enable_mask, + bool *rop_reads_dst, uint32_t *color_bandwidth_per_sample) { - *blend_enable_mask = 0; + *rop_reads_dst = false; *color_bandwidth_per_sample = 0; - bool rop_reads_dst = false; uint32_t rb_mrt_control_rop = 0; if (blend_info->logicOpEnable) { - rop_reads_dst = tu_logic_op_reads_dst(blend_info->logicOp); - rb_mrt_control_rop = - A6XX_RB_MRT_CONTROL_ROP_ENABLE | - A6XX_RB_MRT_CONTROL_ROP_CODE(tu6_rop(blend_info->logicOp)); + pipeline->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; for (uint32_t i = 0; i < blend_info->attachmentCount; i++) { const VkPipelineColorBlendAttachmentState *att = &blend_info->pAttachments[i]; @@ -2189,22 +2196,24 @@ tu6_emit_rb_mrt_controls(struct tu_cs *cs, } total_bpp += write_bpp; + pipeline->color_write_enable |= BIT(i); + if (att->blendEnable) + pipeline->blend_enable |= BIT(i); + if (att->blendEnable || rop_reads_dst) { - *blend_enable_mask |= 1 << i; total_bpp += write_bpp; } } - tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_CONTROL(i), 2); - tu_cs_emit(cs, rb_mrt_control); - tu_cs_emit(cs, rb_mrt_blend_control); + pipeline->rb_mrt_control[i] = rb_mrt_control & pipeline->rb_mrt_control_mask; + pipeline->rb_mrt_blend_control[i] = rb_mrt_blend_control; } *color_bandwidth_per_sample = total_bpp / 8; } static void -tu6_emit_blend_control(struct tu_cs *cs, +tu6_emit_blend_control(struct tu_pipeline *pipeline, uint32_t blend_enable_mask, bool dual_src_blend, const VkPipelineMultisampleStateCreateInfo *msaa_info) @@ -2213,20 +2222,36 @@ tu6_emit_blend_control(struct tu_cs *cs, msaa_info->pSampleMask ? (*msaa_info->pSampleMask & 0xffff) : ((1 << msaa_info->rasterizationSamples) - 1); - tu_cs_emit_regs(cs, - A6XX_SP_BLEND_CNTL(.enable_blend = blend_enable_mask, - .dual_color_in_enable = dual_src_blend, - .alpha_to_coverage = msaa_info->alphaToCoverageEnable, - .unk8 = true)); + + pipeline->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; /* set A6XX_RB_BLEND_CNTL_INDEPENDENT_BLEND only when enabled? */ - tu_cs_emit_regs(cs, - 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)); + pipeline->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; +} + +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)); + + for (unsigned i = 0; i < pipeline->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])); + } } static uint32_t @@ -3031,6 +3056,9 @@ tu_pipeline_builder_parse_dynamic(struct tu_pipeline_builder *builder, 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; if (!dynamic_info) return; @@ -3114,6 +3142,13 @@ tu_pipeline_builder_parse_dynamic(struct tu_pipeline_builder *builder, pipeline->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->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_BLEND); + pipeline->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_LOGIC_OP); + break; default: assert(!"unsupported dynamic state"); break; @@ -3543,19 +3578,21 @@ tu_pipeline_builder_parse_multisample_and_color_blend( : &dummy_blend_info; struct tu_cs cs; - pipeline->blend_state = - tu_cs_draw_state(&pipeline->cs, &cs, blend_info->attachmentCount * 3 + 4); - - uint32_t blend_enable_mask; - tu6_emit_rb_mrt_controls(&cs, blend_info, + tu6_emit_rb_mrt_controls(pipeline, blend_info, builder->color_attachment_formats, - &blend_enable_mask, + &pipeline->rop_reads_dst, &pipeline->color_bandwidth_per_sample); - tu6_emit_blend_control(&cs, blend_enable_mask, + uint32_t blend_enable_mask = + pipeline->rop_reads_dst ? pipeline->color_write_enable : pipeline->blend_enable; + tu6_emit_blend_control(pipeline, blend_enable_mask, builder->use_dual_src_blend, msaa_info); - assert(cs.cur == cs.end); /* validate draw state size */ + if (tu_pipeline_static_state(pipeline, &cs, TU_DYNAMIC_STATE_BLEND, + blend_info->attachmentCount * 3 + 4)) { + tu6_emit_blend(&cs, pipeline); + assert(cs.cur == cs.end); /* validate draw state size */ + } /* Disable LRZ writes when blend or logic op that reads the destination is * enabled, since the resulting pixel value from the blend-draw depends on diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h index 8bf74d365d0..bdeed85c3c3 100644 --- a/src/freedreno/vulkan/tu_private.h +++ b/src/freedreno/vulkan/tu_private.h @@ -695,10 +695,12 @@ enum tu_dynamic_state TU_DYNAMIC_STATE_RB_STENCIL_CNTL, TU_DYNAMIC_STATE_VB_STRIDE, TU_DYNAMIC_STATE_RASTERIZER_DISCARD, + TU_DYNAMIC_STATE_BLEND, TU_DYNAMIC_STATE_COUNT, /* no associated draw state: */ TU_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY = TU_DYNAMIC_STATE_COUNT, TU_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE, + TU_DYNAMIC_STATE_LOGIC_OP, /* re-use the line width enum as it uses GRAS_SU_CNTL: */ TU_DYNAMIC_STATE_GRAS_SU_CNTL = VK_DYNAMIC_STATE_LINE_WIDTH, }; @@ -712,7 +714,6 @@ enum tu_draw_state_group_id TU_DRAW_STATE_VI, TU_DRAW_STATE_VI_BINNING, TU_DRAW_STATE_RAST, - TU_DRAW_STATE_BLEND, TU_DRAW_STATE_SHADER_GEOM_CONST, TU_DRAW_STATE_FS_CONST, TU_DRAW_STATE_DESC_SETS, @@ -925,8 +926,9 @@ enum tu_cmd_dirty_bits TU_CMD_DIRTY_VS_PARAMS = BIT(9), TU_CMD_DIRTY_RASTERIZER_DISCARD = BIT(10), TU_CMD_DIRTY_VIEWPORTS = BIT(11), + TU_CMD_DIRTY_BLEND = BIT(12), /* all draw states were disabled and need to be re-enabled: */ - TU_CMD_DIRTY_DRAW_STATE = BIT(12) + TU_CMD_DIRTY_DRAW_STATE = BIT(13) }; /* There are only three cache domains we have to care about: the CCU, or @@ -1163,6 +1165,12 @@ struct tu_cmd_state uint32_t gras_su_cntl, rb_depth_cntl, rb_stencil_cntl; uint32_t pc_raster_cntl, vpc_unknown_9107; + uint32_t rb_mrt_control[MAX_RTS], rb_mrt_blend_control[MAX_RTS]; + uint32_t rb_mrt_control_rop; + uint32_t rb_blend_cntl, sp_blend_cntl; + uint32_t pipeline_color_write_enable, pipeline_blend_enable; + bool logic_op_enabled; + bool rop_reads_dst; enum pc_di_primtype primtype; bool primitive_restart_enable; @@ -1447,12 +1455,21 @@ struct tu_pipeline 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; /* draw states for the pipeline */ - struct tu_draw_state load_state, rast_state, blend_state; + struct tu_draw_state load_state, rast_state; struct tu_draw_state prim_order_state_sysmem, prim_order_state_gmem; /* for vertex buffers state */ @@ -1539,6 +1556,8 @@ void tu6_emit_window_scissor(struct tu_cs *cs, uint32_t x1, uint32_t y1, uint32_ void tu6_emit_window_offset(struct tu_cs *cs, uint32_t x1, uint32_t y1); +uint32_t tu6_rb_mrt_control_rop(VkLogicOp op, bool *rop_reads_dst); + void tu_disable_draw_states(struct tu_cmd_buffer *cmd, struct tu_cs *cs); void tu6_apply_depth_bounds_workaround(struct tu_device *device,