Skip to content

Commit

Permalink
Cache level facets instead of recalculating every frame.
Browse files Browse the repository at this point in the history
Approx 30% fps boost!
  • Loading branch information
mmdanggg2 committed Nov 21, 2024
1 parent 5d7e7d9 commit 0dd2dfc
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 11 deletions.
8 changes: 7 additions & 1 deletion Inc/D3D9Render.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,19 @@ class UD3D9Render : public URender {
};
struct SurfaceData {
std::vector<INT> nodes;
const FBspSurf* surf;
INT iSurf;
FSurfaceFacet* facet = nullptr;
void calculateSurfaceFacet(ULevel* level, const DWORD flags);
};
struct ModelFacets {
std::array<std::array<SurfKeyBucketVector<UTexture*, SurfaceData>, RPASS_MAX>, FBspNode::MAX_ZONES> facetPairs;
};
static struct {
ULevel* currentLevel;
ModelFacets facets;
FMemStack facetsMem;
FMemMark facetsMemMark;
} cachedLevelModel;
struct FrameActors {
std::vector<AActor*> actors;
std::vector<ABrush*> movers;
Expand Down
31 changes: 22 additions & 9 deletions Src/D3D9Render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand All @@ -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<FSurfaceFacet>(GDynMem);
facet = New<FSurfaceFacet>(cachedLevelModel.facetsMem);
facet->Polys = NULL;
facet->Span = NULL;
facet->MapCoords = FCoords(
Expand Down Expand Up @@ -139,15 +147,15 @@ void UD3D9Render::SurfaceData::calculateSurfaceFacet(ULevel* level, const DWORD
}
#endif
if (panU != 0 || panV != 0) {
FVector* pan = New<FVector>(GDynMem);
FVector* pan = New<FVector>(cachedLevelModel.facetsMem);
*pan = FVector(panU, panV, 0);
// Hide this away in the span coz we're not using it
facet->Span = (FSpanBuffer*)pan;
}

for (const INT& iNode : this->nodes) {
const FBspNode& node = model->Nodes(iNode);
FSavedPoly* poly = (FSavedPoly*)New<BYTE>(GDynMem, sizeof(FSavedPoly) + node.NumVertices * sizeof(FTransform*));
FSavedPoly* poly = (FSavedPoly*)New<BYTE>(cachedLevelModel.facetsMem, sizeof(FSavedPoly) + node.NumVertices * sizeof(FTransform*));
poly->Next = facet->Polys;
facet->Polys = poly;
#if !UTGLR_OLD_POLY_CLASSES
Expand All @@ -156,7 +164,7 @@ void UD3D9Render::SurfaceData::calculateSurfaceFacet(ULevel* level, const DWORD
poly->NumPts = node.NumVertices;

// Allocate and store each point
FTransform* transArr = New<FTransform>(VectorMem, poly->NumPts);
FTransform* transArr = New<FTransform>(cachedLevelModel.facetsMem, poly->NumPts);
for (int i = 0; i < poly->NumPts; i++) {
FVert& vert = model->Verts(node.iVertPool + i);
FTransform* trans = transArr + i;
Expand Down Expand Up @@ -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<UTexture*, FTextureInfo> lockedTextures;

Expand Down Expand Up @@ -479,7 +492,7 @@ void UD3D9Render::drawActorSwitch(FSceneNode* frame, UD3D9RenderDevice* d3d9Dev,
void UD3D9Render::getSurfaceDecals(FSceneNode* frame, const SurfaceData& surfaceData, DecalMap& decals, std::unordered_map<UTexture*, FTextureInfo>& 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;
Expand Down
2 changes: 1 addition & 1 deletion sdks

0 comments on commit 0dd2dfc

Please sign in to comment.