summaryrefslogtreecommitdiffstats
path: root/src/intel/vulkan/anv_pipeline.c
diff options
context:
space:
mode:
authorLionel Landwerlin <[email protected]>2019-03-19 15:23:37 +0000
committerLionel Landwerlin <[email protected]>2019-03-20 16:18:35 +0000
commit6601e5d6fc68cd9f8305508c650289170fef71ff (patch)
treeffab8fd33ffe023b916622d75bf15f0764630b63 /src/intel/vulkan/anv_pipeline.c
parent70904eb99ae0c31c7cca8edeec9ba1c6353e4218 (diff)
anv: implement VK_EXT_pipeline_creation_feedback
An extension reporting cache hit in the user supplied pipeline cache as well as timing information for creating the pipelines & stages. v2: Don't consider no cache for cache hits (Jason) Rework duration accumulation (Jason) v3: Fold feedback creation writing into pipeline compile functions (Jason/Lionel) v4: Get cache hit information from anv_device_search_for_kernel() (Jason) Only set cache hit from the whole pipeline if all stages also have that bit (Lionel) v5: Always user_cache_hit in anv_device_search_for_kernel() (Jason) Signed-off-by: Lionel Landwerlin <[email protected]> Reviewed-by: Jason Ekstrand <[email protected]>
Diffstat (limited to 'src/intel/vulkan/anv_pipeline.c')
-rw-r--r--src/intel/vulkan/anv_pipeline.c87
1 files changed, 84 insertions, 3 deletions
diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c
index 53500fd65d8..e9319f5efef 100644
--- a/src/intel/vulkan/anv_pipeline.c
+++ b/src/intel/vulkan/anv_pipeline.c
@@ -28,6 +28,7 @@
#include <fcntl.h>
#include "util/mesa-sha1.h"
+#include "util/os_time.h"
#include "common/gen_l3_config.h"
#include "anv_private.h"
#include "compiler/brw_nir.h"
@@ -421,6 +422,8 @@ struct anv_pipeline_stage {
struct anv_pipeline_bind_map bind_map;
union brw_any_prog_data prog_data;
+
+ VkPipelineCreationFeedbackEXT feedback;
};
static void
@@ -906,6 +909,11 @@ anv_pipeline_compile_graphics(struct anv_pipeline *pipeline,
struct anv_pipeline_cache *cache,
const VkGraphicsPipelineCreateInfo *info)
{
+ VkPipelineCreationFeedbackEXT pipeline_feedback = {
+ .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT,
+ };
+ int64_t pipeline_start = os_time_get_nano();
+
const struct brw_compiler *compiler =
pipeline->device->instance->physicalDevice.compiler;
struct anv_pipeline_stage stages[MESA_SHADER_STAGES] = {};
@@ -919,6 +927,8 @@ anv_pipeline_compile_graphics(struct anv_pipeline *pipeline,
pipeline->active_stages |= sinfo->stage;
+ int64_t stage_start = os_time_get_nano();
+
stages[stage].stage = stage;
stages[stage].module = anv_shader_module_from_handle(sinfo->module);
stages[stage].entrypoint = sinfo->pName;
@@ -953,6 +963,9 @@ anv_pipeline_compile_graphics(struct anv_pipeline *pipeline,
default:
unreachable("Invalid graphics shader stage");
}
+
+ stages[stage].feedback.duration += os_time_get_nano() - stage_start;
+ stages[stage].feedback.flags |= VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT;
}
if (pipeline->active_stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
@@ -966,24 +979,39 @@ anv_pipeline_compile_graphics(struct anv_pipeline *pipeline,
anv_pipeline_hash_graphics(pipeline, layout, stages, sha1);
unsigned found = 0;
+ unsigned cache_hits = 0;
for (unsigned s = 0; s < MESA_SHADER_STAGES; s++) {
if (!stages[s].entrypoint)
continue;
+ int64_t stage_start = os_time_get_nano();
+
stages[s].cache_key.stage = s;
memcpy(stages[s].cache_key.sha1, sha1, sizeof(sha1));
+ bool cache_hit;
struct anv_shader_bin *bin =
anv_device_search_for_kernel(pipeline->device, cache,
&stages[s].cache_key,
- sizeof(stages[s].cache_key));
+ sizeof(stages[s].cache_key), &cache_hit);
if (bin) {
found++;
pipeline->shaders[s] = bin;
}
+
+ if (cache_hit) {
+ cache_hits++;
+ stages[s].feedback.flags |=
+ VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT;
+ }
+ stages[s].feedback.duration += os_time_get_nano() - stage_start;
}
if (found == __builtin_popcount(pipeline->active_stages)) {
+ if (cache_hits == found) {
+ pipeline_feedback.flags |=
+ VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT;
+ }
/* We found all our shaders in the cache. We're done. */
goto done;
} else if (found > 0) {
@@ -1008,6 +1036,7 @@ anv_pipeline_compile_graphics(struct anv_pipeline *pipeline,
* cache again as part of the compilation process.
*/
for (unsigned s = 0; s < MESA_SHADER_STAGES; s++) {
+ stages[s].feedback.flags = 0;
if (pipeline->shaders[s]) {
anv_shader_bin_unref(pipeline->device, pipeline->shaders[s]);
pipeline->shaders[s] = NULL;
@@ -1021,6 +1050,8 @@ anv_pipeline_compile_graphics(struct anv_pipeline *pipeline,
if (!stages[s].entrypoint)
continue;
+ int64_t stage_start = os_time_get_nano();
+
assert(stages[s].stage == s);
assert(pipeline->shaders[s] == NULL);
@@ -1036,6 +1067,8 @@ anv_pipeline_compile_graphics(struct anv_pipeline *pipeline,
result = vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
goto fail;
}
+
+ stages[s].feedback.duration += os_time_get_nano() - stage_start;
}
/* Walk backwards to link */
@@ -1072,6 +1105,8 @@ anv_pipeline_compile_graphics(struct anv_pipeline *pipeline,
if (!stages[s].entrypoint)
continue;
+ int64_t stage_start = os_time_get_nano();
+
void *stage_ctx = ralloc_context(NULL);
nir_xfb_info *xfb_info = NULL;
@@ -1132,6 +1167,8 @@ anv_pipeline_compile_graphics(struct anv_pipeline *pipeline,
pipeline->shaders[s] = bin;
ralloc_free(stage_ctx);
+ stages[s].feedback.duration += os_time_get_nano() - stage_start;
+
prev_stage = &stages[s];
}
@@ -1150,6 +1187,20 @@ done:
pipeline->active_stages &= ~VK_SHADER_STAGE_FRAGMENT_BIT;
}
+ pipeline_feedback.duration = os_time_get_nano() - pipeline_start;
+
+ const VkPipelineCreationFeedbackCreateInfoEXT *create_feedback =
+ vk_find_struct_const(info->pNext, PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT);
+ if (create_feedback) {
+ *create_feedback->pPipelineCreationFeedback = pipeline_feedback;
+
+ assert(info->stageCount == create_feedback->pipelineStageCreationFeedbackCount);
+ for (uint32_t i = 0; i < info->stageCount; i++) {
+ gl_shader_stage s = vk_to_mesa_shader_stage(info->pStages[i].stage);
+ create_feedback->pPipelineStageCreationFeedbacks[i] = stages[s].feedback;
+ }
+ }
+
return VK_SUCCESS;
fail:
@@ -1171,6 +1222,11 @@ anv_pipeline_compile_cs(struct anv_pipeline *pipeline,
const char *entrypoint,
const VkSpecializationInfo *spec_info)
{
+ VkPipelineCreationFeedbackEXT pipeline_feedback = {
+ .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT,
+ };
+ int64_t pipeline_start = os_time_get_nano();
+
const struct brw_compiler *compiler =
pipeline->device->instance->physicalDevice.compiler;
@@ -1181,7 +1237,10 @@ anv_pipeline_compile_cs(struct anv_pipeline *pipeline,
.spec_info = spec_info,
.cache_key = {
.stage = MESA_SHADER_COMPUTE,
- }
+ },
+ .feedback = {
+ .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT,
+ },
};
anv_pipeline_hash_shader(stage.module,
stage.entrypoint,
@@ -1196,10 +1255,13 @@ anv_pipeline_compile_cs(struct anv_pipeline *pipeline,
ANV_FROM_HANDLE(anv_pipeline_layout, layout, info->layout);
anv_pipeline_hash_compute(pipeline, layout, &stage, stage.cache_key.sha1);
+ bool cache_hit;
bin = anv_device_search_for_kernel(pipeline->device, cache, &stage.cache_key,
- sizeof(stage.cache_key));
+ sizeof(stage.cache_key), &cache_hit);
if (bin == NULL) {
+ int64_t stage_start = os_time_get_nano();
+
stage.bind_map = (struct anv_pipeline_bind_map) {
.surface_to_descriptor = stage.surface_to_descriptor,
.sampler_to_descriptor = stage.sampler_to_descriptor
@@ -1247,6 +1309,25 @@ anv_pipeline_compile_cs(struct anv_pipeline *pipeline,
}
ralloc_free(mem_ctx);
+
+ stage.feedback.duration = os_time_get_nano() - stage_start;
+ }
+
+ if (cache_hit) {
+ stage.feedback.flags |=
+ VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT;
+ pipeline_feedback.flags |=
+ VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT;
+ }
+ pipeline_feedback.duration = os_time_get_nano() - pipeline_start;
+
+ const VkPipelineCreationFeedbackCreateInfoEXT *create_feedback =
+ vk_find_struct_const(info->pNext, PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT);
+ if (create_feedback) {
+ *create_feedback->pPipelineCreationFeedback = pipeline_feedback;
+
+ assert(create_feedback->pipelineStageCreationFeedbackCount == 1);
+ create_feedback->pPipelineStageCreationFeedbacks[0] = stage.feedback;
}
pipeline->active_stages = VK_SHADER_STAGE_COMPUTE_BIT;