anv: Work around the spec question about pipeline feedback vs GPL.
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Fri, 7 Apr 2023 00:14:25 +0000 (17:14 -0700)
committerMarge Bot <emma+marge@anholt.net>
Mon, 17 Apr 2023 22:43:38 +0000 (22:43 +0000)
This gives anv the same behavior as turnip in not asserting, and just not
filling out feedback for those stages.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Acked-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15637>

src/intel/ci/anv-tgl-fails.txt
src/intel/vulkan/anv_pipeline.c
src/intel/vulkan/anv_private.h

index 372cb3c..dfd323f 100644 (file)
@@ -63,14 +63,3 @@ dEQP-VK.dynamic_rendering.suballocation.load_store_op_none.stencil_d32_sfloat_s8
 
 # New CTS failures in 1.3.5.0
 dEQP-VK.drm_format_modifiers.export_import_fmt_features2.b4g4r4a4_unorm_pack16,Crash
-
-# Waiting on clarification from https://gitlab.khronos.org/vulkan/vulkan/-/issues/3115
-dEQP-VK.pipeline.pipeline_library.creation_feedback.graphics_tests.vertex_stage_geometry_stage_fragment_stage_delayed_destroy,Crash
-dEQP-VK.pipeline.pipeline_library.creation_feedback.graphics_tests.vertex_stage_fragment_stage,Crash
-dEQP-VK.pipeline.pipeline_library.creation_feedback.graphics_tests.vertex_stage_tessellation_control_stage_tessellation_evaluation_stage_fragment_stage_no_cache,Crash
-dEQP-VK.pipeline.pipeline_library.creation_feedback.graphics_tests.vertex_stage_geometry_stage_fragment_stage,Crash
-dEQP-VK.pipeline.pipeline_library.creation_feedback.graphics_tests.vertex_stage_tessellation_control_stage_tessellation_evaluation_stage_fragment_stage_delayed_destroy,Crash
-dEQP-VK.pipeline.pipeline_library.creation_feedback.graphics_tests.vertex_stage_fragment_stage_delayed_destroy,Crash
-dEQP-VK.pipeline.pipeline_library.creation_feedback.graphics_tests.vertex_stage_geometry_stage_fragment_stage_no_cache,Crash
-dEQP-VK.pipeline.pipeline_library.creation_feedback.graphics_tests.vertex_stage_fragment_stage_no_cache,Crash
-dEQP-VK.pipeline.pipeline_library.creation_feedback.graphics_tests.vertex_stage_tessellation_control_stage_tessellation_evaluation_stage_fragment_stage,Crash
index d30a933..5834e97 100644 (file)
@@ -676,6 +676,7 @@ struct anv_pipeline_stage {
    char *disasm[3];
 
    VkPipelineCreationFeedback feedback;
+   uint32_t feedback_idx;
 
    const unsigned *code;
 
@@ -1887,7 +1888,8 @@ anv_pipeline_nir_preprocess(struct anv_pipeline *pipeline, nir_shader *nir)
 }
 
 static void
-anv_fill_pipeline_creation_feedback(VkPipelineCreationFeedbackEXT *pipeline_feedback,
+anv_fill_pipeline_creation_feedback(const struct anv_graphics_base_pipeline *pipeline,
+                                    VkPipelineCreationFeedbackEXT *pipeline_feedback,
                                     const VkGraphicsPipelineCreateInfo *info,
                                     struct anv_pipeline_stage *stages)
 {
@@ -1896,15 +1898,46 @@ anv_fill_pipeline_creation_feedback(VkPipelineCreationFeedbackEXT *pipeline_feed
    if (create_feedback) {
       *create_feedback->pPipelineCreationFeedback = *pipeline_feedback;
 
-      uint32_t stage_count = create_feedback->pipelineStageCreationFeedbackCount;
-      assert(stage_count == 0 || info->stageCount == stage_count);
-      for (uint32_t i = 0; i < stage_count; i++) {
-         gl_shader_stage s = vk_to_mesa_shader_stage(info->pStages[i].stage);
-         create_feedback->pPipelineStageCreationFeedbacks[i] = stages[s].feedback;
+      /* VkPipelineCreationFeedbackCreateInfo:
+       *
+       *    "An implementation must set or clear the
+       *     VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT in
+       *     VkPipelineCreationFeedback::flags for pPipelineCreationFeedback
+       *     and every element of pPipelineStageCreationFeedbacks."
+       *
+       */
+      for (uint32_t i = 0; i < create_feedback->pipelineStageCreationFeedbackCount; i++) {
+         create_feedback->pPipelineStageCreationFeedbacks[i].flags &=
+            ~VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT;
+      }
+      /* This part is not really specified in the Vulkan spec at the moment.
+       * We're kind of guessing what the CTS wants. We might need to update
+       * when https://gitlab.khronos.org/vulkan/vulkan/-/issues/3115 is
+       * clarified.
+       */
+      for (uint32_t s = 0; s < ANV_GRAPHICS_SHADER_STAGE_COUNT; s++) {
+         if (!anv_pipeline_base_has_stage(pipeline, s))
+            continue;
+
+         if (stages[s].feedback_idx < create_feedback->pipelineStageCreationFeedbackCount) {
+            create_feedback->pPipelineStageCreationFeedbacks[
+               stages[s].feedback_idx] = stages[s].feedback;
+         }
       }
    }
 }
 
+static uint32_t
+anv_graphics_pipeline_imported_shader_count(struct anv_pipeline_stage *stages)
+{
+   uint32_t count = 0;
+   for (uint32_t s = 0; s < ANV_GRAPHICS_SHADER_STAGE_COUNT; s++) {
+      if (stages[s].imported.bin != NULL)
+         count++;
+   }
+   return count;
+}
+
 static VkResult
 anv_graphics_pipeline_compile(struct anv_graphics_base_pipeline *pipeline,
                               struct anv_pipeline_stage *stages,
@@ -1923,6 +1956,7 @@ anv_graphics_pipeline_compile(struct anv_graphics_base_pipeline *pipeline,
     * Other shaders imported from libraries should have been added by
     * anv_graphics_pipeline_import_lib().
     */
+   uint32_t shader_count = anv_graphics_pipeline_imported_shader_count(stages);
    for (uint32_t i = 0; i < info->stageCount; i++) {
       gl_shader_stage stage = vk_to_mesa_shader_stage(info->pStages[i].stage);
 
@@ -1934,6 +1968,7 @@ anv_graphics_pipeline_compile(struct anv_graphics_base_pipeline *pipeline,
 
       stages[stage].stage = stage;
       stages[stage].info = &info->pStages[i];
+      stages[stage].feedback_idx = shader_count++;
 
       vk_pipeline_hash_shader_stage(stages[stage].info, NULL, stages[stage].shader_sha1);
    }
@@ -2299,9 +2334,16 @@ anv_graphics_pipeline_compile(struct anv_graphics_base_pipeline *pipeline,
 
 done:
 
-   pipeline_feedback->duration = os_time_get_nano() - pipeline_start;
+   /* Write the feedback index into the pipeline */
+   for (unsigned s = 0; s < ARRAY_SIZE(pipeline->shaders); s++) {
+      if (!anv_pipeline_base_has_stage(pipeline, s))
+         continue;
 
-   anv_fill_pipeline_creation_feedback(pipeline_feedback, info, stages);
+      struct anv_pipeline_stage *stage = &stages[s];
+      pipeline->feedback_index[s] = stage->feedback_idx;
+   }
+
+   pipeline_feedback->duration = os_time_get_nano() - pipeline_start;
 
    if (pipeline->shaders[MESA_SHADER_FRAGMENT]) {
       pipeline->fragment_dynamic =
@@ -2738,11 +2780,13 @@ anv_graphics_pipeline_import_lib(struct anv_graphics_base_pipeline *pipeline,
       }
    }
 
+   uint32_t shader_count = anv_graphics_pipeline_imported_shader_count(stages);
    for (uint32_t s = 0; s < ARRAY_SIZE(lib->base.shaders); s++) {
       if (lib->base.shaders[s] == NULL)
          continue;
 
       stages[s].stage = s;
+      stages[s].feedback_idx = shader_count + lib->base.feedback_index[s];
 
       /* Always import the shader sha1, this will be used for cache lookup. */
       memcpy(stages[s].shader_sha1, lib->retained_shaders[s].shader_sha1,
@@ -2866,7 +2910,8 @@ anv_graphics_lib_pipeline_create(struct anv_device *device,
 
    pipeline_feedback.duration = os_time_get_nano() - pipeline_start;
 
-   anv_fill_pipeline_creation_feedback(&pipeline_feedback, pCreateInfo, stages);
+   anv_fill_pipeline_creation_feedback(&pipeline->base, &pipeline_feedback,
+                                       pCreateInfo, stages);
 
    anv_graphics_lib_validate_shaders(pipeline,
                                      pCreateInfo->flags & VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT);
@@ -3004,7 +3049,8 @@ anv_graphics_pipeline_create(struct anv_device *device,
 
    pipeline_feedback.duration = os_time_get_nano() - pipeline_start;
 
-   anv_fill_pipeline_creation_feedback(&pipeline_feedback, pCreateInfo, stages);
+   anv_fill_pipeline_creation_feedback(&pipeline->base, &pipeline_feedback,
+                                       pCreateInfo, stages);
 
    *pPipeline = anv_pipeline_to_handle(&pipeline->base.base);
 
index 6a3697e..ce2f006 100644 (file)
@@ -3210,6 +3210,14 @@ struct anv_graphics_base_pipeline {
    /* Shaders */
    struct anv_shader_bin *                      shaders[ANV_GRAPHICS_SHADER_STAGE_COUNT];
 
+   /* Feedback index in
+    * VkPipelineCreationFeedbackCreateInfo::pPipelineStageCreationFeedbacks
+    *
+    * For pipeline libraries, we need to remember the order at creation when
+    * included into a linked pipeline.
+    */
+   uint32_t                                     feedback_index[ANV_GRAPHICS_SHADER_STAGE_COUNT];
+
    VkShaderStageFlags                           active_stages;
 
    /* True if at the time the fragment shader was compiled, it didn't have all