Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vulkan: Further improvements to GPU profiling #12266

Merged
merged 2 commits into from
Aug 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions GPU/Vulkan/DebugVisVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ void DrawProfilerVis(UIContext *ui, GPUInterface *gpu) {
std::string text = gpuVulkan->GetGpuProfileString();

Draw::DrawContext *draw = ui->GetDrawContext();
ui->SetFontScale(0.4f, 0.4f);
ui->DrawTextShadow(text.c_str(), 10, 50, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII);
ui->Flush();
}
40 changes: 39 additions & 1 deletion ext/native/thin3d/VulkanQueueRunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ VkRenderPass VulkanQueueRunner::GetRenderPass(const RPKey &key) {
return pass;
}

void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector<VKRStep *> &steps) {
void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector<VKRStep *> &steps, VkQueryPool queryPool, std::vector<std::string> *timestampDescriptions) {
// Optimizes renderpasses, then sequences them.
// Planned optimizations:
// * Create copies of render target that are rendered to multiple times and textured from in sequence, and push those render passes
Expand Down Expand Up @@ -461,6 +461,11 @@ void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector<VKRStep *> &st
case VKRStepType::RENDER_SKIP:
break;
}

if (queryPool) {
vkCmdWriteTimestamp(cmd, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, queryPool, (uint32_t)timestampDescriptions->size());
timestampDescriptions->push_back(StepToString(step));
}
}

// Deleting all in one go should be easier on the instruction cache than deleting
Expand Down Expand Up @@ -695,10 +700,43 @@ void VulkanQueueRunner::ApplySonicHack(std::vector<VKRStep *> &steps) {
}
}

std::string VulkanQueueRunner::StepToString(const VKRStep &step) const {
char buffer[256];
switch (step.stepType) {
case VKRStepType::RENDER:
{
int w = step.render.framebuffer ? step.render.framebuffer->width : vulkan_->GetBackbufferWidth();
int h = step.render.framebuffer ? step.render.framebuffer->height : vulkan_->GetBackbufferHeight();
snprintf(buffer, sizeof(buffer), "RenderPass (draws: %d, %dx%d, fb: %p, )", step.render.numDraws, w, h, step.render.framebuffer);
break;
}
case VKRStepType::COPY:
snprintf(buffer, sizeof(buffer), "Copy (%dx%d)", step.copy.srcRect.extent.width, step.copy.srcRect.extent.height);
break;
case VKRStepType::BLIT:
snprintf(buffer, sizeof(buffer), "Blit (%dx%d->%dx%d)", step.blit.srcRect.extent.width, step.blit.srcRect.extent.height, step.blit.dstRect.extent.width, step.blit.dstRect.extent.height);
break;
case VKRStepType::READBACK:
snprintf(buffer, sizeof(buffer), "Readback (%dx%d)", step.readback.srcRect.extent.width, step.readback.srcRect.extent.height);
break;
case VKRStepType::READBACK_IMAGE:
snprintf(buffer, sizeof(buffer), "ReadbackImage");
break;
case VKRStepType::RENDER_SKIP:
snprintf(buffer, sizeof(buffer), "(SKIPPED RenderPass)");
break;
default:
buffer[0] = 0;
break;
}
return std::string(buffer);
}

void VulkanQueueRunner::LogSteps(const std::vector<VKRStep *> &steps) {
ILOG("=======================================");
for (size_t i = 0; i < steps.size(); i++) {
const VKRStep &step = *steps[i];
ILOG("%s", StepToString(step).c_str());
switch (step.stepType) {
case VKRStepType::RENDER:
LogRenderPass(step);
Expand Down
4 changes: 3 additions & 1 deletion ext/native/thin3d/VulkanQueueRunner.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,11 @@ class VulkanQueueRunner {
}

// RunSteps can modify steps but will leave it in a valid state.
void RunSteps(VkCommandBuffer cmd, std::vector<VKRStep *> &steps);
void RunSteps(VkCommandBuffer cmd, std::vector<VKRStep *> &steps, VkQueryPool queryPool, std::vector<std::string> *timestampDescriptions);
void LogSteps(const std::vector<VKRStep *> &steps);

std::string StepToString(const VKRStep &step) const;

void CreateDeviceObjects();
void DestroyDeviceObjects();

Expand Down
16 changes: 5 additions & 11 deletions ext/native/thin3d/VulkanRenderManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,12 +350,12 @@ void VulkanRenderManager::ThreadFunc() {
}

void VulkanRenderManager::BeginFrame(bool enableProfiling) {
gpuProfilingEnabled_ = enableProfiling;
VLOG("BeginFrame");
VkDevice device = vulkan_->GetDevice();

int curFrame = vulkan_->GetCurFrame();
FrameData &frameData = frameData_[curFrame];
frameData.profilingEnabled_ = enableProfiling;

// Make sure the very last command buffer from the frame before the previous has been fully executed.
if (useThread_) {
Expand All @@ -373,7 +373,7 @@ void VulkanRenderManager::BeginFrame(bool enableProfiling) {

uint64_t queryResults[MAX_TIMESTAMP_QUERIES];

if (gpuProfilingEnabled_) {
if (frameData.profilingEnabled_) {
// Pull the profiling results from last time and produce a summary!
if (!frameData.timestampDescriptions.empty()) {
int numQueries = (int)frameData.timestampDescriptions.size();
Expand Down Expand Up @@ -416,7 +416,7 @@ void VulkanRenderManager::BeginFrame(bool enableProfiling) {
insideFrame_ = true;

frameData.timestampDescriptions.clear();
if (gpuProfilingEnabled_) {
if (frameData_->profilingEnabled_) {
// For various reasons, we need to always use an init cmd buffer in this case to perform the vkCmdResetQueryPool,
// unless we want to limit ourselves to only measure the main cmd buffer.
// Reserve the first two queries for initCmd.
Expand Down Expand Up @@ -954,20 +954,14 @@ void VulkanRenderManager::BeginSubmitFrame(int frame) {
void VulkanRenderManager::Submit(int frame, bool triggerFence) {
FrameData &frameData = frameData_[frame];
if (frameData.hasInitCommands) {
if (gpuProfilingEnabled_ && triggerFence) {
if (frameData.profilingEnabled_ && triggerFence) {
// Pre-allocated query ID 1.
vkCmdWriteTimestamp(frameData.initCmd, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, frameData.timestampQueryPool_, 1);
}
VkResult res = vkEndCommandBuffer(frameData.initCmd);
_assert_msg_(G3D, res == VK_SUCCESS, "vkEndCommandBuffer failed (init)! result=%s", VulkanResultToString(res));
}

if (gpuProfilingEnabled_) {
int numQueries = (int)frameData.timestampDescriptions.size();
vkCmdWriteTimestamp(frameData.mainCmd, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, frameData.timestampQueryPool_, numQueries);
frameData.timestampDescriptions.push_back("mainCmd");
}

VkResult res = vkEndCommandBuffer(frameData.mainCmd);
_assert_msg_(G3D, res == VK_SUCCESS, "vkEndCommandBuffer failed (main)! result=%s", VulkanResultToString(res));

Expand Down Expand Up @@ -1063,7 +1057,7 @@ void VulkanRenderManager::Run(int frame) {
auto &stepsOnThread = frameData_[frame].steps;
VkCommandBuffer cmd = frameData.mainCmd;
// queueRunner_.LogSteps(stepsOnThread);
queueRunner_.RunSteps(cmd, stepsOnThread);
queueRunner_.RunSteps(cmd, stepsOnThread, frameData.profilingEnabled_ ? frameData.timestampQueryPool_ : VK_NULL_HANDLE, &frameData.timestampDescriptions);
stepsOnThread.clear();

switch (frameData.type) {
Expand Down
4 changes: 1 addition & 3 deletions ext/native/thin3d/VulkanRenderManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ class VulkanRenderManager {

// Profiling.
VkQueryPool timestampQueryPool_ = VK_NULL_HANDLE;
bool profilingEnabled_;
std::vector<std::string> timestampDescriptions;
std::string profileSummary;
};
Expand All @@ -301,9 +302,6 @@ class VulkanRenderManager {
MAX_TIMESTAMP_QUERIES = 256,
};

// Global state
bool gpuProfilingEnabled_ = false;

// Submission time state
int curWidth_ = -1;
int curHeight_ = -1;
Expand Down