From 1654333a16a9f21949cbf825ce4bac53c3c7f2f3 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Sun, 18 Apr 2021 16:53:51 -0700 Subject: [PATCH] Only allocate particle buffers as needed, greatly improves performance and removes certain hacks --- Runtime/MP1/World/CPhazonPool.cpp | 1 - Runtime/Particle/CElementGen.cpp | 55 ++++++++++++++++++++++--------- Runtime/Particle/CElementGen.hpp | 1 + Runtime/Weapon/CPlayerGun.cpp | 34 ++++++++++++------- 4 files changed, 62 insertions(+), 29 deletions(-) diff --git a/Runtime/MP1/World/CPhazonPool.cpp b/Runtime/MP1/World/CPhazonPool.cpp index 2976e051c..f1f2ee630 100644 --- a/Runtime/MP1/World/CPhazonPool.cpp +++ b/Runtime/MP1/World/CPhazonPool.cpp @@ -180,7 +180,6 @@ void CPhazonPool::Think(float dt, CStateManager& mgr) { } } if (shouldFree) { - fmt::print(FMT_STRING("Freeing myself! ({})"), GetUniqueId()); mgr.FreeScriptObject(GetUniqueId()); } } diff --git a/Runtime/Particle/CElementGen.cpp b/Runtime/Particle/CElementGen.cpp index 021320283..e1c4f9848 100644 --- a/Runtime/Particle/CElementGen.cpp +++ b/Runtime/Particle/CElementGen.cpp @@ -213,22 +213,7 @@ CElementGen::CElementGen(TToken gen, EModelOrientationType orie m_shaderClass = CElementGenShaders::GetShaderClass(*this); } - // HACK: For now force maxInsts to be 2560 - size_t maxInsts = 2560; // (x270_MBSP * x90_MAXP) : x90_MAXP; - maxInsts = (maxInsts == 0 ? 256 : maxInsts); - - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - if (!x26c_31_LINE) { - m_instBuf = ctx.newDynamicBuffer(boo::BufferUse::Vertex, ShadClsSizes[size_t(m_shaderClass)], maxInsts); - m_uniformBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(SParticleUniforms), 1); - } - if (desc->x45_24_x31_26_PMUS) { - m_instBufPmus = ctx.newDynamicBuffer(boo::BufferUse::Vertex, ShadClsSizes[size_t(m_shaderClass)], maxInsts); - m_uniformBufPmus = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(SParticleUniforms), 1); - } - CElementGenShaders::BuildShaderDataBinding(ctx, *this); - return true; - } BooTrace); + _RecreatePipelines(); } CElementGen::~CElementGen() { @@ -237,6 +222,7 @@ CElementGen::~CElementGen() { } bool CElementGen::Update(double t) { + s32 oldMax = x90_MAXP; CParticleGlobals::SParticleSystem* prevSystem = CParticleGlobals::instance()->m_currentParticleSystem; CParticleGlobals::SParticleSystem thisSystem{FOURCC('PART'), this}; CParticleGlobals::instance()->m_currentParticleSystem = &thisSystem; @@ -251,8 +237,29 @@ bool CElementGen::Update(double t) { } bool ret = InternalUpdate(t); CParticleGlobals::instance()->m_currentParticleSystem = prevSystem; + + if (oldMax != x90_MAXP) { + _RecreatePipelines(); + } return ret; } +void CElementGen::_RecreatePipelines() { + size_t maxInsts = x26c_30_MBLR ? (x270_MBSP * x90_MAXP) : x90_MAXP; + maxInsts = (maxInsts == 0 ? 256 : maxInsts); + + CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { + if (!x26c_31_LINE) { + m_instBuf = ctx.newDynamicBuffer(boo::BufferUse::Vertex, ShadClsSizes[size_t(m_shaderClass)], maxInsts); + m_uniformBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(SParticleUniforms), 1); + } + if (x28_loadedGenDesc->x45_24_x31_26_PMUS) { + m_instBufPmus = ctx.newDynamicBuffer(boo::BufferUse::Vertex, ShadClsSizes[size_t(m_shaderClass)], maxInsts); + m_uniformBufPmus = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(SParticleUniforms), 1); + } + CElementGenShaders::BuildShaderDataBinding(ctx, *this); + return true; + } BooTrace); +} bool CElementGen::InternalUpdate(double dt) { CGlobalRandom gr(x27c_randState); @@ -812,6 +819,14 @@ u32 CElementGen::GetSystemCount() const { } void CElementGen::Render(const CActorLights* actorLights) { + // Check to make sure our buffers are ready to render + if (!x26c_31_LINE && (!m_instBuf || !m_uniformBuf)) { + return; + } + if (x28_loadedGenDesc->x45_24_x31_26_PMUS && (!m_instBufPmus || !m_uniformBufPmus)) { + return; + } + SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(FMT_STRING("CElementGen::Render {}"), *x1c_genDesc.GetObjectTag()).c_str(), zeus::skYellow); @@ -842,6 +857,14 @@ void CElementGen::Render(const CActorLights* actorLights) { } void CElementGen::RenderModels(const CActorLights* actorLights) { + // Check to make sure our buffers are ready to render + if (!x26c_31_LINE && (!m_instBuf || !m_uniformBuf)) { + return; + } + if (x28_loadedGenDesc->x45_24_x31_26_PMUS && (!m_instBufPmus || !m_uniformBufPmus)) { + return; + } + CParticleGlobals::instance()->m_particleAccessParameters = nullptr; if (x26d_26_modelsUseLights) CGraphics::SetLightState(x274_backupLightActive); diff --git a/Runtime/Particle/CElementGen.hpp b/Runtime/Particle/CElementGen.hpp index 7920a3415..36ca173d4 100644 --- a/Runtime/Particle/CElementGen.hpp +++ b/Runtime/Particle/CElementGen.hpp @@ -134,6 +134,7 @@ private: void AccumulateBounds(const zeus::CVector3f& pos, float size); + void _RecreatePipelines(); public: explicit CElementGen(TToken gen, EModelOrientationType orientType = EModelOrientationType::Normal, EOptionalSystemFlags flags = EOptionalSystemFlags::One); diff --git a/Runtime/Weapon/CPlayerGun.cpp b/Runtime/Weapon/CPlayerGun.cpp index 02415b95f..99514a2f0 100644 --- a/Runtime/Weapon/CPlayerGun.cpp +++ b/Runtime/Weapon/CPlayerGun.cpp @@ -346,9 +346,11 @@ void CPlayerGun::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CSt if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::PhazonSuit) && isUnmorphed) { x835_24_canFirePhazon = true; x835_25_inPhazonBeam = true; - if (x833_28_phazonBeamActive && static_cast(x72c_currentBeam)->IsFiring()) - if (TCastToPtr ent = mgr.ObjectById(sender)) + if (x833_28_phazonBeamActive && static_cast(x72c_currentBeam)->IsFiring()) { + if (TCastToPtr ent = mgr.ObjectById(sender)) { mgr.SendScriptMsg(ent.GetPtr(), x538_playerId, EScriptObjectMessage::Decrement); + } + } } break; case EScriptObjectMessage::RemovePhazonPoolInhabitant: @@ -367,8 +369,9 @@ void CPlayerGun::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CSt if (ai->IsMakingBigStrike()) { x394_damageTimer = ai->GetDamageDuration(); bigStrike = true; - if (player.GetAttachedActor() != kInvalidUniqueId) + if (player.GetAttachedActor() != kInvalidUniqueId) { metroidAttached = CPatterned::CastTo(mgr.GetObjectById(player.GetAttachedActor())) != nullptr; + } } } if (!x834_30_inBigStrike) { @@ -657,13 +660,15 @@ void CPlayerGun::HandlePhazonBeamChange(CStateManager& mgr) { void CPlayerGun::HandleWeaponChange(const CFinalInput& input, CStateManager& mgr) { x833_25_ = false; - if (ControlMapper::GetPressInput(ControlMapper::ECommands::Morph, input)) + if (ControlMapper::GetPressInput(ControlMapper::ECommands::Morph, input)) { StopContinuousBeam(mgr, true); + } if ((x2f8_stateFlags & 0x8) != 0x8) { - if (!x835_25_inPhazonBeam) + if (!x835_25_inPhazonBeam) { HandleBeamChange(input, mgr); - else + } else { HandlePhazonBeamChange(mgr); + } } } @@ -671,8 +676,9 @@ void CPlayerGun::ProcessInput(const CFinalInput& input, CStateManager& mgr) { CPlayerState& state = *mgr.GetPlayerState(); bool damageNotMorphed = (x834_30_inBigStrike && mgr.GetPlayer().GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed); - if (x832_24_coolingCharge || damageNotMorphed || (x2f8_stateFlags & 0x8) == 0x8) + if (x832_24_coolingCharge || damageNotMorphed || (x2f8_stateFlags & 0x8) == 0x8) { return; + } if (state.HasPowerUp(CPlayerState::EItemType::ChargeBeam)) { if (!state.ItemEnabled(CPlayerState::EItemType::ChargeBeam)) state.EnableItem(CPlayerState::EItemType::ChargeBeam); @@ -1324,8 +1330,9 @@ void CPlayerGun::CancelLockOn() { } void CPlayerGun::FireSecondary(float dt, CStateManager& mgr) { - if (mgr.GetCameraManager()->IsInCinematicCamera()) + if (mgr.GetCameraManager()->IsInCinematicCamera()) { return; + } if (x835_25_inPhazonBeam || x318_comboAmmoIdx == 0 || !mgr.GetPlayerState()->HasPowerUp(skItemArr[x318_comboAmmoIdx]) || (x2f8_stateFlags & 0x4) != 0x4) { @@ -1341,16 +1348,18 @@ void CPlayerGun::FireSecondary(float dt, CStateManager& mgr) { x832_26_comboFiring ? mgr.GetPlayerState()->GetMissileCostForAltAttack() : 1); comboFired = true; } - if (x300_remainingMissiles > 5) + if (x300_remainingMissiles > 5) { x300_remainingMissiles = 5; - else + } else { x300_remainingMissiles -= 1; + } } if (comboFired) { TUniqueId targetId = GetTargetId(mgr); - if (x832_26_comboFiring && targetId == kInvalidUniqueId && x310_currentBeam == CPlayerState::EBeamId::Wave) + if (x832_26_comboFiring && targetId == kInvalidUniqueId && x310_currentBeam == CPlayerState::EBeamId::Wave) { targetId = mgr.GetPlayer().GetAimTarget(); + } zeus::CTransform fireXf = x833_29_pointBlankWorldSurface ? x448_elbowWorldXf : x4a8_gunWorldXf * x418_beamLocalXf; if (!x833_29_pointBlankWorldSurface && x364_gunStrikeCoolTimer <= 0.f) { zeus::CVector3f backupOrigin = fireXf.origin; @@ -1910,8 +1919,9 @@ void CPlayerGun::Update(float grappleSwingT, float cameraBobT, float dt, CStateM x350_shakeZ = chargeShakeTbl[mgr.GetActiveRandom()->Next() % 3] * x340_chargeBeamFactor; } - if (!x72c_currentBeam->IsLoaded()) + if (!x72c_currentBeam->IsLoaded()) { return; + } GetLctrWithShake(x4d8_gunLocalXf, x73c_gunMotion->GetModelData(), "GBSE_SDK", true, true); GetLctrWithShake(x418_beamLocalXf, x72c_currentBeam->GetSolidModelData(), "LBEAM", false, true);