From d4f5c48b056a91c84b3a42733389c88a9ca6e44b Mon Sep 17 00:00:00 2001 From: Andriy Logvin Date: Thu, 10 Oct 2024 20:18:06 +0100 Subject: [PATCH 1/2] fix(game/five): prevent memory corruption in gta-streaming-five Before build 3258 we were using rage::fwEntity::SetModelId to get archetype by model index, because it would not do anything besides setting the archetype. However on 3258+ this function is no longer available, so we used another one. However the new function expects an input of higher size and may have some side efects if the input is not initialized properly. We forgot to increase the fakeEntity size which led to memory corruption. The memory corruption caused a memory leak in fwArchetypePooledMap pool and a few other pools (neither of which are not tracked by Pool Monitor unfortunately). As a result we would run out of space in those pools and some entities would fail to be created. The way visibility for lods is set is that the lod is displayed until all its children (higher resolution pieces of image) are created and added to lod hirerarchy. Because otherwise we may have holes in textures. So when one or two children of a lod would fail to be created (usually a bush or something insignificant) - the lod would stay visible. I.e. a blurred texture would be drawn over the high resolution one. Which was reported in issue https://github.com/citizenfx/fivem/issues/2752. Exactly the same symptoms may be visible if map is just overloaded with resources and the archetype pools run out of space for natural reasons. Unfortunately there fix there is more complex than just increasing a number because the current size limit is already very close to the data type size limit (64000 vs 2^16). It should be increased in followup commits nevetheless. Some people mentioned they've seen this issue on builds before 3258 (but much less often). It could be due to too much resources (as described above), or maybe there is some other (much smaller) issue as well. But I believe that the cause for blurred lods to stay visible is the same - some of it's children are not created. --- .../gta-streaming-five/src/PatchStreamingPreparation.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/components/gta-streaming-five/src/PatchStreamingPreparation.cpp b/code/components/gta-streaming-five/src/PatchStreamingPreparation.cpp index 44b8c84112..d55a5489d9 100644 --- a/code/components/gta-streaming-five/src/PatchStreamingPreparation.cpp +++ b/code/components/gta-streaming-five/src/PatchStreamingPreparation.cpp @@ -532,9 +532,12 @@ static void fwEntity_DtorWrap(rage::fwEntity* entity) // to do this, we use a little hack to not have to manually read the archetype list: // the base rage::fwEntity::SetModelId doesn't do anything other than setting (rcx + 32) // to the resolved archetype, or nullptr if none + // + // Note: for build 3258+ - this function actually tries to do more than just setting the archetype, + // but if the input is initialized with zeroes - it will work as we want it to. rage::fwModelId modelId(midx); - void* fakeEntity[40 / 8] = { 0 }; + void* fakeEntity[64 / 8] = { 0 }; _fwEntity_SetModelId(fakeEntity, modelId); // not the same archetype - bail out From 9e002fd0420e7a8d2c521d5dee995efcb37681d9 Mon Sep 17 00:00:00 2001 From: Andriy Logvin Date: Thu, 10 Oct 2024 20:39:17 +0100 Subject: [PATCH 2/2] fix(game/five): increase fwArchetypePooledMap pool size We get pretty close to the current limit even with some basic resources. But we can't increase the size above 2^16 because the size of this pool is stored in uint16. Increase size of the pool as much as possible. --- data/client/citizen/common/data/gameconfig.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/client/citizen/common/data/gameconfig.xml b/data/client/citizen/common/data/gameconfig.xml index 62820fcd68..e1e5876ec5 100644 --- a/data/client/citizen/common/data/gameconfig.xml +++ b/data/client/citizen/common/data/gameconfig.xml @@ -608,7 +608,7 @@ fwArchetypePooledMap - + CTaskConversationHelper