mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 17:40:11 +01:00
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:
parent
c23eb99357
commit
94be0dd0b8
4 changed files with 200 additions and 43 deletions
|
|
@ -2334,14 +2334,13 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer,
|
||||||
if (!(cmd->state.dirty & TU_CMD_DIRTY_DRAW_STATE)) {
|
if (!(cmd->state.dirty & TU_CMD_DIRTY_DRAW_STATE)) {
|
||||||
uint32_t mask = ~pipeline->dynamic_state_mask & BITFIELD_MASK(TU_DYNAMIC_STATE_COUNT);
|
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_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, 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_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, 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_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_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_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_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(rb_stencil_cntl, RB_STENCIL_CNTL);
|
||||||
UPDATE_REG(pc_raster_cntl, RASTERIZER_DISCARD);
|
UPDATE_REG(pc_raster_cntl, RASTERIZER_DISCARD);
|
||||||
UPDATE_REG(vpc_unknown_9107, 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
|
#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)
|
if (pipeline->rb_depth_cntl_disable)
|
||||||
cmd->state.dirty |= TU_CMD_DIRTY_RB_DEPTH_CNTL;
|
cmd->state.dirty |= TU_CMD_DIRTY_RB_DEPTH_CNTL;
|
||||||
}
|
}
|
||||||
|
|
@ -2793,7 +2832,12 @@ VKAPI_ATTR void VKAPI_CALL
|
||||||
tu_CmdSetLogicOpEXT(VkCommandBuffer commandBuffer,
|
tu_CmdSetLogicOpEXT(VkCommandBuffer commandBuffer,
|
||||||
VkLogicOp logicOp)
|
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
|
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_test_enable = z_read_enable;
|
||||||
gras_lrz_cntl.z_bounds_enable = z_bounds_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"
|
/* LRZ is disabled until it is cleared, which means that one "wrong"
|
||||||
* depth test or shader could disable LRZ until depth buffer is cleared.
|
* 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));
|
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
|
static VkResult
|
||||||
tu6_draw_common(struct tu_cmd_buffer *cmd,
|
tu6_draw_common(struct tu_cmd_buffer *cmd,
|
||||||
struct tu_cs *cs,
|
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))
|
if (!(cmd->state.dirty & ~TU_CMD_DIRTY_COMPUTE_DESC_SETS_LOAD))
|
||||||
return VK_SUCCESS;
|
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 =
|
struct tu_descriptor_state *descriptors_state =
|
||||||
&cmd->descriptors[VK_PIPELINE_BIND_POINT_GRAPHICS];
|
&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);
|
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
|
/* for the first draw in a renderpass, re-emit all the draw states
|
||||||
*
|
*
|
||||||
* and if a draw-state disabling path (CmdClearAttachments 3D fallback) was
|
* 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, 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_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_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_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_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]);
|
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
|
/* emit draw states that were just updated
|
||||||
* note we eventually don't want to have to emit anything here
|
* 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 =
|
uint32_t draw_state_count =
|
||||||
((cmd->state.dirty & TU_CMD_DIRTY_SHADER_CONSTS) ? 2 : 0) +
|
((cmd->state.dirty & TU_CMD_DIRTY_SHADER_CONSTS) ? 2 : 0) +
|
||||||
((cmd->state.dirty & TU_CMD_DIRTY_DESC_SETS_LOAD) ? 1 : 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;
|
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)
|
if (draw_state_count > 0)
|
||||||
tu_cs_emit_pkt7(cs, CP_SET_DRAW_STATE, 3 * draw_state_count);
|
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,
|
tu_cs_emit_draw_state(cs, TU_DRAW_STATE_DYNAMIC + TU_DYNAMIC_STATE_VB_STRIDE,
|
||||||
cmd->state.dynamic_state[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)
|
if (cmd->state.dirty & TU_CMD_DIRTY_VS_PARAMS)
|
||||||
tu_cs_emit_draw_state(cs, TU_DRAW_STATE_VS_PARAMS, cmd->state.vs_params);
|
tu_cs_emit_draw_state(cs, TU_DRAW_STATE_VS_PARAMS, cmd->state.vs_params);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -772,7 +772,7 @@ tu_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
|
||||||
VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *features =
|
VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *features =
|
||||||
(VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *)ext;
|
(VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *)ext;
|
||||||
features->extendedDynamicState2 = true;
|
features->extendedDynamicState2 = true;
|
||||||
features->extendedDynamicState2LogicOp = false;
|
features->extendedDynamicState2LogicOp = true;
|
||||||
features->extendedDynamicState2PatchControlPoints = false;
|
features->extendedDynamicState2PatchControlPoints = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2140,26 +2140,33 @@ tu6_rb_mrt_control(const VkPipelineColorBlendAttachmentState *att,
|
||||||
return rb_mrt_control;
|
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
|
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 VkPipelineColorBlendStateCreateInfo *blend_info,
|
||||||
const VkFormat attachment_formats[MAX_RTS],
|
const VkFormat attachment_formats[MAX_RTS],
|
||||||
uint32_t *blend_enable_mask,
|
bool *rop_reads_dst,
|
||||||
uint32_t *color_bandwidth_per_sample)
|
uint32_t *color_bandwidth_per_sample)
|
||||||
{
|
{
|
||||||
*blend_enable_mask = 0;
|
*rop_reads_dst = false;
|
||||||
*color_bandwidth_per_sample = 0;
|
*color_bandwidth_per_sample = 0;
|
||||||
|
|
||||||
bool rop_reads_dst = false;
|
|
||||||
uint32_t rb_mrt_control_rop = 0;
|
uint32_t rb_mrt_control_rop = 0;
|
||||||
if (blend_info->logicOpEnable) {
|
if (blend_info->logicOpEnable) {
|
||||||
rop_reads_dst = tu_logic_op_reads_dst(blend_info->logicOp);
|
pipeline->logic_op_enabled = true;
|
||||||
rb_mrt_control_rop =
|
rb_mrt_control_rop = tu6_rb_mrt_control_rop(blend_info->logicOp,
|
||||||
A6XX_RB_MRT_CONTROL_ROP_ENABLE |
|
rop_reads_dst);
|
||||||
A6XX_RB_MRT_CONTROL_ROP_CODE(tu6_rop(blend_info->logicOp));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t total_bpp = 0;
|
uint32_t total_bpp = 0;
|
||||||
|
pipeline->num_rts = blend_info->attachmentCount;
|
||||||
for (uint32_t i = 0; i < blend_info->attachmentCount; i++) {
|
for (uint32_t i = 0; i < blend_info->attachmentCount; i++) {
|
||||||
const VkPipelineColorBlendAttachmentState *att =
|
const VkPipelineColorBlendAttachmentState *att =
|
||||||
&blend_info->pAttachments[i];
|
&blend_info->pAttachments[i];
|
||||||
|
|
@ -2189,22 +2196,24 @@ tu6_emit_rb_mrt_controls(struct tu_cs *cs,
|
||||||
}
|
}
|
||||||
total_bpp += write_bpp;
|
total_bpp += write_bpp;
|
||||||
|
|
||||||
|
pipeline->color_write_enable |= BIT(i);
|
||||||
|
if (att->blendEnable)
|
||||||
|
pipeline->blend_enable |= BIT(i);
|
||||||
|
|
||||||
if (att->blendEnable || rop_reads_dst) {
|
if (att->blendEnable || rop_reads_dst) {
|
||||||
*blend_enable_mask |= 1 << i;
|
|
||||||
total_bpp += write_bpp;
|
total_bpp += write_bpp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_CONTROL(i), 2);
|
pipeline->rb_mrt_control[i] = rb_mrt_control & pipeline->rb_mrt_control_mask;
|
||||||
tu_cs_emit(cs, rb_mrt_control);
|
pipeline->rb_mrt_blend_control[i] = rb_mrt_blend_control;
|
||||||
tu_cs_emit(cs, rb_mrt_blend_control);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*color_bandwidth_per_sample = total_bpp / 8;
|
*color_bandwidth_per_sample = total_bpp / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tu6_emit_blend_control(struct tu_cs *cs,
|
tu6_emit_blend_control(struct tu_pipeline *pipeline,
|
||||||
uint32_t blend_enable_mask,
|
uint32_t blend_enable_mask,
|
||||||
bool dual_src_blend,
|
bool dual_src_blend,
|
||||||
const VkPipelineMultisampleStateCreateInfo *msaa_info)
|
const VkPipelineMultisampleStateCreateInfo *msaa_info)
|
||||||
|
|
@ -2213,20 +2222,36 @@ tu6_emit_blend_control(struct tu_cs *cs,
|
||||||
msaa_info->pSampleMask ? (*msaa_info->pSampleMask & 0xffff)
|
msaa_info->pSampleMask ? (*msaa_info->pSampleMask & 0xffff)
|
||||||
: ((1 << msaa_info->rasterizationSamples) - 1);
|
: ((1 << msaa_info->rasterizationSamples) - 1);
|
||||||
|
|
||||||
tu_cs_emit_regs(cs,
|
|
||||||
A6XX_SP_BLEND_CNTL(.enable_blend = blend_enable_mask,
|
pipeline->sp_blend_cntl =
|
||||||
.dual_color_in_enable = dual_src_blend,
|
A6XX_SP_BLEND_CNTL(.enable_blend = blend_enable_mask,
|
||||||
.alpha_to_coverage = msaa_info->alphaToCoverageEnable,
|
.dual_color_in_enable = dual_src_blend,
|
||||||
.unk8 = true));
|
.alpha_to_coverage = msaa_info->alphaToCoverageEnable,
|
||||||
|
.unk8 = true).value & pipeline->sp_blend_cntl_mask;
|
||||||
|
|
||||||
/* set A6XX_RB_BLEND_CNTL_INDEPENDENT_BLEND only when enabled? */
|
/* set A6XX_RB_BLEND_CNTL_INDEPENDENT_BLEND only when enabled? */
|
||||||
tu_cs_emit_regs(cs,
|
pipeline->rb_blend_cntl =
|
||||||
A6XX_RB_BLEND_CNTL(.enable_blend = blend_enable_mask,
|
A6XX_RB_BLEND_CNTL(.enable_blend = blend_enable_mask,
|
||||||
.independent_blend = true,
|
.independent_blend = true,
|
||||||
.sample_mask = sample_mask,
|
.sample_mask = sample_mask,
|
||||||
.dual_color_in_enable = dual_src_blend,
|
.dual_color_in_enable = dual_src_blend,
|
||||||
.alpha_to_coverage = msaa_info->alphaToCoverageEnable,
|
.alpha_to_coverage = msaa_info->alphaToCoverageEnable,
|
||||||
.alpha_to_one = msaa_info->alphaToOneEnable));
|
.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
|
static uint32_t
|
||||||
|
|
@ -3031,6 +3056,9 @@ tu_pipeline_builder_parse_dynamic(struct tu_pipeline_builder *builder,
|
||||||
pipeline->rb_stencil_cntl_mask = ~0u;
|
pipeline->rb_stencil_cntl_mask = ~0u;
|
||||||
pipeline->pc_raster_cntl_mask = ~0u;
|
pipeline->pc_raster_cntl_mask = ~0u;
|
||||||
pipeline->vpc_unknown_9107_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)
|
if (!dynamic_info)
|
||||||
return;
|
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->vpc_unknown_9107_mask &= ~A6XX_VPC_UNKNOWN_9107_RASTER_DISCARD;
|
||||||
pipeline->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_RASTERIZER_DISCARD);
|
pipeline->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_RASTERIZER_DISCARD);
|
||||||
break;
|
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:
|
default:
|
||||||
assert(!"unsupported dynamic state");
|
assert(!"unsupported dynamic state");
|
||||||
break;
|
break;
|
||||||
|
|
@ -3543,19 +3578,21 @@ tu_pipeline_builder_parse_multisample_and_color_blend(
|
||||||
: &dummy_blend_info;
|
: &dummy_blend_info;
|
||||||
|
|
||||||
struct tu_cs cs;
|
struct tu_cs cs;
|
||||||
pipeline->blend_state =
|
tu6_emit_rb_mrt_controls(pipeline, blend_info,
|
||||||
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,
|
|
||||||
builder->color_attachment_formats,
|
builder->color_attachment_formats,
|
||||||
&blend_enable_mask,
|
&pipeline->rop_reads_dst,
|
||||||
&pipeline->color_bandwidth_per_sample);
|
&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);
|
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
|
/* 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
|
* enabled, since the resulting pixel value from the blend-draw depends on
|
||||||
|
|
|
||||||
|
|
@ -695,10 +695,12 @@ enum tu_dynamic_state
|
||||||
TU_DYNAMIC_STATE_RB_STENCIL_CNTL,
|
TU_DYNAMIC_STATE_RB_STENCIL_CNTL,
|
||||||
TU_DYNAMIC_STATE_VB_STRIDE,
|
TU_DYNAMIC_STATE_VB_STRIDE,
|
||||||
TU_DYNAMIC_STATE_RASTERIZER_DISCARD,
|
TU_DYNAMIC_STATE_RASTERIZER_DISCARD,
|
||||||
|
TU_DYNAMIC_STATE_BLEND,
|
||||||
TU_DYNAMIC_STATE_COUNT,
|
TU_DYNAMIC_STATE_COUNT,
|
||||||
/* no associated draw state: */
|
/* no associated draw state: */
|
||||||
TU_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY = TU_DYNAMIC_STATE_COUNT,
|
TU_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY = TU_DYNAMIC_STATE_COUNT,
|
||||||
TU_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE,
|
TU_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE,
|
||||||
|
TU_DYNAMIC_STATE_LOGIC_OP,
|
||||||
/* re-use the line width enum as it uses GRAS_SU_CNTL: */
|
/* re-use the line width enum as it uses GRAS_SU_CNTL: */
|
||||||
TU_DYNAMIC_STATE_GRAS_SU_CNTL = VK_DYNAMIC_STATE_LINE_WIDTH,
|
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,
|
||||||
TU_DRAW_STATE_VI_BINNING,
|
TU_DRAW_STATE_VI_BINNING,
|
||||||
TU_DRAW_STATE_RAST,
|
TU_DRAW_STATE_RAST,
|
||||||
TU_DRAW_STATE_BLEND,
|
|
||||||
TU_DRAW_STATE_SHADER_GEOM_CONST,
|
TU_DRAW_STATE_SHADER_GEOM_CONST,
|
||||||
TU_DRAW_STATE_FS_CONST,
|
TU_DRAW_STATE_FS_CONST,
|
||||||
TU_DRAW_STATE_DESC_SETS,
|
TU_DRAW_STATE_DESC_SETS,
|
||||||
|
|
@ -925,8 +926,9 @@ enum tu_cmd_dirty_bits
|
||||||
TU_CMD_DIRTY_VS_PARAMS = BIT(9),
|
TU_CMD_DIRTY_VS_PARAMS = BIT(9),
|
||||||
TU_CMD_DIRTY_RASTERIZER_DISCARD = BIT(10),
|
TU_CMD_DIRTY_RASTERIZER_DISCARD = BIT(10),
|
||||||
TU_CMD_DIRTY_VIEWPORTS = BIT(11),
|
TU_CMD_DIRTY_VIEWPORTS = BIT(11),
|
||||||
|
TU_CMD_DIRTY_BLEND = BIT(12),
|
||||||
/* all draw states were disabled and need to be re-enabled: */
|
/* 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
|
/* 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 gras_su_cntl, rb_depth_cntl, rb_stencil_cntl;
|
||||||
uint32_t pc_raster_cntl, vpc_unknown_9107;
|
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;
|
enum pc_di_primtype primtype;
|
||||||
bool primitive_restart_enable;
|
bool primitive_restart_enable;
|
||||||
|
|
||||||
|
|
@ -1447,12 +1455,21 @@ struct tu_pipeline
|
||||||
uint32_t vpc_unknown_9107, vpc_unknown_9107_mask;
|
uint32_t vpc_unknown_9107, vpc_unknown_9107_mask;
|
||||||
uint32_t stencil_wrmask;
|
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;
|
bool rb_depth_cntl_disable;
|
||||||
|
|
||||||
enum a5xx_line_mode line_mode;
|
enum a5xx_line_mode line_mode;
|
||||||
|
|
||||||
/* draw states for the pipeline */
|
/* 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;
|
struct tu_draw_state prim_order_state_sysmem, prim_order_state_gmem;
|
||||||
|
|
||||||
/* for vertex buffers state */
|
/* 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);
|
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 tu_disable_draw_states(struct tu_cmd_buffer *cmd, struct tu_cs *cs);
|
||||||
|
|
||||||
void tu6_apply_depth_bounds_workaround(struct tu_device *device,
|
void tu6_apply_depth_bounds_workaround(struct tu_device *device,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue