anv: force primitive shading rate write in last geometry stage
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Wed, 17 Feb 2021 12:39:08 +0000 (14:39 +0200)
committerMarge Bot <emma+marge@anholt.net>
Wed, 2 Feb 2022 17:09:46 +0000 (17:09 +0000)
v2: Use new helper to check if stage supports variable shading rate
    setting

v3: Update comment & iterate backward (Caio)
    Apply only to relevant platforms (Lionel)

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Caio Oliveira <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13739>

src/intel/vulkan/anv_pipeline.c

index 799f990..218981d 100644 (file)
@@ -1772,6 +1772,35 @@ anv_pipeline_compile_graphics(struct anv_graphics_pipeline *pipeline,
       prev_stage = &stages[s];
    }
 
+   /* In the case the platform can write the primitive variable shading rate,
+    * figure out the last geometry stage that should write the primitive
+    * shading rate, and ensure it is marked as used there. The backend will
+    * write a default value if the shader doesn't actually write it.
+    *
+    * We iterate backwards in the stage and stop on the first shader that can
+    * set the value.
+    */
+   const struct intel_device_info *devinfo = &pipeline->base.device->info;
+   if (devinfo->has_coarse_pixel_primitive_and_cb &&
+       stages[MESA_SHADER_FRAGMENT].entrypoint &&
+       stages[MESA_SHADER_FRAGMENT].key.wm.coarse_pixel) {
+      struct anv_pipeline_stage *last_psr = NULL;
+
+      for (unsigned i = 0; i < ARRAY_SIZE(shader_order); i++) {
+         gl_shader_stage s = shader_order[ARRAY_SIZE(shader_order) - i - 1];
+
+         if (!stages[s].entrypoint ||
+             !gl_shader_stage_can_set_fragment_shading_rate(s))
+            continue;
+
+         last_psr = &stages[s];
+         break;
+      }
+
+      assert(last_psr);
+      last_psr->nir->info.outputs_written |= VARYING_BIT_PRIMITIVE_SHADING_RATE;
+   }
+
    prev_stage = NULL;
    for (unsigned i = 0; i < ARRAY_SIZE(shader_order); i++) {
       gl_shader_stage s = shader_order[i];