- implement stat gpu on vulkan and fix it on opengl

This commit is contained in:
Magnus Norddahl 2019-04-30 22:55:35 +02:00
commit 81e32ecc72
12 changed files with 176 additions and 19 deletions

View file

@ -72,6 +72,10 @@ extern bool NoInterpolateView;
extern int rendered_commandbuffers;
int current_rendered_commandbuffers;
extern bool gpuStatActive;
extern bool keepGpuStatActive;
extern FString gpuStatOutput;
VulkanFrameBuffer::VulkanFrameBuffer(void *hMonitor, bool fullscreen, VulkanDevice *dev) :
Super(hMonitor, fullscreen)
{
@ -160,6 +164,12 @@ void VulkanFrameBuffer::InitializeState()
#else
mRenderState.reset(new VkRenderState());
#endif
QueryPoolBuilder querybuilder;
querybuilder.setQueryType(VK_QUERY_TYPE_TIMESTAMP, MaxTimestampQueries);
mTimestampQueryPool = querybuilder.create(device);
GetDrawCommands()->resetQueryPool(mTimestampQueryPool.get(), 0, MaxTimestampQueries);
}
void VulkanFrameBuffer::Update()
@ -180,6 +190,7 @@ void VulkanFrameBuffer::Update()
Flush3D.Unclock();
WaitForCommands(true);
UpdateGpuStats();
Super::Update();
}
@ -779,6 +790,12 @@ TArray<uint8_t> VulkanFrameBuffer::GetScreenshotBuffer(int &pitch, ESSType &colo
void VulkanFrameBuffer::BeginFrame()
{
if (mNextTimestampQuery > 0)
{
GetDrawCommands()->resetQueryPool(mTimestampQueryPool.get(), 0, mNextTimestampQuery);
mNextTimestampQuery = 0;
}
SetViewportRects(nullptr);
mScreenBuffers->BeginFrame(screen->mScreenViewport.width, screen->mScreenViewport.height, screen->mSceneViewport.width, screen->mSceneViewport.height);
mSaveBuffers->BeginFrame(SAVEPICWIDTH, SAVEPICHEIGHT, SAVEPICWIDTH, SAVEPICHEIGHT);
@ -787,6 +804,65 @@ void VulkanFrameBuffer::BeginFrame()
mRenderPassManager->UpdateDynamicSet();
}
void VulkanFrameBuffer::PushGroup(const FString &name)
{
if (!gpuStatActive)
return;
if (mNextTimestampQuery < VulkanFrameBuffer::MaxTimestampQueries)
{
TimestampQuery q;
q.name = name;
q.startIndex = mNextTimestampQuery++;
q.endIndex = 0;
GetDrawCommands()->writeTimestamp(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, mTimestampQueryPool.get(), q.startIndex);
mGroupStack.push_back(timeElapsedQueries.size());
timeElapsedQueries.push_back(q);
}
}
void VulkanFrameBuffer::PopGroup()
{
if (!gpuStatActive || mGroupStack.empty())
return;
TimestampQuery &q = timeElapsedQueries[mGroupStack.back()];
mGroupStack.pop_back();
if (mNextTimestampQuery < VulkanFrameBuffer::MaxTimestampQueries)
{
q.endIndex = mNextTimestampQuery++;
GetDrawCommands()->writeTimestamp(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, mTimestampQueryPool.get(), q.endIndex);
}
}
void VulkanFrameBuffer::UpdateGpuStats()
{
uint64_t timestamps[MaxTimestampQueries];
mTimestampQueryPool->getResults(0, mNextTimestampQuery, sizeof(uint64_t) * mNextTimestampQuery, timestamps, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
double timestampPeriod = device->PhysicalDevice.Properties.limits.timestampPeriod;
gpuStatOutput = "";
for (auto &q : timeElapsedQueries)
{
if (q.endIndex <= q.startIndex)
continue;
int64_t timeElapsed = std::max(static_cast<int64_t>(timestamps[q.endIndex] - timestamps[q.startIndex]), (int64_t)0);
double timeNS = timeElapsed * timestampPeriod;
FString out;
out.Format("%s=%04.2f ms\n", q.name.GetChars(), timeNS / 1000000.0f);
gpuStatOutput += out;
}
timeElapsedQueries.clear();
mGroupStack.clear();
gpuStatActive = keepGpuStatActive;
keepGpuStatActive = false;
}
void VulkanFrameBuffer::Draw2D()
{
::Draw2D(&m2DDrawer, *mRenderState);