Mesa (main): tu: Implement VK_EXT_pipeline_creation_feedback

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed May 18 13:40:14 UTC 2022


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

Author: Connor Abbott <cwabbott0 at gmail.com>
Date:   Mon May 16 19:11:42 2022 +0200

tu: Implement VK_EXT_pipeline_creation_feedback

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16562>

---

 docs/features.txt                  |  2 +-
 src/freedreno/vulkan/tu_device.c   |  1 +
 src/freedreno/vulkan/tu_pipeline.c | 86 +++++++++++++++++++++++++++++++++++---
 3 files changed, 83 insertions(+), 6 deletions(-)

diff --git a/docs/features.txt b/docs/features.txt
index f1a37815c19..7aad2e89948 100644
--- a/docs/features.txt
+++ b/docs/features.txt
@@ -485,7 +485,7 @@ Vulkan 1.3 -- all DONE: anv, radv, lvp
   VK_EXT_extended_dynamic_state2                        DONE (anv, lvp, radv, tu)
   VK_EXT_inline_uniform_block                           DONE (anv, radv, v3dv)
   VK_EXT_pipeline_creation_cache_control                DONE (anv, radv, v3dv)
-  VK_EXT_pipeline_creation_feedback                     DONE (anv, radv, v3dv)
+  VK_EXT_pipeline_creation_feedback                     DONE (anv, radv, tu, v3dv)
   VK_EXT_private_data                                   DONE (anv, lvp, radv, tu, v3dv)
   VK_EXT_image_robustness                               DONE (anv, radv, tu)
   VK_EXT_shader_demote_to_helper_invocation             DONE (anv, radv, tu)
diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c
index 018c85d3663..4e29c42aa60 100644
--- a/src/freedreno/vulkan/tu_device.c
+++ b/src/freedreno/vulkan/tu_device.c
@@ -216,6 +216,7 @@ get_device_extensions(const struct tu_physical_device *device,
       .EXT_image_robustness = true,
       .EXT_primitives_generated_query = true,
       .EXT_image_view_min_lod = true,
+      .EXT_pipeline_creation_feedback = true,
 #ifndef TU_USE_KGSL
       .EXT_physical_device_drm = true,
 #endif
diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c
index 294a9b2073c..3e22ebcabbb 100644
--- a/src/freedreno/vulkan/tu_pipeline.c
+++ b/src/freedreno/vulkan/tu_pipeline.c
@@ -2660,11 +2660,12 @@ tu_shaders_deserialize(struct vk_device *_device,
 
 static struct tu_compiled_shaders *
 tu_pipeline_cache_lookup(struct vk_pipeline_cache *cache,
-                         const void *key_data, size_t key_size)
+                         const void *key_data, size_t key_size,
+                         bool *application_cache_hit)
 {
    struct vk_pipeline_cache_object *object =
       vk_pipeline_cache_lookup_object(cache, key_data, key_size,
-                                      &tu_shaders_ops, NULL);
+                                      &tu_shaders_ops, application_cache_hit);
    if (object)
       return container_of(object, struct tu_compiled_shaders, base);
    else
@@ -2689,6 +2690,16 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder,
    const VkPipelineShaderStageCreateInfo *stage_infos[MESA_SHADER_STAGES] = {
       NULL
    };
+   VkPipelineCreationFeedbackEXT pipeline_feedback = {
+      .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
+   };
+   VkPipelineCreationFeedbackEXT stage_feedbacks[MESA_SHADER_STAGES] = { 0 };
+
+   int64_t pipeline_start = os_time_get_nano();
+
+   const VkPipelineCreationFeedbackCreateInfo *creation_feedback =
+      vk_find_struct_const(builder->create_info->pNext, PIPELINE_CREATION_FEEDBACK_CREATE_INFO);
+
    for (uint32_t i = 0; i < builder->create_info->stageCount; i++) {
       gl_shader_stage stage =
          vk_to_mesa_shader_stage(builder->create_info->pStages[i].stage);
@@ -2718,9 +2729,17 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder,
    struct tu_compiled_shaders *compiled_shaders;
 
    if (!executable_info) {
+      bool application_cache_hit = false;
+
       compiled_shaders =
          tu_pipeline_cache_lookup(builder->cache, &pipeline_sha1,
-                                  sizeof(pipeline_sha1));
+                                  sizeof(pipeline_sha1),
+                                  &application_cache_hit);
+
+      if (application_cache_hit && builder->cache != builder->device->mem_cache) {
+         pipeline_feedback.flags |=
+            VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT;
+      }
 
       if (compiled_shaders)
          goto done;
@@ -2736,11 +2755,16 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder,
       if (!stage_info)
          continue;
 
+      int64_t stage_start = os_time_get_nano();
+
       nir[stage] = tu_spirv_to_nir(builder->device, builder->mem_ctx, stage_info, stage);
       if (!nir[stage]) {
          result = VK_ERROR_OUT_OF_HOST_MEMORY;
          goto fail;
       }
+
+      stage_feedbacks[stage].flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT;
+      stage_feedbacks[stage].duration += os_time_get_nano() - stage_start;
    }
 
    if (!nir[MESA_SHADER_FRAGMENT]) {
@@ -2771,6 +2795,8 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder,
       if (!nir[stage])
          continue;
 
+      int64_t stage_start = os_time_get_nano();
+
       struct tu_shader *shader =
          tu_shader_create(builder->device, nir[stage], &keys[stage],
                           builder->layout, builder->alloc);
@@ -2802,6 +2828,8 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder,
       desc_sets |= shader->active_desc_sets;
 
       shaders[stage] = shader;
+
+      stage_feedbacks[stage].duration += os_time_get_nano() - stage_start;
    }
 
    struct tu_shader *last_shader = shaders[MESA_SHADER_GEOMETRY];
@@ -2832,6 +2860,8 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder,
       if (!shaders[stage])
          continue;
       
+      int64_t stage_start = os_time_get_nano();
+
       compiled_shaders->variants[stage] =
          ir3_shader_create_variant(shaders[stage]->ir3_shader, &ir3_key,
                                    executable_info);
@@ -2839,6 +2869,8 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder,
          return VK_ERROR_OUT_OF_HOST_MEMORY;
 
       compiled_shaders->push_consts[stage] = shaders[stage]->push_consts;
+
+      stage_feedbacks[stage].duration += os_time_get_nano() - stage_start;
    }
 
    uint32_t safe_constlens = ir3_trim_constlen(compiled_shaders->variants, compiler);
@@ -2851,6 +2883,8 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder,
          continue;
 
       if (safe_constlens & (1 << stage)) {
+         int64_t stage_start = os_time_get_nano();
+
          ralloc_free(compiled_shaders->variants[stage]);
          compiled_shaders->variants[stage] =
             ir3_shader_create_variant(shaders[stage]->ir3_shader, &ir3_key,
@@ -2859,6 +2893,8 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder,
             result = VK_ERROR_OUT_OF_HOST_MEMORY;
             goto fail;
          }
+
+         stage_feedbacks[stage].duration += os_time_get_nano() - stage_start;
       }
    }
 
@@ -2902,6 +2938,19 @@ done:
          compiled_shaders->variants[MESA_SHADER_TESS_CTRL]->key.tessellation;
    }
 
+   pipeline_feedback.duration = os_time_get_nano() - pipeline_start;
+   if (creation_feedback) {
+      *creation_feedback->pPipelineCreationFeedback = pipeline_feedback;
+
+      assert(builder->create_info->stageCount == 
+             creation_feedback->pipelineStageCreationFeedbackCount);
+      for (uint32_t i = 0; i < builder->create_info->stageCount; i++) {
+         gl_shader_stage s =
+            vk_to_mesa_shader_stage(builder->create_info->pStages[i].stage);
+         creation_feedback->pPipelineStageCreationFeedbacks[i] = stage_feedbacks[s];
+      }
+   }
+
    return VK_SUCCESS;
 
 fail:
@@ -3820,6 +3869,15 @@ tu_compute_pipeline_create(VkDevice device,
 
    *pPipeline = VK_NULL_HANDLE;
 
+   VkPipelineCreationFeedbackEXT pipeline_feedback = {
+      .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
+   };
+
+   const VkPipelineCreationFeedbackCreateInfo *creation_feedback =
+      vk_find_struct_const(pCreateInfo->pNext, PIPELINE_CREATION_FEEDBACK_CREATE_INFO);
+
+   int64_t pipeline_start = os_time_get_nano();
+
    pipeline = vk_object_zalloc(&dev->vk, pAllocator, sizeof(*pipeline),
                                VK_OBJECT_TYPE_PIPELINE);
    if (!pipeline)
@@ -3841,8 +3899,18 @@ tu_compute_pipeline_create(VkDevice device,
    const bool executable_info = pCreateInfo->flags &
       VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR;
 
-   if (!executable_info)
-      compiled = tu_pipeline_cache_lookup(cache, pipeline_sha1, sizeof(pipeline_sha1));
+   bool application_cache_hit = false;
+
+   if (!executable_info) {
+      compiled =
+         tu_pipeline_cache_lookup(cache, pipeline_sha1, sizeof(pipeline_sha1),
+                                  &application_cache_hit);
+   }
+
+   if (application_cache_hit && cache != dev->mem_cache) {
+      pipeline_feedback.flags |=
+         VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT;
+   }
 
    char *nir_initial_disasm = NULL;
 
@@ -3887,6 +3955,14 @@ tu_compute_pipeline_create(VkDevice device,
       compiled = tu_pipeline_cache_insert(cache, compiled);
    }
 
+   pipeline_feedback.duration = os_time_get_nano() - pipeline_start;
+
+   if (creation_feedback) {
+      *creation_feedback->pPipelineCreationFeedback = pipeline_feedback;
+      assert(creation_feedback->pipelineStageCreationFeedbackCount == 1);
+      creation_feedback->pPipelineStageCreationFeedbacks[0] = pipeline_feedback;
+   }
+
    pipeline->active_desc_sets = compiled->active_desc_sets;
 
    struct ir3_shader_variant *v = compiled->variants[MESA_SHADER_COMPUTE];



More information about the mesa-commit mailing list