From adbdab3ee80017a4939e9cb586ea85f8c4e7efc9 Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Thu, 14 May 2020 17:17:46 +0200 Subject: [PATCH] tu: Implement dual-src blending Part-of: --- src/freedreno/vulkan/tu_pipeline.c | 54 +++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c index 5882f3325f6..54c5103aa3f 100644 --- a/src/freedreno/vulkan/tu_pipeline.c +++ b/src/freedreno/vulkan/tu_pipeline.c @@ -298,6 +298,7 @@ struct tu_pipeline_builder /* these states are affectd by rasterizer_discard */ VkSampleCountFlagBits samples; bool use_color_attachments; + bool use_dual_src_blend; uint32_t color_attachment_count; VkFormat color_attachment_formats[MAX_RTS]; VkFormat depth_attachment_format; @@ -383,6 +384,37 @@ tu_blend_factor_no_dst_alpha(VkBlendFactor factor) } } +static bool tu_blend_factor_is_dual_src(VkBlendFactor factor) +{ + switch (factor) { + case VK_BLEND_FACTOR_SRC1_COLOR: + case VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR: + case VK_BLEND_FACTOR_SRC1_ALPHA: + case VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA: + return true; + default: + return false; + } +} + +static bool +tu_blend_state_is_dual_src(const VkPipelineColorBlendStateCreateInfo *info) +{ + if (!info) + return false; + + for (unsigned i = 0; i < info->attachmentCount; i++) { + const VkPipelineColorBlendAttachmentState *blend = &info->pAttachments[i]; + if (tu_blend_factor_is_dual_src(blend->srcColorBlendFactor) || + tu_blend_factor_is_dual_src(blend->dstColorBlendFactor) || + tu_blend_factor_is_dual_src(blend->srcAlphaBlendFactor) || + tu_blend_factor_is_dual_src(blend->dstAlphaBlendFactor)) + return true; + } + + return false; +} + static enum pc_di_primtype tu6_primtype(VkPrimitiveTopology topology) { @@ -1305,7 +1337,7 @@ tu6_emit_fs_inputs(struct tu_cs *cs, const struct ir3_shader_variant *fs) static void tu6_emit_fs_outputs(struct tu_cs *cs, const struct ir3_shader_variant *fs, - uint32_t mrt_count) + uint32_t mrt_count, bool dual_src_blend) { uint32_t smask_regid, posz_regid; @@ -1327,6 +1359,7 @@ tu6_emit_fs_outputs(struct tu_cs *cs, tu_cs_emit_pkt4(cs, REG_A6XX_SP_FS_OUTPUT_CNTL0, 2); tu_cs_emit(cs, A6XX_SP_FS_OUTPUT_CNTL0_DEPTH_REGID(posz_regid) | A6XX_SP_FS_OUTPUT_CNTL0_SAMPMASK_REGID(smask_regid) | + COND(dual_src_blend, A6XX_SP_FS_OUTPUT_CNTL0_DUAL_COLOR_IN_ENABLE) | 0xfc000000); tu_cs_emit(cs, A6XX_SP_FS_OUTPUT_CNTL1_MRT(mrt_count)); @@ -1343,7 +1376,8 @@ tu6_emit_fs_outputs(struct tu_cs *cs, tu_cs_emit_pkt4(cs, REG_A6XX_RB_FS_OUTPUT_CNTL0, 2); tu_cs_emit(cs, COND(fs->writes_pos, A6XX_RB_FS_OUTPUT_CNTL0_FRAG_WRITES_Z) | - COND(fs->writes_smask, A6XX_RB_FS_OUTPUT_CNTL0_FRAG_WRITES_SAMPMASK)); + COND(fs->writes_smask, A6XX_RB_FS_OUTPUT_CNTL0_FRAG_WRITES_SAMPMASK) | + COND(dual_src_blend, A6XX_RB_FS_OUTPUT_CNTL0_DUAL_COLOR_IN_ENABLE)); tu_cs_emit(cs, A6XX_RB_FS_OUTPUT_CNTL1_MRT(mrt_count)); tu_cs_emit_regs(cs, @@ -1561,7 +1595,8 @@ tu6_emit_program(struct tu_cs *cs, tu6_emit_vpc(cs, vs, gs, fs, binning_pass, tf); tu6_emit_vpc_varying_modes(cs, fs, binning_pass); tu6_emit_fs_inputs(cs, fs); - tu6_emit_fs_outputs(cs, fs, builder->color_attachment_count); + tu6_emit_fs_outputs(cs, fs, builder->color_attachment_count, + builder->use_dual_src_blend); tu6_emit_shader_object(cs, MESA_SHADER_VERTEX, vs, binary_bo, binning_pass ? builder->binning_vs_offset : builder->shader_offsets[MESA_SHADER_VERTEX]); @@ -2029,6 +2064,7 @@ tu6_emit_rb_mrt_controls(struct tu_cs *cs, static void tu6_emit_blend_control(struct tu_cs *cs, uint32_t blend_enable_mask, + bool dual_src_blend, const VkPipelineMultisampleStateCreateInfo *msaa_info) { assert(!msaa_info->alphaToOneEnable); @@ -2036,6 +2072,8 @@ tu6_emit_blend_control(struct tu_cs *cs, uint32_t sp_blend_cntl = A6XX_SP_BLEND_CNTL_UNK8; if (blend_enable_mask) sp_blend_cntl |= A6XX_SP_BLEND_CNTL_ENABLED; + if (dual_src_blend) + sp_blend_cntl |= A6XX_SP_BLEND_CNTL_DUAL_COLOR_IN_ENABLE; if (msaa_info->alphaToCoverageEnable) sp_blend_cntl |= A6XX_SP_BLEND_CNTL_ALPHA_TO_COVERAGE; @@ -2048,6 +2086,8 @@ tu6_emit_blend_control(struct tu_cs *cs, A6XX_RB_BLEND_CNTL_ENABLE_BLEND(blend_enable_mask) | A6XX_RB_BLEND_CNTL_INDEPENDENT_BLEND | A6XX_RB_BLEND_CNTL_SAMPLE_MASK(sample_mask); + if (dual_src_blend) + rb_blend_cntl |= A6XX_RB_BLEND_CNTL_DUAL_COLOR_IN_ENABLE; if (msaa_info->alphaToCoverageEnable) rb_blend_cntl |= A6XX_RB_BLEND_CNTL_ALPHA_TO_COVERAGE; @@ -2478,7 +2518,8 @@ tu_pipeline_builder_parse_multisample_and_color_blend( tu6_emit_sample_locations(&blend_cs, samp_loc); } - tu6_emit_blend_control(&blend_cs, blend_enable_mask, msaa_info); + tu6_emit_blend_control(&blend_cs, blend_enable_mask, + builder->use_dual_src_blend, msaa_info); pipeline->blend.state_ib = tu_cs_end_sub_stream(&pipeline->cs, &blend_cs); } @@ -2592,6 +2633,11 @@ tu_pipeline_builder_init_graphics( builder->color_attachment_formats[i] = pass->attachments[a].format; builder->use_color_attachments = true; } + + if (tu_blend_state_is_dual_src(create_info->pColorBlendState)) { + builder->color_attachment_count++; + builder->use_dual_src_blend = true; + } } } -- 2.30.2