From 0dd2dfc8476fe2db3985ea38cfd285c87e998d29 Mon Sep 17 00:00:00 2001 From: James Horsley Date: Thu, 21 Nov 2024 23:39:32 +0000 Subject: [PATCH] Cache level facets instead of recalculating every frame. Approx 30% fps boost! --- Inc/D3D9Render.h | 8 +++++++- Src/D3D9Render.cpp | 31 ++++++++++++++++++++++--------- sdks | 2 +- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/Inc/D3D9Render.h b/Inc/D3D9Render.h index b975239..a0c3da0 100644 --- a/Inc/D3D9Render.h +++ b/Inc/D3D9Render.h @@ -34,13 +34,19 @@ class UD3D9Render : public URender { }; struct SurfaceData { std::vector nodes; - const FBspSurf* surf; + INT iSurf; FSurfaceFacet* facet = nullptr; void calculateSurfaceFacet(ULevel* level, const DWORD flags); }; struct ModelFacets { std::array, RPASS_MAX>, FBspNode::MAX_ZONES> facetPairs; }; + static struct { + ULevel* currentLevel; + ModelFacets facets; + FMemStack facetsMem; + FMemMark facetsMemMark; + } cachedLevelModel; struct FrameActors { std::vector actors; std::vector movers; diff --git a/Src/D3D9Render.cpp b/Src/D3D9Render.cpp index 8ae17b6..979fd59 100644 --- a/Src/D3D9Render.cpp +++ b/Src/D3D9Render.cpp @@ -16,9 +16,17 @@ void UD3D9Render::StaticConstructor() { guard(UD3D9Render::StaticConstructor); URender::StaticConstructor(); dout << "Static Constructing UD3D9Render!" << std::endl; +#if UTGLR_HP_ENGINE + cachedLevelModel.facetsMem.Init(8192, TEXT("CacheLevelFacetMem")); +#else + cachedLevelModel.facetsMem.Init(8192); +#endif + cachedLevelModel.facetsMemMark = FMemMark(cachedLevelModel.facetsMem); unguard; } +decltype(UD3D9Render::cachedLevelModel) UD3D9Render::cachedLevelModel; + void UD3D9Render::getLevelModelFacets(FSceneNode* frame, ModelFacets& modelFacets) { UModel* model = frame->Level->Model; const UViewport* viewport = frame->Viewport; @@ -80,7 +88,7 @@ void UD3D9Render::getLevelModelFacets(FSceneNode* frame, ModelFacets& modelFacet RPASS pass = (flags & PF_NoOcclude) ? RPASS::NONSOLID : RPASS::SOLID; for (ZoneNodes& zoneNodes: surfaceNodes[iSurf]) { SurfaceData& surfData = modelFacets.facetPairs[zoneNodes.zone][pass].get(texture, flags).emplace_back(); - surfData.surf = surf; + surfData.iSurf = iSurf; surfData.nodes = std::move(zoneNodes.nodes); surfData.calculateSurfaceFacet(frame->Level, flags); } @@ -90,10 +98,10 @@ void UD3D9Render::getLevelModelFacets(FSceneNode* frame, ModelFacets& modelFacet void UD3D9Render::SurfaceData::calculateSurfaceFacet(ULevel* level, const DWORD flags) { UModel* model = level->Model; const FLOAT levelTime = level->GetLevelInfo()->TimeSeconds; - const FBspSurf* const& surf = this->surf; + const FBspSurf* surf = &model->Surfs(this->iSurf); FSurfaceFacet*& facet = this->facet; // New surface, setup... - facet = New(GDynMem); + facet = New(cachedLevelModel.facetsMem); facet->Polys = NULL; facet->Span = NULL; facet->MapCoords = FCoords( @@ -139,7 +147,7 @@ void UD3D9Render::SurfaceData::calculateSurfaceFacet(ULevel* level, const DWORD } #endif if (panU != 0 || panV != 0) { - FVector* pan = New(GDynMem); + FVector* pan = New(cachedLevelModel.facetsMem); *pan = FVector(panU, panV, 0); // Hide this away in the span coz we're not using it facet->Span = (FSpanBuffer*)pan; @@ -147,7 +155,7 @@ void UD3D9Render::SurfaceData::calculateSurfaceFacet(ULevel* level, const DWORD for (const INT& iNode : this->nodes) { const FBspNode& node = model->Nodes(iNode); - FSavedPoly* poly = (FSavedPoly*)New(GDynMem, sizeof(FSavedPoly) + node.NumVertices * sizeof(FTransform*)); + FSavedPoly* poly = (FSavedPoly*)New(cachedLevelModel.facetsMem, sizeof(FSavedPoly) + node.NumVertices * sizeof(FTransform*)); poly->Next = facet->Polys; facet->Polys = poly; #if !UTGLR_OLD_POLY_CLASSES @@ -156,7 +164,7 @@ void UD3D9Render::SurfaceData::calculateSurfaceFacet(ULevel* level, const DWORD poly->NumPts = node.NumVertices; // Allocate and store each point - FTransform* transArr = New(VectorMem, poly->NumPts); + FTransform* transArr = New(cachedLevelModel.facetsMem, poly->NumPts); for (int i = 0; i < poly->NumPts; i++) { FVert& vert = model->Verts(node.iVertPool + i); FTransform* trans = transArr + i; @@ -255,8 +263,13 @@ void UD3D9Render::DrawWorld(FSceneNode* frame) { // Seems to also update mover bsp nodes for colision decal calculations OccludeFrame(frame); - ModelFacets modelFacets; - getLevelModelFacets(frame, modelFacets); + if (cachedLevelModel.currentLevel != frame->Level) { + cachedLevelModel.facetsMemMark.Pop(); + cachedLevelModel.facets = ModelFacets(); + getLevelModelFacets(frame, cachedLevelModel.facets); + cachedLevelModel.currentLevel = frame->Level; + } + ModelFacets& modelFacets = cachedLevelModel.facets; std::unordered_map lockedTextures; @@ -479,7 +492,7 @@ void UD3D9Render::drawActorSwitch(FSceneNode* frame, UD3D9RenderDevice* d3d9Dev, void UD3D9Render::getSurfaceDecals(FSceneNode* frame, const SurfaceData& surfaceData, DecalMap& decals, std::unordered_map& lockedTextures) { const UViewport* viewport = frame->Viewport; const UModel* model = frame->Level->Model; - const FBspSurf& surf = *surfaceData.surf; + const FBspSurf& surf = model->Surfs(surfaceData.iSurf); for (int i = 0; i < surf.Decals.Num(); i++) { const FDecal* decal = &surf.Decals(i); UTexture* texture; diff --git a/sdks b/sdks index 1d0a3ee..8e1040f 160000 --- a/sdks +++ b/sdks @@ -1 +1 @@ -Subproject commit 1d0a3ee4c356651e8665991f2491c86302f346ad +Subproject commit 8e1040feb64af24f53c5d4760f719a6ef8f52652