anv/gen8: Begin enabling pipeline multisample state
authorChad Versace <chad.versace@intel.com>
Tue, 26 Jan 2016 18:56:06 +0000 (10:56 -0800)
committerChad Versace <chad.versace@intel.com>
Thu, 28 Jan 2016 00:52:27 +0000 (16:52 -0800)
As far as I can tell, this patch sets all pipeline multisample state
except:
    - alpha to coverage
    - alpha to one
    - the dispatch count for per-sample dispatch

src/vulkan/anv_device.c
src/vulkan/anv_pipeline.c
src/vulkan/gen7_pipeline.c
src/vulkan/gen8_pipeline.c

index f116f9a7354e27f604fb927b479fed2c4db1bd09..adf33a84cf4052bfad555c0fe8a21760129ae90b 100644 (file)
@@ -502,7 +502,7 @@ void anv_GetPhysicalDeviceProperties(
       .pointSizeGranularity                     = (1.0 / 8.0),
       .lineWidthGranularity                     = (1.0 / 128.0),
       .strictLines                              = false, /* FINISHME */
-      .standardSampleLocations                  = true, /* FINISHME */
+      .standardSampleLocations                  = true,
       .optimalBufferCopyOffsetAlignment         = 128,
       .optimalBufferCopyRowPitchAlignment       = 128,
       .nonCoherentAtomSize                      = 64,
index e879b35388d96fd6724ef4030617e0fac355dea3..106b9221dd76c574171195747429f4d2039dd510 100644 (file)
@@ -1077,9 +1077,6 @@ anv_pipeline_init(struct anv_pipeline *pipeline,
 
    if (pCreateInfo->pTessellationState)
       anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO");
-   if (pCreateInfo->pMultisampleState &&
-       pCreateInfo->pMultisampleState->rasterizationSamples > 1)
-      anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO");
 
    pipeline->use_repclear = extra && extra->use_repclear;
    pipeline->writes_point_size = false;
index ea5b3401121048dc93c242757fc85ad9b0c8e2b9..7b5330e7448c12349c3d80da507c8cdd4afb97de 100644 (file)
@@ -269,6 +269,10 @@ genX(graphics_pipeline_create)(
       .MaximumPointWidth                        = 255.875,
       .MaximumVPIndex = pCreateInfo->pViewportState->viewportCount - 1);
 
+   if (pCreateInfo->pMultisampleState &&
+       pCreateInfo->pMultisampleState->rasterizationSamples > 1)
+      anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO");
+
    uint32_t samples = 1;
    uint32_t log2_samples = __builtin_ffs(samples) - 1;
 
index 5d6b87064e97142955c8f41174d673cdeda0133a..1e9aa0e12bcc5aee15f8fa9dd21a0587fbb0852b 100644 (file)
@@ -46,8 +46,14 @@ emit_ia_state(struct anv_pipeline *pipeline,
 static void
 emit_rs_state(struct anv_pipeline *pipeline,
               const VkPipelineRasterizationStateCreateInfo *info,
+              const VkPipelineMultisampleStateCreateInfo *ms_info,
               const struct anv_graphics_pipeline_create_info *extra)
 {
+   uint32_t samples = 1;
+
+   if (ms_info)
+      samples = ms_info->rasterizationSamples;
+
    struct GENX(3DSTATE_SF) sf = {
       GENX(3DSTATE_SF_header),
       .ViewportTransformEnable = !(extra && extra->disable_viewport),
@@ -64,6 +70,14 @@ emit_rs_state(struct anv_pipeline *pipeline,
 
    struct GENX(3DSTATE_RASTER) raster = {
       GENX(3DSTATE_RASTER_header),
+
+      /* For details on 3DSTATE_RASTER multisample state, see the BSpec table
+       * "Multisample Modes State".
+       */
+      .DXMultisampleRasterizationEnable = samples > 1,
+      .ForcedSampleCount = FSC_NUMRASTSAMPLES_0,
+      .ForceMultisampling = false,
+
       .FrontWinding = vk_to_gen_front_face[info->frontFace],
       .CullMode = vk_to_gen_cullmode[info->cullMode],
       .FrontFaceFillMode = vk_to_gen_fillmode[info->polygonMode],
@@ -193,6 +207,118 @@ emit_ds_state(struct anv_pipeline *pipeline,
    GENX(3DSTATE_WM_DEPTH_STENCIL_pack)(NULL, dw, &wm_depth_stencil);
 }
 
+static void
+emit_ms_state(struct anv_pipeline *pipeline,
+              const VkPipelineMultisampleStateCreateInfo *info)
+{
+   uint32_t samples = 1;
+   uint32_t log2_samples = 0;
+
+   /* From the Vulkan 1.0 spec:
+    *    If pSampleMask is NULL, it is treated as if the mask has all bits
+    *    enabled, i.e. no coverage is removed from fragments.
+    *
+    * 3DSTATE_SAMPLE_MASK.SampleMask is 16 bits.
+    */
+   uint32_t sample_mask = 0xffff;
+
+   if (info) {
+      samples = info->rasterizationSamples;
+      log2_samples = __builtin_ffs(samples) - 1;
+   }
+
+   if (info && info->pSampleMask)
+      sample_mask &= info->pSampleMask[0];
+
+   if (info && info->sampleShadingEnable)
+      anv_finishme("VkPipelineMultisampleStateCreateInfo::sampleShadingEnable");
+
+   anv_batch_emit(&pipeline->batch, GENX(3DSTATE_MULTISAMPLE),
+
+      /* The PRM says that this bit is valid only for DX9:
+       *
+       *    SW can choose to set this bit only for DX9 API. DX10/OGL API's
+       *    should not have any effect by setting or not setting this bit.
+       */
+      .PixelPositionOffsetEnable = false,
+
+      .PixelLocation = CENTER,
+      .NumberofMultisamples = log2_samples);
+
+   anv_batch_emit(&pipeline->batch, GENX(3DSTATE_SAMPLE_MASK),
+      .SampleMask = sample_mask);
+
+   /* See the Vulkan 1.0 spec Table 24.1 "Standard sample locations" and
+    * VkPhysicalDeviceFeatures::standardSampleLocations.
+    */
+   anv_batch_emit(&pipeline->batch, GENX(3DSTATE_SAMPLE_PATTERN),
+      ._1xSample0XOffset      = 0.5,
+      ._1xSample0YOffset      = 0.5,
+      ._2xSample0XOffset      = 0.25,
+      ._2xSample0YOffset      = 0.25,
+      ._2xSample1XOffset      = 0.75,
+      ._2xSample1YOffset      = 0.75,
+      ._4xSample0XOffset      = 0.375,
+      ._4xSample0YOffset      = 0.125,
+      ._4xSample1XOffset      = 0.875,
+      ._4xSample1YOffset      = 0.375,
+      ._4xSample2XOffset      = 0.125,
+      ._4xSample2YOffset      = 0.625,
+      ._4xSample3XOffset      = 0.625,
+      ._4xSample3YOffset      = 0.875,
+      ._8xSample0XOffset      = 0.5625,
+      ._8xSample0YOffset      = 0.3125,
+      ._8xSample1XOffset      = 0.4375,
+      ._8xSample1YOffset      = 0.6875,
+      ._8xSample2XOffset      = 0.8125,
+      ._8xSample2YOffset      = 0.5625,
+      ._8xSample3XOffset      = 0.3125,
+      ._8xSample3YOffset      = 0.1875,
+      ._8xSample4XOffset      = 0.1875,
+      ._8xSample4YOffset      = 0.8125,
+      ._8xSample5XOffset      = 0.0625,
+      ._8xSample5YOffset      = 0.4375,
+      ._8xSample6XOffset      = 0.6875,
+      ._8xSample6YOffset      = 0.9375,
+      ._8xSample7XOffset      = 0.9375,
+      ._8xSample7YOffset      = 0.0625,
+#if ANV_GEN >= 9
+      ._16xSample0XOffset     = 0.5625,
+      ._16xSample0YOffset     = 0.5625,
+      ._16xSample1XOffset     = 0.4375,
+      ._16xSample1YOffset     = 0.3125,
+      ._16xSample2XOffset     = 0.3125,
+      ._16xSample2YOffset     = 0.6250,
+      ._16xSample3XOffset     = 0.7500,
+      ._16xSample3YOffset     = 0.4375,
+      ._16xSample4XOffset     = 0.1875,
+      ._16xSample4YOffset     = 0.3750,
+      ._16xSample5XOffset     = 0.6250,
+      ._16xSample5YOffset     = 0.8125,
+      ._16xSample6XOffset     = 0.8125,
+      ._16xSample6YOffset     = 0.6875,
+      ._16xSample7XOffset     = 0.6875,
+      ._16xSample7YOffset     = 0.1875,
+      ._16xSample8XOffset     = 0.3750,
+      ._16xSample8YOffset     = 0.8750,
+      ._16xSample9XOffset     = 0.5000,
+      ._16xSample9YOffset     = 0.0625,
+      ._16xSample10XOffset    = 0.2500,
+      ._16xSample10YOffset    = 0.1250,
+      ._16xSample11XOffset    = 0.1250,
+      ._16xSample11YOffset    = 0.7500,
+      ._16xSample12XOffset    = 0.0000,
+      ._16xSample12YOffset    = 0.5000,
+      ._16xSample13XOffset    = 0.9375,
+      ._16xSample13YOffset    = 0.2500,
+      ._16xSample14XOffset    = 0.8750,
+      ._16xSample14YOffset    = 0.9375,
+      ._16xSample15XOffset    = 0.0625,
+      ._16xSample15YOffset    = 0.0000,
+#endif
+   );
+}
+
 VkResult
 genX(graphics_pipeline_create)(
     VkDevice                                    _device,
@@ -226,7 +352,9 @@ genX(graphics_pipeline_create)(
    assert(pCreateInfo->pInputAssemblyState);
    emit_ia_state(pipeline, pCreateInfo->pInputAssemblyState, extra);
    assert(pCreateInfo->pRasterizationState);
-   emit_rs_state(pipeline, pCreateInfo->pRasterizationState, extra);
+   emit_rs_state(pipeline, pCreateInfo->pRasterizationState,
+                 pCreateInfo->pMultisampleState, extra);
+   emit_ms_state(pipeline, pCreateInfo->pMultisampleState);
    emit_ds_state(pipeline, pCreateInfo->pDepthStencilState);
    emit_cb_state(pipeline, pCreateInfo->pColorBlendState,
                            pCreateInfo->pMultisampleState);
@@ -270,18 +398,6 @@ genX(graphics_pipeline_create)(
                      pipeline->ps_ksp0 == NO_KERNEL ?
                      0 : pipeline->wm_prog_data.barycentric_interp_modes);
 
-   uint32_t samples = 1;
-   uint32_t log2_samples = __builtin_ffs(samples) - 1;
-   bool enable_sampling = samples > 1 ? true : false;
-
-   anv_batch_emit(&pipeline->batch, GENX(3DSTATE_MULTISAMPLE),
-                  .PixelPositionOffsetEnable = enable_sampling,
-                  .PixelLocation = CENTER,
-                  .NumberofMultisamples = log2_samples);
-
-   anv_batch_emit(&pipeline->batch, GENX(3DSTATE_SAMPLE_MASK),
-                  .SampleMask = 0xffff);
-
    anv_batch_emit(&pipeline->batch, GENX(3DSTATE_URB_VS),
                   .VSURBStartingAddress = pipeline->urb.vs_start,
                   .VSURBEntryAllocationSize = pipeline->urb.vs_size - 1,
@@ -530,7 +646,9 @@ genX(graphics_pipeline_create)(
                      .KernelStartPointer1 = 0,
                      .KernelStartPointer2 = pipeline->ps_ksp2);
 
-      bool per_sample_ps = false;
+      bool per_sample_ps = pCreateInfo->pMultisampleState &&
+                           pCreateInfo->pMultisampleState->sampleShadingEnable;
+
       anv_batch_emit(&pipeline->batch, GENX(3DSTATE_PS_EXTRA),
                      .PixelShaderValid = true,
                      .PixelShaderKillsPixel = wm_prog_data->uses_kill,