anv/pipeline: make FragCoord include sample positions when sample shading
authorIago Toral Quiroga <itoral@igalia.com>
Thu, 23 Mar 2017 10:56:06 +0000 (11:56 +0100)
committerIago Toral Quiroga <itoral@igalia.com>
Fri, 24 Mar 2017 07:11:53 +0000 (08:11 +0100)
We need to know if sample shading has been requested during shader
compilation since that affects the way fragment coordinates are
computed.

Notice that the semantics of fragment coordinates only depend on
whether sample shading has been requested, not on whether more
than one sample will actually be produced (that is,
minSampleShading and rasterizationSamples do not affect this
behavior).

Because this setting affects the code we generate for the shader, we also
need to include it in the WM prog key. Notice we don't need to alter the
OpenGL code because it doesn't ever use this behavior, so they key's
value is always false (the default).

Fixes:
dEQP-VK.glsl.builtin_var.fragcoord_msaa.*

Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/intel/compiler/brw_compiler.h
src/intel/vulkan/anv_pipeline.c
src/intel/vulkan/anv_private.h

index d4128bccbc17945698c3b8b2134fbcf126963610..922841381f2fc3f0e57bc47c9816dbeb8d13ad31 100644 (file)
@@ -292,6 +292,7 @@ struct brw_wm_prog_key {
    bool clamp_fragment_color:1;
    bool persample_interp:1;
    bool multisample_fbo:1;
+   bool frag_coord_adds_sample_pos:1;
    enum brw_wm_aa_enable line_aa:2;
    bool high_quality_derivatives:1;
    bool force_dual_color_blend:1;
index 8ad2d485360036aad944162812f7b76aecd881b4..9d0dc69fa8482b621fed406b73d52adcbdd6d6d5 100644 (file)
@@ -87,12 +87,14 @@ void anv_DestroyShaderModule(
  * we can't do that yet because we don't have the ability to copy nir.
  */
 static nir_shader *
-anv_shader_compile_to_nir(struct anv_device *device,
+anv_shader_compile_to_nir(struct anv_pipeline *pipeline,
                           struct anv_shader_module *module,
                           const char *entrypoint_name,
                           gl_shader_stage stage,
                           const VkSpecializationInfo *spec_info)
 {
+   const struct anv_device *device = pipeline->device;
+
    const struct brw_compiler *compiler =
       device->instance->physicalDevice.compiler;
    const nir_shader_compiler_options *nir_options =
@@ -158,7 +160,7 @@ anv_shader_compile_to_nir(struct anv_device *device,
               nir_var_shader_in | nir_var_shader_out | nir_var_system_value);
 
    if (stage == MESA_SHADER_FRAGMENT)
-      NIR_PASS_V(nir, nir_lower_wpos_center, false);
+      NIR_PASS_V(nir, nir_lower_wpos_center, pipeline->sample_shading_enable);
 
    /* Now that we've deleted all but the main function, we can go ahead and
     * lower the rest of the constant initializers.
@@ -304,14 +306,19 @@ populate_wm_prog_key(const struct anv_pipeline *pipeline,
                           info->pMultisampleState &&
                           info->pMultisampleState->alphaToCoverageEnable;
 
-   if (info->pMultisampleState && info->pMultisampleState->rasterizationSamples > 1) {
+   if (info->pMultisampleState) {
       /* We should probably pull this out of the shader, but it's fairly
        * harmless to compute it and then let dead-code take care of it.
        */
-      key->persample_interp =
-         (info->pMultisampleState->minSampleShading *
-          info->pMultisampleState->rasterizationSamples) > 1;
-      key->multisample_fbo = true;
+      if (info->pMultisampleState->rasterizationSamples > 1) {
+         key->persample_interp =
+            (info->pMultisampleState->minSampleShading *
+             info->pMultisampleState->rasterizationSamples) > 1;
+         key->multisample_fbo = true;
+      }
+
+      key->frag_coord_adds_sample_pos =
+         info->pMultisampleState->sampleShadingEnable;
    }
 }
 
@@ -333,7 +340,7 @@ anv_pipeline_compile(struct anv_pipeline *pipeline,
                      struct brw_stage_prog_data *prog_data,
                      struct anv_pipeline_bind_map *map)
 {
-   nir_shader *nir = anv_shader_compile_to_nir(pipeline->device,
+   nir_shader *nir = anv_shader_compile_to_nir(pipeline,
                                                module, entrypoint, stage,
                                                spec_info);
    if (nir == NULL)
@@ -1207,6 +1214,9 @@ anv_pipeline_init(struct anv_pipeline *pipeline,
    pipeline->depth_clamp_enable = pCreateInfo->pRasterizationState &&
                                   pCreateInfo->pRasterizationState->depthClampEnable;
 
+   pipeline->sample_shading_enable = pCreateInfo->pMultisampleState &&
+                                     pCreateInfo->pMultisampleState->sampleShadingEnable;
+
    pipeline->needs_data_cache = false;
 
    /* When we free the pipeline, we detect stages based on the NULL status
index 68f7359d71d8d669a74432b66adf4b21a13f05c8..27c887c65cc41e5111ba229e9a236ef29c0d36b5 100644 (file)
@@ -1633,6 +1633,7 @@ struct anv_pipeline {
    bool                                         writes_stencil;
    bool                                         stencil_test_enable;
    bool                                         depth_clamp_enable;
+   bool                                         sample_shading_enable;
    bool                                         kill_pixel;
 
    struct {