Only allocate particle buffers as needed, greatly improves performance and removes certain hacks

This commit is contained in:
Phillip Stephens 2021-04-18 16:53:51 -07:00
parent 1039424737
commit 1654333a16
Signed by: Antidote
GPG Key ID: F8BEE4C83DACA60D
4 changed files with 62 additions and 29 deletions

View File

@ -180,7 +180,6 @@ void CPhazonPool::Think(float dt, CStateManager& mgr) {
} }
} }
if (shouldFree) { if (shouldFree) {
fmt::print(FMT_STRING("Freeing myself! ({})"), GetUniqueId());
mgr.FreeScriptObject(GetUniqueId()); mgr.FreeScriptObject(GetUniqueId());
} }
} }

View File

@ -213,22 +213,7 @@ CElementGen::CElementGen(TToken<CGenDescription> gen, EModelOrientationType orie
m_shaderClass = CElementGenShaders::GetShaderClass(*this); m_shaderClass = CElementGenShaders::GetShaderClass(*this);
} }
// HACK: For now force maxInsts to be 2560 _RecreatePipelines();
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);
} }
CElementGen::~CElementGen() { CElementGen::~CElementGen() {
@ -237,6 +222,7 @@ CElementGen::~CElementGen() {
} }
bool CElementGen::Update(double t) { bool CElementGen::Update(double t) {
s32 oldMax = x90_MAXP;
CParticleGlobals::SParticleSystem* prevSystem = CParticleGlobals::instance()->m_currentParticleSystem; CParticleGlobals::SParticleSystem* prevSystem = CParticleGlobals::instance()->m_currentParticleSystem;
CParticleGlobals::SParticleSystem thisSystem{FOURCC('PART'), this}; CParticleGlobals::SParticleSystem thisSystem{FOURCC('PART'), this};
CParticleGlobals::instance()->m_currentParticleSystem = &thisSystem; CParticleGlobals::instance()->m_currentParticleSystem = &thisSystem;
@ -251,8 +237,29 @@ bool CElementGen::Update(double t) {
} }
bool ret = InternalUpdate(t); bool ret = InternalUpdate(t);
CParticleGlobals::instance()->m_currentParticleSystem = prevSystem; CParticleGlobals::instance()->m_currentParticleSystem = prevSystem;
if (oldMax != x90_MAXP) {
_RecreatePipelines();
}
return ret; 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) { bool CElementGen::InternalUpdate(double dt) {
CGlobalRandom gr(x27c_randState); CGlobalRandom gr(x27c_randState);
@ -812,6 +819,14 @@ u32 CElementGen::GetSystemCount() const {
} }
void CElementGen::Render(const CActorLights* actorLights) { 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 {}"), SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(FMT_STRING("CElementGen::Render {}"),
*x1c_genDesc.GetObjectTag()).c_str(), zeus::skYellow); *x1c_genDesc.GetObjectTag()).c_str(), zeus::skYellow);
@ -842,6 +857,14 @@ void CElementGen::Render(const CActorLights* actorLights) {
} }
void CElementGen::RenderModels(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; CParticleGlobals::instance()->m_particleAccessParameters = nullptr;
if (x26d_26_modelsUseLights) if (x26d_26_modelsUseLights)
CGraphics::SetLightState(x274_backupLightActive); CGraphics::SetLightState(x274_backupLightActive);

View File

@ -134,6 +134,7 @@ private:
void AccumulateBounds(const zeus::CVector3f& pos, float size); void AccumulateBounds(const zeus::CVector3f& pos, float size);
void _RecreatePipelines();
public: public:
explicit CElementGen(TToken<CGenDescription> gen, EModelOrientationType orientType = EModelOrientationType::Normal, explicit CElementGen(TToken<CGenDescription> gen, EModelOrientationType orientType = EModelOrientationType::Normal,
EOptionalSystemFlags flags = EOptionalSystemFlags::One); EOptionalSystemFlags flags = EOptionalSystemFlags::One);

View File

@ -346,10 +346,12 @@ void CPlayerGun::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CSt
if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::PhazonSuit) && isUnmorphed) { if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::PhazonSuit) && isUnmorphed) {
x835_24_canFirePhazon = true; x835_24_canFirePhazon = true;
x835_25_inPhazonBeam = true; x835_25_inPhazonBeam = true;
if (x833_28_phazonBeamActive && static_cast<CPhazonBeam*>(x72c_currentBeam)->IsFiring()) if (x833_28_phazonBeamActive && static_cast<CPhazonBeam*>(x72c_currentBeam)->IsFiring()) {
if (TCastToPtr<CEntity> ent = mgr.ObjectById(sender)) if (TCastToPtr<CEntity> ent = mgr.ObjectById(sender)) {
mgr.SendScriptMsg(ent.GetPtr(), x538_playerId, EScriptObjectMessage::Decrement); mgr.SendScriptMsg(ent.GetPtr(), x538_playerId, EScriptObjectMessage::Decrement);
} }
}
}
break; break;
case EScriptObjectMessage::RemovePhazonPoolInhabitant: case EScriptObjectMessage::RemovePhazonPoolInhabitant:
x835_30_inPhazonPool = false; x835_30_inPhazonPool = false;
@ -367,10 +369,11 @@ void CPlayerGun::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CSt
if (ai->IsMakingBigStrike()) { if (ai->IsMakingBigStrike()) {
x394_damageTimer = ai->GetDamageDuration(); x394_damageTimer = ai->GetDamageDuration();
bigStrike = true; bigStrike = true;
if (player.GetAttachedActor() != kInvalidUniqueId) if (player.GetAttachedActor() != kInvalidUniqueId) {
metroidAttached = CPatterned::CastTo<MP1::CMetroid>(mgr.GetObjectById(player.GetAttachedActor())) != nullptr; metroidAttached = CPatterned::CastTo<MP1::CMetroid>(mgr.GetObjectById(player.GetAttachedActor())) != nullptr;
} }
} }
}
if (!x834_30_inBigStrike) { if (!x834_30_inBigStrike) {
if (bigStrike) { if (bigStrike) {
x834_31_gunMotionInFidgetBasePosition = false; x834_31_gunMotionInFidgetBasePosition = false;
@ -657,22 +660,25 @@ void CPlayerGun::HandlePhazonBeamChange(CStateManager& mgr) {
void CPlayerGun::HandleWeaponChange(const CFinalInput& input, CStateManager& mgr) { void CPlayerGun::HandleWeaponChange(const CFinalInput& input, CStateManager& mgr) {
x833_25_ = false; x833_25_ = false;
if (ControlMapper::GetPressInput(ControlMapper::ECommands::Morph, input)) if (ControlMapper::GetPressInput(ControlMapper::ECommands::Morph, input)) {
StopContinuousBeam(mgr, true); StopContinuousBeam(mgr, true);
}
if ((x2f8_stateFlags & 0x8) != 0x8) { if ((x2f8_stateFlags & 0x8) != 0x8) {
if (!x835_25_inPhazonBeam) if (!x835_25_inPhazonBeam) {
HandleBeamChange(input, mgr); HandleBeamChange(input, mgr);
else } else {
HandlePhazonBeamChange(mgr); HandlePhazonBeamChange(mgr);
} }
} }
}
void CPlayerGun::ProcessInput(const CFinalInput& input, CStateManager& mgr) { void CPlayerGun::ProcessInput(const CFinalInput& input, CStateManager& mgr) {
CPlayerState& state = *mgr.GetPlayerState(); CPlayerState& state = *mgr.GetPlayerState();
bool damageNotMorphed = bool damageNotMorphed =
(x834_30_inBigStrike && mgr.GetPlayer().GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed); (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; return;
}
if (state.HasPowerUp(CPlayerState::EItemType::ChargeBeam)) { if (state.HasPowerUp(CPlayerState::EItemType::ChargeBeam)) {
if (!state.ItemEnabled(CPlayerState::EItemType::ChargeBeam)) if (!state.ItemEnabled(CPlayerState::EItemType::ChargeBeam))
state.EnableItem(CPlayerState::EItemType::ChargeBeam); state.EnableItem(CPlayerState::EItemType::ChargeBeam);
@ -1324,8 +1330,9 @@ void CPlayerGun::CancelLockOn() {
} }
void CPlayerGun::FireSecondary(float dt, CStateManager& mgr) { void CPlayerGun::FireSecondary(float dt, CStateManager& mgr) {
if (mgr.GetCameraManager()->IsInCinematicCamera()) if (mgr.GetCameraManager()->IsInCinematicCamera()) {
return; return;
}
if (x835_25_inPhazonBeam || x318_comboAmmoIdx == 0 || if (x835_25_inPhazonBeam || x318_comboAmmoIdx == 0 ||
!mgr.GetPlayerState()->HasPowerUp(skItemArr[x318_comboAmmoIdx]) || (x2f8_stateFlags & 0x4) != 0x4) { !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); x832_26_comboFiring ? mgr.GetPlayerState()->GetMissileCostForAltAttack() : 1);
comboFired = true; comboFired = true;
} }
if (x300_remainingMissiles > 5) if (x300_remainingMissiles > 5) {
x300_remainingMissiles = 5; x300_remainingMissiles = 5;
else } else {
x300_remainingMissiles -= 1; x300_remainingMissiles -= 1;
} }
}
if (comboFired) { if (comboFired) {
TUniqueId targetId = GetTargetId(mgr); 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(); targetId = mgr.GetPlayer().GetAimTarget();
}
zeus::CTransform fireXf = x833_29_pointBlankWorldSurface ? x448_elbowWorldXf : x4a8_gunWorldXf * x418_beamLocalXf; zeus::CTransform fireXf = x833_29_pointBlankWorldSurface ? x448_elbowWorldXf : x4a8_gunWorldXf * x418_beamLocalXf;
if (!x833_29_pointBlankWorldSurface && x364_gunStrikeCoolTimer <= 0.f) { if (!x833_29_pointBlankWorldSurface && x364_gunStrikeCoolTimer <= 0.f) {
zeus::CVector3f backupOrigin = fireXf.origin; 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; x350_shakeZ = chargeShakeTbl[mgr.GetActiveRandom()->Next() % 3] * x340_chargeBeamFactor;
} }
if (!x72c_currentBeam->IsLoaded()) if (!x72c_currentBeam->IsLoaded()) {
return; return;
}
GetLctrWithShake(x4d8_gunLocalXf, x73c_gunMotion->GetModelData(), "GBSE_SDK", true, true); GetLctrWithShake(x4d8_gunLocalXf, x73c_gunMotion->GetModelData(), "GBSE_SDK", true, true);
GetLctrWithShake(x418_beamLocalXf, x72c_currentBeam->GetSolidModelData(), "LBEAM", false, true); GetLctrWithShake(x418_beamLocalXf, x72c_currentBeam->GetSolidModelData(), "LBEAM", false, true);