From 53fe339fb38dd6a503cbe3351e40fb16f948748b Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 12 Sep 2014 01:07:02 +0200 Subject: [PATCH 1/4] Enable simple culling for non indirect codepath --- src/graphics/stkscenemanager.cpp | 50 ++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/src/graphics/stkscenemanager.cpp b/src/graphics/stkscenemanager.cpp index ace0260b9..ba65098ee 100644 --- a/src/graphics/stkscenemanager.cpp +++ b/src/graphics/stkscenemanager.cpp @@ -151,16 +151,11 @@ bool isBoxInFrontOfPlane(const core::plane3df &plane, const core::vector3df edge } static -bool isCulled(const scene::ICameraSceneNode *cam, const scene::ISceneNode *node) +bool isCulledPrecise(const scene::ICameraSceneNode *cam, const scene::ISceneNode *node) { if (!node->getAutomaticCulling()) return false; - // Faster albeit less precise alternative -/* core::aabbox3d tbox = node->getBoundingBox(); - node->getAbsoluteTransformation().transformBoxEx(tbox); - return !(tbox.intersectsWithBox(cam->getViewFrustum()->getBoundingBox()));*/ - scene::SViewFrustum frust = *cam->getViewFrustum(); //transform the frustum to the node's current absolute transformation @@ -177,8 +172,20 @@ bool isCulled(const scene::ICameraSceneNode *cam, const scene::ISceneNode *node) return false; } +static +bool isCulledFast(const scene::ICameraSceneNode *cam, const scene::ISceneNode *node) +{ + if (!node->getAutomaticCulling()) + return false; + + core::aabbox3d tbox = node->getBoundingBox(); + node->getAbsoluteTransformation().transformBoxEx(tbox); + return !(tbox.intersectsWithBox(cam->getViewFrustum()->getBoundingBox())); +} + static void -handleSTKCommon(scene::ISceneNode *Node, std::vector *ImmediateDraw) +handleSTKCommon(scene::ISceneNode *Node, std::vector *ImmediateDraw, + const scene::ICameraSceneNode *cam, scene::ICameraSceneNode *shadowcam[4], const scene::ICameraSceneNode *rsmcam) { STKMeshCommon *node = dynamic_cast(Node); if (!node) @@ -192,7 +199,6 @@ handleSTKCommon(scene::ISceneNode *Node, std::vector *Immed return; } - // Transparent GLMesh *mesh; if (World::getWorld() && World::getWorld()->isFogEnabled()) @@ -263,6 +269,8 @@ handleSTKCommon(scene::ISceneNode *Node, std::vector *Immed } else { + if (isCulledFast(cam, Node)) + continue; core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix; ModelMatrix.getInverse(InvModelMatrix); @@ -311,6 +319,8 @@ handleSTKCommon(scene::ISceneNode *Node, std::vector *Immed } else { + if (isCulledFast(shadowcam[cascade], Node)) + continue; core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix; ModelMatrix.getInverse(InvModelMatrix); @@ -364,6 +374,8 @@ handleSTKCommon(scene::ISceneNode *Node, std::vector *Immed } else { + if (isCulledFast(rsmcam, Node)) + continue; core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix; ModelMatrix.getInverse(InvModelMatrix); @@ -403,7 +415,7 @@ handleSTKCommon(scene::ISceneNode *Node, std::vector *Immed static void parseSceneManager(core::list List, std::vector *ImmediateDraw, - scene::ICameraSceneNode* cam) + const scene::ICameraSceneNode* cam, scene::ICameraSceneNode *shadow_cam[4], const scene::ICameraSceneNode *rsmcam) { core::list::Iterator I = List.begin(), E = List.end(); for (; I != E; ++I) @@ -416,14 +428,14 @@ parseSceneManager(core::list List, std::vector(*I)) { - if (!isCulled(cam, *I) && node->update()) + if (!isCulledPrecise(cam, *I) && node->update()) ParticlesList::getInstance()->push_back(node); continue; } - handleSTKCommon(*I, ImmediateDraw); + handleSTKCommon(*I, ImmediateDraw, cam, shadow_cam, rsmcam); - parseSceneManager((*I)->getChildren(), ImmediateDraw, cam); + parseSceneManager((*I)->getChildren(), ImmediateDraw, cam, shadow_cam, rsmcam); } } @@ -484,18 +496,18 @@ void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode) DeferredUpdate.clear(); core::list List = m_scene_manager->getRootSceneNode()->getChildren(); - parseSceneManager(List, ImmediateDrawList::getInstance(), camnode); + parseSceneManager(List, ImmediateDrawList::getInstance(), camnode, m_shadow_camnodes, m_suncam); #pragma omp parallel for for (int i = 0; i < (int)DeferredUpdate.size(); i++) { scene::ISceneNode *node = dynamic_cast(DeferredUpdate[i]); - DeferredUpdate[i]->setCulledForPlayerCam(isCulled(camnode, node)); - DeferredUpdate[i]->setCulledForRSMCam(isCulled(m_suncam, node)); - DeferredUpdate[i]->setCulledForShadowCam(0, isCulled(m_shadow_camnodes[0], node)); - DeferredUpdate[i]->setCulledForShadowCam(1, isCulled(m_shadow_camnodes[1], node)); - DeferredUpdate[i]->setCulledForShadowCam(2, isCulled(m_shadow_camnodes[2], node)); - DeferredUpdate[i]->setCulledForShadowCam(3, isCulled(m_shadow_camnodes[3], node)); + DeferredUpdate[i]->setCulledForPlayerCam(isCulledPrecise(camnode, node)); + DeferredUpdate[i]->setCulledForRSMCam(isCulledPrecise(m_suncam, node)); + DeferredUpdate[i]->setCulledForShadowCam(0, isCulledPrecise(m_shadow_camnodes[0], node)); + DeferredUpdate[i]->setCulledForShadowCam(1, isCulledPrecise(m_shadow_camnodes[1], node)); + DeferredUpdate[i]->setCulledForShadowCam(2, isCulledPrecise(m_shadow_camnodes[2], node)); + DeferredUpdate[i]->setCulledForShadowCam(3, isCulledPrecise(m_shadow_camnodes[3], node)); } // Add a 1 s timeout From 6f65874ab20d1c76b2bcfdc32a825c8392269ef5 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 12 Sep 2014 01:12:55 +0200 Subject: [PATCH 2/4] Try to disable openMP at runtime --- src/graphics/stkscenemanager.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/graphics/stkscenemanager.cpp b/src/graphics/stkscenemanager.cpp index ba65098ee..4dcd691f2 100644 --- a/src/graphics/stkscenemanager.cpp +++ b/src/graphics/stkscenemanager.cpp @@ -463,6 +463,8 @@ InstanceData *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t ShadowPassCmd::getInstance()->Size[cascade][Mat] = CommandBufferOffset - ShadowPassCmd::getInstance()->Offset[cascade][Mat]; } +int enableOpenMP; + void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode) { windDir = getWindDir(); @@ -558,7 +560,10 @@ void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode) ShadowCmdBuffer = ShadowPassCmd::getInstance()->Ptr; GlowCmdBuffer = GlowPassCmd::getInstance()->Ptr; RSMCmdBuffer = RSMPassCmd::getInstance()->Ptr; + enableOpenMP = 1; } + else + enableOpenMP = 0; ListInstancedMatDefault::getInstance()->clear(); ListInstancedMatAlphaRef::getInstance()->clear(); @@ -573,7 +578,7 @@ void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode) PROFILER_PUSH_CPU_MARKER("- Draw Command upload", 0xFF, 0x0, 0xFF); auto playercamculling = [](const scene::ISceneNode *nd) {return dynamic_cast(nd)->isCulledForPlayerCam(); }; -#pragma omp parallel sections +#pragma omp parallel sections if(enableOpenMP) { #pragma omp section { From 503ecbb6f14daf1ad03a91fbcffcc7c389e953be Mon Sep 17 00:00:00 2001 From: vlj Date: Fri, 12 Sep 2014 02:27:48 +0200 Subject: [PATCH 3/4] Some fixes to ligthshaft --- src/graphics/post_processing.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index 139b6f023..5b225a9f7 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -608,7 +608,7 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo // Grab the sky out_fbo->Bind(); glClear(GL_COLOR_BUFFER_BIT); - irr_driver->renderSkybox(camnode); +// irr_driver->renderSkybox(camnode); // Set the sun's color const SColor col = track->getGodRaysColor(); @@ -617,9 +617,9 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode, boo // The sun interposer STKMeshSceneNode *sun = irr_driver->getSunInterposer(); + sun->setGlowColors(col); sun->setPosition(track->getGodRaysPosition()); sun->updateAbsolutePosition(); - irr_driver->getSceneManager()->drawAll(ESNRP_CAMERA); irr_driver->setPhase(GLOW_PASS); sun->render(); glDisable(GL_DEPTH_TEST); From 0b0fabc7bb0fdcc23d047f3e83440e9a8a290312 Mon Sep 17 00:00:00 2001 From: vlj Date: Fri, 12 Sep 2014 02:58:13 +0200 Subject: [PATCH 4/4] Try to merge all MeshFor_Pass --- src/graphics/stkscenemanager.cpp | 34 ++++++++++---------------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/src/graphics/stkscenemanager.cpp b/src/graphics/stkscenemanager.cpp index 4dcd691f2..25ad1dc91 100644 --- a/src/graphics/stkscenemanager.cpp +++ b/src/graphics/stkscenemanager.cpp @@ -133,8 +133,6 @@ void FillInstancesGrass(const std::unordered_map > > MeshForSolidPass[MAT_COUNT]; -static std::unordered_map > > MeshForShadowPass[4][MAT_COUNT]; -static std::unordered_map > > MeshForRSMPass[MAT_COUNT]; static std::unordered_map > > MeshForGlowPass; static std::vector DeferredUpdate; @@ -312,12 +310,7 @@ handleSTKCommon(scene::ISceneNode *Node, std::vector *Immed { for (unsigned cascade = 0; cascade < 4; ++cascade) { - if (irr_driver->hasARB_draw_indirect()) - { - for_in(mesh, node->MeshSolidMaterial[Mat]) - MeshForShadowPass[cascade][Mat][mesh->mb].emplace_back(mesh, Node); - } - else + if (!irr_driver->hasARB_draw_indirect()) { if (isCulledFast(shadowcam[cascade], Node)) continue; @@ -362,10 +355,8 @@ handleSTKCommon(scene::ISceneNode *Node, std::vector *Immed { if (irr_driver->hasARB_draw_indirect()) { - for_in(mesh, node->MeshSolidMaterial[Mat]) - if (Mat != MAT_SPLATTING) - MeshForRSMPass[Mat][mesh->mb].emplace_back(mesh, Node); - else + if (Mat == MAT_SPLATTING) + for_in(mesh, node->MeshSolidMaterial[Mat]) { core::matrix4 ModelMatrix = Node->getAbsoluteTransformation(), InvModelMatrix; ModelMatrix.getInverse(InvModelMatrix); @@ -446,7 +437,7 @@ GenDrawCalls(unsigned cascade, std::vector &InstancedList, std::function shadowculling = [&](const scene::ISceneNode *nd) {return dynamic_cast(nd)->isCulledForShadowCam(cascade); }; if (irr_driver->hasARB_draw_indirect()) ShadowPassCmd::getInstance()->Offset[cascade][Mat] = CommandBufferOffset; // Store command buffer offset - FillInstances(MeshForShadowPass[cascade][Mat], InstancedList, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, PolyCount, shadowculling); + FillInstances(MeshForSolidPass[Mat], InstancedList, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, PolyCount, shadowculling); if (UserConfigParams::m_azdo) ShadowPassCmd::getInstance()->Size[cascade][Mat] = CommandBufferOffset - ShadowPassCmd::getInstance()->Offset[cascade][Mat]; } @@ -458,7 +449,7 @@ InstanceData *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t std::function shadowculling = [&](const scene::ISceneNode *nd) {return dynamic_cast(nd)->isCulledForShadowCam(cascade); }; if (irr_driver->hasARB_draw_indirect()) ShadowPassCmd::getInstance()->Offset[cascade][Mat] = CommandBufferOffset; // Store command buffer offset - FillInstancesGrass(MeshForShadowPass[cascade][Mat], InstancedList, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, dir, PolyCount, shadowculling); + FillInstancesGrass(MeshForSolidPass[Mat], InstancedList, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, dir, PolyCount, shadowculling); if (UserConfigParams::m_azdo) ShadowPassCmd::getInstance()->Size[cascade][Mat] = CommandBufferOffset - ShadowPassCmd::getInstance()->Offset[cascade][Mat]; } @@ -488,12 +479,7 @@ void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode) ListInstancedGlow::getInstance()->clear(); for (unsigned Mat = 0; Mat < MAT_COUNT; ++Mat) - { MeshForSolidPass[Mat].clear(); - MeshForRSMPass[Mat].clear(); - for (unsigned cascade = 0; cascade < 4; ++cascade) - MeshForShadowPass[cascade][Mat].clear(); - } MeshForGlowPass.clear(); DeferredUpdate.clear(); core::list List = m_scene_manager->getRootSceneNode()->getChildren(); @@ -711,23 +697,23 @@ void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode) // Default Material RSMPassCmd::getInstance()->Offset[MAT_DEFAULT] = current_cmd; - FillInstances(MeshForRSMPass[MAT_DEFAULT], ListInstancedMatDefault::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly, rsmcamculling); + FillInstances(MeshForSolidPass[MAT_DEFAULT], ListInstancedMatDefault::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly, rsmcamculling); RSMPassCmd::getInstance()->Size[MAT_DEFAULT] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_DEFAULT]; // Alpha Ref RSMPassCmd::getInstance()->Offset[MAT_ALPHA_REF] = current_cmd; - FillInstances(MeshForRSMPass[MAT_ALPHA_REF], ListInstancedMatAlphaRef::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly, rsmcamculling); + FillInstances(MeshForSolidPass[MAT_ALPHA_REF], ListInstancedMatAlphaRef::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly, rsmcamculling); RSMPassCmd::getInstance()->Size[MAT_ALPHA_REF] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_ALPHA_REF]; // Unlit RSMPassCmd::getInstance()->Offset[MAT_UNLIT] = current_cmd; - FillInstances(MeshForRSMPass[MAT_UNLIT], ListInstancedMatUnlit::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly, rsmcamculling); + FillInstances(MeshForSolidPass[MAT_UNLIT], ListInstancedMatUnlit::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly, rsmcamculling); RSMPassCmd::getInstance()->Size[MAT_UNLIT] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_UNLIT]; // Detail RSMPassCmd::getInstance()->Offset[MAT_DETAIL] = current_cmd; - FillInstances(MeshForRSMPass[MAT_DETAIL], ListInstancedMatDetails::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly, rsmcamculling); + FillInstances(MeshForSolidPass[MAT_DETAIL], ListInstancedMatDetails::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly, rsmcamculling); RSMPassCmd::getInstance()->Size[MAT_DETAIL] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_DETAIL]; // Normal Map RSMPassCmd::getInstance()->Offset[MAT_NORMAL_MAP] = current_cmd; - FillInstances(MeshForRSMPass[MAT_NORMAL_MAP], ListInstancedMatNormalMap::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly, rsmcamculling); + FillInstances(MeshForSolidPass[MAT_NORMAL_MAP], ListInstancedMatNormalMap::getInstance()->RSM, RSMInstanceBuffer, RSMCmdBuffer, offset, current_cmd, MiscPoly, rsmcamculling); RSMPassCmd::getInstance()->Size[MAT_NORMAL_MAP] = current_cmd - RSMPassCmd::getInstance()->Offset[MAT_NORMAL_MAP]; if (!irr_driver->hasBufferStorageExtension())