From d3206c5124b83a68b3069ce0d426c04f0672bab8 Mon Sep 17 00:00:00 2001
From: D-AIRY <admin@ds-servers.com>
Date: Tue, 1 Dec 2020 10:40:23 +0300
Subject: [PATCH] Add gpu profiling

---
 sdks/graphix                     |  2 +-
 source/light/LightSystem.cpp     | 15 ++++++-
 source/render/RenderPipeline.cpp |  9 ++++
 source/xEngine/Engine.cpp        | 74 +++++++++++++++++++++++++++++---
 source/xEngine/Engine.h          |  2 +
 5 files changed, 94 insertions(+), 8 deletions(-)

diff --git a/sdks/graphix b/sdks/graphix
index 34891650e..fd0456791 160000
--- a/sdks/graphix
+++ b/sdks/graphix
@@ -1 +1 @@
-Subproject commit 34891650ec0f40b548976644f8fe29d83d0d103f
+Subproject commit fd0456791ea7163ec3dceb9043cc07a0ef69cda0
diff --git a/source/light/LightSystem.cpp b/source/light/LightSystem.cpp
index e7b00da43..2deb978d9 100644
--- a/source/light/LightSystem.cpp
+++ b/source/light/LightSystem.cpp
@@ -656,6 +656,7 @@ void XMETHODCALLTYPE CLightSystem::renderGI(IGXTexture2D *pLightTotal, IGXTextur
 	//	pCtx->clear(GX_CLEAR_COLOR | GX_CLEAR_STENCIL);
 
 	m_pRenderPipeline->renderGI();
+	pCtx->addTimestamp("selfillum -");
 
 	float3 vCamDir = m_pMainCamera->getLook();
 	float3 vCamPos = m_pMainCamera->getPosition();
@@ -724,6 +725,9 @@ void XMETHODCALLTYPE CLightSystem::renderGI(IGXTexture2D *pLightTotal, IGXTextur
 
 			pCtx->setDepthStencilSurface(pOldDS);
 			mem_release(pOldDS);
+
+
+			pCtx->addTimestamp("ssao -");
 		}
 	}
 
@@ -757,6 +761,7 @@ void XMETHODCALLTYPE CLightSystem::renderGI(IGXTexture2D *pLightTotal, IGXTextur
 	UINT uShadowCount = 0;
 	while((uShadowCount = m_pShadowCache->processNextBunch()))
 	{
+		pCtx->addTimestamp("shadows -");
 		pCtx->setColorTarget(pAmbientSurf);
 		pCtx->setDepthStencilSurface(pOldDSSurface);
 		pCtx->setBlendState(m_pBlendAlphaOneOne);
@@ -839,6 +844,7 @@ void XMETHODCALLTYPE CLightSystem::renderGI(IGXTexture2D *pLightTotal, IGXTextur
 
 			SGCore_ScreenQuadDraw();
 		}
+		pCtx->addTimestamp("lights -");
 	}
 
 	pCtx->setVSConstant(m_pLPVcentersShaderData, 9);
@@ -916,6 +922,7 @@ void XMETHODCALLTYPE CLightSystem::renderGI(IGXTexture2D *pLightTotal, IGXTextur
 
 		//break;
 	}
+	pCtx->addTimestamp("rsm -");
 
 	bool isClean[3] = {0};
 	if(iCascades)
@@ -1006,7 +1013,8 @@ void XMETHODCALLTYPE CLightSystem::renderGI(IGXTexture2D *pLightTotal, IGXTextur
 		}
 		//}
 
-		SGCore_ShaderUnBind();
+		SGCore_ShaderUnBind(); 
+		pCtx->addTimestamp("lpv_propagate -");
 	}
 
 
@@ -1042,7 +1050,9 @@ void XMETHODCALLTYPE CLightSystem::renderGI(IGXTexture2D *pLightTotal, IGXTextur
 		pCtx->setPSTexture(NULL, 4);
 
 		SGCore_ShaderUnBind();
-		pCtx->setSamplerState(m_pSamplerLinearClamp, 1);
+		pCtx->setSamplerState(m_pSamplerLinearClamp, 1); 
+		
+		pCtx->addTimestamp("lpv_apply -");
 	}
 
 
@@ -1099,6 +1109,7 @@ void XMETHODCALLTYPE CLightSystem::renderGI(IGXTexture2D *pLightTotal, IGXTextur
 	pCtx->setColorTarget(pBackBuf);
 	mem_release(pBackBuf);
 
+	pCtx->addTimestamp("final -");
 	//Sleep(16);
 }
 void XMETHODCALLTYPE CLightSystem::renderToneMapping(IGXTexture2D *pSourceLight)
diff --git a/source/render/RenderPipeline.cpp b/source/render/RenderPipeline.cpp
index 63564a9a9..aa54347a7 100644
--- a/source/render/RenderPipeline.cpp
+++ b/source/render/RenderPipeline.cpp
@@ -685,6 +685,7 @@ void CRenderPipeline::renderFrame(float fDeltaTime)
 
 	Core_PStartSection(PERF_SECTION_MRT);
 	renderGBuffer();
+	pCtx->addTimestamp("gbuffer");
 	Core_PEndSection(PERF_SECTION_MRT);
 
 	switch(*r_final_image)
@@ -718,6 +719,7 @@ void CRenderPipeline::renderFrame(float fDeltaTime)
 
 		pSceneBuf = m_pLightAmbientDiffuse->asRenderTarget();
 		pCtx->setColorTarget(pSceneBuf);
+		pCtx->addTimestamp("gi");
 	}
 	else
 	{
@@ -727,14 +729,18 @@ void CRenderPipeline::renderFrame(float fDeltaTime)
 	showTexture(m_pSceneTexture);
 
 	renderPostprocessMain();
+	pCtx->addTimestamp("post_main");
 	renderTransparent();
+	pCtx->addTimestamp("transparency");
 	renderPostprocessFinal();
+	pCtx->addTimestamp("post_final");
 
 	if(m_pLightSystem)
 	{
 		pCtx->setColorTarget(pBackBuf);
 
 		m_pLightSystem->renderToneMapping(m_pLightAmbientDiffuse);
+		pCtx->addTimestamp("tonemapping");
 
 	//! @todo reimplement me!
 	//	if(*r_final_image == DS_RT_LUMINANCE)
@@ -754,16 +760,19 @@ end:
 	if(m_pLightSystem)
 	{
 		m_pLightSystem->renderDebug();
+		pCtx->addTimestamp("debug");
 	}
 
 	Core_PStartSection(PERF_SECTION_RENDER_INFO);
 	//@FIXME: пока так
 	SGame_RenderHUD();
+	pCtx->addTimestamp("hud");
 	Core_PEndSection(PERF_SECTION_RENDER_INFO);
 	
 	showFrameStats();
 
 	getXUI()->render();
+	pCtx->addTimestamp("ui");
 }
 void CRenderPipeline::endFrame()
 {
diff --git a/source/xEngine/Engine.cpp b/source/xEngine/Engine.cpp
index 5ab4ab24c..4d521ed2d 100644
--- a/source/xEngine/Engine.cpp
+++ b/source/xEngine/Engine.cpp
@@ -222,6 +222,7 @@ bool XMETHODCALLTYPE CEngine::initGraphics(XWINDOW_OS_HANDLE hWindow, IXEngineCa
 	Core_0RegisterCVarFloat("r_default_fov", SM_PI * 0.25f, "Дефолтный fov в радианах");
 	Core_0RegisterCVarFloat("r_near", 0.025f, "Ближняя плоскость отсчечения", FCVAR_NOTIFY);
 	Core_0RegisterCVarFloat("r_far", 800.0f, "Дальняя плоскость отсечения (дальность видимости)", FCVAR_NOTIFY);
+	Core_0RegisterCVarInt("dev_gpu_profile_framerate", 0, "Раз в сколько кадров выводить данные профайлинга (0 отключает эту возможность)", FCVAR_NOTIFY);
 
 	Core_0RegisterCVarInt("r_final_image", DS_RT_SCENELIGHT, "Тип финального (выводимого в окно рендера) изображения из перечисления DS_RT");
 
@@ -367,8 +368,8 @@ bool CEngine::runFrame()
 	
 	// draw frame
 	{
-		static IGXDevice *pRenderContext = SGCore_GetDXDevice();
-		if(pRenderContext && (/*!pRenderContext->canBeginFrame() || */!checkResize()))
+		static IGXDevice *pRenderDevice = SGCore_GetDXDevice();
+		if(pRenderDevice && (/*!pRenderContext->canBeginFrame() || */!checkResize()))
 		{
 			goto end;
 		}
@@ -404,8 +405,10 @@ bool CEngine::runFrame()
 		//#############################################################################
 
 
-		if(pRenderContext)
+		if(pRenderDevice)
 		{
+			auto *pCtx = pRenderDevice->getThreadContext();
+
 			ICamera *pCamera = m_pCallback->getCameraForFrame();
 			SRender_SetCamera(pCamera);
 			SRender_UpdateView();
@@ -425,11 +428,15 @@ bool CEngine::runFrame()
 			pRenderPipeline->endFrame();
 			Core_PEndSection(PERF_SECTION_RENDER_PRESENT);
 
+			showProfile();
+
 			Core_PStartSection(PERF_SECTION_RENDER);
-			pRenderContext->getThreadContext()->beginFrame();
+			pCtx->beginFrame();
+			pCtx->addTimestamp("begin");
 			//! @todo use actual value
 			pRenderPipeline->renderFrame(0.016f);
-			pRenderContext->getThreadContext()->endFrame();
+			pCtx->addTimestamp("end");
+			pCtx->endFrame();
 			Core_PEndSection(PERF_SECTION_RENDER);
 
 			mem_release(pRenderPipeline);
@@ -446,6 +453,63 @@ finish:
 	return(true);
 }
 
+void CEngine::showProfile()
+{
+	static IGXDevice *pRenderDevice = SGCore_GetDXDevice();
+	static int *dev_gpu_profile_framerate = (int*)GET_PCVAR_INT("dev_gpu_profile_framerate");
+
+	if(*dev_gpu_profile_framerate)
+	{
+		pRenderDevice->enableProfiling(true);
+
+		const GXTimeStamp *pTimeStamps;
+		UINT uTimeStampCount;
+		static UINT uFrames = 0;
+		if(pRenderDevice->getProfilingResults(&pTimeStamps, &uTimeStampCount))
+		{
+			if(++uFrames >= *dev_gpu_profile_framerate && uTimeStampCount >= 2)
+			{
+				uFrames = 0;
+
+				UINT uTotalTicks = pTimeStamps[uTimeStampCount - 1].uTicks - pTimeStamps[0].uTicks;
+				float fTotalTime = (float)uTotalTicks / (float)(pTimeStamps[uTimeStampCount - 1].uDenominator / 1000);
+
+				uint64_t uPrev = 0;
+				float fTime = 0.0f;
+				float fDeltaTime;
+				uint64_t uDeltaTicks;
+				const char *pMarker;
+				for(UINT i = 0; i < uTimeStampCount; ++i)
+				{
+					uDeltaTicks = pTimeStamps[i].uTicks - uPrev;
+					pMarker = (const char*)pTimeStamps[i].pMarker;
+					fDeltaTime = (float)uDeltaTicks / (float)(pTimeStamps[i].uDenominator / 1000);
+
+					bool isInner = pMarker[strlen(pMarker) - 1] == '-';
+					if(isInner)
+					{
+						fTime += fDeltaTime;
+					}
+					else if(fTime > 0.0f)
+					{
+						fDeltaTime += fTime;
+						fTime = 0.0f;
+					}
+
+					LogInfo("%20s = %f ms %5.2f%%  --  %llu ticks\n", pMarker, fDeltaTime, fDeltaTime / fTotalTime * 100, uDeltaTicks);
+					uPrev = pTimeStamps[i].uTicks;
+				}
+				LogInfo("%20s = %f ms %5.2f%%  --  %llu ticks\n", "total", fTotalTime, 100.0f, uTotalTicks);
+				LogInfo(" \n");
+			}
+		}
+	}
+	else
+	{
+		pRenderDevice->enableProfiling(false);
+	}
+}
+
 void CEngine::initPaths()
 {
 	char szPath[MAX_PATH];
diff --git a/source/xEngine/Engine.h b/source/xEngine/Engine.h
index e86557770..47cf5b454 100644
--- a/source/xEngine/Engine.h
+++ b/source/xEngine/Engine.h
@@ -47,6 +47,8 @@ protected:
 
 	bool checkResize();
 
+	void showProfile();
+
 	IXEngineCallback *m_pCallback = NULL;
 
 	IXCore *m_pCore = NULL;
-- 
GitLab