CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Common/GPU/Vulkan/VulkanProfiler.cpp
Views: 1401
#include <stdarg.h>12#include "VulkanProfiler.h"3#include "VulkanContext.h"45using namespace PPSSPP_VK;67void VulkanProfiler::Init(VulkanContext *vulkan) {8vulkan_ = vulkan;910int graphicsQueueFamilyIndex = vulkan_->GetGraphicsQueueFamilyIndex();11_assert_(graphicsQueueFamilyIndex >= 0);1213if (queryPool_) {14vulkan->Delete().QueueDeleteQueryPool(queryPool_);15}1617validBits_ = vulkan_->GetQueueFamilyProperties(graphicsQueueFamilyIndex).timestampValidBits;1819if (validBits_) {20VkQueryPoolCreateInfo ci{ VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO };21ci.queryCount = MAX_QUERY_COUNT;22ci.queryType = VK_QUERY_TYPE_TIMESTAMP;23vkCreateQueryPool(vulkan->GetDevice(), &ci, nullptr, &queryPool_);24}25}2627void VulkanProfiler::Shutdown() {28if (queryPool_) {29vulkan_->Delete().QueueDeleteQueryPool(queryPool_);30}31}3233void VulkanProfiler::BeginFrame(VulkanContext *vulkan, VkCommandBuffer firstCommandBuf) {34if (!validBits_) {35return;36}3738vulkan_ = vulkan;3940// Check for old queries belonging to this frame context that we can log out - these are now41// guaranteed to be done.42if (numQueries_ > 0) {43std::vector<uint64_t> results(numQueries_);44vkGetQueryPoolResults(vulkan->GetDevice(), queryPool_, 0, numQueries_, sizeof(uint64_t) * numQueries_, results.data(), sizeof(uint64_t), VK_QUERY_RESULT_64_BIT);4546double timestampConversionFactor = (double)vulkan_->GetPhysicalDeviceProperties().properties.limits.timestampPeriod * (1.0 / 1000000.0);47uint64_t timestampDiffMask = validBits_ == 64 ? 0xFFFFFFFFFFFFFFFFULL : ((1ULL << validBits_) - 1);4849static const char * const indent[4] = { "", " ", " ", " " };5051if (!scopes_.empty()) {52INFO_LOG(Log::G3D, "Profiling events this frame:");53}5455// Log it all out.56for (auto &scope : scopes_) {57if (scope.endQueryId == -1) {58WARN_LOG(Log::G3D, "Unclosed scope: %s", scope.name);59continue;60}61uint64_t startTime = results[scope.startQueryId];62uint64_t endTime = results[scope.endQueryId];6364uint64_t delta = (endTime - startTime) & timestampDiffMask;6566double milliseconds = (double)delta * timestampConversionFactor;6768INFO_LOG(Log::G3D, "%s%s (%0.3f ms)", indent[scope.level & 3], scope.name, milliseconds);69}7071scopes_.clear();72scopeStack_.clear();73}7475// Only need to reset all on the first frame.76if (firstFrame_) {77numQueries_ = MAX_QUERY_COUNT;78firstFrame_ = false;79}80if (numQueries_ > 0) {81vkCmdResetQueryPool(firstCommandBuf, queryPool_, 0, numQueries_);82}83numQueries_ = 0;84}8586void VulkanProfiler::Begin(VkCommandBuffer cmdBuf, VkPipelineStageFlagBits stageFlags, const char *fmt, ...) {87if (!validBits_ || (enabledPtr_ && !*enabledPtr_) || numQueries_ >= MAX_QUERY_COUNT - 1) {88return;89}9091ProfilerScope scope;92va_list args;93va_start(args, fmt);94vsnprintf(scope.name, sizeof(scope.name), fmt, args);95va_end(args);96scope.startQueryId = numQueries_;97scope.endQueryId = -1;98scope.level = (int)scopeStack_.size();99100scopeStack_.push_back(scopes_.size());101scopes_.push_back(scope);102103vkCmdWriteTimestamp(cmdBuf, stageFlags, queryPool_, numQueries_);104numQueries_++;105}106107void VulkanProfiler::End(VkCommandBuffer cmdBuf, VkPipelineStageFlagBits stageFlags) {108if (!validBits_ || (enabledPtr_ && !*enabledPtr_) || numQueries_ >= MAX_QUERY_COUNT - 1) {109return;110}111112size_t scopeId = scopeStack_.back();113scopeStack_.pop_back();114115ProfilerScope &scope = scopes_[scopeId];116scope.endQueryId = numQueries_;117118vkCmdWriteTimestamp(cmdBuf, stageFlags, queryPool_, numQueries_);119numQueries_++;120}121122123