From f7dd43f5eb5b2f423d7b93bd07daf62325600716 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Mon, 30 Sep 2024 17:55:58 +0200 Subject: [PATCH] prepare logging update... right now completely broken --- asset/AssetManagementSystem.h | 9 +- debug/Debug.h | 26 ++++ debug/DebugMemory.h | 171 ++++++++++++++++++++++++++ debug/Log.h | 168 +++++++++++++++++++++++++ debug/TimingStat.h | 46 +++++++ gpuapi/opengl/OpenglUtils.h | 19 +++ image/default_colors.htm | 22 ++-- log/Log.h | 190 ----------------------------- memory/BufferMemory.h | 10 +- memory/ChunkMemory.h | 20 ++- memory/DebugMemory.h | 91 -------------- memory/RingMemory.h | 28 +++-- object/Vertex.h | 7 +- platform/win32/audio/DirectSound.h | 14 +-- platform/win32/audio/XAudio2.h | 12 +- utils/TestUtils.h | 40 ------ 16 files changed, 503 insertions(+), 370 deletions(-) create mode 100644 debug/Debug.h create mode 100644 debug/DebugMemory.h create mode 100644 debug/Log.h create mode 100644 debug/TimingStat.h delete mode 100644 log/Log.h delete mode 100644 memory/DebugMemory.h diff --git a/asset/AssetManagementSystem.h b/asset/AssetManagementSystem.h index f7baac0..8cef685 100644 --- a/asset/AssetManagementSystem.h +++ b/asset/AssetManagementSystem.h @@ -137,12 +137,18 @@ Asset* ams_get_asset(AssetManagementSystem* ams, const char* key) { HashEntry* entry = hashmap_get_entry(&ams->hash_map, key); + // @bug entry->value seems to be an address outside of any known buffer, how? + DEBUG_MEMORY_READ( + (uint64) (entry ? (Asset *) entry->value : 0), + entry ? ((Asset *) entry->value)->ram_size + sizeof(Asset) : 0 + ); + return entry ? (Asset *) entry->value : NULL; } // @todo implement defragment command to optimize memory layout since the memory layout will become fragmented over time -Asset* ams_reserve_asset(AssetManagementSystem* ams, const char* name, uint64 elements = 1) +Asset* ams_reserve_asset(AssetManagementSystem* ams, const char* name, uint32 elements = 1) { int64 free_asset = chunk_reserve(&ams->asset_memory, elements, true); if (free_asset < 0) { @@ -163,6 +169,7 @@ Asset* ams_reserve_asset(AssetManagementSystem* ams, const char* name, uint64 el chunk_reserve_index(&ams->asset_data_memory, free_asset, elements, true); asset->self = chunk_get_element(&ams->asset_data_memory, free_asset); + asset->size = elements; // Curcial for freeing asset->ram_size = ams->asset_memory.chunk_size * elements; // @performance Do we really want a double linked list. Are we really using this feature or is the free_index enough? diff --git a/debug/Debug.h b/debug/Debug.h new file mode 100644 index 0000000..c5e5624 --- /dev/null +++ b/debug/Debug.h @@ -0,0 +1,26 @@ +/** + * Jingga + * + * @copyright Jingga + * @license OMS License 2.0 + * @version 1.0.0 + * @link https://jingga.app + */ +#ifndef TOS_LOG_DEBUG_H +#define TOS_LOG_DEBUG_H + +#include "DebugMemory.h" +#include "Log.h" +#include "TimingStat.h" + +struct DebugContainer { + DebugMemoryContainer dmc; + TimingStat* perf_stats; + LogMemory log_memory; + + #if _WIN32 + HANDLE log_fp; + #endif +}; + +#endif \ No newline at end of file diff --git a/debug/DebugMemory.h b/debug/DebugMemory.h new file mode 100644 index 0000000..862feb0 --- /dev/null +++ b/debug/DebugMemory.h @@ -0,0 +1,171 @@ +/** + * Jingga + * + * @copyright Jingga + * @license OMS License 2.0 + * @version 1.0.0 + * @link https://jingga.app + */ +#ifndef TOS_LOG_DEBUG_MEMORY_H +#define TOS_LOG_DEBUG_MEMORY_H + +#include +#include + +#include "../stdlib/Types.h" +#include "Debug.h" + +// required for __rdtsc +#if _WIN32 + #include +#else + #include +#endif + +// @todo don't use a pointer to this should be in a global together with other logging data (see Log.h) +inline +DebugMemory* debug_memory_find(uint64 start, uint64 size) +{ + for (int i = 0; i < debug_container->dmc->memory_size; ++i) { + if (debug_container->dmc->memory_stats[i].start <= start + && debug_container->dmc->memory_stats[i].start + debug_container->dmc->memory_stats[i].size >= start + ) { + return &debug_container->dmc->memory_stats[i]; + } + } + + return NULL; +} + +void debug_memory_init(uint64 start, uint64 size) +{ + if (!start) { + return; + } + + DebugMemory* mem = debug_memory_find(start, size); + if (mem) { + return; + } + + if (debug_container->dmc->memory_size <= debug_container->dmc->memory_element_idx) { + DebugMemory* old = debug_container->dmc->memory_stats; + + debug_container->dmc->memory_size += 3; + debug_container->dmc->memory_stats = (DebugMemory *) calloc(debug_container->dmc->memory_size, sizeof(DebugMemory)); + + if (old) { + memcpy(debug_container->dmc->memory_stats, old, (debug_container->dmc->memory_size - 3) * sizeof(DebugMemory)); + free(old); + } + } + + debug_container->dmc->memory_stats[debug_container->dmc->memory_element_idx].start = start; + debug_container->dmc->memory_stats[debug_container->dmc->memory_element_idx].size = size; + debug_container->dmc->memory_stats[debug_container->dmc->memory_element_idx].usage = 0; + + ++debug_container->dmc->memory_element_idx; +} + +void debug_memory_write(uint64 start, uint64 size) +{ + if (!start) { + return; + } + + DebugMemory* mem = debug_memory_find(start, size); + if (!mem) { + return; + } + + if (mem->action_idx == DEBUG_MEMORY_RANGE_MAX) { + mem->action_idx = 0; + } + + mem->last_action[mem->action_idx].type = 1; + mem->last_action[mem->action_idx].start = start - mem->start; + mem->last_action[mem->action_idx].size = size; + + // @question consider to use other time_ms() since __rdtsc is variable (boost, power saving) + mem->last_action[mem->action_idx].time = __rdtsc(); + + ++mem->action_idx; + mem->usage += size; +} + +void debug_memory_read(uint64 start, uint64 size) +{ + if (!start) { + return; + } + + DebugMemory* mem = debug_memory_find(start, size); + if (!mem) { + return; + } + + if (mem->action_idx == DEBUG_MEMORY_RANGE_MAX) { + mem->action_idx = 0; + } + + mem->last_action[mem->action_idx].type = 0; + mem->last_action[mem->action_idx].start = start - mem->start; + mem->last_action[mem->action_idx].size = size; + + // @question consider to use other time_ms() since __rdtsc is variable (boost, power saving) + mem->last_action[mem->action_idx].time = __rdtsc(); + + ++mem->action_idx; +} + +void debug_memory_delete(uint64 start, uint64 size) +{ + DebugMemory* mem = debug_memory_find(start, size); + if (!mem) { + return; + } + + if (mem->action_idx == DEBUG_MEMORY_RANGE_MAX) { + mem->action_idx = 0; + } + + mem->last_action[mem->action_idx].type = -1; + mem->last_action[mem->action_idx].start = start - mem->start; + mem->last_action[mem->action_idx].size = size; + + // @question consider to use other time_ms() since __rdtsc is variable (boost, power saving) + mem->last_action[mem->action_idx].time = __rdtsc(); + + ++mem->action_idx; + mem->usage -= size; +} + +inline +void debug_memory_reset() +{ + uint64 time = __rdtsc() - 1000000000; + + for (int i = 0; i < debug_container->dmc->memory_element_idx; ++i) { + for (int j = 0; j < DEBUG_MEMORY_RANGE_MAX; ++j) { + if (debug_container->dmc->memory_stats[i].last_action[j].time < time) { + memset(&debug_container->dmc->memory_stats[i].last_action[j], 0, sizeof(DebugMemoryRange)); + } + } + } +} + +#if DEBUG + #define DEBUG_MEMORY_INIT(start, size) debug_memory_init((start), (size)) + #define DEBUG_MEMORY_READ(start, size) debug_memory_read((start), (size)) + #define DEBUG_MEMORY_WRITE(start, size) debug_memory_write((start), (size)) + #define DEBUG_MEMORY_DELETE(start, size) debug_memory_delete((start), (size)) + #define DEBUG_MEMORY_RESET() debug_memory_reset() +#else + #define DEBUG_MEMORY_INIT(start, size) ((void) 0) + #define DEBUG_MEMORY_READ(start, size) ((void) 0) + #define DEBUG_MEMORY_WRITE(start, size) ((void) 0) + #define DEBUG_MEMORY_DELETE(start, size) ((void) 0) + #define DEBUG_MEMORY_RESET() ((void) 0) +#endif + +#endif \ No newline at end of file diff --git a/debug/Log.h b/debug/Log.h new file mode 100644 index 0000000..7433035 --- /dev/null +++ b/debug/Log.h @@ -0,0 +1,168 @@ +/** + * Jingga + * + * @copyright Jingga + * @license OMS License 2.0 + * @version 1.0.0 + * @link https://jingga.app + */ +#ifndef TOS_LOG_H +#define TOS_LOG_H + +#include +#include + +#include "../stdlib/Types.h" +#include "../utils/TestUtils.h" +#include "../utils/MathUtils.h" +#include "Debug.h" + +#ifdef _WIN32 + #include +#endif + +#ifndef LOG_LEVEL + #define LOG_LEVEL 0 +#endif + +#ifndef MAX_LOG_LENGTH + #define MAX_LOG_LENGTH 128 +#endif + +byte* log_get_memory(uint64 size, byte aligned = 1, bool zeroed = false) +{ + ASSERT_SIMPLE(size <= debug_container->log_memory.size); + + if (aligned > 1) { + uintptr_t address = (uintptr_t) debug_container->log_memory.memory; + int64 adjustment = (aligned - ((address + debug_container->log_memory.pos) & (aligned - 1))) % aligned; + + debug_container->log_memory.pos += adjustment; + } + + size = ROUND_TO_NEAREST(size, aligned); + if (debug_container->log_memory.pos + size > debug_container->log_memory.size) { + debug_container->log_memory.pos = 0; + + if (aligned > 1) { + uintptr_t address = (uintptr_t) debug_container->log_memory.memory; + int64 adjustment = (aligned - ((address + debug_container->log_memory.pos) & (aligned - 1))) % aligned; + + debug_container->log_memory.pos += adjustment; + } + } + + byte* offset = (byte *) (debug_container->log_memory.memory + debug_container->log_memory.pos); + if (zeroed) { + memset((void *) offset, 0, size); + } + + debug_container->log_memory.pos += size; + + return offset; +} + +#ifdef _WIN32 + void log_to_file() + { + // we don't log an empty log pool + if (debug_container->log_memory.pos == 0 || !debug_container->log_fp || debug_container->log_fp == INVALID_HANDLE_VALUE) { + return; + } + + DWORD written; + if (!WriteFile(debug_container->log_fp, (char *) debug_container->log_memory.memory, (uint32) debug_container->log_memory.pos - 1, &written, NULL)) { + CloseHandle(debug_container->log_fp); + } + + memset(debug_container->log_memory.memory, 0, debug_container->log_memory.size); + + // reset log position to start of memory pool + debug_container->log_memory.pos = 0; + debug_container->log_memory.start = 0; + } + + // @todo add file name, function name and function line + void log(const char* str, bool should_log, bool save, const char* file, const char* function, int32 line) + { + if (!should_log) { + return; + } + + size_t length = strlen(str); + ASSERT_SIMPLE(length < MAX_LOG_LENGTH); + + char* temp = (char *) log_get_memory(length + 1); + strcpy(temp, str); + temp[length] = '\0'; + + if (save || debug_container->log_memory.size - debug_container->log_memory.pos < MAX_LOG_LENGTH) { + log_to_file(debug_container->log_fp); + } + } + + void log(const char* format, LogDataType data_type, void* data, bool should_log, bool save, const char* file, const char* function, int32 line) + { + if (!should_log) { + return; + } + + if (data_type == LOG_DATA_VOID) { + log(format, should_log, save, file, function, line); + } + + char* temp = (char *) log_get_memory(MAX_LOG_LENGTH); + + switch (data_type) { + case LOG_DATA_INT32: { + sprintf(temp, format, *((int32 *) data)); + } break; + case LOG_DATA_UINT32: { + sprintf(temp, format, *((uint32 *) data)); + } break; + case LOG_DATA_INT64: { + sprintf(temp, format, *((int64 *) data)); + } break; + case LOG_DATA_UINT64: { + sprintf(temp, format, *((uint64 *) data)); + } break; + case LOG_DATA_CHAR: { + sprintf(temp, format, *((char *) data)); + } break; + case LOG_DATA_CHAR_STR: { + sprintf(temp, format, *((char *) data)); + } break; + case LOG_DATA_FLOAT32: { + sprintf(temp, format, *((f32 *) data)); + } break; + case LOG_DATA_FLOAT64: { + sprintf(temp, format, *((f64 *) data)); + } break; + } + + if (save || debug_container->log_memory.size - debug_container->log_memory.pos < MAX_LOG_LENGTH) { + log_to_file(); + } + } +#endif + +#if (LOG_LEVEL == 0) + // Don't perform any logging at log level 0 + #define LOG(str, should_log, save) ((void) 0) + #define LOG_FORMAT(format, data_type, data, should_log, save) ((void) 0) + #define LOG_TO_FILE(should_log, save) ((void) 0) +#else + #define LOG(str, should_log, save) log((str), (should_log), (save), __FILE__, __func__, __LINE__) + #define LOG_FORMAT(format, data_type, data, should_log, save) log((format), (data_type), (data), (should_log), (save), __FILE__, __func__, __LINE__) + #define LOG_TO_FILE(should_log, save) log_to_file((should_log), (save)) +#endif + +#if DEBUG + #define DEBUG_LOG(str, should_log, save) log((str), (should_log), (save), __FILE__, __func__, __LINE__) + #define DEBUG_LOG_FORMAT(format, data_type, data, should_log, save) log((format), (data_type), (data), (should_log), (save), __FILE__, __func__, __LINE__) +#else + #define DEBUG_LOG(str, should_log, save) ((void) 0) + #define DEBUG_LOG_FORMAT(format, data_type, data, should_log, save) ((void) 0) +#endif + +#endif \ No newline at end of file diff --git a/debug/TimingStat.h b/debug/TimingStat.h new file mode 100644 index 0000000..7395dcd --- /dev/null +++ b/debug/TimingStat.h @@ -0,0 +1,46 @@ +/** + * Jingga + * + * @copyright Jingga + * @license OMS License 2.0 + * @version 1.0.0 + * @link https://jingga.app + */ +#ifndef TOS_LOG_TIMING_STAT_H +#define TOS_LOG_TIMING_STAT_H + +#include +#include +#include "../stdlib/Types.h" +#include "Debug.h" + +#if _WIN32 + #include +#else + #include +#endif + +global_persist uint64 performance_count_frequency; + +// IMPORTANT: This function should only be called when you actually use this data +// e.g. log to display or file +inline +void update_timing_stat(uint32 stat, const char* function) +{ + uint64 new_tick_count = __rdtsc(); + + debug_container->perf_stats[stat].function = function; + debug_container->perf_stats[stat].delta_tick = new_tick_count - debug_container->perf_stats[stat].old_tick_count; + debug_container->perf_stats[stat].delta_time = (double) debug_container->perf_stats[stat].delta_tick / (double) performance_count_frequency; + debug_container->perf_stats[stat].old_tick_count = new_tick_count; +} + +// Sometimes we want to only do logging in debug mode. +// In such cases use the following macro. +#if DEBUG + #define UPDATE_TIMING_STAT(stat) update_timing_stat(stat, __func__) +#else + #define UPDATE_TIMING_STAT(stat) ((void) 0) +#endif + +#endif \ No newline at end of file diff --git a/gpuapi/opengl/OpenglUtils.h b/gpuapi/opengl/OpenglUtils.h index 5742214..5c9926c 100644 --- a/gpuapi/opengl/OpenglUtils.h +++ b/gpuapi/opengl/OpenglUtils.h @@ -443,6 +443,25 @@ uint32 gpuapi_buffer_generate(int size, const void* data) return vbo; } +inline +uint32 gpuapi_buffer_generate_dynamic(int size, const void* data) +{ + uint32 vbo; + + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW); + + return vbo; +} + +inline +void gpuapi_buffer_update_dynamic(uint32 vbo, int size, const void* data) +{ + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW); +} + inline uint32 gpuapi_shaderbuffer_generate(int size, const void* data) { diff --git a/image/default_colors.htm b/image/default_colors.htm index 7d032f1..2188a28 100644 --- a/image/default_colors.htm +++ b/image/default_colors.htm @@ -35,21 +35,21 @@ const table = document.getElementById('colorTable'); const colors = [ - "#", "#FFFFFF", "#F1EEED", "#DCDEDE", "#BFC1BF", "#AEB0AD", "#9E9D9E", "#8E8F94", "#717373", "#5E5F61", "#4D4D4C", "#3F403A", "#332C2A", "#241E22", "#0C1210", "#000000", - "#F6D3CF", "#FABABC", "#FBA699", "#F19580", "#FB837A", "#FC615A", "#FF4E4B", "#FF4040", "#F72128", "#F60303", "#E40000", "#C70002", "#900009", "#630604", "#4f0107", "#2d0205", - "#FDDDCE", "#FCC5AC", "#FFB9A4", "#F6A378", "#F49A80", "#FF7D4F", "#F8742C", "#FE5A22", "#F44A0B", "#DA3A06", "#C03500", "#853004", "#912600", "#672300", "#471608", "#2b0d05", - "#FCEBCF", "#FCD8AA", "#FFCD98", "#FCC27F", "#F3B267", "#FDA660", "#FD942D", "#FF8001", "#DF6E00", "#CC6B00", "#A85D00", "#A55300", "#734700", "#612D08", "#562600", "#351700", - "#FFF6C9", "#FFECA8", "#FDE884", "#FADC6D", "#F8DE6F", "#FFCF43", "#FFBD00", "#EBB800", "#C1A800", "#BC8F09", "#9B7A00", "#8E6C08", "#795F01", "#5C4A00", "#523B00", "#392900", - "#FFFFCD", "#FDFEAF", "#FCFBA1", "#FDFF69", "#F9FF2A", "#FFFE04", "#EFEE00", "#E0DE00", "#BDBF13", "#B4AF00", "#9F9900", "#909002", "#717300", "#505400", "#4A4F00", "#343700", - "#E4FFBD", "#DFFEB9", "#D1FF8F", "#CAFC84", "#C0F96B", "#BAF353", "#98FB00", "#9AEE0F", "#78CE00", "#74C100", "#61A401", "#578A03", "#4F7E02", "#3C6200", "#2E4F00", "#203700", - "#E1F8D8", "#BBFEAD", "#A2F592", "#A1F79A", "#81FF7A", "#5DFF59", "#48FF58", "#00F600", "#12D31F", "#0ACB04", "#10A40A", "#089811", "#06780E", "#05640F", "#005200", "#003100", - "#D5FFF8", "#BCFFEA", "#A7FED3", "#99F2C4", "#6CFFB5", "#53F29E", "#4CFEA1", "#0AF779", "#0CD56A", "#0BC868", "#01AA50", "#07A557", "#008642", "#075A30", "#00562C", "#00331a", - "#D9FDFE", "#B3FCFF", "#ACFFFF", "#90FFFF", "#76FEFF", "#5FFAFD", "#08FEFE", "#22F3F2", "#06C9C2", "#08B2C4", "#049FA4", "#078C97", "#008286", "#025D5D", "#005056", "#003135", + "#", "#FFFFFF", "#E9E9E9", "#D9D9D9", "#C9C9C9", "#B9B9B9", "#A9A9A9", "#999999", "#898989", "#797979", "#696969", "#595959", "#494949", "#393939", "#1F1F1F", "#000000", + "#F6D3CF", "#F8C2BD", "#FB9E91", "#FC8B7E", "#FC796C", "#FD675B", "#FF554B", "#FF4340", "#F82D2E", "#F6171B", "#E60412", "#CC0004", "#A70004", "#7A0306", "#4f0107", "#330004", + "#FDDDCE", "#FCCFB6", "#FDB69E", "#F5A78C", "#F69B7E", "#FF8A65", "#FF7A50", "#FB683A", "#F95523", "#F34413", "#D8390A", "#B22F07", "#8F2905", "#742406", "#57200A", "#2b0d05", + "#FCEBCF", "#FCDAB2", "#FCCB96", "#FBBE7C", "#F3B067", "#FCA45F", "#FB913E", "#FF7F1C", "#E76E09", "#D06B00", "#B05F00", "#9C5300", "#824A00", "#6E3B06", "#5A2E05", "#351700", + "#FFF6C9", "#FFEDB1", "#FFE593", "#FDDC74", "#F9D36A", "#FFC94F", "#FFBD1E", "#F4B600", "#D2A200", "#B78E04", "#9D7D00", "#8C6F07", "#776300", "#614F00", "#503D00", "#392900", + "#FFFFCD", "#FEFDBC", "#FCF9A3", "#FBF583", "#FAF065", "#FFEA2B", "#FEEB04", "#E9DC00", "#D7CC00", "#C4BA00", "#ADA500", "#9A9200", "#7C7700", "#605B00", "#4F4C00", "#343700", + "#E4FFBD", "#DBFDBC", "#CEF9A3", "#C4F48E", "#BAEE76", "#B1E760", "#9FEF29", "#97E313", "#7FC900", "#78BB00", "#67A201", "#5C8E02", "#527F01", "#426600", "#334F00", "#203700", + "#E1F8D8", "#C7F8C2", "#ADF5AB", "#9EEC97", "#85E47F", "#66DF66", "#4EDB5F", "#23D138", "#12C72C", "#0EB522", "#109B17", "#0A8913", "#077311", "#066011", "#004F06", "#003100", + "#D5FFF8", "#C5FDF4", "#A8F7E5", "#99F0D7", "#7BF1C6", "#60E6B1", "#53E0A0", "#1CE76F", "#0DD763", "#0AD056", "#02B548", "#04A94D", "#009A40", "#088133", "#005A2B", "#00331A", + "#D9FDFE", "#B5FBFE", "#A8FFFF", "#92FFFF", "#7AFDFF", "#66F9FD", "#0FF8FE", "#1CE7F5", "#06C5C9", "#0BA2B2", "#04A39E", "#079A8E", "#008B7D", "#027A7A", "#004D4F", "#003135", "#E2F5FF", "#B4EBFF", "#A3DAFF", "#89CCF8", "#79D1FF", "#61C3F7", "#59C5F3", "#3FB9F6", "#05A4FA", "#0592F0", "#0677B8", "#00649A", "#065A77", "#004974", "#003154", "#00243e", "#D1DDFF", "#B5D0EF", "#A7BFF6", "#90B6F4", "#85AAF7", "#67AAFF", "#5386FF", "#437AFF", "#3A6AFF", "#044EFC", "#034EF7", "#0A37BF", "#09268B", "#062871", "#001D4C", "#001435", "#C7C3FF", "#C7C6FE", "#9D9CFF", "#9194F6", "#7E81FE", "#776FF7", "#595AFF", "#4852FF", "#2D2EFF", "#2020F8", "#0400E1", "#0000DD", "#010097", "#000086", "#03005D", "#020035", "#E1D4FF", "#D8ACFF", "#CD9BFF", "#C88DFA", "#BD8AF9", "#B160FF", "#AA52FE", "#9841FD", "#8726FF", "#8700F5", "#7200F4", "#5C00B7", "#460489", "#350077", "#28004F", "#1c0037", - "#FFC7FF", "#FFB2FF", "#FF9AFF", "#F181F1", "#FB6FFD", "#F850FB", "#FB46FF", "#F91FFF", "#F900FF", "#DD00E6", "#BF00C7", "#9B0199", "#B70090", "#670362", "#4F0153", "#330035", + "#FFC7FF", "#FFB8FF", "#FFAAFF", "#F194F7", "#F681F5", "#F77CF1", "#F76DFF", "#F956FF", "#F82FFF", "#EA00E6", "#D200CB", "#B500B3", "#A6009C", "#8A0084", "#6F005E", "#330035", "#FDD2E6", "#F9B5DA", "#F7A4D4", "#F198CB", "#F682BD", "#FF5FAE", "#FF4CA9", "#FF3CA4", "#FF1A94", "#F90979", "#E80071", "#C40061", "#96004A", "#670132", "#4F0024", "#310016", ]; diff --git a/log/Log.h b/log/Log.h deleted file mode 100644 index 8b263ff..0000000 --- a/log/Log.h +++ /dev/null @@ -1,190 +0,0 @@ -/** - * Jingga - * - * @copyright Jingga - * @license OMS License 2.0 - * @version 1.0.0 - * @link https://jingga.app - */ -#ifndef TOS_PLATFORM_WIN32_LOG_H -#define TOS_PLATFORM_WIN32_LOG_H - -#include -#include - -#include "../stdlib/Types.h" -#include "../utils/TestUtils.h" -#include "../utils/MathUtils.h" - -#ifdef _WIN32 - #include -#endif - -#ifndef LOG_LEVEL - #define LOG_LEVEL 0 -#endif - -#ifndef MAX_LOG_LENGTH - #define MAX_LOG_LENGTH 128 -#endif - -enum LogDataType { - LOG_DATA_VOID, - LOG_DATA_INT32, - LOG_DATA_UINT32, - LOG_DATA_INT64, - LOG_DATA_UINT64, - LOG_DATA_CHAR, - LOG_DATA_CHAR_STR, - LOG_DATA_FLOAT32, - LOG_DATA_FLOAT64 -}; - -struct LogMemory { - byte* memory; - - uint32 id; - uint64 size; - uint64 pos; - int alignment; - - uint64 start; - uint64 end; -}; - -byte* log_get_memory(LogMemory* ring, uint64 size, byte aligned = 1, bool zeroed = false) -{ - ASSERT_SIMPLE(size <= ring->size); - - if (aligned > 1) { - uintptr_t address = (uintptr_t) ring->memory; - int64 adjustment = (aligned - ((address + ring->pos) & (aligned - 1))) % aligned; - - ring->pos += adjustment; - } - - size = ROUND_TO_NEAREST(size, aligned); - if (ring->pos + size > ring->size) { - ring->pos = 0; - - if (aligned > 1) { - uintptr_t address = (uintptr_t) ring->memory; - int64 adjustment = (aligned - ((address + ring->pos) & (aligned - 1))) % aligned; - - ring->pos += adjustment; - } - } - - byte* offset = (byte *) (ring->memory + ring->pos); - if (zeroed) { - memset((void *) offset, 0, size); - } - - ring->pos += size; - - return offset; -} - -#ifdef _WIN32 - void log_to_file(LogMemory* logs, HANDLE fp) - { - // we don't log an empty log pool - if (logs->pos == 0 || !fp || fp == INVALID_HANDLE_VALUE) { - return; - } - - DWORD written; - if (!WriteFile(fp, (char *) logs->memory, (uint32) logs->pos - 1, &written, NULL)) { - CloseHandle(fp); - } - - memset(logs->memory, 0, logs->size); - - // reset log position to start of memory pool - logs->pos = 0; - logs->start = 0; - } - - void log(LogMemory* logs, const char* str, HANDLE fp = NULL, bool should_log = true, bool save = false) - { - if (!should_log) { - return; - } - - size_t length = strlen(str); - ASSERT_SIMPLE(length < MAX_LOG_LENGTH); - - char* temp = (char *) log_get_memory(logs, length + 1); - strcpy(temp, str); - temp[length] = '\0'; - - if (fp != NULL && (save || logs->size - logs->pos < MAX_LOG_LENGTH)) { - log_to_file(logs, fp); - } - } - - void log(LogMemory* logs, const char* format, LogDataType data_type, void* data, HANDLE fp = NULL, bool should_log = true, bool save = false) - { - if (!should_log) { - return; - } - - if (data_type == LOG_DATA_VOID) { - log(logs, format, fp, true); - } - - char* temp = (char *) log_get_memory(logs, MAX_LOG_LENGTH); - - switch (data_type) { - case LOG_DATA_INT32: { - sprintf(temp, format, *((int32 *) data)); - } break; - case LOG_DATA_UINT32: { - sprintf(temp, format, *((uint32 *) data)); - } break; - case LOG_DATA_INT64: { - sprintf(temp, format, *((int64 *) data)); - } break; - case LOG_DATA_UINT64: { - sprintf(temp, format, *((uint64 *) data)); - } break; - case LOG_DATA_CHAR: { - sprintf(temp, format, *((char *) data)); - } break; - case LOG_DATA_CHAR_STR: { - sprintf(temp, format, *((char *) data)); - } break; - case LOG_DATA_FLOAT32: { - sprintf(temp, format, *((f32 *) data)); - } break; - case LOG_DATA_FLOAT64: { - sprintf(temp, format, *((f64 *) data)); - } break; - } - - if (fp != NULL && (save || logs->size - logs->pos < MAX_LOG_LENGTH)) { - log_to_file(logs, fp); - } - } -#endif - -#if (LOG_LEVEL == 0) - // Don't perform any logging at log level 0 - #define LOG(logs, str, fp, should_log, save) ((void) 0) - #define LOG_FORMAT(logs, format, data_type, data, fp, should_log, save) ((void) 0) - #define LOG_TO_FILE(logs, fp, should_log, save) ((void) 0) -#else - #define LOG(logs, str, fp, should_log, save) log((logs), (str), (fp), (should_log), (save)) - #define LOG_FORMAT(logs, format, data_type, data, fp, should_log, save) log((logs), (format), (data_type), (data), (fp), (should_log), (save)) - #define LOG_TO_FILE(logs, fp, should_log, save) log_to_file((logs), (fp), (should_log), (save)) -#endif - -#if DEBUG - #define DEBUG_LOG(logs, str, fp, should_log, save) log((logs), (str), (fp), (should_log), (save)) - #define DEBUG_LOG_FORMAT(logs, format, data_type, data, fp, should_log, save) log((logs), (format), (data_type), (data), (fp), (should_log), (save)) -#else - #define DEBUG_LOG(logs, str, fp, should_log, save) ((void) 0) - #define DEBUG_LOG_FORMAT(logs, format, data_type, data, fp, should_log, save) ((void) 0) -#endif - -#endif \ No newline at end of file diff --git a/memory/BufferMemory.h b/memory/BufferMemory.h index c01686c..890cd7f 100644 --- a/memory/BufferMemory.h +++ b/memory/BufferMemory.h @@ -14,14 +14,13 @@ #include "../utils/MathUtils.h" #include "../utils/TestUtils.h" #include "Allocation.h" -#include "DebugMemory.h" +#include "../log/DebugMemory.h" // @question Consider to use element_alignment to automatically align/pad elmeents struct BufferMemory { byte* memory; - uint32 id; uint64 size; uint64 pos; int alignment; @@ -37,11 +36,14 @@ void buffer_alloc(BufferMemory* buf, uint64 size, int alignment = 64) buf->alignment = alignment; buf->size = size; + + DEBUG_MEMORY_INIT((uint64) buf->memory, size); } inline void buffer_free(BufferMemory* buf) { + DEBUG_MEMORY_DELETE((uint64) buf->memory, buf->size); if (buf->alignment < 2) { platform_free(buf->memory, buf->size); } else { @@ -53,8 +55,8 @@ inline void buffer_reset(BufferMemory* buf) { // @bug arent we wasting element 0 (see get_memory, we are not using 0 only next element) + DEBUG_MEMORY_DELETE((uint64) buf->memory, buf->pos); buf->pos = 0; - DEBUG_MEMORY_RESET(&debug_memory[buf->id]); } inline @@ -79,7 +81,7 @@ byte* buffer_get_memory(BufferMemory* buf, uint64 size, int aligned = 0, bool ze memset((void *) offset, 0, size); } - DEBUG_MEMORY(&debug_memory[buf->id], buf->pos, size); + DEBUG_MEMORY_WRITE((uint64) offset, size); buf->pos += size; diff --git a/memory/ChunkMemory.h b/memory/ChunkMemory.h index 5df6457..0b314a9 100644 --- a/memory/ChunkMemory.h +++ b/memory/ChunkMemory.h @@ -13,13 +13,13 @@ #include "../stdlib/Types.h" #include "../utils/MathUtils.h" #include "Allocation.h" -#include "DebugMemory.h" +#include "../log/DebugMemory.h" struct ChunkMemory { byte* memory; - uint32 id; uint64 count; + uint64 size; uint64 chunk_size; int64 last_pos; int alignment; @@ -37,19 +37,23 @@ void chunk_alloc(ChunkMemory* buf, uint64 count, uint64 chunk_size, int alignmen : (byte *) playform_alloc_aligned(count * chunk_size + sizeof(buf->free) * CEIL_DIV(count, 64), alignment); buf->count = count; + buf->size = chunk_size * count; buf->chunk_size = chunk_size; buf->last_pos = -1; buf->alignment = alignment; buf->free = (uint64 *) (buf->memory + count * chunk_size); + + DEBUG_MEMORY_INIT((uint64) buf->memory, buf->size); } inline void chunk_free(ChunkMemory* buf) { + DEBUG_MEMORY_DELETE((uint64) buf->memory, buf->size); if (buf->alignment < 2) { - platform_free(buf->memory, buf->count * buf->chunk_size); + platform_free(buf->memory, buf->size); } else { - platform_aligned_free(buf->memory, buf->count * buf->chunk_size); + platform_aligned_free(buf->memory, buf->size); } } @@ -62,6 +66,8 @@ byte* chunk_get_element(ChunkMemory* buf, uint64 element, bool zeroed = false) memset((void *) offset, 0, buf->chunk_size); } + DEBUG_MEMORY_READ((uint64) offset, buf->chunk_size); + return offset; } @@ -84,7 +90,7 @@ void chunk_reserve_index(ChunkMemory* buf, int64 index, int64 elements = 1, bool memset(buf->memory + index * buf->chunk_size, 0, elements * buf->chunk_size); } - DEBUG_MEMORY(&debug_memory[buf->id], index * buf->chunk_size, elements * buf->chunk_size); + DEBUG_MEMORY_WRITE((uint64) (buf->memory + index * buf->chunk_size), elements * buf->chunk_size); buf->last_pos = index; } @@ -160,7 +166,7 @@ int64 chunk_reserve(ChunkMemory* buf, uint64 elements = 1, bool zeroed = false) memset(buf->memory + free_element * buf->chunk_size, 0, elements * buf->chunk_size); } - DEBUG_MEMORY(&debug_memory[buf->id], free_element * buf->chunk_size, elements * buf->chunk_size); + DEBUG_MEMORY_WRITE((uint64) (buf->memory + free_element * buf->chunk_size), elements * buf->chunk_size); buf->last_pos = free_element; @@ -214,6 +220,8 @@ byte* chunk_find_free(ChunkMemory* buf) inline void chunk_free_element(ChunkMemory* buf, uint64 element) { + DEBUG_MEMORY_DELETE((uint64) (buf->memory + element * buf->chunk_size), buf->chunk_size); + int64 byte_index = element / 64; int bit_index = element % 64; diff --git a/memory/DebugMemory.h b/memory/DebugMemory.h deleted file mode 100644 index 5f211d5..0000000 --- a/memory/DebugMemory.h +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Jingga - * - * @copyright Jingga - * @license OMS License 2.0 - * @version 1.0.0 - * @link https://jingga.app - */ -#ifndef TOS_MEMORY_DEBUG_H -#define TOS_MEMORY_DEBUG_H - -#include -#include - -#include "../stdlib/Types.h" - -// required for __rdtsc -#if _WIN32 - #include -#else - #include -#endif - -struct DebugMemoryRange { - uint64 start; - uint64 size; - uint64 time; -}; - -struct DebugMemory { - uint64 usage; - - uint64 debug_range_size; - uint64 debug_range_idx; - DebugMemoryRange* debug_ranges; -}; - -#if DEBUG - #define DEBUG_MEMORY(mem, start, end) debug_memory_add_range((mem), (start), (end)) - #define DEBUG_MEMORY_RESET(mem) debug_memory_reset((mem)) - #define DEBUG_MEMORY_FREE(mem) debug_memory_free((mem)) -#else - #define DEBUG_MEMORY(mem, start, end) ((void) 0) - #define DEBUG_MEMORY_RESET(mem) ((void) 0) - #define DEBUG_MEMORY_FREE(mem, start, end) ((void) 0) -#endif - -void debug_memory_resize(DebugMemory* mem) -{ - DebugMemoryRange* old = mem->debug_ranges; - - mem->debug_range_size += 100; - mem->debug_ranges = (DebugMemoryRange *) calloc(mem->debug_range_size, sizeof(DebugMemoryRange)); - - if (old) { - memcpy(mem->debug_ranges, old, mem->debug_range_size - 100); - free(old); - } -} - -void debug_memory_add_range(DebugMemory* mem, uint64 start, uint64 size) -{ - if (mem->debug_range_idx >= mem->debug_range_size) { - debug_memory_resize(mem); - } - - mem->debug_ranges[mem->debug_range_idx].start = start; - mem->debug_ranges[mem->debug_range_idx].size = size; - - // @question consider to use other time_ms() since __rdtsc is variable (boost, power saving) - mem->debug_ranges[mem->debug_range_idx].time = __rdtsc(); - - ++mem->debug_range_idx; - mem->usage += size; -} - -inline -void debug_memory_reset(DebugMemory* mem) -{ - mem->usage = 0; - - mem->debug_range_idx = 0; -} - -inline -void debug_memory_free(DebugMemory* mem) -{ - free(mem->debug_ranges); -} - -#endif \ No newline at end of file diff --git a/memory/RingMemory.h b/memory/RingMemory.h index 0c41fe8..be4b0a7 100644 --- a/memory/RingMemory.h +++ b/memory/RingMemory.h @@ -17,12 +17,11 @@ #include "Allocation.h" #include "BufferMemory.h" -#include "DebugMemory.h" +#include "../log/DebugMemory.h" struct RingMemory { byte* memory; - uint32 id; uint64 size; uint64 pos; int alignment; @@ -52,6 +51,8 @@ void ring_alloc(RingMemory* ring, uint64 size, int alignment = 64) ring->alignment = alignment; ring->start = 0; ring->end = 0; + + DEBUG_MEMORY_INIT((uint64) ring->memory, ring->size); } inline @@ -64,6 +65,8 @@ void ring_create(RingMemory* ring, BufferMemory* buf, uint64 size, int alignment ring->alignment = alignment; ring->start = 0; ring->end = 0; + + DEBUG_MEMORY_INIT((uint64) ring->memory, ring->size); } inline @@ -105,6 +108,13 @@ uint64 ring_calculate_position(const RingMemory* ring, uint64 pos, uint64 size, return pos; } +inline +void ring_reset(RingMemory* ring) +{ + DEBUG_MEMORY_DELETE((uint64) ring->memory, ring->size); + ring->pos = 0; +} + byte* ring_get_memory(RingMemory* ring, uint64 size, byte aligned = 0, bool zeroed = false) { ASSERT_SIMPLE(size <= ring->size); @@ -122,7 +132,7 @@ byte* ring_get_memory(RingMemory* ring, uint64 size, byte aligned = 0, bool zero size = ROUND_TO_NEAREST(size, aligned); if (ring->pos + size > ring->size) { - ring->pos = 0; + ring_reset(ring); if (aligned > 1) { uintptr_t address = (uintptr_t) ring->memory; @@ -137,7 +147,7 @@ byte* ring_get_memory(RingMemory* ring, uint64 size, byte aligned = 0, bool zero memset((void *) offset, 0, size); } - DEBUG_MEMORY(&debug_memory[ring->id], ring->pos, size); + DEBUG_MEMORY_WRITE((uint64) offset, size); ring->pos += size; @@ -150,14 +160,10 @@ inline byte* ring_get_element(const RingMemory* ring, uint64 element_count, uint64 element, uint64 size) { int64 index = (element % element_count) - 1; - return ring->memory + index * size; -} -inline -void ring_reset(RingMemory* ring) -{ - ring->pos = 0; - DEBUG_MEMORY_RESET(&debug_memory[ring->id]); + DEBUG_MEMORY_READ((uint64) (ring->memory + index * size), 1); + + return ring->memory + index * size; } /** diff --git a/object/Vertex.h b/object/Vertex.h index 6a797a8..4fb78cf 100644 --- a/object/Vertex.h +++ b/object/Vertex.h @@ -41,9 +41,10 @@ struct Vertex2DColor { struct Vertex2DColorIndex { v2_f32 position; - // opengl shaders don't support individual bytes, - // otherwise we would use byte here for 256 color palettes - uint32 color; + // @bug opengl shaders don't support individual bytes, + // otherwise we would use byte here for 256 color palettes. + // Which is bad since the purpose of this was to save 3 bytes by using a color palette + float color; }; struct VertexRef { diff --git a/platform/win32/audio/DirectSound.h b/platform/win32/audio/DirectSound.h index 2a2feb3..1140a0f 100644 --- a/platform/win32/audio/DirectSound.h +++ b/platform/win32/audio/DirectSound.h @@ -33,7 +33,7 @@ HRESULT WINAPI DirectSoundCreate8Stub(LPCGUID, LPDIRECTSOUND8*, LPUNKNOWN) { void audio_load(HWND hwnd, AudioSetting* setting, DirectSoundSetting* api_setting) { HMODULE lib = LoadLibraryExA((LPCSTR) "dsound.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); if (!lib) { - LOG(log_memory, "DirectSound: Couldn't load dsound.dll\n", log_fp, true, true); + LOG("DirectSound: Couldn't load dsound.dll\n", true, true); return; } @@ -41,13 +41,13 @@ void audio_load(HWND hwnd, AudioSetting* setting, DirectSoundSetting* api_settin audio_create* DirectSoundCreate8 = (audio_create *) GetProcAddress(lib, "DirectSoundCreate8"); if (!DirectSoundCreate8 || !SUCCEEDED(DirectSoundCreate8(0, &api_setting->audio_handle, 0))) { - LOG(log_memory, "DirectSound: DirectSoundCreate8 failed\n", log_fp, true, true); + LOG("DirectSound: DirectSoundCreate8 failed\n", true, true); return; } if(!SUCCEEDED(api_setting->audio_handle->SetCooperativeLevel(hwnd, DSSCL_PRIORITY))) { - LOG(log_memory, "DirectSound: SetCooperativeLevel failed.\n", log_fp, true, true); + LOG("DirectSound: SetCooperativeLevel failed.\n", true, true); return; } @@ -69,13 +69,13 @@ void audio_load(HWND hwnd, AudioSetting* setting, DirectSoundSetting* api_settin buffer_desc.dwFlags = DSBCAPS_PRIMARYBUFFER; if(!SUCCEEDED(api_setting->audio_handle->CreateSoundBuffer(&buffer_desc, &api_setting->primary_buffer, 0))) { - LOG(log_memory, "DirectSound: CreateSoundBuffer1 failed.\n", log_fp, true, true); + LOG("DirectSound: CreateSoundBuffer1 failed.\n", true, true); return; } if (!SUCCEEDED(api_setting->primary_buffer->SetFormat(&wf))) { - LOG(log_memory, "DirectSound: SetFormat failed.\n", log_fp, true, true); + LOG("DirectSound: SetFormat failed.\n", true, true); return; } @@ -91,7 +91,7 @@ void audio_load(HWND hwnd, AudioSetting* setting, DirectSoundSetting* api_settin buffer_desc2.lpwfxFormat = &wf; if(!SUCCEEDED(api_setting->audio_handle->CreateSoundBuffer(&buffer_desc2, &api_setting->secondary_buffer, 0))) { - LOG(log_memory, "DirectSound: CreateSoundBuffer2 failed.\n", log_fp, true, true); + LOG("DirectSound: CreateSoundBuffer2 failed.\n", true, true); return; } @@ -143,7 +143,7 @@ uint32 audio_buffer_fillable(const AudioSetting* setting, const DirectSoundSetti DWORD player_cursor; DWORD write_cursor; if (!SUCCEEDED(api_setting->secondary_buffer->GetCurrentPosition(&player_cursor, &write_cursor))) { - LOG(log_memory, "DirectSound: GetCurrentPosition failed.\n", log_fp, true, true); + LOG("DirectSound: GetCurrentPosition failed.\n", true, true); return 0; } diff --git a/platform/win32/audio/XAudio2.h b/platform/win32/audio/XAudio2.h index f2f569f..76189a9 100644 --- a/platform/win32/audio/XAudio2.h +++ b/platform/win32/audio/XAudio2.h @@ -37,20 +37,20 @@ void audio_load(HWND hwnd, AudioSetting* setting, XAudio2Setting* api_setting) { CoInitialize(NULL); HMODULE lib = LoadLibraryExA((LPCSTR) "xaudio2_9.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); if (!lib) { - LOG(log_memory, "Xaudio2: Couldn't load xaudio2_9.dll\n", log_fp, true, true); + LOG("Xaudio2: Couldn't load xaudio2_9.dll\n", true, true); lib = LoadLibraryExA((LPCSTR) "xaudio2_8.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); } if (!lib) { - LOG(log_memory, "Xaudio2: Couldn't load xaudio2_8.dll\n", log_fp, true, true); + LOG("Xaudio2: Couldn't load xaudio2_8.dll\n", true, true); return; } audio_create* XAudio2Create = (audio_create *) GetProcAddress(lib, "XAudio2Create"); if (!XAudio2Create || !SUCCEEDED(XAudio2Create(&api_setting->audio_handle, 0, XAUDIO2_DEFAULT_PROCESSOR))) { - LOG(log_memory, "Xaudio2: XAudio2Create failed\n", log_fp, true, true); + LOG("Xaudio2: XAudio2Create failed\n", true, true); return; } @@ -63,7 +63,7 @@ void audio_load(HWND hwnd, AudioSetting* setting, XAudio2Setting* api_setting) { 0, NULL)) ) { - LOG(log_memory, "Xaudio2: CreateMasteringVoice failed\n", log_fp, true, true); + LOG("Xaudio2: CreateMasteringVoice failed\n", true, true); return; } @@ -78,7 +78,7 @@ void audio_load(HWND hwnd, AudioSetting* setting, XAudio2Setting* api_setting) { wf.cbSize = 0; if (!SUCCEEDED(api_setting->audio_handle->CreateSourceVoice(&api_setting->source_voice, &wf))) { - LOG(log_memory, "Xaudio2: CreateSourceVoice failed\n", log_fp, true, true); + LOG("Xaudio2: CreateSourceVoice failed\n", true, true); return; } @@ -203,7 +203,7 @@ void audio_play_buffer(AudioSetting* setting, XAudio2Setting* api_setting) { ); if (!SUCCEEDED(api_setting->source_voice->SubmitSourceBuffer(&api_setting->internal_buffer[idx]))) { - LOG(log_memory, "Xaudio2: SubmitSourceBuffer failed\n", log_fp, true, true); + LOG("Xaudio2: SubmitSourceBuffer failed\n", true, true); return; } diff --git a/utils/TestUtils.h b/utils/TestUtils.h index f60bf1e..9fa68bd 100644 --- a/utils/TestUtils.h +++ b/utils/TestUtils.h @@ -10,46 +10,6 @@ #define TOS_UTILS_TEST_UTILS_H #include -#include -#include "../stdlib/Types.h" - -#if _WIN32 - #include -#else - #include -#endif - -global_persist uint64 performance_count_frequency; -struct TimingStat { - uint64 old_tick_count; - - uint64 delta_tick; - double delta_time; -}; - -// IMPORTANT: This function should only be called when you actually use this data -// e.g. log to display or file -inline -void update_timing_stat(TimingStat *stat) -{ - // @question consider to use other time_ms() since __rdtsc is variable (boost, power saving) - uint64 new_tick_count = __rdtsc(); - - stat->delta_tick = new_tick_count - stat->old_tick_count; - stat->delta_time = (double) stat->delta_tick / (double) performance_count_frequency; - - stat->old_tick_count = new_tick_count; -} - -// Sometimes we want to only do logging in debug mode. -// In such cases use the following macro. -#if DEBUG - #define UPDATE_TIMING_STAT(stat) update_timing_stat(stat) - #define DEBUG_OUTPUT(str) OutputDebugStringA(str) -#else - #define UPDATE_TIMING_STAT(stat) ((void) 0) - #define DEBUG_OUTPUT(str) ((void) 0) -#endif #define ASSERT_EQUALS(a, b, t1, t2) \ ({ \