diff --git a/examples/render_groups/main.cpp b/examples/render_groups/main.cpp index 24adad9..cc971fd 100644 --- a/examples/render_groups/main.cpp +++ b/examples/render_groups/main.cpp @@ -176,16 +176,12 @@ main() renDoRenderLoop(rs, 60, doFrameCallbackPre); #endif - //rs->assets = memInitBlock(INITIAL_ASSET_BLOCK_SIZE); - rs->assets = memInitBlock(10 * 1024 * 1024); // NOTE: 10MB - assert(rs->assets != nullptr); + rs->arena = arenaInit(); + rs->asset_list = + (render_asset*) arenaAllocateBlock(rs->arena, sizeof(render_asset)); - // load assets manually - render_asset* icosphere = memPushAsset(rs->assets, "../data/icosphere.glb"); - assert(icosphere != nullptr); - - render_asset* ship = memPushAsset(rs->assets, "../data/spaceship.glb"); - assert(ship != nullptr); + mesh_group mg; + meLoadFromFile(mg, "../data/blender/icosphere.gltf"); renShutdown(rs); return 0; diff --git a/include/renderer.h b/include/renderer.h index a5e6d47..107d921 100644 --- a/include/renderer.h +++ b/include/renderer.h @@ -46,13 +46,10 @@ struct SDL_Handles struct mesh_asset { - // header uint asset_size; uint num_vertices; uint num_indices; mesh_asset* next; - - // data glm::mat4 model_transform; glm::vec3* vertices; uint* indices; @@ -62,48 +59,19 @@ struct mesh_asset #define MAX_PATH_SIZE 256 struct render_asset { - // header uint total_size; uint num_meshes; uint name_len; render_asset* next; - - // data char* filepath; - mesh_asset* head_mesh; - // FIXME: also need to flatten diffuse_texture->pixels and track size of - // util_image structure, ie) another heaader + pixels - //uint tex_size; + mesh_asset* meshes; // NOTE: fixed sized array + // NOTE: pointer to a texture in render_state->textures util_image* diffuse_texture; // FIXME: node_animation has a pointer to a render_object. need to decouple // that somehow //node_animation* node_anim; }; -// NOTE: This is a linearly allocated block to contain all used mesh assets -// Assets are loaded once, and then copied to video memory as needed. -// NOTE: sub-data structures are implemented as a write only single linked list, -// with no insertion or moving of items -// https://en.wikipedia.org/wiki/Region-based_memory_management -// http://cslibrary.stanford.edu/103/LinkedListBasics.pdf -struct asset_memory_block -{ - size_t max_size; - render_asset* head; - render_asset* tail; - uint asset_count; -}; - -#define INITIAL_ASSET_BLOCK_SIZE 256 * 1024 * 1024 // 256MB -asset_memory_block* -memInitBlock(size_t initial_size = INITIAL_ASSET_BLOCK_SIZE); - -render_asset* -memPushAsset(asset_memory_block* block, const char* filepath); - -void -memFreeBlock(asset_memory_block* block); - // Memory allocation WIP // -------------------------- @@ -121,7 +89,11 @@ struct render_state uint render_group_count; // WIP - asset_memory_block* assets; + render_asset* asset_list; // NOTE: head pointer of linked list + memory_arena* arena; + // FIXME: should be a hashmap for textures loaded from assets + // ie) pallete textures + util_image* textures; // TODO: hide shaders behind a better abstraction than 'shader_wrapper' default_shader_program* default_shader; diff --git a/include/util.h b/include/util.h index 3ec7225..e869632 100644 --- a/include/util.h +++ b/include/util.h @@ -94,6 +94,22 @@ void* utilLogAlloc(uint item_count, uint type_size, const char* file_name, const #define UTIL_FREE(mem_ptr) utilSafeFree((void*&) mem_ptr) void utilSafeFree(const void* mem); +struct memory_arena +{ + size_t max_size; + void* head; + void* next_free; +}; + +#define DEFAULT_ARENA_SIZE 10 * 1024 * 1024 // 10MB +memory_arena* arenaInit(size_t initial_size = DEFAULT_ARENA_SIZE); + +void arenaFree(memory_arena*& arena); + +uint arenaGetFreeSize(memory_arena* arena); + +void* arenaAllocateBlock(memory_arena* arena, size_t block_size); + //----------------- // File I/O diff --git a/src/renderer.cpp b/src/renderer.cpp index 13b3a9d..480315b 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -37,146 +37,6 @@ void setDefaults(render_state* rs, glm::vec2 viewport_dims); // interface -// WIP -size_t -getBlockFreeSpace(asset_memory_block* block) -{ - return (uint8_t*) block - + block->max_size - - (uint8_t*) block->tail - + block->tail->total_size; -} - -uint -getAssetSize(const mesh_group& mg, uint name_len) -{ - uint total = sizeof(render_asset); - total += name_len; - - for (uint i = 0; i < mg.num_meshes; i++) { - mesh_info* mi = mg.meshes[i]; - total += sizeof(mesh_asset); - // NOTE: vertices, normals, and tex coords - total += 3 * mi->num_vertices * sizeof(glm::vec3); - total += mi->num_indices * sizeof(uint); - } - - return total; -} - -void* -getAddressOffset(void* address, uint offset) -{ - return (void*) ((uint8_t*) address + offset); -} - -// TODO: replace mesh_info structure -mesh_asset* -initMeshAsset(mesh_asset* mesh, mesh_info* mi) -{ - mesh->num_vertices = mi->num_vertices; - mesh->num_indices = mi->num_indices; - mesh->asset_size = sizeof(mesh_asset); - mesh->vertices = (glm::vec3*) ((uint8_t*) mesh + mesh->asset_size); - // NOTE: vertices, normals, and tex coords - mesh->asset_size += 3 * mesh->num_vertices * sizeof(glm::vec3); - mesh->asset_size += mesh->num_indices * sizeof(uint); - mesh->asset_size += sizeof(glm::mat4); - // FIXME: this should be set in the outer loop - //mesh->next = (mesh_asset*) ((uint8_t*) mesh + mesh->asset_size); - // FIXME: copy vertices, normals, tex coords, and xform - - return mesh; -} - -render_asset* -getNextFreeRenderAsset(asset_memory_block* block) -{ - return (render_asset*) - getAddressOffset(block->tail, block->tail->total_size); -} - -#include -render_asset* -initRenderAsset( - render_asset* ra, - uint total_size, - uint num_meshes, - const char* filepath) -{ - ra->total_size = total_size; - ra->num_meshes = num_meshes; - ra->name_len = (uint) std::strlen(filepath) + 1; - ra->next = nullptr; - ra->filepath = (char*) ra + sizeof(render_asset); - std::memcpy(ra->filepath, filepath, ra->name_len); - ra->head_mesh = (mesh_asset*) ((uint8_t*) ra->filepath + ra->name_len); - // TODO: texture - //ra->diffuse_texture = (util_image*) ra->filepath; - - return ra; -} - -asset_memory_block* -memInitBlock(size_t initial_size) -{ - // NOTE: need to alloc as uint8_t and recast here so we can get the correct - // size in bytes - asset_memory_block* block = (asset_memory_block*) UTIL_ALLOC( - sizeof(asset_memory_block) + initial_size, uint8_t); - block->max_size = initial_size - sizeof(asset_memory_block); - block->head = block->tail = - (render_asset*) ((uint8_t*) block + sizeof(asset_memory_block)); - return block; -} - -void -memFreeBlock(asset_memory_block* block) -{ - utilSafeFree(block); -} - -render_asset* -memPushAsset(asset_memory_block* block, const char* filepath) -{ - // TODO: rewrite mesh.cpp to load assimp structure into render_asset - // directly - mesh_group mg; - meLoadFromFile(mg, filepath); - uint name_len = (uint) std::strlen(filepath) + 1; - assert(name_len <= MAX_PATH_SIZE); - uint asize = getAssetSize(mg, name_len); - - if (getBlockFreeSpace(block) < asize) { - LOG(Error) << "not enough free space in block\n"; - return nullptr; - } - - render_asset* ra = getNextFreeRenderAsset(block); - initRenderAsset(ra, asize, mg.num_meshes, filepath); - block->max_size -= asize; - block->asset_count++; - - // NOTE: special case when adding the first asset - if (block->head == block->tail) - block->head->next = ra; - else - block->tail->next = ra; - - block->tail = ra; - mesh_asset* next = ra->head_mesh; - - for (uint i = 0; i < mg.num_meshes; i++) { - mesh_asset* mesh = initMeshAsset(next, mg.meshes[i]); - next = (mesh_asset*) getAddressOffset(mesh, mesh->asset_size); - // NOTE: leave the last link as nullptr - (i < mg.num_meshes - 1) ? mesh->next = next : mesh->next = nullptr; - } - - return ra; -} -// end WIP - render_state* renInit(const char* title, glm::vec2 viewport_dims, Uint32 SDL_init_flags) { @@ -217,8 +77,8 @@ renShutdown(render_state* rs) lightsOut(rs->lights); utilSafeFree(rs->render_groups); - memFreeBlock(rs->assets); - rs->assets = nullptr; + rs->render_groups = nullptr; + arenaFree(rs->arena); meShutdownAssimp(); SDL_GL_DeleteContext(rs->handles->glContext); SDL_DestroyWindow(rs->handles->window); diff --git a/src/util.cpp b/src/util.cpp index 6fc0a17..d7974ec 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -84,6 +84,41 @@ utilSafeFree(const void* mem) if (mem != nullptr) std::free((void *) mem); } +memory_arena* +arenaInit(size_t initial_size) +{ + uint sz = sizeof(memory_arena); + memory_arena* arena = + (memory_arena*) UTIL_ALLOC(initial_size + sz, uint8_t); + arena->head = arena->next_free = (uint8_t*) arena + sz; + arena->max_size = initial_size; + return arena; +} + +void +arenaFree(memory_arena*& arena) +{ + utilSafeFree(arena); + arena = nullptr; +} + +uint +arenaGetFreeSize(memory_arena* arena) +{ + return (uint8_t*) arena->head + + arena->max_size + - (uint8_t*) arena->next_free; +} + +void* +arenaAllocateBlock(memory_arena* arena, size_t block_size) +{ + assert(arenaGetFreeSize(arena) >= block_size); + void* ret = arena->next_free; + arena->next_free = (uint8_t*) arena->next_free + block_size; + return ret; +} + //----------------- // File I/O