anv_cmd_buffer: Don't make the initial state dirty
[mesa.git] / src / intel / vulkan / gen7_pipeline.c
index 2167f296b2f8e493c2e922566889d70c9f01bfd4..37e4639b287cc283c26ff0a736e3675e1be75bd2 100644 (file)
@@ -61,12 +61,15 @@ gen7_emit_rs_state(struct anv_pipeline *pipeline,
 
       .TriangleStripListProvokingVertexSelect   = 0,
       .LineStripListProvokingVertexSelect       = 0,
-      .TriangleFanProvokingVertexSelect         = 0,
+      .TriangleFanProvokingVertexSelect         = 1,
 
       /* uint32_t                                     AALineDistanceMode; */
       /* uint32_t                                     VertexSubPixelPrecisionSelect; */
-      .UsePointWidthState                       = !pipeline->writes_point_size,
+      .UsePointWidthState                       = false,
       .PointWidth                               = 1.0,
+      .GlobalDepthOffsetEnableSolid             = info->depthBiasEnable,
+      .GlobalDepthOffsetEnableWireframe         = info->depthBiasEnable,
+      .GlobalDepthOffsetEnablePoint             = info->depthBiasEnable,
    };
 
    GENX(3DSTATE_SF_pack)(NULL, &pipeline->gen7.sf, &sf);
@@ -92,6 +95,7 @@ gen7_emit_ds_state(struct anv_pipeline *pipeline,
       .DoubleSidedStencilEnable = true,
 
       .StencilTestEnable = info->stencilTestEnable,
+      .StencilBufferWriteEnable = info->stencilTestEnable,
       .StencilFailOp = vk_to_gen_stencil_op[info->front.failOp],
       .StencilPassDepthPassOp = vk_to_gen_stencil_op[info->front.passOp],
       .StencilPassDepthFailOp = vk_to_gen_stencil_op[info->front.depthFailOp],
@@ -123,50 +127,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),
@@ -225,7 +231,7 @@ genX(graphics_pipeline_create)(
       .ClipMode                                 = CLIPMODE_NORMAL,
       .TriangleStripListProvokingVertexSelect   = 0,
       .LineStripListProvokingVertexSelect       = 0,
-      .TriangleFanProvokingVertexSelect         = 0,
+      .TriangleFanProvokingVertexSelect         = 1,
       .MinimumPointWidth                        = 0.125,
       .MaximumPointWidth                        = 255.875,
       .MaximumVPIndex = pCreateInfo->pViewportState->viewportCount - 1);
@@ -244,11 +250,7 @@ genX(graphics_pipeline_create)(
    anv_batch_emit(&pipeline->batch, GENX(3DSTATE_SAMPLE_MASK),
       .SampleMask                               = 0xff);
 
-   const struct brw_vue_prog_data *vue_prog_data = &pipeline->vs_prog_data.base;
-   /* The last geometry producing stage will set urb_offset and urb_length,
-    * which we use in 3DSTATE_SBE. Skip the VUE header and position slots. */
-   uint32_t urb_offset = 1;
-   uint32_t urb_length = (vue_prog_data->vue_map.num_slots + 1) / 2 - urb_offset;
+   const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
 
 #if 0 
    /* From gen7_vs_state.c */
@@ -275,25 +277,22 @@ genX(graphics_pipeline_create)(
       anv_batch_emit(&pipeline->batch, GENX(3DSTATE_VS),
          .KernelStartPointer                    = pipeline->vs_vec4,
          .ScratchSpaceBaseOffset                = pipeline->scratch_start[MESA_SHADER_VERTEX],
-         .PerThreadScratchSpace                 = scratch_space(&vue_prog_data->base),
+         .PerThreadScratchSpace                 = scratch_space(&vs_prog_data->base.base),
 
          .DispatchGRFStartRegisterforURBData    =
-            vue_prog_data->base.dispatch_grf_start_reg,
-         .VertexURBEntryReadLength              = vue_prog_data->urb_read_length,
+            vs_prog_data->base.base.dispatch_grf_start_reg,
+         .VertexURBEntryReadLength              = vs_prog_data->base.urb_read_length,
          .VertexURBEntryReadOffset              = 0,
 
          .MaximumNumberofThreads                = device->info.max_vs_threads - 1,
          .StatisticsEnable                      = true,
          .VSFunctionEnable                      = true);
 
-   const struct brw_gs_prog_data *gs_prog_data = &pipeline->gs_prog_data;
+   const struct brw_gs_prog_data *gs_prog_data = get_gs_prog_data(pipeline);
 
    if (pipeline->gs_kernel == NO_KERNEL || (extra && extra->disable_vs)) {
       anv_batch_emit(&pipeline->batch, GENX(3DSTATE_GS), .GSEnable = false);
    } else {
-      urb_offset = 1;
-      urb_length = (gs_prog_data->base.vue_map.num_slots + 1) / 2 - urb_offset;
-
       anv_batch_emit(&pipeline->batch, GENX(3DSTATE_GS),
          .KernelStartPointer                    = pipeline->gs_kernel,
          .ScratchSpaceBasePointer               = pipeline->scratch_start[MESA_SHADER_GEOMETRY],
@@ -323,41 +322,30 @@ genX(graphics_pipeline_create)(
    }
 
    if (pipeline->ps_ksp0 == NO_KERNEL) {
-     anv_finishme("disabling ps");
-
-     /* FIXME: generated header doesn't emit attr swizzle fields */
-     anv_batch_emit(&pipeline->batch, GENX(3DSTATE_SBE));
-
-     /* FIXME-GEN7: This needs a lot more work, cf gen7 upload_wm_state(). */
-     anv_batch_emit(&pipeline->batch, GENX(3DSTATE_WM),
-                   .StatisticsEnable                         = true,
-                   .ThreadDispatchEnable                     = false,
-                   .LineEndCapAntialiasingRegionWidth        = 0, /* 0.5 pixels */
-                   .LineAntialiasingRegionWidth              = 1, /* 1.0 pixels */
-                   .EarlyDepthStencilControl                 = EDSC_NORMAL,
-                   .PointRasterizationRule                   = RASTRULE_UPPER_RIGHT);
+      anv_batch_emit(&pipeline->batch, GENX(3DSTATE_SBE));
 
+      anv_batch_emit(&pipeline->batch, GENX(3DSTATE_WM),
+                     .StatisticsEnable                         = true,
+                     .ThreadDispatchEnable                     = false,
+                     .LineEndCapAntialiasingRegionWidth        = 0, /* 0.5 pixels */
+                     .LineAntialiasingRegionWidth              = 1, /* 1.0 pixels */
+                     .EarlyDepthStencilControl                 = EDSC_NORMAL,
+                     .PointRasterizationRule                   = RASTRULE_UPPER_RIGHT);
 
-     /* Even if no fragments are ever dispatched, the hardware hangs if we
-      * don't at least set the maximum number of threads.
-      */
-     anv_batch_emit(&pipeline->batch, GENX(3DSTATE_PS),
-                    .MaximumNumberofThreads                   = device->info.max_wm_threads - 1);
-
+      /* Even if no fragments are ever dispatched, the hardware hangs if we
+       * don't at least set the maximum number of threads.
+       */
+      anv_batch_emit(&pipeline->batch, GENX(3DSTATE_PS),
+                     .MaximumNumberofThreads                   = device->info.max_wm_threads - 1);
    } else {
-      const struct brw_wm_prog_data *wm_prog_data = &pipeline->wm_prog_data;
+      const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline);
       if (wm_prog_data->urb_setup[VARYING_SLOT_BFC0] != -1 ||
           wm_prog_data->urb_setup[VARYING_SLOT_BFC1] != -1)
          anv_finishme("two-sided color needs sbe swizzling setup");
       if (wm_prog_data->urb_setup[VARYING_SLOT_PRIMITIVE_ID] != -1)
          anv_finishme("primitive_id needs sbe swizzling setup");
 
-      /* FIXME: generated header doesn't emit attr swizzle fields */
-      anv_batch_emit(&pipeline->batch, GENX(3DSTATE_SBE),
-                     .NumberofSFOutputAttributes               = pipeline->wm_prog_data.num_varying_inputs,
-                     .VertexURBEntryReadLength                 = urb_length,
-                     .VertexURBEntryReadOffset                 = urb_offset,
-                     .PointSpriteTextureCoordinateOrigin       = UPPERLEFT);
+      emit_3dstate_sbe(pipeline);
 
       anv_batch_emit(&pipeline->batch, GENX(3DSTATE_PS),
                      .KernelStartPointer0                      = pipeline->ps_ksp0,