Add asset array memory api stubs
This commit is contained in:
parent
f89b3ff706
commit
96ac39724d
@ -962,33 +962,35 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
|
||||
DTRAsset_InitGlobalState();
|
||||
|
||||
memory->isInit = true;
|
||||
memory->context = DqnMemStack_Push(&memory->permMemStack, sizeof(DTRState));
|
||||
DQN_ASSERT(memory->context);
|
||||
memory->context = DqnMemStack_Push(&memory->mainStack, sizeof(DTRState));
|
||||
|
||||
DqnMemStack *const assetStack = &memory->assetStack;
|
||||
DqnMemStack *const tempStack = &memory->tempStack;
|
||||
DQN_ASSERT(memory->context);
|
||||
state = (DTRState *)memory->context;
|
||||
DTRAsset_FontToBitmapLoad(input->api, memory, &state->font, "Roboto-bold.ttf",
|
||||
DqnV2i_2i(256, 256), DqnV2i_2i(' ', '~'), 12);
|
||||
DTRAsset_BitmapLoad(input->api, &memory->permMemStack,
|
||||
&memory->transMemStack, &state->bitmap, "tree00.bmp");
|
||||
DTRAsset_BitmapLoad(input->api, assetStack,
|
||||
tempStack, &state->bitmap, "tree00.bmp");
|
||||
|
||||
if (DTR_DEBUG)
|
||||
{
|
||||
DTRBitmap test = {};
|
||||
DqnTempMemStack tmp = DqnMemStack_BeginTempRegion(&memory->transMemStack);
|
||||
DTRAsset_BitmapLoad(input->api, &memory->permMemStack, &memory->transMemStack, &test, "byte_read_check.bmp");
|
||||
DqnTempMemStack tmp = DqnMemStack_BeginTempRegion(&memory->tempStack);
|
||||
DTRAsset_BitmapLoad(input->api, assetStack, &memory->tempStack, &test, "byte_read_check.bmp");
|
||||
DqnMemStack_EndTempRegion(tmp);
|
||||
}
|
||||
|
||||
if (DTRAsset_WavefModelLoad(input->api, memory, &state->obj, "african_head.obj"))
|
||||
{
|
||||
DTRAsset_BitmapLoad(input->api, &memory->permMemStack, &memory->transMemStack,
|
||||
&state->objTex, "african_head_diffuse.tga");
|
||||
DTRAsset_BitmapLoad(input->api, assetStack, tempStack, &state->objTex,
|
||||
"african_head_diffuse.tga");
|
||||
}
|
||||
|
||||
DTRDebug_TestWavefFaceAndVertexParser(&state->obj);
|
||||
}
|
||||
|
||||
DqnTempMemStack transMemTmpRegion = DqnMemStack_BeginTempRegion(&memory->transMemStack);
|
||||
DqnTempMemStack transMemTmpRegion = DqnMemStack_BeginTempRegion(&memory->tempStack);
|
||||
|
||||
DTRRenderBuffer renderBuffer = {};
|
||||
renderBuffer.width = platformRenderBuffer->width;
|
||||
@ -997,7 +999,7 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
|
||||
renderBuffer.memory = (u8 *)platformRenderBuffer->memory;
|
||||
|
||||
u32 zBufferSize = platformRenderBuffer->width * platformRenderBuffer->height;
|
||||
renderBuffer.zBuffer = (f32 *)DqnMemStack_Push(&memory->transMemStack,
|
||||
renderBuffer.zBuffer = (f32 *)DqnMemStack_Push(&memory->tempStack,
|
||||
zBufferSize * sizeof(*renderBuffer.zBuffer));
|
||||
|
||||
for (u32 i = 0; i < zBufferSize; i++) renderBuffer.zBuffer[i] = DQN_F32_MIN;
|
||||
@ -1153,8 +1155,8 @@ extern "C" void DTR_Update(PlatformRenderBuffer *const platformRenderBuffer,
|
||||
// End Update
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
DqnMemStack_EndTempRegion(transMemTmpRegion);
|
||||
DqnMemStack_ClearCurrBlock(&memory->transMemStack, true);
|
||||
DqnMemStack_ClearCurrBlock(&memory->tempStack, true);
|
||||
|
||||
DQN_ASSERT(memory->transMemStack.tempStackCount == 0);
|
||||
DQN_ASSERT(memory->permMemStack.tempStackCount == 0);
|
||||
DQN_ASSERT(memory->tempStack.tempStackCount == 0);
|
||||
DQN_ASSERT(memory->mainStack.tempStackCount == 0);
|
||||
}
|
||||
|
@ -17,17 +17,117 @@ void DTRAsset_InitGlobalState()
|
||||
stbi_set_flip_vertically_on_load(true);
|
||||
}
|
||||
|
||||
FILE_SCOPE bool WavefModelInit(DTRWavefModel *const obj, const i32 vertexInitCapacity = 100,
|
||||
const i32 faceInitCapacity = 100)
|
||||
FILE_SCOPE void MemcopyInternal(u8 *dest, u8 *src, size_t numBytes)
|
||||
{
|
||||
if (!dest || !src || numBytes == 0) return;
|
||||
for (size_t i = 0; i < numBytes; i++)
|
||||
dest[i] = src[i];
|
||||
}
|
||||
|
||||
FILE_SCOPE void AssetDqnArrayMemAPICallback(DqnMemAPICallbackInfo info, DqnMemAPICallbackResult *result)
|
||||
{
|
||||
DQN_ASSERT(info.type != DqnMemAPICallbackType_Invalid);
|
||||
DqnMemStack *stack = static_cast<DqnMemStack *>(info.userContext);
|
||||
switch (info.type)
|
||||
{
|
||||
case DqnMemAPICallbackType_Alloc:
|
||||
{
|
||||
void *ptr = DqnMemStack_Push(stack, info.requestSize);
|
||||
result->newMemPtr = ptr;
|
||||
result->type = DqnMemAPICallbackType_Alloc;
|
||||
}
|
||||
break;
|
||||
|
||||
case DqnMemAPICallbackType_Free:
|
||||
{
|
||||
DqnMemStackBlock **blockPtr = &stack->block;
|
||||
while (*blockPtr && (*blockPtr)->memory != info.ptrToFree)
|
||||
{
|
||||
// NOTE(doyle): Ensure that the base ptr of each block is always
|
||||
// actually aligned so we don't ever miss finding the block if
|
||||
// the allocator had to realign the pointer from the base
|
||||
// address.
|
||||
if (DTR_DEBUG)
|
||||
{
|
||||
size_t memBaseAddr = (size_t)((*blockPtr)->memory);
|
||||
DQN_ASSERT(DQN_ALIGN_POW_N(memBaseAddr, stack->byteAlign) ==
|
||||
memBaseAddr);
|
||||
}
|
||||
blockPtr = &((*blockPtr)->prevBlock);
|
||||
}
|
||||
|
||||
DQN_ASSERT(*blockPtr && (*blockPtr)->memory == info.ptrToFree);
|
||||
DqnMemStackBlock *blockToFree = *blockPtr;
|
||||
*blockPtr = blockToFree->prevBlock;
|
||||
DqnMem_Free(blockToFree);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case DqnMemAPICallbackType_Realloc:
|
||||
{
|
||||
result->type = DqnMemAPICallbackType_Realloc;
|
||||
|
||||
// Check if the ptr is the last thing that was allocated. If so we
|
||||
// can check if there's enough space in place for realloc and give
|
||||
// them that.
|
||||
u8 *currMemPtr = (u8 *)(stack->block->memory + stack->block->used);
|
||||
u8 *checkPtr = currMemPtr - info.oldSize;
|
||||
if (checkPtr == info.oldMemPtr)
|
||||
{
|
||||
if ((stack->block->used + info.newRequestSize) < stack->block->size)
|
||||
{
|
||||
stack->block->used += info.newRequestSize;
|
||||
result->newMemPtr = info.oldMemPtr;
|
||||
return;
|
||||
}
|
||||
|
||||
// The allocation was the last one allocated, but there's not
|
||||
// enough space to realloc in the block. For book-keeping,
|
||||
// "deallocate" the old mem ptr by reverting the usage of the
|
||||
// memory stack.
|
||||
stack->block->used -= info.oldSize;
|
||||
}
|
||||
|
||||
// NOTE(doyle): This leaves chunks of memory dead!!! But, we use
|
||||
// this in our custom allocator, which its strategy is to load all
|
||||
// the data, using as much re-allocations as required then after the
|
||||
// fact, recompact the data by Memcopying the data together and free
|
||||
// the extraneous blocks we've made.
|
||||
|
||||
// Otherwise, not enough space or, allocation is not the last
|
||||
// allocated, so can't expand inplace.
|
||||
DqnMemStackBlock *newBlock =
|
||||
DqnMemStack_AllocateCompatibleBlock(stack, info.newRequestSize);
|
||||
if (DqnMemStack_AttachBlock(stack, newBlock))
|
||||
{
|
||||
void *newPtr = DqnMemStack_Push(stack, info.newRequestSize);
|
||||
MemcopyInternal((u8 *)newPtr, (u8 *)info.oldMemPtr, info.oldSize);
|
||||
|
||||
result->newMemPtr = newPtr;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO(doyle): Die out of memory
|
||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FILE_SCOPE bool WavefModelInit(DTRWavefModel *const obj,
|
||||
DqnMemAPI memAPI = DqnMemAPI_DefaultUseCalloc(),
|
||||
const i32 vertexInitCapacity = 100, const i32 faceInitCapacity = 100)
|
||||
{
|
||||
if (!obj) return false;
|
||||
|
||||
bool initialised = false;
|
||||
|
||||
initialised |= DqnArray_Init(&obj->geometryArray, vertexInitCapacity);
|
||||
initialised |= DqnArray_Init(&obj->textureArray, vertexInitCapacity);
|
||||
initialised |= DqnArray_Init(&obj->normalArray, vertexInitCapacity);
|
||||
initialised |= DqnArray_Init(&obj->faces, faceInitCapacity);
|
||||
initialised |= DqnArray_Init(&obj->geometryArray, vertexInitCapacity, memAPI);
|
||||
initialised |= DqnArray_Init(&obj->textureArray, vertexInitCapacity, memAPI);
|
||||
initialised |= DqnArray_Init(&obj->normalArray, vertexInitCapacity, memAPI);
|
||||
initialised |= DqnArray_Init(&obj->faces, faceInitCapacity, memAPI);
|
||||
|
||||
if (!initialised)
|
||||
{
|
||||
@ -40,7 +140,8 @@ FILE_SCOPE bool WavefModelInit(DTRWavefModel *const obj, const i32 vertexInitCap
|
||||
return initialised;
|
||||
}
|
||||
|
||||
FILE_SCOPE inline DTRWavefModelFace WavefModelFaceInit(i32 capacity = 3)
|
||||
FILE_SCOPE inline DTRWavefModelFace
|
||||
WavefModelFaceInit(i32 capacity = 3, DqnMemAPI memAPI = DqnMemAPI_DefaultUseCalloc())
|
||||
{
|
||||
DTRWavefModelFace result = {};
|
||||
DQN_ASSERT(DqnArray_Init(&result.vertexIndexArray, capacity));
|
||||
@ -60,8 +161,8 @@ bool DTRAsset_WavefModelLoad(const PlatformAPI api, PlatformMemory *const memory
|
||||
return false; // TODO(doyle): Logging
|
||||
|
||||
// TODO(doyle): Make arrays use given memory not malloc
|
||||
DqnTempMemStack tmpMemRegion = DqnMemStack_BeginTempRegion(&memory->transMemStack);
|
||||
u8 *rawBytes = (u8 *)DqnMemStack_Push(&memory->transMemStack, file.size);
|
||||
DqnTempMemStack tmpMemRegion = DqnMemStack_BeginTempRegion(&memory->tempStack);
|
||||
u8 *rawBytes = (u8 *)DqnMemStack_Push(&memory->tempStack, file.size);
|
||||
size_t bytesRead = api.FileRead(&file, rawBytes, file.size);
|
||||
size_t fileSize = file.size;
|
||||
api.FileClose(&file);
|
||||
@ -79,6 +180,10 @@ bool DTRAsset_WavefModelLoad(const PlatformAPI api, PlatformMemory *const memory
|
||||
WavefVertexType_Normal,
|
||||
};
|
||||
|
||||
DqnMemAPI memAPI = {};
|
||||
memAPI.callback = AssetDqnArrayMemAPICallback;
|
||||
memAPI.userContext = &memory->assetStack;
|
||||
|
||||
if (!WavefModelInit(obj))
|
||||
{
|
||||
DqnMemStack_EndTempRegion(tmpMemRegion);
|
||||
@ -223,6 +328,9 @@ bool DTRAsset_WavefModelLoad(const PlatformAPI api, PlatformMemory *const memory
|
||||
// so offset by -1 to make it zero-based indexes.
|
||||
i32 vertIndex = (i32)Dqn_StrToI64(numStartPtr, numLen) - 1;
|
||||
|
||||
// TODO(doyle): Does not supprot relative vertexes yet
|
||||
DQN_ASSERT(vertIndex >= 0);
|
||||
|
||||
if (type == WavefVertexType_Geometric)
|
||||
{
|
||||
DQN_ASSERT(DqnArray_Push(&face.vertexIndexArray, vertIndex));
|
||||
@ -288,7 +396,7 @@ bool DTRAsset_WavefModelLoad(const PlatformAPI api, PlatformMemory *const memory
|
||||
|
||||
DQN_ASSERT(!obj->groupName[obj->groupNameIndex]);
|
||||
obj->groupName[obj->groupNameIndex++] = (char *)DqnMemStack_Push(
|
||||
&memory->permMemStack, (nameLen + 1) * sizeof(char));
|
||||
&memory->mainStack, (nameLen + 1) * sizeof(char));
|
||||
|
||||
for (i32 i = 0; i < nameLen; i++)
|
||||
obj->groupName[obj->groupNameIndex - 1][i] = namePtr[i];
|
||||
@ -370,8 +478,8 @@ bool DTRAsset_FontToBitmapLoad(const PlatformAPI api, PlatformMemory *const memo
|
||||
if (!api.FileOpen(path, &file, PlatformFilePermissionFlag_Read, PlatformFileAction_OpenOnly))
|
||||
return false; // TODO(doyle): Logging
|
||||
|
||||
DqnTempMemStack tmpMemRegion = DqnMemStack_BeginTempRegion(&memory->transMemStack);
|
||||
u8 *fontBuf = (u8 *)DqnMemStack_Push(&memory->transMemStack, file.size);
|
||||
DqnTempMemStack tmpMemRegion = DqnMemStack_BeginTempRegion(&memory->tempStack);
|
||||
u8 *fontBuf = (u8 *)DqnMemStack_Push(&memory->tempStack, file.size);
|
||||
size_t bytesRead = api.FileRead(&file, fontBuf, file.size);
|
||||
api.FileClose(&file);
|
||||
if (bytesRead != file.size)
|
||||
@ -393,7 +501,7 @@ bool DTRAsset_FontToBitmapLoad(const PlatformAPI api, PlatformMemory *const memo
|
||||
// Pack font data to bitmap
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
loadedFont.bitmap = (u8 *)DqnMemStack_Push(
|
||||
&memory->permMemStack,
|
||||
&memory->mainStack,
|
||||
(size_t)(loadedFont.bitmapDim.w * loadedFont.bitmapDim.h));
|
||||
|
||||
stbtt_pack_context fontPackContext = {};
|
||||
@ -406,7 +514,7 @@ bool DTRAsset_FontToBitmapLoad(const PlatformAPI api, PlatformMemory *const memo
|
||||
(i32)((codepointRange.max + 1) - codepointRange.min);
|
||||
|
||||
loadedFont.atlas = (stbtt_packedchar *)DqnMemStack_Push(
|
||||
&memory->permMemStack, numCodepoints * sizeof(stbtt_packedchar));
|
||||
&memory->mainStack, numCodepoints * sizeof(stbtt_packedchar));
|
||||
stbtt_PackFontRange(&fontPackContext, fontBuf, 0,
|
||||
STBTT_POINT_SIZE(sizeInPt), (i32)codepointRange.min,
|
||||
numCodepoints, loadedFont.atlas);
|
||||
@ -456,13 +564,6 @@ bool DTRAsset_FontToBitmapLoad(const PlatformAPI api, PlatformMemory *const memo
|
||||
// TODO(doyle): Not threadsafe
|
||||
FILE_SCOPE DqnMemStack *globalSTBImageAllocator;
|
||||
|
||||
FILE_SCOPE void MemcopyInternal(u8 *dest, u8 *src, size_t numBytes)
|
||||
{
|
||||
if (!dest || !src || numBytes == 0) return;
|
||||
for (size_t i = 0; i < numBytes; i++)
|
||||
dest[i] = src[i];
|
||||
}
|
||||
|
||||
FILE_SCOPE void *STBImageReallocSized(void *ptr, size_t oldSize, size_t newSize)
|
||||
{
|
||||
// TODO(doyle): Implement when needed. There's no easy way using our stack
|
||||
@ -506,18 +607,18 @@ FILE_SCOPE void *STBImageMalloc(size_t size)
|
||||
|
||||
// TODO(doyle): Uses malloc
|
||||
bool DTRAsset_BitmapLoad(const PlatformAPI api, DqnMemStack *const bitmapMemStack,
|
||||
DqnMemStack *const transMemStack, DTRBitmap *bitmap,
|
||||
DqnMemStack *const tempStack, DTRBitmap *bitmap,
|
||||
const char *const path)
|
||||
{
|
||||
if (!bitmap || !bitmapMemStack || !transMemStack) return false;
|
||||
if (!bitmap || !bitmapMemStack || !tempStack) return false;
|
||||
|
||||
bool result = false;
|
||||
PlatformFile file = {};
|
||||
if (!api.FileOpen(path, &file, PlatformFilePermissionFlag_Read, PlatformFileAction_OpenOnly))
|
||||
return result;
|
||||
|
||||
DqnTempMemStack tmpMemRegion = DqnMemStack_BeginTempRegion(transMemStack);
|
||||
u8 *const rawData = (u8 *)DqnMemStack_Push (transMemStack, file.size);
|
||||
DqnTempMemStack tmpMemRegion = DqnMemStack_BeginTempRegion(tempStack);
|
||||
u8 *const rawData = (u8 *)DqnMemStack_Push (tempStack, file.size);
|
||||
size_t bytesRead = api.FileRead (&file, rawData, file.size);
|
||||
|
||||
if (bytesRead != file.size) goto cleanup;
|
||||
|
@ -46,7 +46,7 @@ void DTRDebug_TestWavefFaceAndVertexParser(DTRWavefModel *const obj)
|
||||
}
|
||||
}
|
||||
|
||||
void DTRDebug_DumpZBuffer(DTRRenderBuffer *const renderBuffer, DqnMemStack *const transMemStack)
|
||||
void DTRDebug_DumpZBuffer(DTRRenderBuffer *const renderBuffer, DqnMemStack *const tempStack)
|
||||
{
|
||||
if (DTR_DEBUG)
|
||||
{
|
||||
@ -64,10 +64,10 @@ void DTRDebug_DumpZBuffer(DTRRenderBuffer *const renderBuffer, DqnMemStack *cons
|
||||
}
|
||||
}
|
||||
|
||||
DqnTempMemStack tmpMemRegion = DqnMemStack_BeginTempRegion(transMemStack);
|
||||
DqnTempMemStack tmpMemRegion = DqnMemStack_BeginTempRegion(tempStack);
|
||||
|
||||
size_t bufSize = DQN_MEGABYTE(16);
|
||||
char *bufString = (char *)DqnMemStack_Push(transMemStack, bufSize);
|
||||
char *bufString = (char *)DqnMemStack_Push(tempStack, bufSize);
|
||||
char *bufPtr = bufString;
|
||||
for (i32 i = 0; i < renderBuffer->width * renderBuffer->height; i++)
|
||||
{
|
||||
@ -149,6 +149,7 @@ FILE_SCOPE void PushMemStackText(const char *const name, const DqnMemStack *cons
|
||||
i32 numBlocks = 0;
|
||||
|
||||
DqnMemStackBlock *blockPtr = stack->block;
|
||||
size_t freeSizeOfCurrBlock = (blockPtr) ? blockPtr->size - blockPtr->used : 0;
|
||||
while (blockPtr)
|
||||
{
|
||||
totalUsed += blockPtr->used;
|
||||
@ -159,7 +160,7 @@ FILE_SCOPE void PushMemStackText(const char *const name, const DqnMemStack *cons
|
||||
|
||||
size_t totalUsedKb = totalUsed / 1024;
|
||||
size_t totalSizeKb = totalSize / 1024;
|
||||
size_t totalWastedKb = totalWasted / 1024;
|
||||
size_t totalWastedKb = (totalSize - totalUsed - freeSizeOfCurrBlock) / 1024;
|
||||
|
||||
char str[128] = {};
|
||||
Dqn_sprintf(str, "%s: %d block(s): %_$lld/%_$lld: wasted: %_$lld", name, numBlocks,
|
||||
@ -194,8 +195,9 @@ void DTRDebug_Update(DTRState *const state,
|
||||
|
||||
// memory
|
||||
{
|
||||
PushMemStackText("PermBuffer", &memory->permMemStack);
|
||||
PushMemStackText("TransBuffer", &memory->transMemStack);
|
||||
PushMemStackText("MainStack", &memory->mainStack);
|
||||
PushMemStackText("TempStack", &memory->tempStack);
|
||||
PushMemStackText("AssetStack", &memory->assetStack);
|
||||
}
|
||||
|
||||
DTRDebug_PushText("Mouse: %d, %d", input->mouse.x, input->mouse.y);
|
||||
|
@ -128,8 +128,9 @@ typedef struct PlatformInput
|
||||
|
||||
typedef struct PlatformMemory
|
||||
{
|
||||
DqnMemStack permMemStack;
|
||||
DqnMemStack transMemStack;
|
||||
DqnMemStack mainStack;
|
||||
DqnMemStack tempStack;
|
||||
DqnMemStack assetStack;
|
||||
bool isInit;
|
||||
void *context;
|
||||
} PlatformMemory;
|
||||
|
@ -273,21 +273,21 @@ FILE_SCOPE void Win32HandleMenuMessages(HWND window, MSG msg,
|
||||
|
||||
case Win32Menu_FileFlushMemory:
|
||||
{
|
||||
DqnMemStack permMemStack = globalPlatformMemory.permMemStack;
|
||||
DqnMemStack transMemStack = globalPlatformMemory.transMemStack;
|
||||
while (permMemStack.block->prevBlock)
|
||||
DqnMemStack_FreeLastBlock(&permMemStack);
|
||||
DqnMemStack mainStack = globalPlatformMemory.mainStack;
|
||||
DqnMemStack tempStack = globalPlatformMemory.tempStack;
|
||||
while (mainStack.block->prevBlock)
|
||||
DqnMemStack_FreeLastBlock(&mainStack);
|
||||
|
||||
while (transMemStack.block->prevBlock)
|
||||
DqnMemStack_FreeLastBlock(&transMemStack);
|
||||
while (tempStack.block->prevBlock)
|
||||
DqnMemStack_FreeLastBlock(&tempStack);
|
||||
|
||||
DqnMemStack_ClearCurrBlock(&transMemStack, true);
|
||||
DqnMemStack_ClearCurrBlock(&permMemStack, true);
|
||||
DqnMemStack_ClearCurrBlock(&tempStack, true);
|
||||
DqnMemStack_ClearCurrBlock(&mainStack, true);
|
||||
|
||||
PlatformMemory empty = {};
|
||||
globalPlatformMemory = empty;
|
||||
globalPlatformMemory.permMemStack = permMemStack;
|
||||
globalPlatformMemory.transMemStack = transMemStack;
|
||||
globalPlatformMemory.mainStack = mainStack;
|
||||
globalPlatformMemory.tempStack = tempStack;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -546,8 +546,10 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Platform Data Pre-amble
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
DQN_ASSERT(DqnMemStack_Init(&globalPlatformMemory.permMemStack, DQN_MEGABYTE(4), true, 4) &&
|
||||
DqnMemStack_Init(&globalPlatformMemory.transMemStack, DQN_MEGABYTE(4), true, 4));
|
||||
DQN_ASSERT(DqnMemStack_Init(&globalPlatformMemory.mainStack, DQN_MEGABYTE(4), true, 4) &&
|
||||
DqnMemStack_Init(&globalPlatformMemory.tempStack, DQN_MEGABYTE(4), true, 4) &&
|
||||
DqnMemStack_Init(&globalPlatformMemory.assetStack, DQN_MEGABYTE(4), true, 4)
|
||||
);
|
||||
|
||||
PlatformAPI platformAPI = {};
|
||||
platformAPI.FileOpen = Platform_FileOpen;
|
||||
|
39
src/dqn.h
39
src/dqn.h
@ -96,24 +96,18 @@ DQN_FILE_SCOPE void DqnMem_Free (void *memory);
|
||||
// BeginTempRegion and EndTempRegion functions. Specifically freeing
|
||||
// individual items is typically not generalisable in this scheme.
|
||||
|
||||
typedef struct DqnMemStackBlock
|
||||
{
|
||||
u8 *memory;
|
||||
size_t used;
|
||||
size_t size;
|
||||
|
||||
DqnMemStackBlock *prevBlock;
|
||||
} DqnMemStackBlock;
|
||||
|
||||
enum DqnMemStackFlag
|
||||
{
|
||||
DqnMemStackFlag_IsNotExpandable = (1 << 0),
|
||||
DqnMemStackFlag_IsFixedMemoryFromUser = (1 << 1), // NOTE(doyle): Required to indicate we CAN'T free this memory when free is called.
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Advanced API Structs
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct DqnMemStack
|
||||
{
|
||||
DqnMemStackBlock *block;
|
||||
struct DqnMemStackBlock *block;
|
||||
|
||||
u32 flags;
|
||||
i32 tempStackCount;
|
||||
@ -123,7 +117,7 @@ typedef struct DqnMemStack
|
||||
typedef struct DqnTempMemStack
|
||||
{
|
||||
DqnMemStack *stack;
|
||||
DqnMemStackBlock *startingBlock;
|
||||
struct DqnMemStackBlock *startingBlock;
|
||||
size_t used;
|
||||
|
||||
} DqnTempMemStack;
|
||||
@ -132,12 +126,12 @@ DQN_FILE_SCOPE bool DqnMemStack_InitWithFixedMem (DqnMemStack *const stack, u8 *
|
||||
DQN_FILE_SCOPE bool DqnMemStack_InitWithFixedSize(DqnMemStack *const stack, size_t size, const bool zeroClear, const u32 byteAlign = 4); // Single allocation from platform, no further allocations, returns NULL of allocate if out of space
|
||||
DQN_FILE_SCOPE bool DqnMemStack_Init (DqnMemStack *const stack, size_t size, const bool zeroClear, const u32 byteAlign = 4); // Allocates from platform dynamically as space runs out
|
||||
|
||||
DQN_FILE_SCOPE void *DqnMemStack_Push (DqnMemStack *const stack, size_t size); // Returns NULL if out of space and stack is using fixed memory/size, or platform allocation fails
|
||||
DQN_FILE_SCOPE bool DqnMemStack_Pop (DqnMemStack *const stack, void *ptr, size_t size); // Frees the given ptr. It MUST be the last allocated item in the stack
|
||||
DQN_FILE_SCOPE void DqnMemStack_Free (DqnMemStack *const stack); // Frees all blocks belonging to this stack
|
||||
DQN_FILE_SCOPE bool DqnMemStack_FreeStackBlock(DqnMemStack *const stack, DqnMemStackBlock *block); // Frees the specified block, returns false if block doesn't belong
|
||||
DQN_FILE_SCOPE void *DqnMemStack_Push (DqnMemStack *const stack, size_t size); // Returns NULL if out of space and stack is using fixed memory/size, or platform allocation fails.
|
||||
DQN_FILE_SCOPE bool DqnMemStack_Pop (DqnMemStack *const stack, void *ptr, size_t size); // Frees the given ptr. It MUST be the last allocated item in the stack.
|
||||
DQN_FILE_SCOPE void DqnMemStack_Free (DqnMemStack *const stack); // Frees all blocks belonging to this stack.
|
||||
DQN_FILE_SCOPE bool DqnMemStack_FreeStackBlock(DqnMemStack *const stack, DqnMemStackBlock *block); // Frees the specified block, returns false if block doesn't belong, calls DqnMem_Free().
|
||||
DQN_FILE_SCOPE bool DqnMemStack_FreeLastBlock (DqnMemStack *const stack); // Frees the last-most memory block. If last block, free that block, next allocate will attach a block.
|
||||
DQN_FILE_SCOPE void DqnMemStack_ClearCurrBlock(DqnMemStack *const stack, const bool zeroClear); // Reset the current memory block usage to 0
|
||||
DQN_FILE_SCOPE void DqnMemStack_ClearCurrBlock(DqnMemStack *const stack, const bool zeroClear); // Reset the current memory block usage to 0.
|
||||
|
||||
// TempMemStack is only required for the function. Once BeginTempRegion() is called, subsequent allocation calls can be made using the original stack.
|
||||
// Upon EndTempRegion() the original stack will free any additional blocks it allocated during the temp region and revert to the original
|
||||
@ -147,7 +141,20 @@ DQN_FILE_SCOPE void DqnMemStack_ClearCurrBlock(DqnMemStack *const stack, const
|
||||
DQN_FILE_SCOPE DqnTempMemStack DqnMemStack_BeginTempRegion(DqnMemStack *const stack);
|
||||
DQN_FILE_SCOPE void DqnMemStack_EndTempRegion (DqnTempMemStack tempstack);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// (OPTIONAL) DqnMemStack Advanced API
|
||||
// Blocks are freely modifiable if you want fine grained control. Size value and
|
||||
// memory ptr should _NOT_ be modified directly, only indirectly through the
|
||||
// regular API.
|
||||
typedef struct DqnMemStackBlock
|
||||
{
|
||||
u8 *memory;
|
||||
size_t size;
|
||||
size_t used;
|
||||
|
||||
DqnMemStackBlock *prevBlock;
|
||||
} DqnMemStackBlock;
|
||||
|
||||
// This is useful for forcing a new block to be used. AllocateCompatibleBlock
|
||||
// will fail if the supplied stack has flags set such that the stack is not
|
||||
// allowed to have new blocks.
|
||||
|
Loading…
Reference in New Issue
Block a user