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: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16936>
This commit is contained in:
Connor Abbott 2022-06-07 01:48:44 +02:00 committed by Marge Bot
parent c23eb99357
commit 94be0dd0b8
4 changed files with 200 additions and 43 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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,