Module: Mesa
Branch: main
Commit: 2d4fbb3025ee6c3603f7d3d6a133b2db732a9dad
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=2d4fbb3025ee6c3603f7d3d6a133b2db732a9dad

Author: Lionel Landwerlin <[email protected]>
Date:   Thu Apr  6 17:14:25 2023 -0700

anv: Work around the spec question about pipeline feedback vs GPL.

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 <[email protected]>
Acked-by: Emma Anholt <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15637>

---

 src/intel/ci/anv-tgl-fails.txt  | 11 -------
 src/intel/vulkan/anv_pipeline.c | 66 ++++++++++++++++++++++++++++++++++-------
 src/intel/vulkan/anv_private.h  |  8 +++++
 3 files changed, 64 insertions(+), 21 deletions(-)

diff --git a/src/intel/ci/anv-tgl-fails.txt b/src/intel/ci/anv-tgl-fails.txt
index 372cb3cc98d..dfd323f8621 100644
--- a/src/intel/ci/anv-tgl-fails.txt
+++ b/src/intel/ci/anv-tgl-fails.txt
@@ -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
diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c
index d30a933fdc6..5834e978fae 100644
--- a/src/intel/vulkan/anv_pipeline.c
+++ b/src/intel/vulkan/anv_pipeline.c
@@ -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);
 
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 6a3697e6a02..ce2f0062497 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -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

Reply via email to