- 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
parent 692aed0551
commit 81e32ecc72
12 changed files with 176 additions and 19 deletions

View file

@ -857,8 +857,6 @@ FShaderProgram *GLPPRenderState::GetGLShader(PPShader *shader)
void GLPPRenderState::Draw()
{
//FGLDebug::PushGroup(name.GetChars());
FGLPostProcessState savedState;
// Bind input textures
@ -971,8 +969,16 @@ void GLPPRenderState::Draw()
buffers->NextTexture();
glViewport(screen->mScreenViewport.left, screen->mScreenViewport.top, screen->mScreenViewport.width, screen->mScreenViewport.height);
}
//FGLDebug::PopGroup();
void GLPPRenderState::PushGroup(const FString &name)
{
FGLDebug::PushGroup(name.GetChars());
}
void GLPPRenderState::PopGroup()
{
FGLDebug::PopGroup();
}

View file

@ -88,6 +88,9 @@ class GLPPRenderState : public PPRenderState
{
public:
GLPPRenderState(FGLRenderBuffers *buffers) : buffers(buffers) { }
void PushGroup(const FString &name) override;
void PopGroup() override;
void Draw() override;
private:

View file

@ -172,8 +172,6 @@ sector_t * FGLRenderer::RenderViewpoint (FRenderViewpoint &mainvp, AActor * came
if (mainview) // Bind the scene frame buffer and turn on draw buffers used by ssao
{
FGLDebug::PushGroup("MainView");
bool useSSAO = (gl_ssao != 0);
mBuffers->BindSceneFB(useSSAO);
gl_RenderState.SetPassType(useSSAO ? GBUFFER_PASS : NORMAL_PASS);
@ -214,8 +212,6 @@ sector_t * FGLRenderer::RenderViewpoint (FRenderViewpoint &mainvp, AActor * came
mBuffers->BlitSceneToTexture(); // Copy the resulting scene to the current post process texture
FGLDebug::PopGroup(); // MainView
PostProcessScene(cm, [&]() { di->DrawEndScene2D(mainvp.sector, gl_RenderState); });
PostProcess.Unclock();
}

View file

@ -43,21 +43,16 @@ CUSTOM_CVAR(Int, gl_debug_level, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOIN
CVAR(Bool, gl_debug_breakpoint, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
extern bool gpuStatActive;
extern bool keepGpuStatActive;
extern FString gpuStatOutput;
namespace OpenGLRenderer
{
namespace
{
bool gpuStatActive = false;
bool keepGpuStatActive = false;
std::vector<std::pair<FString, GLuint>> timeElapsedQueries;
FString gpuStatOutput;
}
ADD_STAT(gpu)
{
keepGpuStatActive = true;
return gpuStatOutput;
}
//-----------------------------------------------------------------------------

View file

@ -445,10 +445,8 @@ void OpenGLFrameBuffer::Draw2D()
{
if (GLRenderer != nullptr)
{
FGLDebug::PushGroup("Draw2D");
GLRenderer->mBuffers->BindCurrentFB();
::Draw2D(&m2DDrawer, gl_RenderState);
FGLDebug::PopGroup();
}
}

View file

@ -10,6 +10,16 @@ Postprocess hw_postprocess;
PPResource *PPResource::First = nullptr;
bool gpuStatActive = false;
bool keepGpuStatActive = false;
FString gpuStatOutput;
ADD_STAT(gpu)
{
keepGpuStatActive = true;
return gpuStatOutput;
}
/////////////////////////////////////////////////////////////////////////////
void PPBloom::UpdateTextures(int width, int height)
@ -46,6 +56,8 @@ void PPBloom::RenderBloom(PPRenderState *renderstate, int sceneWidth, int sceneH
return;
}
renderstate->PushGroup("bloom");
UpdateTextures(sceneWidth, sceneHeight);
ExtractUniforms extractUniforms;
@ -121,6 +133,8 @@ void PPBloom::RenderBloom(PPRenderState *renderstate, int sceneWidth, int sceneH
renderstate->SetOutputCurrent();
renderstate->SetAdditiveBlend();
renderstate->Draw();
renderstate->PopGroup();
}
void PPBloom::RenderBlur(PPRenderState *renderstate, int sceneWidth, int sceneHeight, float gameinfobluramount)
@ -144,6 +158,8 @@ void PPBloom::RenderBlur(PPRenderState *renderstate, int sceneWidth, int sceneHe
return;
}
renderstate->PushGroup("blur");
int numLevels = 3;
assert(numLevels <= NumBloomLevels);
@ -214,6 +230,8 @@ void PPBloom::RenderBlur(PPRenderState *renderstate, int sceneWidth, int sceneHe
renderstate->SetOutputCurrent();
renderstate->SetNoBlend();
renderstate->Draw();
renderstate->PopGroup();
}
void PPBloom::BlurStep(PPRenderState *renderstate, const BlurUniforms &blurUniforms, PPTexture &input, PPTexture &output, PPViewport viewport, bool vertical)
@ -295,6 +313,8 @@ void PPLensDistort::Render(PPRenderState *renderstate)
uniforms.LensDistortionCoefficient = k;
uniforms.CubicDistortionValue = kcube;
renderstate->PushGroup("lens");
renderstate->Clear();
renderstate->Shader = &Lens;
renderstate->Uniforms.Set(uniforms);
@ -303,6 +323,8 @@ void PPLensDistort::Render(PPRenderState *renderstate)
renderstate->SetOutputNext();
renderstate->SetNoBlend();
renderstate->Draw();
renderstate->PopGroup();
}
/////////////////////////////////////////////////////////////////////////////
@ -319,6 +341,8 @@ void PPFXAA::Render(PPRenderState *renderstate)
FXAAUniforms uniforms;
uniforms.ReciprocalResolution = { 1.0f / screen->mScreenViewport.width, 1.0f / screen->mScreenViewport.height };
renderstate->PushGroup("fxaa");
renderstate->Clear();
renderstate->Shader = &FXAALuma;
renderstate->Uniforms.Clear();
@ -332,6 +356,8 @@ void PPFXAA::Render(PPRenderState *renderstate)
renderstate->Uniforms.Set(uniforms);
renderstate->SetInputCurrent(0, PPFilterMode::Linear);
renderstate->Draw();
renderstate->PopGroup();
}
int PPFXAA::GetMaxVersion()
@ -385,6 +411,8 @@ void PPCameraExposure::Render(PPRenderState *renderstate, int sceneWidth, int sc
return;
}
renderstate->PushGroup("exposure");
UpdateTextures(sceneWidth, sceneHeight);
ExposureExtractUniforms extractUniforms;
@ -439,6 +467,8 @@ void PPCameraExposure::Render(PPRenderState *renderstate, int sceneWidth, int sc
renderstate->SetNoBlend();
renderstate->Draw();
renderstate->PopGroup();
FirstExposureFrame = false;
}
@ -492,6 +522,8 @@ void PPColormap::Render(PPRenderState *renderstate, int fixedcm)
uniforms.MapStart = { scm->ColorizeStart[0], scm->ColorizeStart[1], scm->ColorizeStart[2], 0.f };
uniforms.MapRange = m;
renderstate->PushGroup("colormap");
renderstate->Clear();
renderstate->Shader = &Colormap;
renderstate->Uniforms.Set(uniforms);
@ -500,6 +532,8 @@ void PPColormap::Render(PPRenderState *renderstate, int fixedcm)
renderstate->SetOutputNext();
renderstate->SetNoBlend();
renderstate->Draw();
renderstate->PopGroup();
}
/////////////////////////////////////////////////////////////////////////////
@ -552,6 +586,8 @@ void PPTonemap::Render(PPRenderState *renderstate)
case Palette: shader = &PaletteShader; break;
}
renderstate->PushGroup("tonemap");
renderstate->Clear();
renderstate->Shader = shader;
renderstate->Viewport = screen->mScreenViewport;
@ -561,6 +597,8 @@ void PPTonemap::Render(PPRenderState *renderstate)
renderstate->SetOutputNext();
renderstate->SetNoBlend();
renderstate->Draw();
renderstate->PopGroup();
}
/////////////////////////////////////////////////////////////////////////////
@ -713,6 +751,8 @@ void PPAmbientOcclusion::Render(PPRenderState *renderstate, float m5, int sceneW
ambientViewport.width = AmbientWidth;
ambientViewport.height = AmbientHeight;
renderstate->PushGroup("ssao");
// Calculate linear depth values
renderstate->Clear();
renderstate->Shader = gl_multisample > 1 ? &LinearDepthMS : &LinearDepth;
@ -774,6 +814,8 @@ void PPAmbientOcclusion::Render(PPRenderState *renderstate, float m5, int sceneW
else
renderstate->SetAlphaBlend();
renderstate->Draw();
renderstate->PopGroup();
}
/////////////////////////////////////////////////////////////////////////////
@ -804,6 +846,8 @@ void PPShadowMap::Update(PPRenderState *renderstate)
ShadowMapUniforms uniforms;
uniforms.ShadowmapQuality = (float)gl_shadowmap_quality;
renderstate->PushGroup("shadowmap");
renderstate->Clear();
renderstate->Shader = &ShadowMap;
renderstate->Uniforms.Set(uniforms);
@ -812,6 +856,8 @@ void PPShadowMap::Update(PPRenderState *renderstate)
renderstate->SetOutputShadowMap();
renderstate->SetNoBlend();
renderstate->Draw();
renderstate->PopGroup();
}
/////////////////////////////////////////////////////////////////////////////
@ -905,6 +951,8 @@ PPCustomShaderInstance::PPCustomShaderInstance(PostProcessShader *desc) : Desc(d
void PPCustomShaderInstance::Run(PPRenderState *renderstate)
{
renderstate->PushGroup(Desc->Name);
renderstate->Clear();
renderstate->Shader = &Shader;
renderstate->Viewport = screen->mScreenViewport;
@ -916,6 +964,8 @@ void PPCustomShaderInstance::Run(PPRenderState *renderstate)
SetUniforms(renderstate);
renderstate->Draw();
renderstate->PopGroup();
}
void PPCustomShaderInstance::SetTextures(PPRenderState *renderstate)

View file

@ -78,6 +78,9 @@ class PPRenderState
public:
virtual ~PPRenderState() = default;
virtual void PushGroup(const FString &name) = 0;
virtual void PopGroup() = 0;
virtual void Draw() = 0;
void Clear()

View file

@ -419,6 +419,16 @@ FString VkPPShader::LoadShaderCode(const FString &lumpName, const FString &defin
/////////////////////////////////////////////////////////////////////////////
void VkPPRenderState::PushGroup(const FString &name)
{
GetVulkanFrameBuffer()->PushGroup(name);
}
void VkPPRenderState::PopGroup()
{
GetVulkanFrameBuffer()->PopGroup();
}
void VkPPRenderState::Draw()
{
auto fb = GetVulkanFrameBuffer();

View file

@ -128,6 +128,9 @@ private:
class VkPPRenderState : public PPRenderState
{
public:
void PushGroup(const FString &name) override;
void PopGroup() override;
void Draw() override;
private:

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);

View file

@ -103,6 +103,10 @@ public:
void WaitForCommands(bool finish);
void PushGroup(const FString &name);
void PopGroup();
void UpdateGpuStats();
private:
sector_t *RenderViewpoint(FRenderViewpoint &mainvp, AActor * camera, IntRect * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen);
void RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV);
@ -136,6 +140,19 @@ private:
std::unique_ptr<VulkanSemaphore> mRenderFinishedSemaphore;
VkRenderBuffers *mActiveRenderBuffers = nullptr;
struct TimestampQuery
{
FString name;
uint32_t startIndex;
uint32_t endIndex;
};
enum { MaxTimestampQueries = 100 };
std::unique_ptr<VulkanQueryPool> mTimestampQueryPool;
int mNextTimestampQuery = 0;
std::vector<size_t> mGroupStack;
std::vector<TimestampQuery> timeElapsedQueries;
};
inline VulkanFrameBuffer *GetVulkanFrameBuffer() { return static_cast<VulkanFrameBuffer*>(screen); }

View file

@ -830,7 +830,7 @@ inline void VulkanCommandBuffer::resetQueryPool(VkQueryPool queryPool, uint32_t
inline void VulkanCommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage, VulkanQueryPool *queryPool, uint32_t query)
{
writeTimestamp(pipelineStage, queryPool, query);
writeTimestamp(pipelineStage, queryPool->pool, query);
}
inline void VulkanCommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query)