summaryrefslogtreecommitdiffstats
path: root/src/intel/vulkan/genX_pipeline_util.h
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2016-07-14 18:00:50 -0700
committerJason Ekstrand <[email protected]>2016-07-15 15:48:21 -0700
commita2e7b2e6538a87c60219319456f55cb42298745c (patch)
tree4c299f1c439aea0e5471bd210517edf2795b0b8b /src/intel/vulkan/genX_pipeline_util.h
parentaaa202ebe7b86f71f596bf01f6177f4cb66f2c4c (diff)
anv/pipeline: Unify blend state setup between gen7 and gen8
This fixes all 674 broken dEQP-VK.pipeline.blend Vulkan CTS tests on Haswell. Signed-off-by: Jason Ekstrand <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]> Cc: "12.0" <[email protected]>
Diffstat (limited to 'src/intel/vulkan/genX_pipeline_util.h')
-rw-r--r--src/intel/vulkan/genX_pipeline_util.h134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/intel/vulkan/genX_pipeline_util.h b/src/intel/vulkan/genX_pipeline_util.h
index 669b456860e..4385112b421 100644
--- a/src/intel/vulkan/genX_pipeline_util.h
+++ b/src/intel/vulkan/genX_pipeline_util.h
@@ -512,3 +512,137 @@ emit_ds_state(struct anv_pipeline *pipeline,
GENX(3DSTATE_WM_DEPTH_STENCIL_pack)(NULL, depth_stencil_dw, &depth_stencil);
#endif
}
+
+static void
+emit_cb_state(struct anv_pipeline *pipeline,
+ const VkPipelineColorBlendStateCreateInfo *info,
+ const VkPipelineMultisampleStateCreateInfo *ms_info)
+{
+ struct anv_device *device = pipeline->device;
+
+ const uint32_t num_dwords = GENX(BLEND_STATE_length);
+ pipeline->blend_state =
+ anv_state_pool_alloc(&device->dynamic_state_pool, num_dwords * 4, 64);
+
+ struct GENX(BLEND_STATE) blend_state = {
+#if GEN_GEN >= 8
+ .AlphaToCoverageEnable = ms_info && ms_info->alphaToCoverageEnable,
+ .AlphaToOneEnable = ms_info && ms_info->alphaToOneEnable,
+#else
+ /* Make sure it gets zeroed */
+ .Entry = { { 0, }, },
+#endif
+ };
+
+ /* Default everything to disabled */
+ for (uint32_t i = 0; i < 8; i++) {
+ blend_state.Entry[i].WriteDisableAlpha = true;
+ blend_state.Entry[i].WriteDisableRed = true;
+ blend_state.Entry[i].WriteDisableGreen = true;
+ blend_state.Entry[i].WriteDisableBlue = true;
+ }
+
+ struct anv_pipeline_bind_map *map =
+ &pipeline->bindings[MESA_SHADER_FRAGMENT];
+
+ bool has_writeable_rt = false;
+ for (unsigned i = 0; i < map->surface_count; i++) {
+ struct anv_pipeline_binding *binding = &map->surface_to_descriptor[i];
+
+ /* All color attachments are at the beginning of the binding table */
+ if (binding->set != ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS)
+ break;
+
+ /* We can have at most 8 attachments */
+ assert(i < 8);
+
+ if (binding->index >= info->attachmentCount)
+ continue;
+
+ assert(binding->binding == 0);
+ const VkPipelineColorBlendAttachmentState *a =
+ &info->pAttachments[binding->index];
+
+ blend_state.Entry[i] = (struct GENX(BLEND_STATE_ENTRY)) {
+#if GEN_GEN < 8
+ .AlphaToCoverageEnable = ms_info && ms_info->alphaToCoverageEnable,
+ .AlphaToOneEnable = ms_info && ms_info->alphaToOneEnable,
+#endif
+ .LogicOpEnable = info->logicOpEnable,
+ .LogicOpFunction = vk_to_gen_logic_op[info->logicOp],
+ .ColorBufferBlendEnable = a->blendEnable,
+ .ColorClampRange = COLORCLAMP_RTFORMAT,
+ .PreBlendColorClampEnable = true,
+ .PostBlendColorClampEnable = true,
+ .SourceBlendFactor = vk_to_gen_blend[a->srcColorBlendFactor],
+ .DestinationBlendFactor = vk_to_gen_blend[a->dstColorBlendFactor],
+ .ColorBlendFunction = vk_to_gen_blend_op[a->colorBlendOp],
+ .SourceAlphaBlendFactor = vk_to_gen_blend[a->srcAlphaBlendFactor],
+ .DestinationAlphaBlendFactor = vk_to_gen_blend[a->dstAlphaBlendFactor],
+ .AlphaBlendFunction = vk_to_gen_blend_op[a->alphaBlendOp],
+ .WriteDisableAlpha = !(a->colorWriteMask & VK_COLOR_COMPONENT_A_BIT),
+ .WriteDisableRed = !(a->colorWriteMask & VK_COLOR_COMPONENT_R_BIT),
+ .WriteDisableGreen = !(a->colorWriteMask & VK_COLOR_COMPONENT_G_BIT),
+ .WriteDisableBlue = !(a->colorWriteMask & VK_COLOR_COMPONENT_B_BIT),
+ };
+
+ if (a->srcColorBlendFactor != a->srcAlphaBlendFactor ||
+ a->dstColorBlendFactor != a->dstAlphaBlendFactor ||
+ a->colorBlendOp != a->alphaBlendOp) {
+#if GEN_GEN >= 8
+ blend_state.IndependentAlphaBlendEnable = true;
+#else
+ blend_state.Entry[i].IndependentAlphaBlendEnable = true;
+#endif
+ }
+
+ if (a->colorWriteMask != 0)
+ has_writeable_rt = true;
+
+ /* Our hardware applies the blend factor prior to the blend function
+ * regardless of what function is used. Technically, this means the
+ * hardware can do MORE than GL or Vulkan specify. However, it also
+ * means that, for MIN and MAX, we have to stomp the blend factor to
+ * ONE to make it a no-op.
+ */
+ if (a->colorBlendOp == VK_BLEND_OP_MIN ||
+ a->colorBlendOp == VK_BLEND_OP_MAX) {
+ blend_state.Entry[i].SourceBlendFactor = BLENDFACTOR_ONE;
+ blend_state.Entry[i].DestinationBlendFactor = BLENDFACTOR_ONE;
+ }
+ if (a->alphaBlendOp == VK_BLEND_OP_MIN ||
+ a->alphaBlendOp == VK_BLEND_OP_MAX) {
+ blend_state.Entry[i].SourceAlphaBlendFactor = BLENDFACTOR_ONE;
+ blend_state.Entry[i].DestinationAlphaBlendFactor = BLENDFACTOR_ONE;
+ }
+ }
+
+#if GEN_GEN >= 8
+ struct GENX(BLEND_STATE_ENTRY) *bs0 = &blend_state.Entry[0];
+ anv_batch_emit(&pipeline->batch, GENX(3DSTATE_PS_BLEND), blend) {
+ blend.AlphaToCoverageEnable = blend_state.AlphaToCoverageEnable;
+ blend.HasWriteableRT = has_writeable_rt;
+ blend.ColorBufferBlendEnable = bs0->ColorBufferBlendEnable;
+ blend.SourceAlphaBlendFactor = bs0->SourceAlphaBlendFactor;
+ blend.DestinationAlphaBlendFactor = bs0->DestinationAlphaBlendFactor;
+ blend.SourceBlendFactor = bs0->SourceBlendFactor;
+ blend.DestinationBlendFactor = bs0->DestinationBlendFactor;
+ blend.AlphaTestEnable = false;
+ blend.IndependentAlphaBlendEnable =
+ blend_state.IndependentAlphaBlendEnable;
+ }
+#else
+ (void)has_writeable_rt;
+#endif
+
+ GENX(BLEND_STATE_pack)(NULL, pipeline->blend_state.map, &blend_state);
+ if (!device->info.has_llc)
+ anv_state_clflush(pipeline->blend_state);
+
+ anv_batch_emit(&pipeline->batch, GENX(3DSTATE_BLEND_STATE_POINTERS), bsp) {
+ bsp.BlendStatePointer = pipeline->blend_state.offset;
+#if GEN_GEN >= 8
+ bsp.BlendStatePointerValid = true;
+#endif
+ }
+}