summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConnor Abbott <cwabbott0@gmail.com>2020-05-14 17:17:46 +0200
committerMarge Bot <eric+marge@anholt.net>2020-05-14 18:15:31 +0000
commitadbdab3ee80017a4939e9cb586ea85f8c4e7efc9 (patch)
treeb9fdb55d5e14a2f61a697a7cec935b690dfe2545
parent078aa9df8daff60e52a66d8f8062dce135b94ec1 (diff)
tu: Implement dual-src blending
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5039>
-rw-r--r--src/freedreno/vulkan/tu_pipeline.c54
1 files 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;
+ }
}
}