gen7/pipeline: Add competent blending
authorJason Ekstrand <jason.ekstrand@intel.com>
Tue, 1 Mar 2016 21:51:50 +0000 (13:51 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Tue, 1 Mar 2016 21:51:58 +0000 (13:51 -0800)
This is mostly a copy-and-paste from gen8.  Blending still isn't 100% but
it fixes about 1100 CTS blend tests on HSW.

src/intel/vulkan/gen7_pipeline.c

index c356fed7d688205b43a4919f75a2b56ecd66e31b..7d283f18f4099bc96d725fd6dd7cb99d6b94e126 100644 (file)
@@ -123,50 +123,52 @@ gen7_emit_cb_state(struct anv_pipeline *pipeline,
             .WriteDisableGreen = true,
             .WriteDisableBlue = true);
    } else {
-      /* FIXME-GEN7: All render targets share blend state settings on gen7, we
-       * can't implement this.
-       */
       const VkPipelineColorBlendAttachmentState *a = &info->pAttachments[0];
-      pipeline->blend_state =
-         anv_state_pool_emit(&device->dynamic_state_pool,
-            GENX(BLEND_STATE), 64,
-
-            .ColorBufferBlendEnable = a->blendEnable,
-            .IndependentAlphaBlendEnable = true, /* FIXME: yes? */
-            .AlphaBlendFunction = vk_to_gen_blend_op[a->alphaBlendOp],
-
-            .SourceAlphaBlendFactor = vk_to_gen_blend[a->srcAlphaBlendFactor],
-            .DestinationAlphaBlendFactor = vk_to_gen_blend[a->dstAlphaBlendFactor],
-
-            .ColorBlendFunction = vk_to_gen_blend_op[a->colorBlendOp],
-            .SourceBlendFactor = vk_to_gen_blend[a->srcColorBlendFactor],
-            .DestinationBlendFactor = vk_to_gen_blend[a->dstColorBlendFactor],
-            .AlphaToCoverageEnable = ms_info && ms_info->alphaToCoverageEnable,
-
-#     if 0
-            bool                                AlphaToOneEnable;
-            bool                                AlphaToCoverageDitherEnable;
-#     endif
-
-            .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),
-
-            .LogicOpEnable = info->logicOpEnable,
-            .LogicOpFunction = vk_to_gen_logic_op[info->logicOp],
-
-#     if 0
-            bool                                AlphaTestEnable;
-            uint32_t                            AlphaTestFunction;
-            bool                                ColorDitherEnable;
-            uint32_t                            XDitherOffset;
-            uint32_t                            YDitherOffset;
-            uint32_t                            ColorClampRange;
-            bool                                PreBlendColorClampEnable;
-            bool                                PostBlendColorClampEnable;
-#     endif
-            );
+      struct GENX(BLEND_STATE) blend = {
+         .AlphaToCoverageEnable = ms_info && ms_info->alphaToCoverageEnable,
+         .AlphaToOneEnable = ms_info && ms_info->alphaToOneEnable,
+
+         .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),
+      };
+
+      /* 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.SourceBlendFactor = BLENDFACTOR_ONE;
+         blend.DestinationBlendFactor = BLENDFACTOR_ONE;
+      }
+      if (a->alphaBlendOp == VK_BLEND_OP_MIN ||
+          a->alphaBlendOp == VK_BLEND_OP_MAX) {
+         blend.SourceAlphaBlendFactor = BLENDFACTOR_ONE;
+         blend.DestinationAlphaBlendFactor = BLENDFACTOR_ONE;
+      }
+
+      pipeline->blend_state = anv_state_pool_alloc(&device->dynamic_state_pool,
+                                                   GENX(BLEND_STATE_length) * 4,
+                                                   64);
+      GENX(BLEND_STATE_pack)(NULL, pipeline->blend_state.map, &blend);
+      if (pipeline->device->info.has_llc)
+         anv_state_clflush(pipeline->blend_state);
     }
 
    anv_batch_emit(&pipeline->batch, GENX(3DSTATE_BLEND_STATE_POINTERS),