diff --git a/source/SkyXEngine.h b/source/SkyXEngine.h index 33a90bd6224f2d95007c27ca4e0dde76f0423a3c..cd3cb60f7bbd1c8c360b6ff1ed1f5381b891333c 100644 --- a/source/SkyXEngine.h +++ b/source/SkyXEngine.h @@ -292,7 +292,7 @@ QT стиль документирования (!) и QT_AUTOBRIEF - корот #ifndef __SKYXENGINE_H #define __SKYXENGINE_H -#define SKYXENGINE_VERSION "X.7.0-dev" +#define SKYXENGINE_VERSION "X.7.0" #define SKYXENGINE_VERSION4EDITORS "SkyXEngine version " ## SKYXENGINE_VERSION diff --git a/source/anim/DynamicModelProvider.cpp b/source/anim/DynamicModelProvider.cpp index a535262fb278981a478d1938de8cfb7a5e3a4d14..7e85e07760c6fd57f1913dd9b0efec8803d830c0 100644 --- a/source/anim/DynamicModelProvider.cpp +++ b/source/anim/DynamicModelProvider.cpp @@ -87,6 +87,67 @@ protected: }; */ +class CVisUpdate: public IParallelForBody +{ +public: + CVisUpdate(const IFrustum *pFrustum, CRenderableVisibility *pVisibility, CRenderableVisibility *pReference, Array<CDynamicModel*> &m_apModels): + m_pFrustum(pFrustum), + m_pVisibility(pVisibility), + m_pReference(pReference), + m_apModels(m_apModels) + { + } + + void forLoop(int iStart, int iEnd) const + { + CDynamicModel *pMdl; + for(int i = iStart; i < iEnd; ++i) + { + pMdl = m_apModels[i]; + auto *pItem = m_pVisibility->getItemDynamic(i); + if(pMdl->isEnabled()) + { + float3 vDelta = pMdl->getPosition(); + pItem->isVisible = (m_pReference ? m_pReference->getItemDynamic(i)->isVisible : true) + && m_pFrustum->boxInFrustum(&float3(pMdl->getLocalBoundMin() + vDelta), &float3(pMdl->getLocalBoundMax() + vDelta)); + + if(pItem->isVisible) + { + pItem->isTransparent = pMdl->hasTransparentSubsets(pItem->uLod); + if(pItem->isTransparent) + { + IXMaterial *pMaterial = pMdl->getTransparentMaterial(pItem->uLod); + UINT uPSPcount = pMdl->getPSPcount(pItem->uLod); + { + ScopedLock lock(m_transparency); + if(uPSPcount) + { + m_pVisibility->addItemTransparentDynamic({pMdl, true, pMdl->getPSP(pItem->uLod, 0), 0, pMaterial}); + } + else + { + m_pVisibility->addItemTransparentDynamic({pMdl, false, SMPLANE(), 0, pMaterial}); + } + } + mem_release(pMaterial); + } + } + } + else + { + pItem->isVisible = false; + } + } + }; + +protected: + const IFrustum *m_pFrustum; + CRenderableVisibility *m_pVisibility; + CRenderableVisibility *m_pReference; + Array<CDynamicModel*> &m_apModels; + mutable mutex m_transparency; +}; + //########################################################################## CDynamicModelProvider::CDynamicModelProvider(IXCore *pCore): @@ -290,7 +351,11 @@ void CDynamicModelProvider::computeVisibility(const IFrustum *pFrustum, CRendera { pVisibility->setItemCountDynamic(m_apModels.size()); pVisibility->resetItemTransparentDynamic(); - +#if 1 + CVisUpdate cycle(pFrustum, pVisibility, pReference, m_apModels); + ID id = m_pCore->getAsyncTaskRunner()->forLoop(0, m_apModels.size(), &cycle, 500); + m_pCore->getAsyncTaskRunner()->waitForLoop(id); +#else CDynamicModel *pMdl; for(UINT i = 0, l = m_apModels.size(); i < l; ++i) { @@ -305,9 +370,9 @@ void CDynamicModelProvider::computeVisibility(const IFrustum *pFrustum, CRendera if(pItem->isVisible) { pItem->isTransparent = pMdl->hasTransparentSubsets(pItem->uLod); - IXMaterial *pMaterial = pMdl->getTransparentMaterial(pItem->uLod); if(pItem->isTransparent) { + IXMaterial *pMaterial = pMdl->getTransparentMaterial(pItem->uLod); UINT uPSPcount = pMdl->getPSPcount(pItem->uLod); if(uPSPcount) { @@ -317,8 +382,8 @@ void CDynamicModelProvider::computeVisibility(const IFrustum *pFrustum, CRendera { pVisibility->addItemTransparentDynamic({pMdl, false, SMPLANE(), 0, pMaterial}); } + mem_release(pMaterial); } - mem_release(pMaterial); } } else @@ -326,6 +391,7 @@ void CDynamicModelProvider::computeVisibility(const IFrustum *pFrustum, CRendera pItem->isVisible = false; } } +#endif } void CDynamicModelProvider::getLevelSize(const XEventLevelSize *pData) diff --git a/source/core/AsyncTaskRunner.cpp b/source/core/AsyncTaskRunner.cpp index 56d116c4464d3d73381b808ae38e2f3adaf8afa0..8c407ce60a3d413093b379795eb7fc3c8df83504 100644 --- a/source/core/AsyncTaskRunner.cpp +++ b/source/core/AsyncTaskRunner.cpp @@ -154,3 +154,12 @@ void XMETHODCALLTYPE CAsyncTaskRunner::runCallbacks() g_pTaskManager->addTask(m_vpQueue[0]); } } + +ID XMETHODCALLTYPE CAsyncTaskRunner::forLoop(int iStart, int iEnd, const IParallelForBody *pBody, int iMaxChunkSize) +{ + return(g_pTaskManager->forLoop(iStart, iEnd, pBody, iMaxChunkSize)); +} +void XMETHODCALLTYPE CAsyncTaskRunner::waitForLoop(ID id) +{ + g_pTaskManager->waitFor(id); +} diff --git a/source/core/AsyncTaskRunner.h b/source/core/AsyncTaskRunner.h index 8b5275246f7894d893ab46339a67c5890d0d8e81..9d2a2ea298df20f106ca82bda1ac282be2218486 100644 --- a/source/core/AsyncTaskRunner.h +++ b/source/core/AsyncTaskRunner.h @@ -15,6 +15,9 @@ public: void XMETHODCALLTYPE runTask(IAsyncTask *pTask) override; void XMETHODCALLTYPE runCallbacks() override; + ID XMETHODCALLTYPE forLoop(int iStart, int iEnd, const IParallelForBody *pBody, int iMaxChunkSize = 0) override; + void XMETHODCALLTYPE waitForLoop(ID id) override; + protected: IXCore *m_pCore; diff --git a/source/core/TaskManager.cpp b/source/core/TaskManager.cpp index db6ada934593dcf3c0221b0a744309038af0c598..0ecc383bcf207ccd21625a8c258c9417cf12c4e6 100644 --- a/source/core/TaskManager.cpp +++ b/source/core/TaskManager.cpp @@ -225,7 +225,7 @@ void CTaskManager::synchronize() { execute(m_OnSyncTasks.pop()); } - + g_pPerfMon->syncBegin(); /*std::unique_lock<std::mutex> lock(m_mutexSync); while(m_iNumTasksToWaitFor > 0) diff --git a/source/core/sxcore.h b/source/core/sxcore.h index c9a84844274bdc2a7f83ee82d42e258775a2b8d8..bf665fe3825f52960da96633f1ac9aa9d9230d15 100644 --- a/source/core/sxcore.h +++ b/source/core/sxcore.h @@ -141,7 +141,7 @@ SX_LIB_API ID Core_MGetThreadID(); //! получить количество потоков SX_LIB_API int Core_MGetThreadCount(); - +#if 0 class IParallelForBody { public: @@ -149,6 +149,7 @@ public: virtual void forLoop(int iStart, int iEnd) const = 0; }; +#endif //! запускает в параллельную обработку pBody SX_LIB_API ID Core_MForLoop(int iStart, int iEnd, const IParallelForBody *pBody, int iMaxChunkSize = 0); @@ -184,9 +185,9 @@ enum PERF_SECTION PERF_SECTION_AMBIENT_SND_UPDATE, // 8 PERF_SECTION_MATSORT_UPDATE, // 9 PERF_SECTION_OC_REPROJECTION, // A - PERF_SECTION_VIS_CAMERA, // B + PERF_SECTION_VIS_ALL, // B PERF_SECTION_RENDER, // C - PERF_SECTION_SML_UPDATE, // D + PERF_SECTION_CORE_UPDATE, // D PERF_SECTION_SHADOW_UPDATE, // E PERF_SECTION_MRT, // F PERF_SECTION_LIGHTING, // G @@ -226,9 +227,9 @@ static const char *g_szPerfSectionName[] = { "Ambient sound update", "Matsort update", "OC reprojection", - "Vis camera", + "Vis all", "Render overall", - "SML update", + "Core update", "Shadow update", "Render MRT", "Render lighting", diff --git a/source/xEngine/Engine.cpp b/source/xEngine/Engine.cpp index 9b85b4f9ddc3610b5c916d30a971f8972e8883b8..8ac1a687d138d033f58330c8adafddf2f67642af 100644 --- a/source/xEngine/Engine.cpp +++ b/source/xEngine/Engine.cpp @@ -238,7 +238,7 @@ bool CEngine::runFrame() Core_0ConsoleUpdate(); SSInput_Update(); - + // draw frame { @@ -250,19 +250,31 @@ bool CEngine::runFrame() //############################################################################# + Core_PStartSection(PERF_SECTION_GAME_UPDATE); SGame_Update(); + Core_PEndSection(PERF_SECTION_GAME_UPDATE); + Core_PStartSection(PERF_SECTION_PHYS_UPDATE); SPhysics_Update(); + Core_PEndSection(PERF_SECTION_PHYS_UPDATE); //############################################################################# + Core_PStartSection(PERF_SECTION_PHYS_SYNC); SPhysics_Sync(); + Core_PEndSection(PERF_SECTION_PHYS_SYNC); + Core_PStartSection(PERF_SECTION_GAME_SYNC); SGame_Sync(); + Core_PEndSection(PERF_SECTION_GAME_SYNC); + Core_PStartSection(PERF_SECTION_MATSORT_UPDATE); SMtrl_Update(0); + Core_PEndSection(PERF_SECTION_MATSORT_UPDATE); + Core_PStartSection(PERF_SECTION_CORE_UPDATE); m_pCore->runUpdate(); + Core_PEndSection(PERF_SECTION_CORE_UPDATE); //############################################################################# @@ -275,12 +287,19 @@ bool CEngine::runFrame() IXRenderPipeline *pRenderPipeline; m_pCore->getRenderPipeline(&pRenderPipeline); + Core_PStartSection(PERF_SECTION_VIS_ALL); pRenderPipeline->updateVisibility(); + Core_PEndSection(PERF_SECTION_VIS_ALL); + + Core_PStartSection(PERF_SECTION_RENDER_PRESENT); pRenderPipeline->endFrame(); + Core_PEndSection(PERF_SECTION_RENDER_PRESENT); + Core_PStartSection(PERF_SECTION_RENDER); pRenderContext->getThreadContext()->beginFrame(); pRenderPipeline->renderFrame(); pRenderContext->getThreadContext()->endFrame(); + Core_PEndSection(PERF_SECTION_RENDER); mem_release(pRenderPipeline); } diff --git a/source/xcommon/IAsyncTaskRunner.h b/source/xcommon/IAsyncTaskRunner.h index b4027a09ebd44a48a809712aedc177a4950d6f86..b98b32220eb5cff5300cfb51cd7c82f33a226b89 100644 --- a/source/xcommon/IAsyncTaskRunner.h +++ b/source/xcommon/IAsyncTaskRunner.h @@ -3,6 +3,15 @@ #include <gdefines.h> + +class IParallelForBody +{ +public: + virtual ~IParallelForBody() = default; + + virtual void forLoop(int iStart, int iEnd) const = 0; +}; + class IAsyncTask: public IXUnknown { public: @@ -25,6 +34,9 @@ class IAsyncTaskRunner: public IXUnknown public: virtual void XMETHODCALLTYPE runTask(IAsyncTask *pTask) = 0; virtual void XMETHODCALLTYPE runCallbacks() = 0; + + virtual ID XMETHODCALLTYPE forLoop(int iStart, int iEnd, const IParallelForBody *pBody, int iMaxChunkSize = 0) = 0; + virtual void XMETHODCALLTYPE waitForLoop(ID id) = 0; }; #endif