diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c index a80a979b89c..149ccd5b6b7 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.c +++ b/src/freedreno/vulkan/tu_cmd_buffer.c @@ -2679,12 +2679,14 @@ tu_CmdBindPipeline(VkCommandBuffer commandBuffer, cmd->state.pipeline_blend_enable = pipeline->blend.blend_enable; cmd->state.dirty |= TU_CMD_DIRTY_BLEND; } - if (cmd->state.logic_op_enabled != pipeline->blend.logic_op_enabled) { + if (!(pipeline->dynamic_state_mask & BIT(TU_DYNAMIC_STATE_LOGIC_OP_ENABLE)) && + 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->blend.rop_reads_dst) { + cmd->state.rb_mrt_control_rop != pipeline->blend.rb_mrt_control_rop) { + cmd->state.rb_mrt_control_rop = pipeline->blend.rb_mrt_control_rop; cmd->state.rop_reads_dst = pipeline->blend.rop_reads_dst; cmd->state.dirty |= TU_CMD_DIRTY_BLEND; } @@ -3065,6 +3067,17 @@ tu_CmdSetLogicOpEXT(VkCommandBuffer commandBuffer, cmd->state.dirty |= TU_CMD_DIRTY_BLEND; } +VKAPI_ATTR void VKAPI_CALL +tu_CmdSetLogicOpEnableEXT(VkCommandBuffer commandBuffer, + VkBool32 logicOpEnable) +{ + TU_FROM_HANDLE(tu_cmd_buffer, cmd, commandBuffer); + + cmd->state.logic_op_enabled = logicOpEnable; + + cmd->state.dirty |= TU_CMD_DIRTY_BLEND; +} + VKAPI_ATTR void VKAPI_CALL tu_CmdSetPatchControlPointsEXT(VkCommandBuffer commandBuffer, uint32_t patchControlPoints) @@ -4416,9 +4429,8 @@ tu6_emit_blend(struct tu_cs *cs, struct tu_cmd_buffer *cmd) 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->blend.rb_mrt_control_mask)); + (cmd->state.logic_op_enabled ? + cmd->state.rb_mrt_control_rop : 0)); tu_cs_emit(cs, cmd->state.rb_mrt_blend_control[i]); } else { tu_cs_emit(cs, 0); diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c index b35801451f1..b2a4b7c1907 100644 --- a/src/freedreno/vulkan/tu_device.c +++ b/src/freedreno/vulkan/tu_device.c @@ -765,7 +765,7 @@ tu_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice, features->extendedDynamicState3TessellationDomainOrigin = true; features->extendedDynamicState3DepthClampEnable = true; features->extendedDynamicState3DepthClipEnable = true; - features->extendedDynamicState3LogicOpEnable = false; + features->extendedDynamicState3LogicOpEnable = true; features->extendedDynamicState3SampleMask = false; features->extendedDynamicState3RasterizationSamples = false; features->extendedDynamicState3AlphaToCoverageEnable = false; diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c index 51c9f883fb6..41d32c97c26 100644 --- a/src/freedreno/vulkan/tu_pipeline.c +++ b/src/freedreno/vulkan/tu_pipeline.c @@ -2250,14 +2250,11 @@ tu6_rb_mrt_blend_control(const VkPipelineColorBlendAttachmentState *att, static uint32_t tu6_rb_mrt_control(const VkPipelineColorBlendAttachmentState *att, - uint32_t rb_mrt_control_rop, bool has_alpha) { uint32_t rb_mrt_control = A6XX_RB_MRT_CONTROL_COMPONENT_ENABLE(att->colorWriteMask); - rb_mrt_control |= rb_mrt_control_rop; - if (att->blendEnable) { rb_mrt_control |= A6XX_RB_MRT_CONTROL_BLEND; @@ -2297,12 +2294,9 @@ tu6_emit_rb_mrt_controls(struct tu_pipeline *pipeline, *rop_reads_dst = false; *color_bandwidth_per_sample = 0; - uint32_t rb_mrt_control_rop = 0; - if (blend_info->logicOpEnable) { - pipeline->blend.logic_op_enabled = true; - rb_mrt_control_rop = tu6_rb_mrt_control_rop(blend_info->logicOp, - rop_reads_dst); - } + pipeline->blend.rb_mrt_control_rop = + tu6_rb_mrt_control_rop(blend_info->logicOp, rop_reads_dst); + pipeline->blend.logic_op_enabled = blend_info->logicOpEnable; uint32_t total_bpp = 0; pipeline->blend.num_rts = blend_info->attachmentCount; @@ -2318,7 +2312,7 @@ tu6_emit_rb_mrt_controls(struct tu_pipeline *pipeline, const bool has_alpha = vk_format_has_alpha(format); rb_mrt_control = - tu6_rb_mrt_control(att, rb_mrt_control_rop, has_alpha); + tu6_rb_mrt_control(att, has_alpha); rb_mrt_blend_control = tu6_rb_mrt_blend_control(att, has_alpha); /* calculate bpp based on format and write mask */ @@ -2340,7 +2334,7 @@ tu6_emit_rb_mrt_controls(struct tu_pipeline *pipeline, if (att->blendEnable) pipeline->blend.blend_enable |= BIT(i); - if (att->blendEnable || *rop_reads_dst) { + if (att->blendEnable || (blend_info->logicOpEnable && *rop_reads_dst)) { total_bpp += write_bpp; } } @@ -2391,7 +2385,9 @@ tu6_emit_blend(struct tu_cs *cs, for (unsigned i = 0; i < pipeline->blend.num_rts; i++) { tu_cs_emit_regs(cs, - A6XX_RB_MRT_CONTROL(i, .dword = pipeline->blend.rb_mrt_control[i]), + A6XX_RB_MRT_CONTROL(i, .dword = pipeline->blend.rb_mrt_control[i] | + (pipeline->blend.logic_op_enabled ? + pipeline->blend.rb_mrt_control_rop : 0)), A6XX_RB_MRT_BLEND_CONTROL(i, .dword = pipeline->blend.rb_mrt_blend_control[i])); } } @@ -3686,10 +3682,15 @@ tu_pipeline_builder_parse_dynamic(struct tu_pipeline_builder *builder, case VK_DYNAMIC_STATE_LOGIC_OP_EXT: 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_LOGIC_OP_ENABLE_EXT: + 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); + pipeline->dynamic_state_mask |= BIT(TU_DYNAMIC_STATE_LOGIC_OP_ENABLE); + break; case VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT: 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; @@ -3829,6 +3830,7 @@ tu_pipeline_builder_parse_libraries(struct tu_pipeline_builder *builder, BIT(TU_DYNAMIC_STATE_SAMPLE_LOCATIONS) | BIT(TU_DYNAMIC_STATE_BLEND) | BIT(TU_DYNAMIC_STATE_LOGIC_OP) | + BIT(TU_DYNAMIC_STATE_LOGIC_OP_ENABLE) | BIT(TU_DYNAMIC_STATE_COLOR_WRITE_ENABLE); } @@ -4474,7 +4476,7 @@ tu_pipeline_builder_parse_multisample_and_color_blend( } uint32_t blend_enable_mask = - pipeline->blend.rop_reads_dst ? + (pipeline->blend.logic_op_enabled && pipeline->blend.rop_reads_dst) ? pipeline->blend.color_write_enable : pipeline->blend.blend_enable; tu6_emit_blend_control(pipeline, blend_enable_mask, diff --git a/src/freedreno/vulkan/tu_pipeline.h b/src/freedreno/vulkan/tu_pipeline.h index a85f7b161e1..68db185535a 100644 --- a/src/freedreno/vulkan/tu_pipeline.h +++ b/src/freedreno/vulkan/tu_pipeline.h @@ -33,6 +33,7 @@ enum tu_dynamic_state TU_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY = TU_DYNAMIC_STATE_COUNT, TU_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE, TU_DYNAMIC_STATE_LOGIC_OP, + TU_DYNAMIC_STATE_LOGIC_OP_ENABLE, TU_DYNAMIC_STATE_COLOR_WRITE_ENABLE, TU_DYNAMIC_STATE_POLYGON_MODE, TU_DYNAMIC_STATE_TESS_DOMAIN_ORIGIN, @@ -161,6 +162,7 @@ struct tu_pipeline struct { unsigned num_rts; uint32_t rb_mrt_control[MAX_RTS], rb_mrt_control_mask; + uint32_t rb_mrt_control_rop; 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;