diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index aed9f8f60..2f1c97ee1 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -819,6 +819,8 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, f stereo3dMode.SetUp(); for (int eye_ix = 0; eye_ix < stereo3dMode.eye_count(); ++eye_ix) { + if (eye_ix > 0) + SetFixedColormap(camera->player); // reiterate color map for each eye, so night vision goggles work in both eyes const s3d::EyePose * eye = stereo3dMode.getEyePose(eye_ix); eye->SetUp(); GLRenderer->SetOutputViewport(bounds); diff --git a/src/swrenderer/plane/r_visibleplanelist.cpp b/src/swrenderer/plane/r_visibleplanelist.cpp index c97c6a6dc..7a4f5a57c 100644 --- a/src/swrenderer/plane/r_visibleplanelist.cpp +++ b/src/swrenderer/plane/r_visibleplanelist.cpp @@ -331,6 +331,9 @@ namespace swrenderer int VisiblePlaneList::Render() { + if (Thread->MainThread) + PlaneCycles.Clock(); + VisiblePlane *pl; int i; int vpcount = 0; @@ -351,6 +354,10 @@ namespace swrenderer } } } + + if (Thread->MainThread) + PlaneCycles.Unclock(); + return vpcount; } diff --git a/src/swrenderer/scene/r_opaque_pass.cpp b/src/swrenderer/scene/r_opaque_pass.cpp index bb8081a27..7d6d6b461 100644 --- a/src/swrenderer/scene/r_opaque_pass.cpp +++ b/src/swrenderer/scene/r_opaque_pass.cpp @@ -779,11 +779,17 @@ namespace swrenderer void RenderOpaquePass::RenderScene() { + if (Thread->MainThread) + WallCycles.Clock(); + SeenSpriteSectors.clear(); SeenActors.clear(); InSubsector = nullptr; RenderBSPNode(level.HeadNode()); // The head node is the last node output. + + if (Thread->MainThread) + WallCycles.Unclock(); } // diff --git a/src/swrenderer/scene/r_portal.cpp b/src/swrenderer/scene/r_portal.cpp index 06812f0ba..9e9a347a4 100644 --- a/src/swrenderer/scene/r_portal.cpp +++ b/src/swrenderer/scene/r_portal.cpp @@ -438,10 +438,8 @@ namespace swrenderer Thread->Clip3D->ResetClip(); // reset clips (floor/ceiling) if (!savedvisibility && viewpoint.camera) viewpoint.camera->renderflags &= ~RF_INVISIBLE; - PlaneCycles.Clock(); Thread->PlaneList->Render(); RenderPlanePortals(); - PlaneCycles.Unclock(); double vzp = viewpoint.Pos.Z; @@ -458,9 +456,7 @@ namespace swrenderer if (Thread->MainThread) NetUpdate(); - MaskedCycles.Clock(); // [ZZ] count sprites in portals/mirrors along with normal ones. Thread->TranslucentPass->Render(); // this is required since with portals there often will be cases when more than 80% of the view is inside a portal. - MaskedCycles.Unclock(); if (Thread->MainThread) NetUpdate(); diff --git a/src/swrenderer/scene/r_scene.cpp b/src/swrenderer/scene/r_scene.cpp index 53c1d5325..4667f25eb 100644 --- a/src/swrenderer/scene/r_scene.cpp +++ b/src/swrenderer/scene/r_scene.cpp @@ -70,7 +70,7 @@ CVAR(Bool, r_scene_multithreaded, false, 0); namespace swrenderer { - cycle_t WallCycles, PlaneCycles, MaskedCycles, WallScanCycles; + cycle_t WallCycles, PlaneCycles, MaskedCycles, DrawerWaitCycles; RenderScene::RenderScene() { @@ -124,7 +124,9 @@ namespace swrenderer DrawerThreads::Execute(queue); } + DrawerWaitCycles.Clock(); DrawerThreads::WaitForWorkers(); + DrawerWaitCycles.Unclock(); } void RenderScene::RenderActorView(AActor *actor, bool dontmaplines) @@ -132,7 +134,7 @@ namespace swrenderer WallCycles.Reset(); PlaneCycles.Reset(); MaskedCycles.Reset(); - WallScanCycles.Reset(); + DrawerWaitCycles.Reset(); R_SetupFrame(MainThread()->Viewport->viewpoint, MainThread()->Viewport->viewwindow, actor); @@ -179,7 +181,9 @@ namespace swrenderer { // Player sprites needs to be rendered after all the slices because they may be hardware accelerated. // If they are not hardware accelerated the drawers must run after all sliced drawers finished. + DrawerWaitCycles.Clock(); DrawerThreads::WaitForWorkers(); + DrawerWaitCycles.Unclock(); MainThread()->DrawQueue->Clear(); MainThread()->PlayerSprites->Render(); DrawerThreads::Execute(MainThread()->DrawQueue); @@ -266,42 +270,24 @@ namespace swrenderer if (thread->X2 < viewwidth) thread->ClipSegments->Clip(thread->X2, viewwidth, true, &visitor); - if (thread->MainThread) - WallCycles.Clock(); - thread->OpaquePass->RenderScene(); thread->Clip3D->ResetClip(); // reset clips (floor/ceiling) - if (thread == MainThread()) - WallCycles.Unclock(); - if (thread->MainThread) NetUpdate(); if (viewactive) { - if (thread->MainThread) - PlaneCycles.Clock(); - thread->PlaneList->Render(); + thread->Portal->RenderPlanePortals(); - - if (thread->MainThread) - PlaneCycles.Unclock(); - thread->Portal->RenderLinePortals(); if (thread->MainThread) NetUpdate(); - if (thread->MainThread) - MaskedCycles.Clock(); - thread->TranslucentPass->Render(); - if (thread->MainThread) - MaskedCycles.Unclock(); - if (thread->MainThread) NetUpdate(); } @@ -373,7 +359,9 @@ namespace swrenderer viewport->SetViewport(MainThread(), width, height, MainThread()->Viewport->viewwindow.WidescreenRatio); RenderActorView(actor, dontmaplines); + DrawerWaitCycles.Clock(); DrawerThreads::WaitForWorkers(); + DrawerWaitCycles.Unclock(); viewport->RenderTarget = screen; @@ -419,12 +407,12 @@ namespace swrenderer ADD_STAT(fps) { FString out; - out.Format("frame=%04.1f ms walls=%04.1f ms planes=%04.1f ms masked=%04.1f ms", - FrameCycles.TimeMS(), WallCycles.TimeMS(), PlaneCycles.TimeMS(), MaskedCycles.TimeMS()); + out.Format("frame=%04.1f ms walls=%04.1f ms planes=%04.1f ms masked=%04.1f ms drawers=%04.1f ms", + FrameCycles.TimeMS(), WallCycles.TimeMS(), PlaneCycles.TimeMS(), MaskedCycles.TimeMS(), DrawerWaitCycles.TimeMS()); return out; } - static double f_acc, w_acc, p_acc, m_acc; + static double f_acc, w_acc, p_acc, m_acc, drawer_acc; static int acc_c; ADD_STAT(fps_accumulated) @@ -433,10 +421,11 @@ namespace swrenderer w_acc += WallCycles.TimeMS(); p_acc += PlaneCycles.TimeMS(); m_acc += MaskedCycles.TimeMS(); + drawer_acc += DrawerWaitCycles.TimeMS(); acc_c++; FString out; - out.Format("frame=%04.1f ms walls=%04.1f ms planes=%04.1f ms masked=%04.1f ms %d counts", - f_acc / acc_c, w_acc / acc_c, p_acc / acc_c, m_acc / acc_c, acc_c); + out.Format("frame=%04.1f ms walls=%04.1f ms planes=%04.1f ms masked=%04.1f ms drawers=%04.1f ms %d counts", + f_acc / acc_c, w_acc / acc_c, p_acc / acc_c, m_acc / acc_c, drawer_acc / acc_c, acc_c); Printf(PRINT_LOG, "%s\n", out.GetChars()); return out; } @@ -457,24 +446,4 @@ namespace swrenderer { bestwallcycles = HUGE_VAL; } - -#if 0 - // The replacement code for Build's wallscan doesn't have any timing calls so this does not work anymore. - static double bestscancycles = HUGE_VAL; - - ADD_STAT(scancycles) - { - FString out; - double scancycles = WallScanCycles.Time(); - if (scancycles && scancycles < bestscancycles) - bestscancycles = scancycles; - out.Format("%g", bestscancycles); - return out; - } - - CCMD(clearscancycles) - { - bestscancycles = HUGE_VAL; - } -#endif } diff --git a/src/swrenderer/scene/r_scene.h b/src/swrenderer/scene/r_scene.h index b4124812b..a5fd57bec 100644 --- a/src/swrenderer/scene/r_scene.h +++ b/src/swrenderer/scene/r_scene.h @@ -34,7 +34,7 @@ extern cycle_t FrameCycles; namespace swrenderer { - extern cycle_t WallCycles, PlaneCycles, MaskedCycles, WallScanCycles; + extern cycle_t WallCycles, PlaneCycles, MaskedCycles, DrawerWaitCycles; class RenderThread; diff --git a/src/swrenderer/scene/r_translucent_pass.cpp b/src/swrenderer/scene/r_translucent_pass.cpp index a8ba85d25..905974571 100644 --- a/src/swrenderer/scene/r_translucent_pass.cpp +++ b/src/swrenderer/scene/r_translucent_pass.cpp @@ -173,6 +173,9 @@ namespace swrenderer void RenderTranslucentPass::Render() { + if (Thread->MainThread) + MaskedCycles.Clock(); + CollectPortals(); Thread->SpriteList->Sort(); Thread->DrawSegments->BuildSegmentGroups(); @@ -223,5 +226,8 @@ namespace swrenderer clip3d->DeleteHeights(); clip3d->fake3D = 0; } + + if (Thread->MainThread) + MaskedCycles.Unclock(); } }