+
+VkResult
+radv_dump_shader_stats(struct radv_device *device,
+ struct radv_pipeline *pipeline,
+ gl_shader_stage stage, FILE *output)
+{
+ struct radv_shader_variant *shader = pipeline->shaders[stage];
+ VkPipelineExecutablePropertiesKHR *props = NULL;
+ uint32_t prop_count = 0;
+ VkResult result;
+
+ VkPipelineInfoKHR pipeline_info = {};
+ pipeline_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR;
+ pipeline_info.pipeline = radv_pipeline_to_handle(pipeline);
+
+ result = radv_GetPipelineExecutablePropertiesKHR(radv_device_to_handle(device),
+ &pipeline_info,
+ &prop_count, NULL);
+ if (result != VK_SUCCESS)
+ return result;
+
+ props = calloc(prop_count, sizeof(*props));
+ if (!props)
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+
+ result = radv_GetPipelineExecutablePropertiesKHR(radv_device_to_handle(device),
+ &pipeline_info,
+ &prop_count, props);
+ if (result != VK_SUCCESS)
+ goto fail;
+
+ for (unsigned i = 0; i < prop_count; i++) {
+ if (!(props[i].stages & mesa_to_vk_shader_stage(stage)))
+ continue;
+
+ VkPipelineExecutableStatisticKHR *stats = NULL;
+ uint32_t stat_count = 0;
+ VkResult result;
+
+ VkPipelineExecutableInfoKHR exec_info = {};
+ exec_info.pipeline = radv_pipeline_to_handle(pipeline);
+ exec_info.executableIndex = i;
+
+ result = radv_GetPipelineExecutableStatisticsKHR(radv_device_to_handle(device),
+ &exec_info,
+ &stat_count, NULL);
+ if (result != VK_SUCCESS)
+ goto fail;
+
+ stats = calloc(stat_count, sizeof(*stats));
+ if (!stats) {
+ result = VK_ERROR_OUT_OF_HOST_MEMORY;
+ goto fail;
+ }
+
+ result = radv_GetPipelineExecutableStatisticsKHR(radv_device_to_handle(device),
+ &exec_info,
+ &stat_count, stats);
+ if (result != VK_SUCCESS) {
+ free(stats);
+ goto fail;
+ }
+
+ fprintf(output, "\n%s:\n",
+ radv_get_shader_name(&shader->info, stage));
+ fprintf(output, "*** SHADER STATS ***\n");
+
+ for (unsigned i = 0; i < stat_count; i++) {
+ fprintf(output, "%s: ", stats[i].name);
+ switch (stats[i].format) {
+ case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR:
+ fprintf(output, "%s", stats[i].value.b32 == VK_TRUE ? "true" : "false");
+ break;
+ case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_INT64_KHR:
+ fprintf(output, "%"PRIi64, stats[i].value.i64);
+ break;
+ case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR:
+ fprintf(output, "%"PRIu64, stats[i].value.u64);
+ break;
+ case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR:
+ fprintf(output, "%f", stats[i].value.f64);
+ break;
+ default:
+ unreachable("Invalid pipeline statistic format");
+ }
+ fprintf(output, "\n");
+ }
+
+ fprintf(output, "********************\n\n\n");
+
+ free(stats);
+ }
+
+fail:
+ free(props);
+ return result;
+}