vk: Add support for dynamic and pipeline color blend state
authorKristian Høgsberg <kristian.h.kristensen@intel.com>
Wed, 27 May 2015 00:12:18 +0000 (17:12 -0700)
committerKristian Høgsberg <kristian.h.kristensen@intel.com>
Wed, 27 May 2015 00:12:37 +0000 (17:12 -0700)
src/vulkan/device.c
src/vulkan/pipeline.c
src/vulkan/private.h

index fb190025c7897b00d580dedc2db08cfc9a74f6bc..3729a3c544cbb5fe6b7f364823b3bcdbe56bc6fe 100644 (file)
@@ -2490,6 +2490,8 @@ void anv_CmdBindDynamicStateObject(
       cmd_buffer->dirty |= ANV_CMD_BUFFER_RS_DIRTY;
       break;
    case VK_STATE_BIND_POINT_COLOR_BLEND:
+      cmd_buffer->cb_state = (struct anv_dynamic_cb_state *) dynamicState;
+      cmd_buffer->dirty |= ANV_CMD_BUFFER_CB_DIRTY;
       break;
    case VK_STATE_BIND_POINT_DEPTH_STENCIL:
       cmd_buffer->ds_state = (struct anv_dynamic_ds_state *) dynamicState;
@@ -2773,15 +2775,19 @@ anv_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
 
    if (cmd_buffer->dirty & (ANV_CMD_BUFFER_CB_DIRTY | ANV_CMD_BUFFER_DS_DIRTY)) {
       struct anv_state state;
-      if (cmd_buffer->ds_state)
+      if (cmd_buffer->ds_state == NULL)
+         state = anv_cmd_buffer_emit_dynamic(cmd_buffer,
+                                             cmd_buffer->cb_state->state_color_calc,
+                                             GEN8_COLOR_CALC_STATE_length, 32);
+      else if (cmd_buffer->cb_state == NULL)
+         state = anv_cmd_buffer_emit_dynamic(cmd_buffer,
+                                             cmd_buffer->ds_state->state_color_calc,
+                                             GEN8_COLOR_CALC_STATE_length, 32);
+      else
          state = anv_cmd_buffer_merge_dynamic(cmd_buffer,
                                               cmd_buffer->ds_state->state_color_calc,
                                               cmd_buffer->cb_state->state_color_calc,
                                               GEN8_COLOR_CALC_STATE_length, 32);
-      else
-         state = anv_cmd_buffer_emit_dynamic(cmd_buffer,
-                                             cmd_buffer->cb_state->state_color_calc,
-                                             GEN8_COLOR_CALC_STATE_length, 32);
 
       anv_batch_emit(&cmd_buffer->batch,
                      GEN8_3DSTATE_CC_STATE_POINTERS,
index ca11ca8b343aed598e2d9d77d3e02d478340bafd..e33b7e6c37637df598ed4bd8f703641fac3f86e5 100644 (file)
@@ -192,12 +192,12 @@ emit_rs_state(struct anv_pipeline *pipeline, VkPipelineRsStateCreateInfo *info,
       .PointWidthSource = info->programPointSize ? Vertex : State,
    };
 
-   /* bool32_t                                    rasterizerDiscardEnable; */
-
+   /* FINISHME: bool32_t rasterizerDiscardEnable; */
 
    GEN8_3DSTATE_SF_pack(NULL, pipeline->state_sf, &sf);
 
    struct GEN8_3DSTATE_RASTER raster = {
+      GEN8_3DSTATE_RASTER_header,
       .FrontWinding = vk_to_gen_front_face[info->frontFace],
       .CullMode = vk_to_gen_cullmode[info->cullMode],
       .FrontFaceFillMode = vk_to_gen_fillmode[info->fillMode],
@@ -218,6 +218,101 @@ emit_rs_state(struct anv_pipeline *pipeline, VkPipelineRsStateCreateInfo *info,
 
 }
 
+static void
+emit_cb_state(struct anv_pipeline *pipeline, VkPipelineCbStateCreateInfo *info)
+{
+   struct anv_device *device = pipeline->device;
+
+   static const uint32_t vk_to_gen_logic_op[] = {
+      [VK_LOGIC_OP_COPY]                        = LOGICOP_COPY,
+      [VK_LOGIC_OP_CLEAR]                       = LOGICOP_CLEAR,
+      [VK_LOGIC_OP_AND]                         = LOGICOP_AND,
+      [VK_LOGIC_OP_AND_REVERSE]                 = LOGICOP_AND_REVERSE,
+      [VK_LOGIC_OP_AND_INVERTED]                = LOGICOP_AND_INVERTED,
+      [VK_LOGIC_OP_NOOP]                        = LOGICOP_NOOP,
+      [VK_LOGIC_OP_XOR]                         = LOGICOP_XOR,
+      [VK_LOGIC_OP_OR]                          = LOGICOP_OR,
+      [VK_LOGIC_OP_NOR]                         = LOGICOP_NOR,
+      [VK_LOGIC_OP_EQUIV]                       = LOGICOP_EQUIV,
+      [VK_LOGIC_OP_INVERT]                      = LOGICOP_INVERT,
+      [VK_LOGIC_OP_OR_REVERSE]                  = LOGICOP_OR_REVERSE,
+      [VK_LOGIC_OP_COPY_INVERTED]               = LOGICOP_COPY_INVERTED,
+      [VK_LOGIC_OP_OR_INVERTED]                 = LOGICOP_OR_INVERTED,
+      [VK_LOGIC_OP_NAND]                        = LOGICOP_NAND,
+      [VK_LOGIC_OP_SET]                         = LOGICOP_SET,
+   };
+
+   static const uint32_t vk_to_gen_blend[] = {
+      [VK_BLEND_ZERO]                           = BLENDFACTOR_ZERO,
+      [VK_BLEND_ONE]                            = BLENDFACTOR_ONE,
+      [VK_BLEND_SRC_COLOR]                      = BLENDFACTOR_SRC_COLOR,
+      [VK_BLEND_ONE_MINUS_SRC_COLOR]            = BLENDFACTOR_INV_SRC_COLOR,
+      [VK_BLEND_DEST_COLOR]                     = BLENDFACTOR_DST_COLOR,
+      [VK_BLEND_ONE_MINUS_DEST_COLOR]           = BLENDFACTOR_INV_DST_COLOR,
+      [VK_BLEND_SRC_ALPHA]                      = BLENDFACTOR_SRC_ALPHA,
+      [VK_BLEND_ONE_MINUS_SRC_ALPHA]            = BLENDFACTOR_INV_SRC_ALPHA,
+      [VK_BLEND_DEST_ALPHA]                     = BLENDFACTOR_DST_ALPHA,
+      [VK_BLEND_ONE_MINUS_DEST_ALPHA]           = BLENDFACTOR_INV_DST_ALPHA,
+      [VK_BLEND_CONSTANT_COLOR]                 = BLENDFACTOR_CONST_COLOR,
+      [VK_BLEND_ONE_MINUS_CONSTANT_COLOR]       = BLENDFACTOR_INV_CONST_COLOR,
+      [VK_BLEND_CONSTANT_ALPHA]                 = BLENDFACTOR_CONST_ALPHA,
+      [VK_BLEND_ONE_MINUS_CONSTANT_ALPHA]       = BLENDFACTOR_INV_CONST_ALPHA,
+      [VK_BLEND_SRC_ALPHA_SATURATE]             = BLENDFACTOR_SRC_ALPHA_SATURATE,
+      [VK_BLEND_SRC1_COLOR]                     = BLENDFACTOR_SRC1_COLOR,
+      [VK_BLEND_ONE_MINUS_SRC1_COLOR]           = BLENDFACTOR_INV_SRC1_COLOR,
+      [VK_BLEND_SRC1_ALPHA]                     = BLENDFACTOR_SRC1_ALPHA,
+      [VK_BLEND_ONE_MINUS_SRC1_ALPHA]           = BLENDFACTOR_INV_SRC1_ALPHA,
+   };
+
+   static const uint32_t vk_to_gen_blend_op[] = {
+      [VK_BLEND_OP_ADD]                         = BLENDFUNCTION_ADD,
+      [VK_BLEND_OP_SUBTRACT]                    = BLENDFUNCTION_SUBTRACT,
+      [VK_BLEND_OP_REVERSE_SUBTRACT]            = BLENDFUNCTION_REVERSE_SUBTRACT,
+      [VK_BLEND_OP_MIN]                         = BLENDFUNCTION_MIN,
+      [VK_BLEND_OP_MAX]                         = BLENDFUNCTION_MAX,
+   };
+
+   uint32_t num_dwords = 1 + info->attachmentCount * 2;
+   pipeline->blend_state =
+      anv_state_pool_alloc(&device->dynamic_state_pool, num_dwords * 4, 64);
+
+   struct GEN8_BLEND_STATE blend_state = {
+      .AlphaToCoverageEnable = info->alphaToCoverageEnable,
+   };
+
+   uint32_t *state = pipeline->blend_state.map;
+   GEN8_BLEND_STATE_pack(NULL, state, &blend_state);
+
+   for (uint32_t i = 0; i < info->attachmentCount; i++) {
+      const VkPipelineCbAttachmentState *a = &info->pAttachments[i];
+
+      struct GEN8_BLEND_STATE_ENTRY entry = {
+         .LogicOpEnable = info->logicOpEnable,
+         .LogicOpFunction = vk_to_gen_logic_op[info->logicOp],
+         .ColorBufferBlendEnable = a->blendEnable,
+         .PreBlendSourceOnlyClampEnable = false,
+         .PreBlendColorClampEnable = false,
+         .PostBlendColorClampEnable = false,
+         .SourceBlendFactor = vk_to_gen_blend[a->srcBlendColor],
+         .DestinationBlendFactor = vk_to_gen_blend[a->destBlendColor],
+         .ColorBlendFunction = vk_to_gen_blend_op[a->blendOpColor],
+         .SourceAlphaBlendFactor = vk_to_gen_blend[a->srcBlendAlpha],
+         .DestinationAlphaBlendFactor = vk_to_gen_blend[a->destBlendAlpha],
+         .AlphaBlendFunction = vk_to_gen_blend_op[a->blendOpAlpha],
+         .WriteDisableAlpha = !(a->channelWriteMask & VK_CHANNEL_A_BIT),
+         .WriteDisableRed = !(a->channelWriteMask & VK_CHANNEL_R_BIT),
+         .WriteDisableGreen = !(a->channelWriteMask & VK_CHANNEL_G_BIT),
+         .WriteDisableBlue = !(a->channelWriteMask & VK_CHANNEL_B_BIT),
+      };
+
+      GEN8_BLEND_STATE_ENTRY_pack(NULL, state + i * 2 + 1, &entry);
+   }
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_BLEND_STATE_POINTERS,
+                  .BlendStatePointer = pipeline->blend_state.offset,
+                  .BlendStatePointerValid = true);
+}
+
 static const uint32_t vk_to_gen_compare_op[] = {
    [VK_COMPARE_OP_NEVER] = COMPAREFUNCTION_NEVER,
    [VK_COMPARE_OP_LESS] = COMPAREFUNCTION_LESS,
@@ -301,6 +396,7 @@ anv_pipeline_create(
    VkPipelineIaStateCreateInfo *ia_info = NULL;
    VkPipelineRsStateCreateInfo *rs_info = NULL;
    VkPipelineDsStateCreateInfo *ds_info = NULL;
+   VkPipelineCbStateCreateInfo *cb_info = NULL;
    VkPipelineVertexInputCreateInfo *vi_info;
    VkResult result;
    uint32_t offset, length;
@@ -344,7 +440,7 @@ anv_pipeline_create(
          anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO");
          break;
       case VK_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
-         anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO");
+         cb_info = (VkPipelineCbStateCreateInfo *) common;
          break;
       case VK_STRUCTURE_TYPE_PIPELINE_DS_STATE_CREATE_INFO:
          ds_info = (VkPipelineDsStateCreateInfo *) common;
@@ -381,6 +477,8 @@ anv_pipeline_create(
    if (ds_info)
       emit_ds_state(pipeline, ds_info);
 
+   emit_cb_state(pipeline, cb_info);
+
    anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_CLIP,
                   .ClipEnable = true,
                   .ViewportXYClipTestEnable = !(extra && extra->disable_viewport));
index cad3423984b09c72ffe9f8069fd7f9539b90c65d..7dbf288022ebdee34fe13b6c2aa5896b2e5c9875 100644 (file)
@@ -639,6 +639,7 @@ struct anv_pipeline {
 
    uint32_t                                     active_stages;
    struct anv_state_stream                      program_stream;
+   struct anv_state                             blend_state;
    uint32_t                                     vs_simd8;
    uint32_t                                     ps_simd8;
    uint32_t                                     ps_simd16;