fix memory arena alloc
This commit is contained in:
@@ -98,8 +98,9 @@ struct SharedDevData
|
|||||||
|
|
||||||
struct MemoryArena
|
struct MemoryArena
|
||||||
{
|
{
|
||||||
uint8_t* Ptr = nullptr;
|
uint8_t* Base = nullptr;
|
||||||
uint64_t Size = 0;
|
uint64_t Used = 0;
|
||||||
|
uint64_t MaxSize = 0;
|
||||||
uint64_t LastAllocSize = 0;
|
uint64_t LastAllocSize = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -266,9 +266,10 @@ bool ReloadDLL()
|
|||||||
|
|
||||||
void InitMemoryArena(MemoryArena& arena, uint64_t size)
|
void InitMemoryArena(MemoryArena& arena, uint64_t size)
|
||||||
{
|
{
|
||||||
arena.Size = size;
|
arena.MaxSize = size;
|
||||||
arena.Ptr = reinterpret_cast<uint8_t*>(
|
arena.Base = reinterpret_cast<uint8_t*>(
|
||||||
VirtualAllocEx(GetCurrentProcess(), NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE));
|
VirtualAllocEx(GetCurrentProcess(), NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE));
|
||||||
|
arena.Used = 0;
|
||||||
arena.LastAllocSize = 0;
|
arena.LastAllocSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,21 +37,20 @@ namespace Game
|
|||||||
GameInst = &instance;
|
GameInst = &instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* AllocateScratch(size_t byteCount, size_t align)
|
uint8_t* AllocateScratch(uint64_t byteCount, uint32_t align)
|
||||||
{
|
{
|
||||||
size_t offset = GetInstance().UsedScratchAmount;
|
assert(align <= 64); // The alignment of the arena limits the alignment that can be specified here!
|
||||||
uint8_t* base = GetShared().Game.TransientArena.Ptr;
|
auto& arena = GetShared().Game.TransientArena;
|
||||||
uint8_t* current = base + offset;
|
uint64_t offsetAligned = ((arena.Used + align - 1) / align) * align;
|
||||||
size_t offsetAligned = ((offset + align - 1) / align) * align;
|
uint8_t* ptrAligned = arena.Base + offsetAligned;
|
||||||
uint8_t* ptrAligned = base + offsetAligned;
|
uint64_t newOffset = offsetAligned + byteCount;
|
||||||
size_t newOffset = offsetAligned + byteCount;
|
if (newOffset > arena.MaxSize) return nullptr;
|
||||||
if (newOffset > GetShared().Game.TransientArena.Size) return nullptr;
|
arena.Used = newOffset;
|
||||||
GetInstance().UsedScratchAmount = newOffset;
|
arena.LastAllocSize = byteCount;
|
||||||
GetShared().Game.TransientArena.LastAllocSize = byteCount;
|
|
||||||
return ptrAligned;
|
return ptrAligned;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResizeLastScratchAlloc(size_t newByteCount)
|
bool ResizeLastScratchAlloc(uint64_t newByteCount)
|
||||||
{
|
{
|
||||||
auto& arena = GetShared().Game.TransientArena;
|
auto& arena = GetShared().Game.TransientArena;
|
||||||
if (newByteCount > arena.LastAllocSize)
|
if (newByteCount > arena.LastAllocSize)
|
||||||
@@ -59,8 +58,17 @@ namespace Game
|
|||||||
LOG_ERROR("Can't resize to more than previous size!");
|
LOG_ERROR("Can't resize to more than previous size!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
arena.Ptr -= arena.LastAllocSize;
|
LOG("Resizing last allocation from %llu to %llu", arena.LastAllocSize, newByteCount);
|
||||||
arena.Ptr += newByteCount;
|
arena.Used -= arena.LastAllocSize;
|
||||||
|
arena.Used += newByteCount;
|
||||||
|
LOG("New total: %llu", arena.Used);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResetScratch()
|
||||||
|
{
|
||||||
|
auto& arena = GetShared().Game.TransientArena;
|
||||||
|
arena.Used = 0;
|
||||||
|
arena.LastAllocSize = 0;
|
||||||
|
}
|
||||||
} // namespace Game
|
} // namespace Game
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ namespace Game
|
|||||||
void SetShared(SharedData& instance);
|
void SetShared(SharedData& instance);
|
||||||
GameInstance& GetInstance();
|
GameInstance& GetInstance();
|
||||||
void SetInstance(GameInstance& instance);
|
void SetInstance(GameInstance& instance);
|
||||||
uint8_t* AllocateScratch(size_t byteCount, size_t align = 16);
|
uint8_t* AllocateScratch(uint64_t byteCount, uint32_t align = 16);
|
||||||
bool ResizeLastScratchAlloc(size_t newByteCount);
|
bool ResizeLastScratchAlloc(uint64_t newByteCount);
|
||||||
|
void ResetScratch();
|
||||||
} // namespace Game
|
} // namespace Game
|
||||||
|
|||||||
@@ -75,7 +75,6 @@ namespace Game
|
|||||||
{
|
{
|
||||||
bool IsInitialized = false;
|
bool IsInitialized = false;
|
||||||
uint64_t Size = sizeof(GameInstance);
|
uint64_t Size = sizeof(GameInstance);
|
||||||
uint64_t UsedScratchAmount = 0;
|
|
||||||
Time Time;
|
Time Time;
|
||||||
PlayerData Player;
|
PlayerData Player;
|
||||||
Level GameLevel;
|
Level GameLevel;
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ namespace Game
|
|||||||
void Level::Setup(GameData& data)
|
void Level::Setup(GameData& data)
|
||||||
{
|
{
|
||||||
LOG("Level setup");
|
LOG("Level setup");
|
||||||
uint8_t* storagePtr = data.EntityArena.Ptr;
|
uint8_t* storagePtr = data.EntityArena.Base;
|
||||||
bool needReset = false;
|
bool needReset = false;
|
||||||
needReset |= Cubes.Setup(storagePtr, needReset);
|
needReset |= Cubes.Setup(storagePtr, needReset);
|
||||||
needReset |= Tests.Setup(storagePtr, needReset);
|
needReset |= Tests.Setup(storagePtr, needReset);
|
||||||
|
|||||||
@@ -33,30 +33,30 @@ namespace Game
|
|||||||
tracy::StartupProfiler();
|
tracy::StartupProfiler();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (shared.Game.PermanentArena.Ptr == nullptr)
|
if (shared.Game.PermanentArena.Base == nullptr)
|
||||||
{
|
{
|
||||||
LOG_ERROR("Game memory not initialized!!");
|
LOG_ERROR("Game memory not initialized!!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (shared.Game.EntityArena.Ptr == nullptr)
|
if (shared.Game.EntityArena.Base == nullptr)
|
||||||
{
|
{
|
||||||
LOG_ERROR("Entity memory not initialized!");
|
LOG_ERROR("Entity memory not initialized!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (shared.Game.PermanentArena.Size < sizeof(GameInstance))
|
if (shared.Game.PermanentArena.MaxSize < sizeof(GameInstance))
|
||||||
{
|
{
|
||||||
LOG_ERROR("Game memory too small! %u < %u", shared.Game.PermanentArena.Size, sizeof(GameInstance));
|
LOG_ERROR("Game memory too small! %u < %u", shared.Game.PermanentArena.MaxSize, sizeof(GameInstance));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GameInstance& instance = *reinterpret_cast<GameInstance*>(shared.Game.PermanentArena.Ptr);
|
GameInstance& instance = *reinterpret_cast<GameInstance*>(shared.Game.PermanentArena.Base);
|
||||||
if (sizeof(GameInstance) != instance.Size)
|
if (sizeof(GameInstance) != instance.Size)
|
||||||
{
|
{
|
||||||
LOG_WARN("Game instance size changed, resetting!");
|
LOG_WARN("Game instance size changed, resetting!");
|
||||||
instance = {};
|
instance = {};
|
||||||
}
|
}
|
||||||
instance.UsedScratchAmount = 0;
|
|
||||||
SetShared(shared);
|
SetShared(shared);
|
||||||
SetInstance(instance);
|
SetInstance(instance);
|
||||||
|
ResetScratch();
|
||||||
Puzzle::LoadStaticPuzzleData();
|
Puzzle::LoadStaticPuzzleData();
|
||||||
SetupInstance.Rendering.Setup();
|
SetupInstance.Rendering.Setup();
|
||||||
instance.GameLevel.Setup(shared.Game);
|
instance.GameLevel.Setup(shared.Game);
|
||||||
|
|||||||
@@ -36,13 +36,14 @@ namespace Game
|
|||||||
constexpr size_t MaxFileSize = ChunkSize * 1024 * 1024;
|
constexpr size_t MaxFileSize = ChunkSize * 1024 * 1024;
|
||||||
constexpr size_t MaxChunkCount = MaxFileSize / ChunkSize;
|
constexpr size_t MaxChunkCount = MaxFileSize / ChunkSize;
|
||||||
|
|
||||||
bool BufferedFileRead(FILE* file, uint8_t* writePtr, size_t& totalReadCount)
|
bool BufferedFileRead(FILE* const file, uint8_t* const writePtrIn, size_t& outTotalReadCount)
|
||||||
{
|
{
|
||||||
|
uint8_t* writePtr = writePtrIn;
|
||||||
for (int32_t i = 0; i < MaxChunkCount; ++i)
|
for (int32_t i = 0; i < MaxChunkCount; ++i)
|
||||||
{
|
{
|
||||||
size_t readCount = std::fread(writePtr, 1, ChunkSize, file);
|
size_t readCount = std::fread(writePtr, 1, ChunkSize, file);
|
||||||
writePtr += readCount;
|
writePtr += readCount;
|
||||||
totalReadCount += readCount;
|
outTotalReadCount += readCount;
|
||||||
|
|
||||||
if (readCount != ChunkSize)
|
if (readCount != ChunkSize)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user