Merge pull request #6759 from ReinUsesLisp/pipeline-statistics
renderer_vulkan: Add setting to log pipeline statisticsmaster
commit
7530594602
@ -0,0 +1,100 @@
|
|||||||
|
// Copyright 2021 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "video_core/renderer_vulkan/pipeline_statistics.h"
|
||||||
|
#include "video_core/vulkan_common/vulkan_device.h"
|
||||||
|
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||||
|
|
||||||
|
namespace Vulkan {
|
||||||
|
|
||||||
|
using namespace std::string_view_literals;
|
||||||
|
|
||||||
|
static u64 GetUint64(const VkPipelineExecutableStatisticKHR& statistic) {
|
||||||
|
switch (statistic.format) {
|
||||||
|
case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_INT64_KHR:
|
||||||
|
return static_cast<u64>(statistic.value.i64);
|
||||||
|
case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR:
|
||||||
|
return statistic.value.u64;
|
||||||
|
case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR:
|
||||||
|
return static_cast<u64>(statistic.value.f64);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PipelineStatistics::PipelineStatistics(const Device& device_) : device{device_} {}
|
||||||
|
|
||||||
|
void PipelineStatistics::Collect(VkPipeline pipeline) {
|
||||||
|
const auto& dev{device.GetLogical()};
|
||||||
|
const std::vector properties{dev.GetPipelineExecutablePropertiesKHR(pipeline)};
|
||||||
|
const u32 num_executables{static_cast<u32>(properties.size())};
|
||||||
|
for (u32 executable = 0; executable < num_executables; ++executable) {
|
||||||
|
const auto statistics{dev.GetPipelineExecutableStatisticsKHR(pipeline, executable)};
|
||||||
|
if (statistics.empty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Stats stage_stats;
|
||||||
|
for (const auto& statistic : statistics) {
|
||||||
|
const char* const name{statistic.name};
|
||||||
|
if (name == "Binary Size"sv || name == "Code size"sv || name == "Instruction Count"sv) {
|
||||||
|
stage_stats.code_size = GetUint64(statistic);
|
||||||
|
} else if (name == "Register Count"sv) {
|
||||||
|
stage_stats.register_count = GetUint64(statistic);
|
||||||
|
} else if (name == "SGPRs"sv || name == "numUsedSgprs"sv) {
|
||||||
|
stage_stats.sgpr_count = GetUint64(statistic);
|
||||||
|
} else if (name == "VGPRs"sv || name == "numUsedVgprs"sv) {
|
||||||
|
stage_stats.vgpr_count = GetUint64(statistic);
|
||||||
|
} else if (name == "Branches"sv) {
|
||||||
|
stage_stats.branches_count = GetUint64(statistic);
|
||||||
|
} else if (name == "Basic Block Count"sv) {
|
||||||
|
stage_stats.basic_block_count = GetUint64(statistic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::lock_guard lock{mutex};
|
||||||
|
collected_stats.push_back(stage_stats);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipelineStatistics::Report() const {
|
||||||
|
double num{};
|
||||||
|
Stats total;
|
||||||
|
{
|
||||||
|
std::lock_guard lock{mutex};
|
||||||
|
for (const Stats& stats : collected_stats) {
|
||||||
|
total.code_size += stats.code_size;
|
||||||
|
total.register_count += stats.register_count;
|
||||||
|
total.sgpr_count += stats.sgpr_count;
|
||||||
|
total.vgpr_count += stats.vgpr_count;
|
||||||
|
total.branches_count += stats.branches_count;
|
||||||
|
total.basic_block_count += stats.basic_block_count;
|
||||||
|
}
|
||||||
|
num = static_cast<double>(collected_stats.size());
|
||||||
|
}
|
||||||
|
std::string report;
|
||||||
|
const auto add = [&](const char* fmt, u64 value) {
|
||||||
|
if (value > 0) {
|
||||||
|
report += fmt::format(fmt::runtime(fmt), static_cast<double>(value) / num);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
add("Code size: {:9.03f}\n", total.code_size);
|
||||||
|
add("Register count: {:9.03f}\n", total.register_count);
|
||||||
|
add("SGPRs: {:9.03f}\n", total.sgpr_count);
|
||||||
|
add("VGPRs: {:9.03f}\n", total.vgpr_count);
|
||||||
|
add("Branches count: {:9.03f}\n", total.branches_count);
|
||||||
|
add("Basic blocks: {:9.03f}\n", total.basic_block_count);
|
||||||
|
|
||||||
|
LOG_INFO(Render_Vulkan,
|
||||||
|
"\nAverage pipeline statistics\n"
|
||||||
|
"==========================================\n"
|
||||||
|
"{}\n",
|
||||||
|
report);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Vulkan
|
@ -0,0 +1,40 @@
|
|||||||
|
// Copyright 2021 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||||
|
|
||||||
|
namespace Vulkan {
|
||||||
|
|
||||||
|
class Device;
|
||||||
|
|
||||||
|
class PipelineStatistics {
|
||||||
|
public:
|
||||||
|
explicit PipelineStatistics(const Device& device_);
|
||||||
|
|
||||||
|
void Collect(VkPipeline pipeline);
|
||||||
|
|
||||||
|
void Report() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Stats {
|
||||||
|
u64 code_size{};
|
||||||
|
u64 register_count{};
|
||||||
|
u64 sgpr_count{};
|
||||||
|
u64 vgpr_count{};
|
||||||
|
u64 branches_count{};
|
||||||
|
u64 basic_block_count{};
|
||||||
|
};
|
||||||
|
|
||||||
|
const Device& device;
|
||||||
|
mutable std::mutex mutex;
|
||||||
|
std::vector<Stats> collected_stats;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Vulkan
|
Loading…
Reference in New Issue