diff --git a/.gitignore b/.gitignore index 28dfaf71..c20346e2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .*.swp *.lnk *.rdbg +*.raddbg *.10x *.cap *.wpix diff --git a/build.c b/build.c index 9210c70a..3ade0cc0 100644 --- a/build.c +++ b/build.c @@ -1051,6 +1051,7 @@ void OnBuild(StringList cli_args) BuildStepSimpleCommandArg *bs_arg = ArenaPush(&perm, BuildStepSimpleCommandArg); bs_arg->cmd = StringF(&perm, link_args_fmt, FmtStr(link_files_str), FmtStr(executable_file.full_path)); bs_arg->skip_flag = &src_success_flag; + bs_arg->delete_file_on_failure = executable_file; String step_name = Lit("Link"); AddStep(step_name, &BuildStepSimpleCommand, bs_arg); } @@ -1102,20 +1103,22 @@ void OnBuild(StringList cli_args) SH_Print(Lit("No work to do\n")); } + if (success) + { + T_ShutdownWorkers(); + D_WriteStoreToHistFile(&store, hist_path); + } + else + { + D_WriteStoreToHistFile(&store, hist_path); + Error(Lit("Build failed\n")); + OS_Exit(1); + } + if (!D_Exists(executable_file)) { /* Create blank executible if build fails (since Visual Studio can get * confused if no build target exists) */ D_ClearWrite(executable_file, Lit("")); } - -#if 0 - if (!success) - { - Error(Lit("Build failed\n")); - } -#endif - - T_ShutdownWorkers(); - D_WriteStoreToHistFile(&store, hist_path); } diff --git a/src/app/app_core.c b/src/app/app_core.c index 7fd91836..092dfb27 100644 --- a/src/app/app_core.c +++ b/src/app/app_core.c @@ -18,7 +18,8 @@ String InitializeAppWriteDirectory(Arena *arena, String write_dir) ); /* Create write dir if not present */ - if (!P_IsDir(write_path)) { + if (!P_IsDir(write_path)) + { P_MkDir(write_path); /* TODO: handle failure */ } @@ -41,19 +42,20 @@ P_WindowSettings GetDefaultAppWindowSettings(P_Window *window) { __prof; - Vec2 monitor_size = P_GetWindowMonitorSize(window); + Vec2I32 monitor_size = P_GetWindowMonitorSize(window); i32 width = 1280; i32 height = RoundF32ToI32(width / (f32)(DEFAULT_CAMERA_WIDTH / DEFAULT_CAMERA_HEIGHT)); i32 x = RoundF32ToI32(monitor_size.x / 2.f - width / 2); i32 y = RoundF32ToI32(monitor_size.y / 2.f - height / 2); - return (P_WindowSettings) { + return (P_WindowSettings) + { .title = WINDOW_TITLE, - .floating_x = x, - .floating_y = y, - .floating_width = width, - .floating_height = height + .floating_x = x, + .floating_y = y, + .floating_width = width, + .floating_height = height }; } @@ -70,12 +72,15 @@ AppArgList ParseAppArgs(Arena *arena, String args_str) i64 key_end = -1; i64 value_start = -1; i64 value_end = -1; - while (i < (i64)args_str.len) { + while (i < (i64)args_str.len) + { u8 c = args_str.text[i]; - switch (mode) { + switch (mode) + { case 0: { - if (c == '-') { + if (c == '-') + { mode = 1; key_start = i + 1; } @@ -84,7 +89,8 @@ AppArgList ParseAppArgs(Arena *arena, String args_str) case 1: { - if (c == '=') { + if (c == '=') + { key_end = i; value_start = i + 1; mode = 2; @@ -94,21 +100,29 @@ AppArgList ParseAppArgs(Arena *arena, String args_str) case 2: { - if (c == '-' || i == (i64)args_str.len - 1) { - if (c == '-') { + if (c == '-' || i == (i64)args_str.len - 1) + { + if (c == '-') + { value_end = i; - } else { + } + else + { value_end = i + 1; } - if (key_start >= 0 && key_end > key_start && key_end <= (i64)args_str.len && value_start >= 0 && value_end > value_start && value_end <= (i64)args_str.len) { + if (key_start >= 0 && key_end > key_start && key_end <= (i64)args_str.len && value_start >= 0 && value_end > value_start && value_end <= (i64)args_str.len) + { String key = PushString(arena, STRING(key_end - key_start, args_str.text + key_start)); String value = PushString(arena, STRING(value_end - value_start, args_str.text + value_start)); AppArg *arg = PushStruct(arena, AppArg); arg->key = key; arg->value = value; - if (result.last) { + if (result.last) + { result.last->next = arg; - } else { + } + else + { result.first = arg; } result.last = arg; @@ -139,14 +153,20 @@ void Startup(void) String logfile_name = Lit("log.log"); String settings_file_name = Lit("settings.txt"); String connect_address = ZI; - for (AppArg *arg = args.first; arg; arg = arg->next) { + for (AppArg *arg = args.first; arg; arg = arg->next) + { String key = arg->key; String value = arg->value; - if (EqString(key, Lit("log"))) { + if (EqString(key, Lit("log"))) + { logfile_name = value; - } else if (EqString(key, Lit("settings"))) { + } + else if (EqString(key, Lit("settings"))) + { settings_file_name = value; - } else if (EqString(key, Lit("connect"))) { + } + else if (EqString(key, Lit("connect"))) + { connect_address = value; } } @@ -185,7 +205,8 @@ void Startup(void) EndTempArena(temp); } P_LogInfoF("App started with args \"%F\" (%F parsed)", FmtString(args_str), FmtUint(args.count)); - for (AppArg *arg = args.first; arg; arg = arg->next) { + for (AppArg *arg = args.first; arg; arg = arg->next) + { P_LogInfoF("Parsed arg: key = \"%F\", value = \"%F\"", FmtString(arg->key), FmtString(arg->value)); } #endif @@ -198,7 +219,8 @@ void Startup(void) P_WindowSettings window_settings = ZI; String settings_path = CatAppWritePath(temp.arena, settings_file_name); P_LogInfoF("Looking for settings file \"%F\"", FmtString(settings_path)); - if (P_IsFile(settings_path)) { + if (P_IsFile(settings_path)) + { P_LogInfoF("Settings file found"); P_File settings_file = P_OpenFileRead(settings_path); String file_data = P_ReadFile(temp.arena, settings_file); @@ -206,23 +228,26 @@ void Startup(void) P_LogInfoF("Deserializing settings file data: %F", FmtString(file_data)); String error = ZI; P_WindowSettings *deser = SETTINGS_WindowSettingsFromString(temp.arena, file_data, &error); - if (error.len > 0) { + if (error.len > 0) + { P_LogInfoF("Failed to load settings file with error - %F", FmtString(error)); String msg = StringFormat(temp.arena, - Lit( - "Failed to loading settings file \"%F\":\n" - "------------\n" - "%F\n" - "------------\n" - "To stop this error from appearing, either fix the issue above or delete the file from the system." - ), - FmtString(settings_path), - FmtString(error)); + Lit( + "Failed to loading settings file \"%F\":\n" + "------------\n" + "%F\n" + "------------\n" + "To stop this error from appearing, either fix the issue above or delete the file from the system." + ), + FmtString(settings_path), + FmtString(error)); Panic(msg); } P_LogInfoF("Settings file loaded successfully"); window_settings = *deser; - } else { + } + else + { P_LogInfoF("Settings file not found, loading default"); window_settings = GetDefaultAppWindowSettings(window); } diff --git a/src/asset_cache/asset_cache_core.c b/src/asset_cache/asset_cache_core.c index 13f1ba21..8b8db97b 100644 --- a/src/asset_cache/asset_cache_core.c +++ b/src/asset_cache/asset_cache_core.c @@ -168,9 +168,9 @@ void AC_MarkReady(AC_Asset *asset, void *store_data) AddCounter(&asset->counter, -1); } -void AC_WaitOnAssetReady(AC_Asset *asset) +void AC_YieldOnAssetReady(AC_Asset *asset) { - WaitOnCounter(&asset->counter); + YieldOnCounter(&asset->counter); } //////////////////////////////// diff --git a/src/asset_cache/asset_cache_core.h b/src/asset_cache/asset_cache_core.h index 0c040be7..fd1e8b33 100644 --- a/src/asset_cache/asset_cache_core.h +++ b/src/asset_cache/asset_cache_core.h @@ -84,7 +84,7 @@ AC_Asset *AC_TouchCache(String key, u64 hash, b32 *is_first_touch); void AC_MarkLoading(AC_Asset *asset); void AC_MarkReady(AC_Asset *asset, void *store_data); -void AC_WaitOnAssetReady(AC_Asset *asset); +void AC_YieldOnAssetReady(AC_Asset *asset); //////////////////////////////// //~ Store operations diff --git a/src/base/base_arena.h b/src/base/base_arena.h index 72eaf39b..c7cb54c4 100644 --- a/src/base/base_arena.h +++ b/src/base/base_arena.h @@ -134,9 +134,10 @@ Inline void *AlignArena(Arena *arena, u64 align) } } -Inline void ResetArena(Arena *arena) +Inline void *ResetArena(Arena *arena) { PopTo(arena, 0); + return (void *)ArenaBase(arena); } //////////////////////////////// diff --git a/src/base/base_job.h b/src/base/base_job.h index 6311f6ea..324a1ae0 100644 --- a/src/base/base_job.h +++ b/src/base/base_job.h @@ -41,7 +41,7 @@ void StartupBaseJobs(void); //~ @hookdecl Futex /* Futex-like wait & wake */ -void FutexWait(volatile void *addr, void *cmp, u32 size, i64 timeout_ns); +void FutexYield(volatile void *addr, void *cmp, u32 size, i64 timeout_ns); void FutexWake(void *addr, i32 count); //////////////////////////////// diff --git a/src/base/base_memory.c b/src/base/base_memory.c index 5f709fa9..b4b4ef75 100644 --- a/src/base/base_memory.c +++ b/src/base/base_memory.c @@ -52,40 +52,37 @@ void SetMemoryReadWrite(void *address, u64 size) #endif //////////////////////////////// -//~ Crtlib memory.h stubs +//~ Memory operations -#if !CrtlibIsEnabled - -//- memcpy -__attribute((section(".text.memcpy"))) -void *memcpy(void *__restrict dst, const void *__restrict src, u64 n) +void *CopyBytes(void *dst, void *src, u64 count) { - for (u64 i = 0; i < n; ++i) + char *dst_pchar = dst; + char *src_pchar = src; + for (u64 i = 0; i < count; ++i) { - ((u8 *)dst)[i] = ((u8 *)src)[i]; + dst_pchar[i] = src_pchar[i]; } return dst; } -//- memset -__attribute((section(".text.memset"))) -void *memset(void *dst, i32 c, u64 n) +void *SetBytes(void *dst, u8 c, u64 count) { - for (u64 i = 0; i < n; ++i) + char *dst_pchar = dst; + for (u64 i = 0; i < count; ++i) { - ((u8 *)dst)[i] = c; + dst_pchar[i] = (char)c; } return dst; } -//- memcmp -__attribute((section(".text.memcmp"))) -i32 memcmp(const void *p1, const void *p2, u64 n) +i32 CmpBytes(void *p1, void *p2, u64 count) { i32 result = 0; - for (u64 i = 0; i < n; ++i) + char *p1_pchar = p1; + char *p2_pchar = p2; + for (u64 i = 0; i < count; ++i) { - result = ((u8 *)p1)[i] - ((u8 *)p2)[i]; + result = p1_pchar[i] - p2_pchar[i]; if (result != 0) { break; @@ -94,4 +91,30 @@ i32 memcmp(const void *p1, const void *p2, u64 n) return result; } +//////////////////////////////// +//~ Crtlib memory.h stubs + +#if !CrtlibIsEnabled + +//- memcpy +__attribute((section(".text.memcpy"))) +void *memcpy(void *__restrict dst, const void *__restrict src, u64 count) +{ + return CopyBytes(dst, src, count); +} + +//- memset +__attribute((section(".text.memset"))) +void *memset(void *dst, i32 c, u64 count) +{ + return SetBytes(dst, c, count); +} + +//- memcmp +__attribute((section(".text.memcmp"))) +i32 memcmp(const void *p1, const void *p2, u64 count) +{ + return CmpBytes(p1, p2, count); +} + #endif /* !CrtlibIsEnabled */ diff --git a/src/base/base_memory.h b/src/base/base_memory.h index f50e6f37..876a6e0d 100644 --- a/src/base/base_memory.h +++ b/src/base/base_memory.h @@ -16,21 +16,21 @@ void SetMemoryReadWrite(void *address, u64 size); //////////////////////////////// //~ Memory operations +//- Wrappers #define ZeroStruct(ptr) ZeroBytes((ptr), sizeof(*(ptr))) #define ZeroArray(a) Assert(IsArray(a)); ZeroBytes((a), sizeof((a))) -#define ZeroBytes(ptr, count) SetBytes((ptr), 0, (count)) - #define CopyStruct(ptr_dst, ptr_src) CopyBytes((ptr_dst), (ptr_src), sizeof(*(ptr_dst))) -#define CopyBytes(dst, src, count) memcpy((dst), (src), (count)) - #define EqStruct(p1, p2) EqBytes((p1), (p2), sizeof(*p1)) +#define ZeroBytes(ptr, count) SetBytes((ptr), 0, (count)) #define EqBytes(p1, p2, n) (CmpBytes((p1), (p2), (n)) == 0) -#define CmpBytes(p1, p2, n) memcmp((p1), (p2), (n)) +void *CopyBytes(void *dst, void *src, u64 count); +void *SetBytes(void *dst, u8 c, u64 count); +i32 CmpBytes(void *p1, void *p2, u64 count); -#define SetBytes(ptr, val, count) memset((ptr), (val), (count)) +//////////////////////////////// +//~ Crtlib stubs -//- Crtlib stubs #if CrtlibIsEnabled # include #else diff --git a/src/base/base_rand.h b/src/base/base_rand.h index 8fa3a4d4..6b3ebc65 100644 --- a/src/base/base_rand.h +++ b/src/base/base_rand.h @@ -1,7 +1,8 @@ //////////////////////////////// //~ Rand types -Struct(RandState) { +Struct(RandState) +{ u64 seed; /* If a state's seed == 0 upon a call to a related function, it will be initialized using platform's true rng source */ u64 counter; }; diff --git a/src/base/base_snc.c b/src/base/base_snc.c index 6964ac9a..e3bfe6e6 100644 --- a/src/base/base_snc.c +++ b/src/base/base_snc.c @@ -49,7 +49,7 @@ Lock LockSpinE(Mutex *m, i32 spin) } else { - FutexWait(&m->v, &v, 4, I64Max); + FutexYield(&m->v, &v, 4, I64Max); spin_cnt = 0; } } @@ -96,7 +96,7 @@ Lock LockSpinS(Mutex *m, i32 spin) } else { - FutexWait(&m->v, &v, 4, I64Max); + FutexYield(&m->v, &v, 4, I64Max); spin_cnt = 0; } } @@ -138,12 +138,12 @@ void Unlock(Lock *l) //////////////////////////////// //~ Condition variable -void WaitOnCv(Cv *cv, Lock *l) +void YieldOnCv(Cv *cv, Lock *l) { - WaitOnCvTime(cv, l, I64Max); + YieldOnCvTime(cv, l, I64Max); } -void WaitOnCvTime(Cv *cv, Lock *l, i64 timeout_ns) +void YieldOnCvTime(Cv *cv, Lock *l, i64 timeout_ns) { u64 old_wake_gen = Atomic64Fetch(&cv->wake_gen); Mutex *mutex = l->mutex; @@ -151,7 +151,7 @@ void WaitOnCvTime(Cv *cv, Lock *l, i64 timeout_ns) { Unlock(l); { - FutexWait(&cv->wake_gen, &old_wake_gen, sizeof(old_wake_gen), timeout_ns); + FutexYield(&cv->wake_gen, &old_wake_gen, sizeof(old_wake_gen), timeout_ns); } if (exclusive) { @@ -183,12 +183,12 @@ void AddCounter(Counter *counter, i64 x) } } -void WaitOnCounter(Counter *counter) +void YieldOnCounter(Counter *counter) { i64 v = Atomic64Fetch(&counter->v); while (v > 0) { - FutexWait(&counter->v, &v, sizeof(v), I64Max); + FutexYield(&counter->v, &v, sizeof(v), I64Max); v = Atomic64Fetch(&counter->v); } } diff --git a/src/base/base_snc.h b/src/base/base_snc.h index d272ec11..9f5743d4 100644 --- a/src/base/base_snc.h +++ b/src/base/base_snc.h @@ -72,12 +72,12 @@ void Unlock(Lock *lock); //////////////////////////////// //~ Condition variable operations -void WaitOnCv(Cv *cv, Lock *lock); -void WaitOnCvTime(Cv *cv, Lock *l, i64 timeout_ns); +void YieldOnCv(Cv *cv, Lock *lock); +void YieldOnCvTime(Cv *cv, Lock *l, i64 timeout_ns); void SignalCv(Cv *cv, i32 count); //////////////////////////////// //~ Counter operations void AddCounter(Counter *counter, i64 x); -void WaitOnCounter(Counter *counter); +void YieldOnCounter(Counter *counter); diff --git a/src/base/base_string.c b/src/base/base_string.c index f81bf5aa..2b35b023 100644 --- a/src/base/base_string.c +++ b/src/base/base_string.c @@ -10,7 +10,7 @@ String StringFromChar(Arena *arena, char c) return (String) { .len = 1, - .text = dst + .text = dst }; } @@ -51,7 +51,7 @@ String StringFromU64(Arena *arena, u64 n, u64 base, u64 zfill) return (String) { .len = len, - .text = final_text + .text = final_text }; } @@ -73,7 +73,7 @@ String StringFromI64(Arena *arena, i64 n, u64 base, u64 zfill) return (String) { .len = len + uint_str.len, - .text = final_text + .text = final_text }; } @@ -86,7 +86,7 @@ String StringFromPtr(Arena *arena, void *ptr) return (String) { .len = prepend.len + uint_str.len, - .text = prepend.text + .text = prepend.text }; } @@ -166,7 +166,7 @@ String StringFromF64(Arena *arena, f64 f, u32 precision) return (String) { .len = final_len, - .text = final_text + .text = final_text }; } @@ -230,7 +230,7 @@ String RepeatString(Arena *arena, String src, u64 count) return (String) { .text = final_text, - .len = final_len + .len = final_len }; } @@ -320,7 +320,7 @@ String IndentString(Arena *arena, String str, u32 indent) return (String) { .len = final_len, - .text = final_text + .text = final_text }; } @@ -599,7 +599,7 @@ String StringFormatV(Arena *arena, String fmt, va_list args) return (String) { .len = final_len, - .text = final_text + .text = final_text }; } @@ -815,7 +815,7 @@ String StringFromCstrNoLimit(char *cstr) return (String) { .len = len, - .text = (u8 *)cstr + .text = (u8 *)cstr }; } @@ -825,7 +825,7 @@ String StringFromCstr(char *cstr, u64 limit) return (String) { .text = (u8 *)cstr, - .len = len + .len = len }; } @@ -896,7 +896,7 @@ String16 String16FromWstrNoLimit(wchar_t *wstr) return (String16) { .len = len, - .text = (u16 *)wstr + .text = (u16 *)wstr }; } @@ -906,6 +906,6 @@ String16 String16FromWstr(wchar_t *wstr, u64 limit) return (String16) { .len = len, - .text = (u16 *)wstr + .text = (u16 *)wstr }; } diff --git a/src/base/build.bat b/src/base/build.bat new file mode 100644 index 00000000..fbd1a8ee --- /dev/null +++ b/src/base/build.bat @@ -0,0 +1,7 @@ +@echo off + +set opts=-FC -GR- -EHa- -nologo -Zi +set code=%cd% +pushd build +cl %opts% %code%\build.c -Febuild +popd diff --git a/src/base/build.sh b/src/base/build.sh new file mode 100644 index 00000000..e1582689 --- /dev/null +++ b/src/base/build.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +code="$PWD" +opts=-g +cd build > /dev/null +g++ $opts $code/build.c -o build +cd $code > /dev/null diff --git a/src/base/win32/base_win32_entry.c b/src/base/win32/base_win32_entry.c index 57f3d532..57ca12f9 100644 --- a/src/base/win32/base_win32_entry.c +++ b/src/base/win32/base_win32_entry.c @@ -63,7 +63,7 @@ void Panic(String msg) WstrLen += countof(prefix) - 1; /* Perform manual string encode to avoid any implicit memory - * allocation (in case allocation is unreliable) */ + * allocation (in case allocation is unreliable) */ String str8 = msg; u64 pos8 = 0; while (pos8 < str8.len) @@ -102,7 +102,6 @@ void Panic(String msg) } } - //////////////////////////////// //~ Winmain @@ -116,7 +115,6 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, __profthread("Main thread", PROF_THREAD_GROUP_MAIN); W32_SharedEntryCtx *g = &W32_shared_entry_ctx; - #if ProfilingIsEnabled /* Start profiler */ { diff --git a/src/base/win32/base_win32_job.c b/src/base/win32/base_win32_job.c index a6e97ef2..a8d4efe3 100644 --- a/src/base/win32/base_win32_job.c +++ b/src/base/win32/base_win32_job.c @@ -1355,7 +1355,7 @@ W32_ThreadDef(W32_JobSchedulerEntryFunc, UNUSED arg) //////////////////////////////// //~ @hookdef Futex -void FutexWait(volatile void *addr, void *cmp, u32 size, i64 timeout_ns) +void FutexYield(volatile void *addr, void *cmp, u32 size, i64 timeout_ns) { W32_Fiber *fiber = W32_FiberFromId(FiberId()); i16 parent_id = fiber->parent_id; diff --git a/src/collider/collider_core.c b/src/collider/collider_core.c index 131790c2..dc588466 100644 --- a/src/collider/collider_core.c +++ b/src/collider/collider_core.c @@ -46,6 +46,7 @@ CLD_SupportPoint CLD_SupportPointFromDirEx(CLD_Shape *shape, Xform xf, Vec2 dir, Vec2 furthest = ZI; u32 furthest_index = 0; f32 furthest_dot = -F32Infinity; + for (u32 i = 0; i < count; ++i) { if ((i32)i == ignore) diff --git a/src/font/font_core.c b/src/font/font_core.c index 2834bb73..064011b4 100644 --- a/src/font/font_core.c +++ b/src/font/font_core.c @@ -120,7 +120,7 @@ AC_Asset *F_LoadAsset(String path, f32 point_size, b32 wait) RunJobEx((GenericJobDesc *)desc); if (wait) { - AC_WaitOnAssetReady(asset); + AC_YieldOnAssetReady(asset); } } @@ -140,7 +140,7 @@ F_Font *F_LoadFontWait(String path, f32 point_size) { __prof; AC_Asset *asset = F_LoadAsset(path, point_size, 1); - AC_WaitOnAssetReady(asset); + AC_YieldOnAssetReady(asset); F_Font *f = (F_Font *)AC_DataFromStore(asset); return f; } diff --git a/src/gpu/dx12/gpu_dx12.c b/src/gpu/dx12/gpu_dx12.c index 0e6b8fdd..c1e9dbb5 100644 --- a/src/gpu/dx12/gpu_dx12.c +++ b/src/gpu/dx12/gpu_dx12.c @@ -14,9 +14,8 @@ GPU_D12_SharedState GPU_D12_shared_state = ZI; # pragma comment(lib, "advapi32") #endif -/* ========================== * - * Startup - * ========================== */ +//////////////////////////////// +//~ Startup void GPU_StartupCore(void) { @@ -97,12 +96,11 @@ ExitFuncDef(GPU_D12_Shutdown) SignalCv(&g->evictor_wake_cv, I32Max); Unlock(&lock); } - WaitOnCounter(&g->evictor_job_counter); + YieldOnCounter(&g->evictor_job_counter); } -/* ========================== * - * Dx12 device initialization - * ========================== */ +//////////////////////////////// +//~ Dx12 device initialization void GPU_D12_PushInitError(String error) { @@ -290,9 +288,8 @@ void GPU_D12_InitDevice(void) EndScratch(scratch); } -/* ========================== * - * Dx12 object initialization - * ========================== */ +//////////////////////////////// +//~ Dx12 object initialization void GPU_D12_InitObjects(void) { @@ -325,7 +322,7 @@ void GPU_D12_InitObjects(void) { Counter counter = ZI; RunJob(DX12_NUM_QUEUES, GPU_D12_AcquireCommandQueueJob, JobPool_Inherit, JobPriority_Low, &counter, .descs_in = params, .cqs_out = g->command_queues); - WaitOnCounter(&counter); + YieldOnCounter(&counter); } #if ProfilingIsEnabled { @@ -343,9 +340,8 @@ void GPU_D12_InitObjects(void) } } -/* ========================== * - * Dx12 pipeline initialization - * ========================== */ +//////////////////////////////// +//~ Dx12 pipeline initialization void GPU_InitPipelines(void) { @@ -417,7 +413,7 @@ void GPU_InitPipelines(void) __profn("Acquire pipelines"); Counter counter = ZI; RunJob(num_pipelines, GPU_D12_AcquirePipelineJob, JobPool_Inherit, JobPriority_Inherit, &counter, .descs_in = descs, .pipelines_out = pipelines); - WaitOnCounter(&counter); + YieldOnCounter(&counter); } for (u32 i = 0; i < num_pipelines; ++i) { @@ -444,9 +440,8 @@ void GPU_InitPipelines(void) EndScratch(scratch); } -/* ========================== * - * Noise texture initialization - * ========================== */ +//////////////////////////////// +//~ Noise texture initialization void GPU_D12_InitNoise(void) { @@ -497,7 +492,7 @@ void GPU_D12_InitNoise(void) { Counter counter = ZI; RunJob(1, GPU_D12_UploadJob, JobPool_Inherit, JobPriority_Low, &counter, .resource = r, .data = data.text); - WaitOnCounter(&counter); + YieldOnCounter(&counter); } } } @@ -511,9 +506,8 @@ void GPU_D12_InitNoise(void) EndScratch(scratch); } -/* ========================== * - * Shader compilation - * ========================== */ +//////////////////////////////// +//~ Shader compilation #if RESOURCE_RELOADING @@ -563,9 +557,8 @@ JobDef(GPU_D12_CompileShaderJob, sig, id) #endif -/* ========================== * - * Pipeline - * ========================== */ +//////////////////////////////// +//~ Pipeline JobDef(GPU_D12_AcquirePipelineJob, sig, id) { @@ -910,9 +903,8 @@ void GPU_D12_ReleasePipelineNow(GPU_D12_Pipeline *pipeline) Unlock(&lock); } -/* ========================== * - * Pipeline cache - * ========================== */ +//////////////////////////////// +//~ Pipeline cache GPU_D12_PipelineScope *GPU_D12_BeginPipelineScope(void) { @@ -1109,7 +1101,7 @@ W_CallbackFuncDef(GPU_D12_WatchPipelineCallback, name) job_desc->count = num_shaders; job_desc->counter = &counter; RunJobEx((GenericJobDesc *)job_desc); - WaitOnCounter(&counter); + YieldOnCounter(&counter); } } P_CloseFIle(file); @@ -1170,7 +1162,7 @@ W_CallbackFuncDef(GPU_D12_WatchPipelineCallback, name) { Counter counter = ZI; RunJob(num_pipelines, GPU_D12_AcquirePipelineJob, JobPool_Inherit, JobPriority_Low, &counter, .descs_in = pipeline_descs, .pipelines_out = pipelines); - WaitOnCounter(&counter); + YieldOnCounter(&counter); } { Lock lock = LockS(&g->pipelines_mutex); @@ -1214,9 +1206,8 @@ W_CallbackFuncDef(GPU_D12_WatchPipelineCallback, name) } #endif -/* ========================== * - * Descriptor - * ========================== */ +//////////////////////////////// +//~ Descriptor GPU_D12_Descriptor *GPU_D12_AcquireDescriptor(GPU_D12_CpuDescriptorHeap *dh) { @@ -1263,9 +1254,8 @@ void GPU_D12_ReleaseDescriptor(GPU_D12_Descriptor *descriptor) Unlock(&lock); } -/* ========================== * - * CPU descriptor heap - * ========================== */ +//////////////////////////////// +//~ CPU descriptor heap GPU_D12_CpuDescriptorHeap *GPU_D12_AcquireCpuDescriptorHeap(enum D3D12_DESCRIPTOR_HEAP_TYPE type) { @@ -1313,9 +1303,8 @@ void cpu_descriptor_heap_release(GPU_D12_CpuDescriptorHeap *dh) } #endif -/* ========================== * - * Fenced release - * ========================== */ +//////////////////////////////// +//~ Fenced release void GPU_D12_ReleaseDataFenced(void *data, GPU_D12_FencedReleaseKind kind) { @@ -1358,9 +1347,8 @@ void GPU_D12_ReleaseDataFenced(void *data, GPU_D12_FencedReleaseKind kind) } } -/* ========================== * - * Resource - * ========================== */ +//////////////////////////////// +//~ Resource GPU_D12_Resource *GPU_D12_AcquireResource(D3D12_HEAP_PROPERTIES heap_props, D3D12_HEAP_FLAGS heap_flags, D3D12_RESOURCE_DESC desc, D3D12_RESOURCE_STATES initial_state) { @@ -1441,9 +1429,8 @@ void GPU_ReleaseResourceFenced(GPU_Resource *resource) GPU_D12_ReleaseDataFenced(r, GPU_D12_FencedReleaseKind_Resource); } -/* ========================== * - * Resource barrier - * ========================== */ +//////////////////////////////// +//~ Resource barrier void GPU_D12_InsertBarrier(ID3D12GraphicsCommandList *cl, i32 num_descs, GPU_D12_ResourceBarrierDesc *descs) { @@ -1497,9 +1484,8 @@ void GPU_D12_InsertBarrier(ID3D12GraphicsCommandList *cl, i32 num_descs, GPU_D12 EndScratch(scratch); } -/* ========================== * - * Command queue - * ========================== */ +//////////////////////////////// +//~ Command queue GPU_D12_CommandListPool *GPU_D12_AcquireCommandListPool(GPU_D12_CommandQueue *cq); @@ -1547,9 +1533,8 @@ void GPU_D12_ReleaseCommandQueue(GPU_D12_CommandQueue *cq) //ID3D12CommandQueue_Release(cq->cq); } -/* ========================== * - * Command list - * ========================== */ +//////////////////////////////// +//~ Command list GPU_D12_CommandListPool *GPU_D12_AcquireCommandListPool(GPU_D12_CommandQueue *cq) { @@ -1757,9 +1742,8 @@ u64 GPU_D12_EndCommandList(GPU_D12_CommandList *cl) return submit_fence_target; } -/* ========================== * - * Command descriptor heap (GPU / shader visible descriptor heap) - * ========================== */ +//////////////////////////////// +//~ Command descriptor heap (GPU / shader visible descriptor heap) GPU_D12_CommandDescriptorHeap *GPU_D12_PushDescriptorHeap(GPU_D12_CommandList *cl, GPU_D12_CpuDescriptorHeap *dh_cpu) { @@ -1854,9 +1838,8 @@ GPU_D12_CommandDescriptorHeap *GPU_D12_PushDescriptorHeap(GPU_D12_CommandList *c return cdh; } -/* ========================== * - * Command buffer - * ========================== */ +//////////////////////////////// +//~ Command buffer u64 GPU_D12_CommandBufferHashFromSize(u64 size) { @@ -1864,8 +1847,7 @@ u64 GPU_D12_CommandBufferHashFromSize(u64 size) return hash; } -#define GPU_D12_PushCommandBuffer(cl, count, elems) GPU_D12__PushCommandBuffer((cl), count * ((elems) ? sizeof(*(elems)) : 0), (elems), (elems) ? sizeof(*(elems)) : 1) -GPU_D12_CommandBuffer *GPU_D12__PushCommandBuffer(GPU_D12_CommandList *cl, u64 data_len, void *data, u64 data_stride) +GPU_D12_CommandBuffer *GPU_D12_PushCommandBufferEx(GPU_D12_CommandList *cl, u64 data_len, void *data, u64 data_stride) { __prof; GPU_D12_SharedState *g = &GPU_D12_shared_state; @@ -2000,9 +1982,8 @@ GPU_D12_CommandBuffer *GPU_D12__PushCommandBuffer(GPU_D12_CommandList *cl, u64 d return cb; } -/* ========================== * - * Wait job - * ========================== */ +//////////////////////////////// +//~ Wait job JobDef(GPU_D12_WaitOnFenceJob, sig, UNUSED id) { @@ -2019,9 +2000,8 @@ JobDef(GPU_D12_WaitOnFenceJob, sig, UNUSED id) } } -/* ========================== * - * Texture - * ========================== */ +//////////////////////////////// +//~ Texture GPU_Resource *GPU_AcquireTexture(GPU_TextureFormat format, u32 flags, Vec2I32 size, void *initial_data) { @@ -2087,7 +2067,7 @@ GPU_Resource *GPU_AcquireTexture(GPU_TextureFormat format, u32 flags, Vec2I32 si /* TODO: Make wait optional */ Counter counter = ZI; RunJob(1, GPU_D12_UploadJob, JobPool_Inherit, JobPriority_Inherit, &counter, .resource = r, .data = initial_data); - WaitOnCounter(&counter); + YieldOnCounter(&counter); } return (GPU_Resource *)r; @@ -2099,9 +2079,8 @@ Vec2I32 GPU_GetTextureSize(GPU_Resource *resource) return r->texture_size; } -/* ========================== * - * Upload - * ========================== */ +//////////////////////////////// +//~ Upload JobDef(GPU_D12_UploadJob, sig, UNUSED id) { @@ -2193,14 +2172,15 @@ JobDef(GPU_D12_UploadJob, sig, UNUSED id) ID3D12GraphicsCommandList_CopyTextureRegion(cl->cl, &dst_loc, 0, 0, 0, &src_loc, 0); } - } u64 fence_target = GPU_D12_EndCommandList(cl); + } + u64 fence_target = GPU_D12_EndCommandList(cl); - /* Wait on fence so we know it's safe to release upload heap */ + /* Yield on fence so we know it's safe to release upload heap */ if (ID3D12Fence_GetCompletedValue(cq->submit_fence) < fence_target) { Counter counter = ZI; RunJob(1, GPU_D12_WaitOnFenceJob, JobPool_Floating, JobPriority_Inherit, &counter, .fence = cq->submit_fence, .target = fence_target); - WaitOnCounter(&counter); + YieldOnCounter(&counter); } /* Release upload heap now */ @@ -2208,9 +2188,8 @@ JobDef(GPU_D12_UploadJob, sig, UNUSED id) } } -/* ========================== * - * Run utils - * ========================== */ +//////////////////////////////// +//~ Run utils void GPU_D12_SetPipeline(GPU_D12_CommandList *cl, GPU_D12_Pipeline *pipeline) { @@ -2344,9 +2323,8 @@ D3D12_GPU_DESCRIPTOR_HANDLE GPU_D12_GpuHandleFromDescriptor(GPU_D12_Descriptor * return result; } -/* ========================== * - * Render sig - * ========================== */ +//////////////////////////////// +//~ Render sig GPU_D12_RenderSig *GPU_D12_AcquireRenderSig(void) { @@ -2466,9 +2444,8 @@ u32 GPU_PushRenderCmd(GPU_RenderSig *render_sig, GPU_RenderCmdDesc *cmd_desc) return ret; } -/* ========================== * - * Render - * ========================== */ +//////////////////////////////// +//~ Render GPU_Resource *GPU_RunRender(GPU_RenderSig *gp_render_sig, GPU_RenderParams params) { @@ -2948,9 +2925,8 @@ GPU_Resource *GPU_RunRender(GPU_RenderSig *gp_render_sig, GPU_RenderParams param return (GPU_Resource *)rsig->ui_target; } -/* ========================== * - * Memory info - * ========================== */ +//////////////////////////////// +//~ Memory info GPU_MemoryInfo GPU_QueryMemoryInfo(void) { @@ -2984,9 +2960,8 @@ GPU_MemoryInfo GPU_QueryMemoryInfo(void) return result; } -/* ========================== * - * Swapchain - * ========================== */ +//////////////////////////////// +//~ Swapchain void GPU_D12_InitSwapchainResources(GPU_D12_Swapchain *swapchain) { @@ -3151,9 +3126,8 @@ GPU_D12_SwapchainBuffer *GPU_D12_UpdateSwapchain(GPU_D12_Swapchain *swapchain, V return &swapchain->buffers[backbuffer_index]; } -/* ========================== * - * Present - * ========================== */ +//////////////////////////////// +//~ Present void GPU_D12_BlitToSwapchain(GPU_D12_SwapchainBuffer *dst, GPU_D12_Resource *src, Xform src_xf) { @@ -3312,9 +3286,8 @@ void GPU_PresentSwapchain(GPU_Swapchain *gp_swapchain, Vec2I32 backbuffer_resolu #endif } -/* ========================== * - * Evictor job - * ========================== */ +//////////////////////////////// +//~ Evictor job JobDef(GPU_D12_EvictorJob, UNUSED sig, UNUSED id) { @@ -3343,7 +3316,7 @@ JobDef(GPU_D12_EvictorJob, UNUSED sig, UNUSED id) Unlock(&lock); } - /* Wait until fences reach target */ + /* Yield until fences reach target */ { __profn("Check fences"); for (u32 i = 0; i < countof(targets); ++i) @@ -3354,11 +3327,11 @@ JobDef(GPU_D12_EvictorJob, UNUSED sig, UNUSED id) completed_targets[i] = ID3D12Fence_GetCompletedValue(cq->submit_fence); if (completed_targets[i] < targets[i]) { - __profn("Wait on fence"); + __profn("Yield on fence"); { Counter counter = ZI; RunJob(1, GPU_D12_WaitOnFenceJob, JobPool_Floating, JobPriority_Inherit, &counter, .fence = cq->submit_fence, .target = targets[i]); - WaitOnCounter(&counter); + YieldOnCounter(&counter); } } } @@ -3396,7 +3369,7 @@ JobDef(GPU_D12_EvictorJob, UNUSED sig, UNUSED id) { while (!g->evictor_shutdown && g->evictor_wake_gen == 0) { - WaitOnCv(&g->evictor_wake_cv, &lock); + YieldOnCv(&g->evictor_wake_cv, &lock); } shutdown = g->evictor_shutdown; g->evictor_wake_gen = 0; diff --git a/src/gpu/dx12/gpu_dx12.h b/src/gpu/dx12/gpu_dx12.h index 1e92d227..bfcf4355 100644 --- a/src/gpu/dx12/gpu_dx12.h +++ b/src/gpu/dx12/gpu_dx12.h @@ -47,9 +47,8 @@ # define DX12_DEBUG 0 #endif -/* ========================== * - * structs - * ========================== */ +//////////////////////////////// +//~ structs Struct(GPU_D12_Descriptor) { @@ -343,9 +342,8 @@ Struct(GPU_D12_ResourceBarrierDesc) enum D3D12_RESOURCE_STATES new_state; /* 0 if type != D3D12_RESOURCE_BARRIER_TYPE_TRANSITION */ }; -/* ========================== * - * Shared state - * ========================== */ +//////////////////////////////// +//~ Shared state Struct(GPU_D12_SharedState) { @@ -421,55 +419,47 @@ Struct(GPU_D12_SharedState) extern GPU_D12_SharedState GPU_D12_shared_state; -/* ========================== * - * Startup - * ========================== */ +//////////////////////////////// +//~ Startup ExitFuncDef(GPU_D12_Shutdown); -/* ========================== * - * Dx12 device initialization - * ========================== */ +//////////////////////////////// +//~ Dx12 device initialization void GPU_D12_PushInitError(String error); void GPU_D12_InitDevice(void); -/* ========================== * - * Dx12 object initialization - * ========================== */ +//////////////////////////////// +//~ Dx12 object initialization void GPU_D12_InitObjects(void); -/* ========================== * - * Dx12 pipeline initialization - * ========================== */ +//////////////////////////////// +//~ Dx12 pipeline initialization void GPU_InitPipelines(void); -/* ========================== * - * Noise texture initialization - * ========================== */ +//////////////////////////////// +//~ Noise texture initialization void GPU_D12_InitNoise(void); -/* ========================== * - * Shader compilation - * ========================== */ +//////////////////////////////// +//~ Shader compilation JobDecl(GPU_D12_CompileShaderJob, { Arena *arena; GPU_D12_ShaderDesc *descs; GPU_D12_CompiledShaderResult *results; }); -/* ========================== * - * Pipeline - * ========================== */ +//////////////////////////////// +//~ Pipeline JobDecl(GPU_D12_AcquirePipelineJob, { GPU_D12_PipelineDesc *descs_in; GPU_D12_Pipeline **pipelines_out; }); void GPU_D12_ReleasePipelineNow(GPU_D12_Pipeline *pipeline); -/* ========================== * - * Pipeline cache - * ========================== */ +//////////////////////////////// +//~ Pipeline cache GPU_D12_PipelineScope *GPU_D12_BeginPipelineScope(void); @@ -482,29 +472,25 @@ void GPU_D12_RegisterPipeline(u64 num_pipelines, GPU_D12_Pipeline **pipelines); W_CallbackFuncDef(GPU_D12_WatchPipelineCallback, name); -/* ========================== * - * Descriptor - * ========================== */ +//////////////////////////////// +//~ Descriptor GPU_D12_Descriptor *GPU_D12_AcquireDescriptor(GPU_D12_CpuDescriptorHeap *dh); void GPU_D12_ReleaseDescriptor(GPU_D12_Descriptor *descriptor); -/* ========================== * - * CPU descriptor heap - * ========================== */ +//////////////////////////////// +//~ CPU descriptor heap GPU_D12_CpuDescriptorHeap *GPU_D12_AcquireCpuDescriptorHeap(enum D3D12_DESCRIPTOR_HEAP_TYPE type); -/* ========================== * - * Fenced release - * ========================== */ +//////////////////////////////// +//~ Fenced release void GPU_D12_ReleaseDataFenced(void *data, GPU_D12_FencedReleaseKind kind); -/* ========================== * - * Resource - * ========================== */ +//////////////////////////////// +//~ Resource GPU_D12_Resource *GPU_D12_AcquireResource(D3D12_HEAP_PROPERTIES heap_props, D3D12_HEAP_FLAGS heap_flags, D3D12_RESOURCE_DESC desc, D3D12_RESOURCE_STATES initial_state); @@ -512,23 +498,20 @@ void GPU_D12_ReleaseResourceNow(GPU_D12_Resource *t); void GPU_ReleaseResourceFenced(GPU_Resource *resource); -/* ========================== * - * Resource barrier - * ========================== */ +//////////////////////////////// +//~ Resource barrier void GPU_D12_InsertBarrier(ID3D12GraphicsCommandList *cl, i32 num_descs, GPU_D12_ResourceBarrierDesc *descs); -/* ========================== * - * Command queue - * ========================== */ +//////////////////////////////// +//~ Command queue JobDecl(GPU_D12_AcquireCommandQueueJob, { GPU_D12_CommandQueueDesc *descs_in; GPU_D12_CommandQueue **cqs_out; }); void GPU_D12_ReleaseCommandQueue(GPU_D12_CommandQueue *cq); -/* ========================== * - * Command list - * ========================== */ +//////////////////////////////// +//~ Command list GPU_D12_CommandListPool *GPU_D12_AcquireCommandListPool(GPU_D12_CommandQueue *cq); @@ -537,36 +520,31 @@ GPU_D12_CommandList *GPU_D12_BeginCommandList(GPU_D12_CommandListPool *pool); /* TODO: Allow multiple command list submissions */ u64 GPU_D12_EndCommandList(GPU_D12_CommandList *cl); -/* ========================== * - * Command descriptor heap (GPU / shader visible descriptor heap) - * ========================== */ +//////////////////////////////// +//~ Command descriptor heap (GPU / shader visible descriptor heap) GPU_D12_CommandDescriptorHeap *GPU_D12_PushDescriptorHeap(GPU_D12_CommandList *cl, GPU_D12_CpuDescriptorHeap *dh_cpu); -/* ========================== * - * Command buffer - * ========================== */ +//////////////////////////////// +//~ Command buffer u64 GPU_D12_CommandBufferHashFromSize(u64 size); -#define GPU_D12_PushCommandBuffer(cl, count, elems) GPU_D12__PushCommandBuffer((cl), count * ((elems) ? sizeof(*(elems)) : 0), (elems), (elems) ? sizeof(*(elems)) : 1) -GPU_D12_CommandBuffer *GPU_D12__PushCommandBuffer(GPU_D12_CommandList *cl, u64 data_len, void *data, u64 data_stride); +#define GPU_D12_PushCommandBuffer(cl, count, elems) GPU_D12_PushCommandBufferEx((cl), count * ((elems) ? sizeof(*(elems)) : 0), (elems), (elems) ? sizeof(*(elems)) : 1) +GPU_D12_CommandBuffer *GPU_D12_PushCommandBufferEx(GPU_D12_CommandList *cl, u64 data_len, void *data, u64 data_stride); -/* ========================== * - * Wait job - * ========================== */ +//////////////////////////////// +//~ Wait job JobDecl(GPU_D12_WaitOnFenceJob, { ID3D12Fence *fence; u64 target; }); -/* ========================== * - * Upload - * ========================== */ +//////////////////////////////// +//~ Upload JobDecl(GPU_D12_UploadJob, { GPU_D12_Resource *resource; void *data; }); -/* ========================== * - * Run utils - * ========================== */ +//////////////////////////////// +//~ Run utils void GPU_D12_SetPipeline(GPU_D12_CommandList *cl, GPU_D12_Pipeline *pipeline); @@ -585,9 +563,8 @@ GPU_D12_Resource *GPU_D12_AcquireGbuff(DXGI_FORMAT format, Vec2I32 size, D3D12_R D3D12_GPU_DESCRIPTOR_HANDLE GPU_D12_GpuHandleFromDescriptor(GPU_D12_Descriptor *descriptor, GPU_D12_CommandDescriptorHeap *cdh); -/* ========================== * - * Render sig - * ========================== */ +//////////////////////////////// +//~ Render sig GPU_D12_RenderSig *GPU_D12_AcquireRenderSig(void); @@ -595,22 +572,19 @@ void GPU_D12_ResetRenderSig(GPU_D12_RenderSig *sig); GPU_RenderSig *GPU_AcquireRenderSig(void); -/* ========================== * - * Swapchain - * ========================== */ +//////////////////////////////// +//~ Swapchain void GPU_D12_InitSwapchainResources(GPU_D12_Swapchain *swapchain); GPU_D12_SwapchainBuffer *GPU_D12_UpdateSwapchain(GPU_D12_Swapchain *swapchain, Vec2I32 resolution); -/* ========================== * - * Present - * ========================== */ +//////////////////////////////// +//~ Present void GPU_D12_BlitToSwapchain(GPU_D12_SwapchainBuffer *dst, GPU_D12_Resource *src, Xform src_xf); -/* ========================== * - * Evictor job - * ========================== */ +//////////////////////////////// +//~ Evictor job JobDecl(GPU_D12_EvictorJob, EmptySig); diff --git a/src/gtest/dx12/gtest_dx12.c b/src/gtest/dx12/gtest_dx12.c index de663713..43a3e51d 100644 --- a/src/gtest/dx12/gtest_dx12.c +++ b/src/gtest/dx12/gtest_dx12.c @@ -1,6 +1,206 @@ //////////////////////////////// -//~ Startup +//~ @hookdef Startup hook void GT_StartupCore(void) { } + +//////////////////////////////// +//~ @hookdef Rasterizer helper hooks + +GT_Viewport GT_ViewportFromRect(Rect rect) +{ + LAX rect; + return (GT_Viewport) ZI; +} + +GT_Scissor GT_ScissorRectFromRect(Rect rect) +{ + LAX rect; + return (GT_Scissor) ZI; +} + +//////////////////////////////// +//~ @hookdef Fence hooks + +GT_Fence GT_GetGlobalFence(void) +{ + return (GT_Fence) ZI; +} + +//////////////////////////////// +//~ @hookdef Resource hooks + +GT_Resource *GT_AcquireResource(GT_ResourceDesc desc) +{ + LAX desc; + return (GT_Resource *)0; +} + +void GT_ReleaseResource(GT_Resource *resource, GT_Fence fence, GT_ReleaseFlag flags) +{ + LAX resource; + LAX fence; + LAX flags; +} + +u32 GT_GetResourceId(GT_Resource *resource) +{ + LAX resource; + return 0; +} + +Vec2I32 GT_GetTextureSize(GT_Resource *resource) +{ + LAX resource; + return VEC2I32(0, 0); +} + +//////////////////////////////// +//~ @hookdef Command list hooks + +GT_CommandList *GT_BeginCommandList(void) +{ + return 0; +} + +GT_Fence GT_EndCommandList(GT_CommandList *cl) +{ + LAX cl; + return (GT_Fence) ZI; +} + +void GT_ProfileDF(GT_CommandList *cl, String zone_name) +{ + LAX cl; + LAX zone_name; +} + +//////////////////////////////// +//~ @hookdef Resource transition hooks + +void GT_TransitionToSrv(GT_CommandList *cl, GT_Resource *resource) +{ + LAX cl; + LAX resource; +} + +void GT_TransitionToUav(GT_CommandList *cl, GT_Resource *resource) +{ + LAX cl; + LAX resource; +} + +void GT_TransitionToRtv(GT_CommandList *cl, GT_Resource *resource) +{ + LAX cl; + LAX resource; +} + +void GT_Flush(GT_CommandList *cl, GT_Resource *resource) +{ + LAX cl; + LAX resource; +} + +//////////////////////////////// +//~ @hookdef Dispatch hooks + +void GT_DispatchClear(GT_CommandList *cl, GT_Resource *resource) +{ + LAX cl; + LAX resource; +} + +void GT_DispatchRasterize(GT_CommandList *cl, + GT_ShaderDesc vs, + GT_ShaderDesc ps, + void *sig, + u32 rts_count, + GT_Resource **rts, + u32 viewports_count, + GT_Viewport *viewports, + u32 scissors_count, + GT_Scissor *scissors, + u32 instances_count, + GT_Resource *index_buffer, + GT_RasterizeMode mode) +{ + LAX cl; + LAX vs; + LAX ps; + LAX sig; + LAX rts_count; + LAX rts; + LAX viewports_count; + LAX *viewports; + LAX scissors_count; + LAX scissors; + LAX instances_count; + LAX index_buffer; + LAX mode; +} + +void GT_DispatchCompute(GT_CommandList *cl, GT_ShaderDesc cs, void *sig, u32 num_threads_x, u32 num_threads_y, u32 num_threads_z) +{ + LAX cl; + LAX cs; + LAX sig; + LAX num_threads_x; + LAX num_threads_y; + LAX num_threads_z; +} + +//////////////////////////////// +//~ @hookdef Copy hooks + +void GT_PushResource(GT_CommandList *cl, GT_Resource *dst, GT_Resource *src) +{ + LAX cl; + LAX dst; + LAX src; +} + +void GT_PushString(GT_CommandList *cl, GT_Resource *dst, String src) +{ + LAX cl; + LAX dst; + LAX src; +} + +//////////////////////////////// +//~ @hookdef Memory info hooks + +GT_MemoryInfo GT_QueryMemoryInfo(void) +{ + return (GT_MemoryInfo) ZI; +} + +//////////////////////////////// +//~ @hookdef Swapchain hooks + +GT_Swapchain *GT_AcquireSwapchain(P_Window *window, Vec2I32 size) +{ + LAX window; + LAX size; + return 0; +} + +void GT_ReleaseSwapchain(GT_Swapchain *swapchain) +{ + LAX swapchain; +} + +void GT_WaitOnSwapchain(GT_Swapchain *swapchain) +{ + LAX swapchain; +} + +void GT_PresentSwapchain(GT_Swapchain *swapchain, Vec2I32 backbuffer_resolution, GT_Resource *texture, Xform texture_xf, i32 vsync) +{ + LAX swapchain; + LAX backbuffer_resolution; + LAX texture; + LAX texture_xf; + LAX vsync; +} diff --git a/src/gtest/gtest.h b/src/gtest/gtest.h index 1644faa6..5f4c3792 100644 --- a/src/gtest/gtest.h +++ b/src/gtest/gtest.h @@ -5,9 +5,11 @@ //~ Layer dependencies #include "../base/base.h" +#include "../platform/platform.h" inline void GT_StartupDeps(void) { BaseMain(); + P_Main(); } //////////////////////////////// diff --git a/src/gtest/gtest_core.h b/src/gtest/gtest_core.h index b38d99e2..0ee9513a 100644 --- a/src/gtest/gtest_core.h +++ b/src/gtest/gtest_core.h @@ -1,4 +1,349 @@ +//////////////////////////////// +//~ Opaque types + +Struct(GT_Resource); +Struct(GT_CommandList); +Struct(GT_VertexShader); +Struct(GT_PixelShader); +Struct(GT_ComputeShader); +Struct(GT_Swapchain); + +//////////////////////////////// +//~ Queue types + +#define GT_MultiQueueEnabled !ProfilingIsEnabled +typedef i32 GT_QueueKind; +#if GT_MultiQueueEnabled +# define GT_QueueKind_Direct 0 +# define GT_QueueKind_Compute 1 +# define GT_QueueKind_Copy 2 +# define GT_QueueKind_BackgroundCopy 3 +# define GT_NumQueues 4 +#else +# define GT_QueueKind_Direct 0 +# define GT_QueueKind_Compute 0 +# define GT_QueueKind_Copy 0 +# define GT_QueueKind_BackgroundCopy 0 +# define GT_NumQueues 1 +#endif + +//////////////////////////////// +//~ Format types + +/* NOTE: Matches DXGI_FORMAT */ +typedef i32 GT_Format; enum +{ + GT_Format_Unknown = 0, + GT_Format_R32G32B32A32_Typeless = 1, + GT_Format_R32G32B32A32_Float = 2, + GT_Format_R32G32B32A32_Uint = 3, + GT_Format_R32G32B32A32_Sint = 4, + GT_Format_R32G32B32_Typeless = 5, + GT_Format_R32G32B32_Float = 6, + GT_Format_R32G32B32_Uint = 7, + GT_Format_R32G32B32_Sint = 8, + GT_Format_R16G16B16A16_Typeless = 9, + GT_Format_R16G16B16A16_Float = 10, + GT_Format_R16G16B16A16_Unorm = 11, + GT_Format_R16G16B16A16_Uint = 12, + GT_Format_R16G16B16A16_Snorm = 13, + GT_Format_R16G16B16A16_Sint = 14, + GT_Format_R32G32_Typeless = 15, + GT_Format_R32G32_Float = 16, + GT_Format_R32G32_Uint = 17, + GT_Format_R32G32_Sint = 18, + GT_Format_R32G8X24_Typeless = 19, + GT_Format_D32_Float_S8X24_Uint = 20, + GT_Format_R32_Float_X8X24_Typeless = 21, + GT_Format_X32_Typeless_G8X24_Uint = 22, + GT_Format_R10G10B10A2_Typeless = 23, + GT_Format_R10G10B10A2_Unorm = 24, + GT_Format_R10G10B10A2_Uint = 25, + GT_Format_R11G11B10_Float = 26, + GT_Format_R8G8B8A8_Typeless = 27, + GT_Format_R8G8B8A8_Unorm = 28, + GT_Format_R8G8B8A8_Unorm_Srgb = 29, + GT_Format_R8G8B8A8_Uint = 30, + GT_Format_R8G8B8A8_Snorm = 31, + GT_Format_R8G8B8A8_Sint = 32, + GT_Format_R16G16_Typeless = 33, + GT_Format_R16G16_Float = 34, + GT_Format_R16G16_Unorm = 35, + GT_Format_R16G16_Uint = 36, + GT_Format_R16G16_Snorm = 37, + GT_Format_R16G16_Sint = 38, + GT_Format_R32_Typeless = 39, + GT_Format_D32_Float = 40, + GT_Format_R32_Float = 41, + GT_Format_R32_Uint = 42, + GT_Format_R32_Sint = 43, + GT_Format_R24G8_Typeless = 44, + GT_Format_D24_Unorm_S8_Uint = 45, + GT_Format_R24_Unorm_X8_Typeless = 46, + GT_Format_X24_Typeless_G8_Uint = 47, + GT_Format_R8G8_Typeless = 48, + GT_Format_R8G8_Unorm = 49, + GT_Format_R8G8_Uint = 50, + GT_Format_R8G8_Snorm = 51, + GT_Format_R8G8_Sint = 52, + GT_Format_R16_Typeless = 53, + GT_Format_R16_Float = 54, + GT_Format_D16_Unorm = 55, + GT_Format_R16_Unorm = 56, + GT_Format_R16_Uint = 57, + GT_Format_R16_Snorm = 58, + GT_Format_R16_Sint = 59, + GT_Format_R8_Typeless = 60, + GT_Format_R8_Unorm = 61, + GT_Format_R8_Uint = 62, + GT_Format_R8_Snorm = 63, + GT_Format_R8_Sint = 64, + GT_Format_A8_Unorm = 65, + GT_Format_R1_Unorm = 66, + GT_Format_R9G9B9E5_SharedXP = 67, + GT_Format_R8G8_B8G8_Unorm = 68, + GT_Format_G8R8_G8B8_Unorm = 69, + GT_Format_BC1_Typeless = 70, + GT_Format_BC1_Unorm = 71, + GT_Format_BC1_Unorm_Srgb = 72, + GT_Format_BC2_Typeless = 73, + GT_Format_BC2_Unorm = 74, + GT_Format_BC2_Unorm_Srgb = 75, + GT_Format_BC3_Typeless = 76, + GT_Format_BC3_Unorm = 77, + GT_Format_BC3_Unorm_Srgb = 78, + GT_Format_BC4_Typeless = 79, + GT_Format_BC4_Unorm = 80, + GT_Format_BC4_Snorm = 81, + GT_Format_BC5_Typeless = 82, + GT_Format_BC5_Unorm = 83, + GT_Format_BC5_Snorm = 84, + GT_Format_B5G6R5_Unorm = 85, + GT_Format_B5G5R5A1_Unorm = 86, + GT_Format_B8G8R8A8_Unorm = 87, + GT_Format_B8G8R8X8_Unorm = 88, + GT_Format_R10G10B10_XR_BIAS_A2_Unorm = 89, + GT_Format_B8G8R8A8_Typeless = 90, + GT_Format_B8G8R8A8_Unorm_Srgb = 91, + GT_Format_B8G8R8X8_Typeless = 92, + GT_Format_B8G8R8X8_Unorm_Srgb = 93, + GT_Format_BC6H_Typeless = 94, + GT_Format_BC6H_UF16 = 95, + GT_Format_BC6H_SF16 = 96, + GT_Format_BC7_Typeless = 97, + GT_Format_BC7_Unorm = 98, + GT_Format_BC7_Unorm_Srgb = 99, + GT_Format_AYUV = 100, + GT_Format_Y410 = 101, + GT_Format_Y416 = 102, + GT_Format_NV12 = 103, + GT_Format_P010 = 104, + GT_Format_P016 = 105, + GT_Format_420_Opaque = 106, + GT_Format_YUY2 = 107, + GT_Format_Y210 = 108, + GT_Format_Y216 = 109, + GT_Format_NV11 = 110, + GT_Format_AI44 = 111, + GT_Format_IA44 = 112, + GT_Format_P8 = 113, + GT_Format_A8P8 = 114, + GT_Format_B4G4R4A4_Unorm = 115, + GT_Format_P208 = 130, + GT_Format_V208 = 131, + GT_Format_V408 = 132, + GT_Format_SAMPLER_FEEDBACK_MIN_MIP_Opaque = 189, + GT_Format_SAMPLER_FEEDBACK_MIP_REGION_USED_Opaque = 190, + GT_Format_A4B4G4R4_Unorm = 191, + GT_Format_Count = 192 +}; + +//////////////////////////////// +//~ Resource types + +typedef i32 GT_ResourceKind; enum +{ + GT_ResourceKind_Unknown, + GT_ResourceKind_Buffer, + GT_ResourceKind_Texture1D, + GT_ResourceKind_Texture2D, + GT_ResourceKind_Texture3D, + GT_ResourceKind_Sampler +}; + +typedef i32 GT_ResourceFlag; enum +{ + GT_ResourceFlag_None = 0, + GT_ResourceFlag_AllowSrv = (1 << 0), + GT_ResourceFlag_AllowUav = (1 << 1), + GT_ResourceFlag_AllowRtv = (1 << 2) +}; + +typedef i32 GT_HeapKind; enum +{ + GT_HeapKind_Default, + GT_HeapKind_Upload, + GT_HeapKind_Download +}; + +typedef i32 GT_ReleaseFlag; enum +{ + GT_ReleaseFlag_None = 0, + GT_ReleaseFlag_Reuse = (1 << 0) +}; + +Struct(GT_ResourceDesc) +{ + GT_ResourceKind kind; + GT_ResourceFlag flags; + union + { + struct + { + GT_Format format; + Vec3I32 size; + i32 mip_levels; + } texture; + struct + { + GT_HeapKind heap_kind; + u32 size; + u32 element_count; + u32 element_size; + } buffer; + }; +}; + +//////////////////////////////// +//~ Shader types + +Struct(GT_ShaderDesc) +{ + char *shader_id; +}; + +#define GT_ShaderDecl(name) static GT_ShaderDesc name = { .shader_id = #name } + +//////////////////////////////// +//~ Rasterizer types + +typedef i32 GT_RasterizeMode; enum +{ + GT_RasterizeMode_None, + GT_RasterizeMode_TriangleList +}; + +Struct(GT_Viewport) +{ + i32 _; +}; + +Struct(GT_Scissor) +{ + i32 _; +}; + +//////////////////////////////// +//~ Fence types + +Struct(GT_Fence) +{ + u64 targets[GT_NumQueues]; + u32 num_targets; +}; + +//////////////////////////////// +//~ Memory info types + +Struct(GT_MemoryInfo) +{ + i32 _; +}; + //////////////////////////////// //~ Startup void GT_StartupCore(void); + +//////////////////////////////// +//~ Rasterizer helpers + +GT_Viewport GT_ViewportFromRect(Rect rect); +GT_Scissor GT_ScissorRectFromRect(Rect rect); + +//////////////////////////////// +//~ Fence operations + +GT_Fence GT_GetGlobalFence(void); + +//////////////////////////////// +//~ Resource operations + +GT_Resource *GT_AcquireResource(GT_ResourceDesc desc); +void GT_ReleaseResource(GT_Resource *resource, GT_Fence fence, GT_ReleaseFlag flags); + +u32 GT_GetResourceId(GT_Resource *resource); +Vec2I32 GT_GetTextureSize(GT_Resource *resource); + +//////////////////////////////// +//~ Command list operations + +GT_CommandList *GT_BeginCommandList(void); +GT_Fence GT_EndCommandList(GT_CommandList *cl); + +void GT_ProfileDF(GT_CommandList *cl, String zone_name); + +//////////////////////////////// +//~ Resource transition operations + +void GT_TransitionToSrv(GT_CommandList *cl, GT_Resource *resource); +void GT_TransitionToUav(GT_CommandList *cl, GT_Resource *resource); +void GT_TransitionToRtv(GT_CommandList *cl, GT_Resource *resource); +void GT_Flush(GT_CommandList *cl, GT_Resource *resource); + +//////////////////////////////// +//~ Dispatch operations + +void GT_DispatchClear(GT_CommandList *cl, GT_Resource *resource); + +void GT_DispatchRasterize(GT_CommandList *cl, + GT_ShaderDesc vs, + GT_ShaderDesc ps, + void *sig, + u32 rts_count, + GT_Resource **rts, + u32 viewports_count, + GT_Viewport *viewports, + u32 scissors_count, + GT_Scissor *scissors, + u32 instances_count, + GT_Resource *index_buffer, + GT_RasterizeMode mode); + +void GT_DispatchCompute(GT_CommandList *cl, GT_ShaderDesc cs, void *sig, u32 num_threads_x, u32 num_threads_y, u32 num_threads_z); + +//////////////////////////////// +//~ Resource copy operations + +void GT_PushResource(GT_CommandList *cl, GT_Resource *dst, GT_Resource *src); +void GT_PushString(GT_CommandList *cl, GT_Resource *dst, String src); + +//////////////////////////////// +//~ Memory info operations + +GT_MemoryInfo GT_QueryMemoryInfo(void); + +//////////////////////////////// +//~ Swapchain operations + +GT_Swapchain *GT_AcquireSwapchain(P_Window *window, Vec2I32 size); +void GT_ReleaseSwapchain(GT_Swapchain *swapchain); + +/* Waits until a new backbuffer is ready to be written to. +* This should be called before rendering for minimum latency. */ +void GT_WaitOnSwapchain(GT_Swapchain *swapchain); + +/* 1. Clears the backbuffer and ensures it's at size `backbuffer_resolution` + * 2. Blits `texture` to the backbuffer using `texture_xf` + * 3. Presents the backbuffer */ +void GT_PresentSwapchain(GT_Swapchain *swapchain, Vec2I32 backbuffer_resolution, GT_Resource *texture, Xform texture_xf, i32 vsync); diff --git a/src/json/json_core.c b/src/json/json_core.c index 3ae5bfad..5e885986 100644 --- a/src/json/json_core.c +++ b/src/json/json_core.c @@ -803,7 +803,7 @@ void JSON_Parse(Arena *arena, JSON_Parser *p) { case JSON_TokenKind_Number: { - String t_text = (String) { .len = at->end - at->start, .text = &src.text[at->start] }; + String t_text = STRING(at->end - at->start, &src.text[at->start]); f64 value = interpret_number(t_text); json->type = JSON_Type_Number; json->value.number = value; @@ -812,7 +812,7 @@ void JSON_Parse(Arena *arena, JSON_Parser *p) case JSON_TokenKind_String: { - String t_text = (String) { .len = at->end - at->start, .text = &src.text[at->start] }; + String t_text = STRING(at->end - at->start, &src.text[at->start]); String error = ZI; String value = interpret_string(arena, t_text, &error); if (error.len > 0) diff --git a/src/platform/platform_core.h b/src/platform/platform_core.h index c39fdb18..fb07fca3 100644 --- a/src/platform/platform_core.h +++ b/src/platform/platform_core.h @@ -374,8 +374,8 @@ void P_DisableWindoweCursorClip(P_Window *window); void P_ToggleWindowTopmost(P_Window *window); //- Info -Vec2 P_GetWindowSize(P_Window *window); -Vec2 P_GetWindowMonitorSize(P_Window *window); +Vec2I32 P_GetWindowSize(P_Window *window); +Vec2I32 P_GetWindowMonitorSize(P_Window *window); u64 P_GetInternalWindowHandle(P_Window *window); //////////////////////////////// diff --git a/src/platform/platform_log.h b/src/platform/platform_log.h index 454771a1..34b0cfd9 100644 --- a/src/platform/platform_log.h +++ b/src/platform/platform_log.h @@ -113,7 +113,6 @@ Global Readonly P_LogLevelSettings P_log_settings[P_LogLevel_Count] = { } }; - //////////////////////////////// //~ Startup diff --git a/src/platform/platform_win32.c b/src/platform/platform_win32.c index f6df1fd1..3d7de946 100644 --- a/src/platform/platform_win32.c +++ b/src/platform/platform_win32.c @@ -196,7 +196,7 @@ P_W32_Window *P_W32_AcquireWindow(void) * the same thread that created the window. */ AddCounter(&window->ready_fence, 1); window->window_thread = W32_AcquireThread(&P_W32_WindowThreadEntryFunc, window, Lit("Window thread"), PROF_THREAD_GROUP_WINDOW); - WaitOnCounter(&window->ready_fence); + YieldOnCounter(&window->ready_fence); return window; } @@ -1563,16 +1563,16 @@ void P_ToggleWindowTopmost(P_Window *p_window) } //- Window info -Vec2 P_GetWindowSize(P_Window *p_window) +Vec2I32 P_GetWindowSize(P_Window *p_window) { P_W32_Window *window = (P_W32_Window *)p_window; - return VEC2((f32)window->width, (f32)window->height); + return VEC2I32(window->width, window->height); } -Vec2 P_GetWindowMonitorSize(P_Window *p_window) +Vec2I32 P_GetWindowMonitorSize(P_Window *p_window) { P_W32_Window *window = (P_W32_Window *)p_window; - return VEC2((f32)window->monitor_width, (f32)window->monitor_height); + return VEC2I32(window->monitor_width, window->monitor_height); } u64 P_GetInternalWindowHandle(P_Window *p_window) @@ -1995,7 +1995,7 @@ void P_SleepPrecise(i64 sleep_time_ns) while (now_ns < target_ns - big_sleep - tolerance) { __profn("Sleep part"); - FutexWait(0, 0, 0, big_sleep); + FutexYield(0, 0, 0, big_sleep); now_ns = TimeNs(); } diff --git a/src/playback/win32/playback_win32.c b/src/playback/win32/playback_win32.c index 0d1ebddc..0c72a0ea 100644 --- a/src/playback/win32/playback_win32.c +++ b/src/playback/win32/playback_win32.c @@ -24,7 +24,7 @@ ExitFuncDef(PB_WSP_Shutdown) __prof; PB_WSP_SharedState *g = &PB_WSP_shared_state; Atomic32FetchSet(&g->shutdown, 1); - WaitOnCounter(&g->PB_WSP_PlaybackJob_counter); + YieldOnCounter(&g->PB_WSP_PlaybackJob_counter); } void PB_WSP_InitializeWasapi(void) diff --git a/src/pp/pp.h b/src/pp/pp.h index 160edd1b..a53f2cd6 100644 --- a/src/pp/pp.h +++ b/src/pp/pp.h @@ -36,6 +36,7 @@ inline void StartupPpDeps(void) #include "pp_space.h" #include "pp_ent.h" #include "pp_step.h" +#include "pp_draw.h" #include "pp_core.h" void PpMain(void); diff --git a/src/pp/pp_core.c b/src/pp/pp_core.c index 79d8cfad..ed16f648 100644 --- a/src/pp/pp_core.c +++ b/src/pp/pp_core.c @@ -24,23 +24,27 @@ void StartupUser(void) g->user_client_store = AcquireClientStore(); g->user_unblended_client = AcquireClient(g->user_client_store); g->user_blended_client = AcquireClient(g->user_client_store); - g->ss_blended = sim_snapshot_nil(); + g->ss_blended = NilSnapshot(); + + /* Renderer data arenas */ + g->material_instances_arena = AcquireArena(Gibi(64)); + g->ui_rect_instances_arena = AcquireArena(Gibi(64)); + g->ui_shape_verts_arena = AcquireArena(Gibi(64)); + g->ui_shape_indices_arena = AcquireArena(Gibi(64)); + g->grids_arena = AcquireArena(Gibi(64)); /* Local to user client */ g->local_to_user_client_store = AcquireClientStore(); g->local_to_user_client = AcquireClient(g->local_to_user_client_store); - /* GPU handles */ g->world_to_ui_xf = XformIdentity; g->world_to_render_xf = XformIdentity; - g->render_sig = GPU_AcquireRenderSig(); g->console_logs_arena = AcquireArena(Gibi(64)); //P_RegisterLogCallback(ConsoleLogCallback, P_LogLevel_Success); P_RegisterLogCallback(ConsoleLogCallback, P_LogLevel_Debug); - g->window = P_AcquireWindow(); - g->swapchain = GPU_AcquireSwapchain(g->window, VEC2I32(100, 100)); + g->swapchain = GT_AcquireSwapchain(g->window, VEC2I32(100, 100)); P_ShowWindow(g->window); /* Start jobs */ @@ -57,7 +61,7 @@ ExitFuncDef(ShutdownUser) __prof; SharedUserState *g = &shared_user_state; Atomic32FetchSet(&g->shutdown, 1); - WaitOnCounter(&g->shutdown_job_counters); + YieldOnCounter(&g->shutdown_job_counters); P_ReleaseWindow(g->window); } @@ -79,8 +83,19 @@ void DrawDebugXform(Xform xf, u32 color_x, u32 color_y) x_ray = MulVec2(x_ray, ray_scale); y_ray = MulVec2(y_ray, ray_scale); + /* FIXME: Enable this */ +#if 0 D_DrawArrowRay(g->render_sig, pos, x_ray, thickness, arrowhead_len, color_x); D_DrawArrowRay(g->render_sig, pos, y_ray, thickness, arrowhead_len, color_y); +#else + LAX x_ray; + LAX y_ray; + LAX thickness; + LAX arrowhead_len; + LAX pos; + LAX color_x; + LAX color_y; +#endif //u32 color_quad = Rgba32F(0, 1, 1, 0.3); //Quad quad = QuadFromRect(RectFromScalar(0, 0, 1, -1)); @@ -105,7 +120,18 @@ void DrawDebugMovement(Entity *ent) if (Vec2Len(vel_ray) > 0.00001) { + /* FIXME: Enable this */ +#if 0 D_DrawArrowRay(g->render_sig, pos, vel_ray, thickness, arrow_len, color_vel); +#else + LAX thickness; + LAX arrow_len; + LAX color_vel; + LAX xf; + LAX velocity; + LAX pos; + LAX vel_ray; +#endif } } @@ -250,6 +276,8 @@ P_LogEventCallbackFuncDef(ConsoleLogCallback, log) //- Draw console void DrawDebugConsole(i32 level, b32 minimized) { + /* FIXME: Enable this */ +#if 0 __prof; SharedUserState *g = &shared_user_state; TempArena scratch = BeginScratchNoConflict(); @@ -350,6 +378,56 @@ void DrawDebugConsole(i32 level, b32 minimized) g->console_logs_height = bounds_bottom - bounds_top; } EndScratch(scratch); +#else + LAX level; + LAX minimized; +#endif +} + +//////////////////////////////// +//~ Render buffers + +//- Gbuffer + +GT_Resource *AcquireGbuffer(GT_Format format, Vec2I32 size) +{ + __prof; + GT_ResourceDesc desc = ZI; + desc.kind = GT_ResourceKind_Texture2D; + desc.flags = GT_ResourceFlag_AllowSrv | GT_ResourceFlag_AllowUav | GT_ResourceFlag_AllowRtv; + desc.texture.format = format; + desc.texture.size = VEC3I32(size.x, size.y, 1); + desc.texture.mip_levels = 1; + return GT_AcquireResource(desc); +} + +//- Transfer buffer + +GT_Resource *AcquireTransferBuffer(u32 element_count, u32 element_size, void *src) +{ + __prof; + u64 size = element_size * element_count; + GT_ResourceDesc desc = ZI; + desc.kind = GT_ResourceKind_Buffer; + desc.flags = GT_ResourceFlag_None; + desc.buffer.heap_kind = GT_HeapKind_Upload; + desc.buffer.size = size; + desc.buffer.element_count = element_count; + desc.buffer.element_size = element_size; + GT_Resource *r = GT_AcquireResource(desc); + { + __profn("Copy to transfer buffer"); + GT_PushString(0, r, STRING(size, src)); + } + return r; +} + +GT_Resource *AcquireTransferBufferFromArena(u32 element_count, Arena *arena) +{ + __prof; + u64 element_size = element_count > 0 ? arena->pos / element_count : 0; + GT_Resource *r = AcquireTransferBuffer(element_count, element_size, (void *)ArenaBase(arena)); + return r; } //////////////////////////////// @@ -470,7 +548,7 @@ void UpdateUser(P_Window *window) } /* Get two snapshots nearest to render time */ - Snapshot *left_snapshot = sim_snapshot_nil(); + Snapshot *left_snapshot = NilSnapshot(); Snapshot *right_snapshot = newest_snapshot; { Snapshot *ss = SnapshotFromTick(g->user_unblended_client, g->user_unblended_client->first_tick); @@ -781,7 +859,7 @@ void UpdateUser(P_Window *window) { height = CeilF32(width / aspect_ratio); } - g->ui_size = VEC2(width, height); + g->ui_size = VEC2I32(width, height); /* Center ui in window */ f32 x = RoundF32(g->screen_size.x / 2 - width / 2); @@ -839,19 +917,19 @@ void UpdateUser(P_Window *window) f32 rot = RotationFromXform(xf); /* Scale view into viewport based on camera size */ - Vec2 scale = g->ui_size; + Vec2 scale = VEC2(g->ui_size.x, g->ui_size.y); { Xform quad_xf = MulXform(xf, local_camera->camera_quad_xform); Vec2 camera_size = ScaleFromXform(quad_xf); if (!IsVec2Zero(camera_size)) { - scale = DivVec2Vec2(g->ui_size, camera_size); + scale = DivVec2Vec2(scale, camera_size); } } scale.x = MinF32(scale.x, scale.y); scale.y = scale.x; - Vec2 ui_center = MulVec2(g->ui_size, 0.5); + Vec2 ui_center = MulVec2(VEC2(g->ui_size.x, g->ui_size.y), 0.5); Trs trs = TRS(.t = SubVec2(ui_center, world_center), .r = rot, .s = scale); Vec2 pivot = world_center; g->world_to_ui_xf = XformIdentity; @@ -868,7 +946,7 @@ void UpdateUser(P_Window *window) //- Update world to render xform from world to ui xform b32 effects_disabled = 0; - g->render_size = RoundVec2(VEC2(RENDER_WIDTH, RENDER_HEIGHT)); + g->render_size = RoundVec2ToVec2I32(VEC2(RENDER_WIDTH, RENDER_HEIGHT)); if (g->debug_camera) { @@ -879,13 +957,13 @@ void UpdateUser(P_Window *window) else { Xform ui_to_world_xf = InvertXform(g->world_to_ui_xf); - Vec2 world_center = MulXformV2(ui_to_world_xf, MulVec2(g->ui_size, 0.5)); + Vec2 world_center = MulXformV2(ui_to_world_xf, MulVec2(VEC2(g->ui_size.x, g->ui_size.y), 0.5)); Vec2 scale = VEC2(PIXELS_PER_UNIT, PIXELS_PER_UNIT); Xform xf = XformIdentity; - xf = TranslateXform(xf, MulVec2(g->render_size, 0.5)); + xf = TranslateXform(xf, MulVec2(VEC2(g->render_size.x, g->render_size.y), 0.5)); xf = ScaleXform(xf, scale); xf = TranslateXform(xf, MulVec2(world_center, -1)); @@ -908,7 +986,7 @@ void UpdateUser(P_Window *window) { Vec2 up = VEC2(0, -1); - Vec2 ui_center = MulVec2(g->ui_size, 0.5f); + Vec2 ui_center = MulVec2(VEC2(g->ui_size.x, g->ui_size.y), 0.5f); Vec2 listener_pos = InvertXformMulV2(g->world_to_ui_xf, ui_center); Vec2 listener_dir = NormVec2(InvertXformBasisMulV2(g->world_to_ui_xf, up)); MIX_UpdateListener(listener_pos, listener_dir); @@ -916,6 +994,8 @@ void UpdateUser(P_Window *window) //- Draw grid + /* FIXME: Enable this */ +#if 0 { f32 thickness = 2; @@ -923,11 +1003,13 @@ void UpdateUser(P_Window *window) f32 spacing = ScaleFromXform(g->world_to_render_xf).x; Vec2 pos = InvertXformMulV2(g->world_to_render_xf, VEC2(0, 0)); - Vec2 size = InvertXformBasisMulV2(g->world_to_render_xf, g->render_size); + Vec2 size = InvertXformBasisMulV2(g->world_to_render_xf, VEC2(g->render_size.x, g->render_size.y)); u32 color0 = Rgba32F(0.17f, 0.17f, 0.17f, 1.f); u32 color1 = Rgba32F(0.15f, 0.15f, 0.15f, 1.f); D_DrawGrid(g->render_sig, XformFromRect(RectFromVec2(pos, size)), color0, color1, Rgba32(0x3f, 0x3f, 0x3f, 0xFF), ColorRed, ColorGreen, thickness, spacing, offset); } +#else +#endif #if 0 //- Acquire / release tile cache entries @@ -1030,8 +1112,6 @@ void UpdateUser(P_Window *window) Entity *chunk_ent_br = sim_ent_from_chunk_pos(chunk_pos_br); String data = sim_ent_get_chunk_tile_data(chunk_ent); - - //for (u64 x = 0; x < } } } @@ -1078,7 +1158,7 @@ void UpdateUser(P_Window *window) Entity *parent = EntityFromId(g->ss_blended, ent->parent); Xform xf = XformFromEntity(ent); - Xform parent_xf = XformFromEntity(parent); + UNUSED Xform parent_xf = XformFromEntity(parent); b32 skip_debug_draw = !g->debug_camera && ent == local_camera; skip_debug_draw = skip_debug_draw || HasProp(ent, Prop_MotorJoint); @@ -1086,7 +1166,7 @@ void UpdateUser(P_Window *window) b32 skip_debug_draw_transform = HasProp(ent, Prop_Camera); skip_debug_draw_transform = 1; - Xform sprite_xform = MulXform(xf, ent->sprite_local_xform); + UNUSED Xform sprite_xform = MulXform(xf, ent->sprite_local_xform); /* Draw tracer */ /* TODO: Enable this */ @@ -1147,8 +1227,16 @@ void UpdateUser(P_Window *window) Vec3 emittance = ent->sprite_emittance; u32 tint = ent->sprite_tint; S_Frame frame = S_FrameFromIndex(sheet, ent->animation_frame); - D_MaterialParams params = D_MATERIALPARAMS(.xf = sprite_xform, .texture = texture->gp_texture, .tint = tint, .clip = frame.clip, .is_light = is_light, .light_emittance = emittance); + /* FIXME: Enable this */ +#if 0 + D_MaterialParams params = D_MATERIALPARAMS(.xf = sprite_xform, .texture = texture->gpu_resource, .tint = tint, .clip = frame.clip, .is_light = is_light, .light_emittance = emittance); D_DrawMaterial(g->render_sig, params); +#else + LAX is_light; + LAX emittance; + LAX tint; + LAX frame; +#endif } } @@ -1169,14 +1257,22 @@ void UpdateUser(P_Window *window) Vec2I32 local_tile_index = VEC2I32(tile_x, tile_y); TileKind tile = ent->tile_chunk_tiles[local_tile_index.x + (local_tile_index.y * SIM_TILES_PER_CHUNK_SQRT)]; //if (tile > -1) { + /* FIXME: Enable this */ +#if 0 if (tile == TileKind_Wall) { Vec2I32 world_tile_index = WorldTileIndexFromLocalTileIndex(chunk_index, local_tile_index); Vec2 pos = PosFromWorldTileIndex(world_tile_index); Xform tile_xf = XformFromRect(RectFromVec2(pos, VEC2(tile_size, tile_size))); - D_MaterialParams params = D_MATERIALPARAMS(.xf = tile_xf, .texture = tile_texture->gp_texture, .is_light = 1, .light_emittance = VEC3(0, 0, 0)); + D_MaterialParams params = D_MATERIALPARAMS(.xf = tile_xf, .texture = tile_texture->gpu_resource, .is_light = 1, .light_emittance = VEC3(0, 0, 0)); D_DrawMaterial(g->render_sig, params); } +#else + LAX local_tile_index; + LAX tile; + LAX tile_size; + LAX chunk_index; +#endif } } } @@ -1201,6 +1297,8 @@ void UpdateUser(P_Window *window) } /* Draw AABB */ + /* FIXME: Enable this */ +#if 0 if (ent->local_collider.count > 0) { Aabb aabb = CLD_AabbFromShape(&ent->local_collider, xf); @@ -1222,6 +1320,7 @@ void UpdateUser(P_Window *window) end = MulXformV2(g->world_to_ui_xf, end); D_DrawArrowLine(g->render_sig, start, end, 3, 10, Rgba32F(1, 1, 1, 0.5)); } +#endif #if 0 /* Draw slices */ @@ -1285,6 +1384,8 @@ void UpdateUser(P_Window *window) #endif /* Draw mouse joint */ + /* FIXME: Enable this */ +#if 0 if (HasProp(ent, Prop_MouseJoint)) { Entity *target = EntityFromId(g->ss_blended, ent->mouse_joint_data.target); @@ -1297,8 +1398,11 @@ void UpdateUser(P_Window *window) D_DrawArrowLine(g->render_sig, point_start, point_end, 3, 10, color); D_DrawCircle(g->render_sig, point_start, 4, color, 10); } +#endif /* Draw collider */ + /* FIXME: Enable this */ +#if 0 if (ent->local_collider.count > 0) { CLD_Shape collider = ent->local_collider; @@ -1336,8 +1440,11 @@ void UpdateUser(P_Window *window) } #endif } +#endif /* Draw contact constraint */ + /* FIXME: Enable this */ +#if 0 if (HasProp(ent, Prop_ContactConstraint)) { ContactConstraint *data = &ent->contact_constraint_data; @@ -1407,6 +1514,7 @@ void UpdateUser(P_Window *window) } #endif } +#endif /* Draw collision debug */ #if COLLIDER_DEBUG @@ -1610,6 +1718,8 @@ void UpdateUser(P_Window *window) #endif /* Draw hierarchy */ + /* FIXME: Enable this */ +#if 0 if (HasProp(parent, Prop_Active) && !parent->is_root) { u32 color = Rgba32F(0.6, 0.6, 1, 0.75); @@ -1633,6 +1743,7 @@ void UpdateUser(P_Window *window) D_DrawQuadLine(g->render_sig, quad, thickness, color); } +#endif EndTempArena(temp); } @@ -1640,6 +1751,8 @@ void UpdateUser(P_Window *window) } /* Draw crosshair or show cursor */ + /* FIXME: Enable this */ +#if 0 if (!g->debug_camera) { __profn("Draw crosshair"); @@ -1648,8 +1761,9 @@ void UpdateUser(P_Window *window) S_Texture *t = S_TextureFromTagAsync(sprite_frame_scope, crosshair); Vec2 size = VEC2(t->width, t->height); Xform xf = XformFromTrs(TRS(.t = crosshair_pos, .s = size)); - D_DrawUiRect(g->render_sig, D_UIRECTPARAMS(.xf = xf, .texture = t->gp_texture)); + D_DrawUiRect(g->render_sig, D_UIRECTPARAMS(.xf = xf, .texture = t->gpu_resource)); } +#endif /* FIXME: Enable this */ #if 0 @@ -1870,7 +1984,8 @@ void UpdateUser(P_Window *window) } //- Draw ent debug info - + /* FIXME: Enable this */ +#if 0 if (g->debug_draw && hovered_ent->valid) { Entity *ent = hovered_ent; @@ -1889,13 +2004,16 @@ void UpdateUser(P_Window *window) EndTempArena(temp); } } +#endif //- Query vram - GPU_MemoryInfo vram = GPU_QueryMemoryInfo(); + GT_MemoryInfo vram = GT_QueryMemoryInfo(); //- Draw global debug info + /* FIXME: Enable this */ +#if 0 if (g->debug_draw) { __profn("Draw debug info"); @@ -2006,6 +2124,9 @@ void UpdateUser(P_Window *window) EndTempArena(temp); } } +#else + LAX vram; +#endif { #if DeveloperIsEnabled @@ -2024,24 +2145,299 @@ void UpdateUser(P_Window *window) { __profn("Render"); - Vec2I32 world_resolution = RoundVec2ToVec2I32(g->render_size); - Vec2I32 user_resolution = RoundVec2ToVec2I32(g->ui_size); - Vec2I32 backbuffer_resolution = RoundVec2ToVec2I32(g->screen_size); - - /* Draw world to user texture */ - GPU_Resource *render_texture = 0; + Rect ui_viewport = RectFromVec2(VEC2(0, 0), VEC2(g->ui_size.x, g->ui_size.y)); + Rect render_viewport = RectFromVec2(VEC2(0, 0), VEC2(g->render_size.x, g->render_size.y)); + /* Acquire gbuffers */ + if (g->shade_target && !EqVec2I32(g->render_size, GT_GetTextureSize(g->shade_target))) { - GPU_RenderParams params = ZI; - params.ui_size = user_resolution; - params.render_size = world_resolution; - params.world_to_render_xf = g->world_to_render_xf; - params.render_to_ui_xf = g->render_to_ui_xf; - params.effects_disabled = effects_disabled; - render_texture = GPU_RunRender(g->render_sig, params); + __profn("Release render resources"); + GT_ReleaseResource(g->albedo, g->render_fence, GT_ReleaseFlag_None); + GT_ReleaseResource(g->emittance, g->render_fence, GT_ReleaseFlag_None); + GT_ReleaseResource(g->emittance_flood_read, g->render_fence, GT_ReleaseFlag_None); + GT_ReleaseResource(g->emittance_flood_target, g->render_fence, GT_ReleaseFlag_None); + GT_ReleaseResource(g->shade_read, g->render_fence, GT_ReleaseFlag_None); + GT_ReleaseResource(g->shade_target, g->render_fence, GT_ReleaseFlag_None); + g->shade_target = 0; + } + if (!g->shade_target) + { + __profn("Acquire sig resources"); + g->albedo = AcquireGbuffer(GT_Format_R8G8B8A8_Unorm, g->render_size); + g->emittance = AcquireGbuffer(GT_Format_R16G16B16A16_Float, g->render_size); + g->emittance_flood_read = AcquireGbuffer(GT_Format_R16G16_Uint, g->render_size); + g->emittance_flood_target = AcquireGbuffer(GT_Format_R16G16_Uint, g->render_size); + g->shade_read = AcquireGbuffer(GT_Format_R16G16B16A16_Float, g->render_size); + g->shade_target = AcquireGbuffer(GT_Format_R16G16B16A16_Float, g->render_size); } - /* Present */ - GPU_PresentSwapchain(g->swapchain, backbuffer_resolution, render_texture, g->ui_to_screen_xf, VSYNC); + /* Acquire ui buffers */ + if (g->ui_target && !EqVec2I32(g->ui_size, GT_GetTextureSize(g->ui_target))) + { + GT_ReleaseResource(g->ui_target, g->render_fence, GT_ReleaseFlag_None); + g->ui_target = 0; + } + if (!g->ui_target) + { + g->ui_target = AcquireGbuffer(GT_Format_R8G8B8A8_Unorm, g->ui_size); + } + + /* Acquiretransfer buffers */ + /* TODO: Make these static */ + LocalPersist u16 quad_indices[6] = { 0, 1, 2, 0, 2, 3 }; + GT_Resource *quad_index_buffer = AcquireTransferBuffer(countof(quad_indices), sizeof(*quad_indices), quad_indices); + GT_Resource *material_instance_buffer = AcquireTransferBufferFromArena(g->material_instances_count, g->material_instances_arena); + GT_Resource *ui_rect_instance_buffer = AcquireTransferBufferFromArena(g->ui_rect_instances_count, g->ui_rect_instances_arena); + GT_Resource *ui_shape_verts_buffer = AcquireTransferBufferFromArena(g->ui_shape_verts_count, g->ui_shape_verts_arena); + GT_Resource *ui_shape_indices_buffer = AcquireTransferBufferFromArena(g->ui_shape_indices_count, g->ui_shape_indices_arena); + GT_Resource *grids_buffer = AcquireTransferBufferFromArena(g->grids_count, g->grids_arena); + + GT_CommandList *cl = GT_BeginCommandList(); + GT_ProfileDF(cl, Lit("Run render")); + { + __profn("Run render"); + Mat4x4 world_to_render_vp_matrix = ProjectMat4x4View(g->world_to_render_xf, render_viewport.width, render_viewport.height); + Mat4x4 ui_vp_matrix = ProjectMat4x4View(XformIdentity, ui_viewport.width, ui_viewport.height); + Mat4x4 blit_vp_matrix = ZI; + { + Xform xf = g->render_to_ui_xf; + xf = ScaleXform(xf, VEC2(g->render_size.x, g->render_size.y)); + xf = TranslateXform(xf, VEC2(0.5, 0.5)); + blit_vp_matrix = ProjectMat4x4View(xf, ui_viewport.width, ui_viewport.height); + } + + //- Prep material pass + GT_ProfileDF(cl, Lit("Clear gbuffers")); + { + __profn("Clear gbuffers"); + GT_TransitionToRtv(cl, g->albedo); + GT_TransitionToRtv(cl, g->emittance); + GT_DispatchClear(cl, g->albedo); + GT_DispatchClear(cl, g->emittance); + } + + //- Material pass + GT_ProfileDF(cl, Lit("Material pass")); + { + __profn("Material pass"); + + GT_Resource *rts[] = { + g->albedo, + g->emittance + }; + GT_Viewport viewport = GT_ViewportFromRect(render_viewport); + GT_Scissor scissor = GT_ScissorRectFromRect(render_viewport); + + MaterialSig sig = ZI; + sig.projection = world_to_render_vp_matrix; + sig.instances_urid = GT_GetResourceId(material_instance_buffer); + sig.grids_urid = GT_GetResourceId(grids_buffer); + GT_DispatchRasterize(cl, + MaterialVS, MaterialPS, + &sig, + countof(rts), rts, + 1, &viewport, + 1, &scissor, + g->material_instances_count, + quad_index_buffer, + GT_RasterizeMode_TriangleList); + } + + //- Prep flood pass + { + GT_TransitionToSrv(cl, g->emittance); + GT_TransitionToUav(cl, g->emittance_flood_read); + GT_TransitionToUav(cl, g->emittance_flood_target); + } + + //- Flood pass + if (!effects_disabled) + GT_ProfileDF(cl, Lit("Flood pass")); + { + __profn("Flood pass"); + + i32 step_length = -1; + + /* TODO: Remove this */ + u64 max_steps = GetGstat(GSTAT_DEBUG_STEPS); + u64 step = 0; + while (step_length != 0 && step < max_steps) + GT_ProfileDF(cl, Lit("Flood step")); + { + __profn("Flood step"); + + GT_Flush(cl, g->emittance_flood_read); + + FloodSig sig = ZI; + sig.step_len = step_length; + sig.emittance_tex_urid = GT_GetResourceId(g->emittance); + sig.read_flood_tex_urid = GT_GetResourceId(g->emittance_flood_read); + sig.target_flood_tex_urid = GT_GetResourceId(g->emittance_flood_target); + sig.tex_width = g->render_size.x; + sig.tex_height = g->render_size.y; + GT_DispatchCompute(cl, FloodCS, &sig, (g->render_size.x + 7) / 8, (g->render_size.y + 7) / 8, 1); + + /* Swap buffers */ + GT_Resource *swp = g->emittance_flood_read; + g->emittance_flood_read = g->emittance_flood_target; + g->emittance_flood_target = swp; + + /* Update step */ + if (step_length == -1) + { + step_length = MaxI32(g->render_size.x, g->render_size.y) / 2; + } + else + { + step_length /= 2; + } + ++step; + } + } + + //- Prep shade pass + GT_ProfileDF(cl, Lit("Clear shade target")); + { + __profn("Clear shade target"); + GT_TransitionToSrv(cl, g->albedo); + GT_TransitionToSrv(cl, g->emittance); + GT_TransitionToUav(cl, g->shade_target); + GT_Flush(cl, g->emittance_flood_read); + GT_Flush(cl, g->shade_read); + GT_DispatchClear(cl, g->shade_target); + } + + //- Shade pass + GT_ProfileDF(cl, Lit("Shade pass")); + { + __profn("Shade pass"); + + u32 shade_flags = K_SHADE_FLAG_NONE; + if (effects_disabled) + { + shade_flags |= K_SHADE_FLAG_DISABLE_EFFECTS; + } + ShadeSig sig = ZI; + sig.flags = shade_flags; + sig.tex_width = g->render_size.x; + sig.tex_height = g->render_size.y; + sig.frame_seed = VEC4I32((u32)(RandU64FromState(&g->frame_rand) & 0xFFFFFFFF), + (u32)(RandU64FromState(&g->frame_rand) & 0xFFFFFFFF), + (u32)(RandU64FromState(&g->frame_rand) & 0xFFFFFFFF), + (u32)(RandU64FromState(&g->frame_rand) & 0xFFFFFFFF)); + sig.frame_index = g->frame_index; + sig.camera_offset = g->world_to_render_xf.og; + sig.albedo_tex_urid = GT_GetResourceId(g->albedo); + sig.emittance_tex_urid = GT_GetResourceId(g->emittance); + sig.emittance_flood_tex_urid = GT_GetResourceId(g->emittance_flood_read); + sig.read_tex_urid = GT_GetResourceId(g->shade_read); + sig.target_tex_urid = GT_GetResourceId(g->shade_target); + GT_DispatchCompute(cl, ShadeCS, &sig, (g->render_size.x + 7) / 8, (g->render_size.y + 7) / 8, 1); + + /* Swap */ + GT_Resource *swp = g->shade_read; + g->shade_read = g->shade_target; + g->shade_target = swp; + } + + //- Prep ui pass + GT_ProfileDF(cl, Lit("Clear ui target")); + { + __profn("Clear ui target"); + GT_TransitionToRtv(cl, g->ui_target); + GT_Flush(cl, g->shade_read); + GT_DispatchClear(cl, g->ui_target); + } + + //- Ui blit pass + GT_ProfileDF(cl, Lit("UI blit pass")); + { + __profn("UI blit pass"); + + GT_Viewport viewport = GT_ViewportFromRect(ui_viewport); + GT_Scissor scissor = GT_ScissorRectFromRect(ui_viewport); + + UiBlitSig sig = ZI; + sig.projection = blit_vp_matrix; + sig.flags = UiBlitFlag_ToneMap | UiBlitFlag_GammaCorrect; + sig.exposure = 2.0; + sig.gamma = (f32)2.2; + sig.tex_urid = GT_GetResourceId(g->shade_read); + GT_DispatchRasterize(cl, + UiBlitVS, UiBlitPS, + &sig, + 1, &g->ui_target, + 1, &viewport, + 1, &scissor, + 1, + quad_index_buffer, + GT_RasterizeMode_TriangleList); + } + + //- Ui rect pass + GT_ProfileDF(cl, Lit("UI rect pass")); + { + __profn("UI rect pass"); + + GT_Viewport viewport = GT_ViewportFromRect(ui_viewport); + GT_Scissor scissor = GT_ScissorRectFromRect(ui_viewport); + + UiRectSig sig = ZI; + sig.projection = ui_vp_matrix; + sig.instances_urid = GT_GetResourceId(ui_rect_instance_buffer); + GT_DispatchRasterize(cl, + UiRectVS, UiRectPS, + &sig, + 1, &g->ui_target, + 1, &viewport, + 1, &scissor, + g->ui_rect_instances_count, + quad_index_buffer, + GT_RasterizeMode_TriangleList); + } + + //- Ui shape pass + GT_ProfileDF(cl, Lit("UI shape pass")); + { + __profn("UI shape pass"); + + GT_Viewport viewport = GT_ViewportFromRect(ui_viewport); + GT_Scissor scissor = GT_ScissorRectFromRect(ui_viewport); + + UiShapeSig sig = ZI; + sig.projection = ui_vp_matrix; + sig.verts_urid = GT_GetResourceId(ui_shape_verts_buffer); + GT_DispatchRasterize(cl, + UiShapeVS, UiShapePS, + &sig, + 1, &g->ui_target, + 1, &viewport, + 1, &scissor, + 1, + ui_shape_indices_buffer, + GT_RasterizeMode_TriangleList); + } + } + g->render_fence = GT_EndCommandList(cl); + + /* Release transfer buffers */ + { + GT_ReleaseResource(quad_index_buffer, g->render_fence, GT_ReleaseFlag_Reuse); + GT_ReleaseResource(material_instance_buffer, g->render_fence, GT_ReleaseFlag_Reuse); + GT_ReleaseResource(ui_rect_instance_buffer, g->render_fence, GT_ReleaseFlag_Reuse); + GT_ReleaseResource(ui_shape_verts_buffer, g->render_fence, GT_ReleaseFlag_Reuse); + GT_ReleaseResource(ui_shape_indices_buffer, g->render_fence, GT_ReleaseFlag_Reuse); + GT_ReleaseResource(grids_buffer, g->render_fence, GT_ReleaseFlag_Reuse); + ResetArena(g->material_instances_arena); + ResetArena(g->ui_rect_instances_arena); + ResetArena(g->ui_shape_verts_arena); + ResetArena(g->ui_shape_indices_arena); + ResetArena(g->grids_arena); + g->material_instances_count = 0; + g->ui_rect_instances_count = 0; + g->ui_shape_verts_count = 0; + g->ui_shape_indices_count = 0; + g->grids_count = 0; + } } //- End frame cache scopes @@ -2051,7 +2447,8 @@ void UpdateUser(P_Window *window) EndScratch(scratch); } -//- User update job +//////////////////////////////// +//~ User update job JobDef(UpdateUserJob, UNUSED sig, UNUSED id) { @@ -2064,7 +2461,7 @@ JobDef(UpdateUserJob, UNUSED sig, UNUSED id) __profn("User sleep"); { __profn("Swapchain wait"); - GPU_WaitOnSwapchain(g->swapchain); + GT_WaitOnSwapchain(g->swapchain); } { __profn("Frame limiter wait"); @@ -2506,7 +2903,7 @@ JobDef(SimJob, UNUSED sig, UNUSED id) b32 master_ss_is_blended = 0; - Snapshot *master_ss = sim_snapshot_nil(); + Snapshot *master_ss = NilSnapshot(); { /* How along are we between master sim ticks (0 = start of tick, 1 = end of tick) */ f64 tick_progress = 0; @@ -2537,7 +2934,7 @@ JobDef(SimJob, UNUSED sig, UNUSED id) /* Get snapshot nearest to master blend time */ /* TODO: Blend */ - Snapshot *left_snapshot = sim_snapshot_nil(); + Snapshot *left_snapshot = NilSnapshot(); Snapshot *right_snapshot = newest_snapshot; { Snapshot *ss = SnapshotFromTick(master_client, master_client->first_tick); diff --git a/src/pp/pp_core.h b/src/pp/pp_core.h index b67f921b..8c25a681 100644 --- a/src/pp/pp_core.h +++ b/src/pp/pp_core.h @@ -155,9 +155,7 @@ Struct(SharedUserState) Atomic32 shutdown; Counter shutdown_job_counters; P_Window *window; - GPU_Swapchain *swapchain; - - struct sim_ctx *local_sim_ctx; + GT_Swapchain *swapchain; Arena *arena; String connect_address_str; @@ -173,8 +171,31 @@ Struct(SharedUserState) SecondsStat net_bytes_sent; //- Gpu resources - GPU_RenderSig *render_sig; + GT_Resource *albedo; + GT_Resource *emittance; + GT_Resource *emittance_flood_read; + GT_Resource *emittance_flood_target; + GT_Resource *shade_read; + GT_Resource *shade_target; + GT_Resource *ui_target; + RandState frame_rand; + u64 frame_index; + + Arena *material_instances_arena; + Arena *ui_rect_instances_arena; + Arena *ui_shape_verts_arena; + Arena *ui_shape_indices_arena; + Arena *grids_arena; + u32 material_instances_count; + u32 ui_rect_instances_count; + u32 ui_shape_verts_count; + u32 ui_shape_indices_count; + u32 grids_count; + + GT_Fence render_fence; + + //- Bind state BindState bind_states[BindKind_Count]; //- Debug camera @@ -230,15 +251,15 @@ Struct(SharedUserState) //- Per frame - Vec2 screen_size; + Vec2I32 screen_size; Vec2 screen_cursor; Xform ui_to_screen_xf; - Vec2 ui_size; + Vec2I32 ui_size; Vec2 ui_cursor; Xform render_to_ui_xf; - Vec2 render_size; + Vec2I32 render_size; Xform world_to_render_xf; Xform world_to_ui_xf; @@ -272,6 +293,13 @@ String DebugStringFromEntity(Arena *arena, Entity *ent); P_LogEventCallbackFuncDef(ConsoleLogCallback, log); void DrawDebugConsole(i32 level, b32 minimized); +//////////////////////////////// +//~ Gpu buffer helpers + +GT_Resource *AcquireGbuffer(GT_Format format, Vec2I32 size); +GT_Resource *AcquireTransferBuffer(u32 element_count, u32 element_size, void *src); +GT_Resource *AcquireTransferBufferFromArena(u32 element_count, Arena *arena); + //////////////////////////////// //~ Entity sorting @@ -281,6 +309,10 @@ MergesortCompareFuncDef(EntitySortCmp, arg_a, arg_b, _); //~ User update void UpdateUser(P_Window *window); + +//////////////////////////////// +//~ User update job + JobDecl(UpdateUserJob, EmptySig); //////////////////////////////// diff --git a/src/pp/pp_draw.gpu b/src/pp/pp_draw.gpu new file mode 100644 index 00000000..988425c0 --- /dev/null +++ b/src/pp/pp_draw.gpu @@ -0,0 +1,445 @@ +//////////////////////////////// +//~ Signatures + +ConstantBuffer blit_sig : register(b0); +ConstantBuffer flood_sig : register(b0); +ConstantBuffer mat_sig : register(b0); +ConstantBuffer shade_sig : register(b0); +ConstantBuffer ui_sig : register(b0); +ConstantBuffer shape_sig : register(b0); + +//////////////////////////////// +//~ Material + +Struct(MaterialPS_Input) +{ + nointerpolation Semantic(u32, tex_nurid); + nointerpolation Semantic(u32, grid_id); + Semantic(Vec2, uv); + Semantic(Vec4, tint_lin); + Semantic(Vec4, emittance_lin); + Semantic(Vec4, SV_Position); +}; + +Struct(MaterialPS_Output) +{ + Semantic(Vec4, SV_Target0); /* Albedo */ + Semantic(Vec4, SV_Target1); /* Emittance */ +}; + +//- Vertex shader + +MaterialPS_Input GPU_VertexShaderDef(MaterialVS)(Semantic(u32, SV_InstanceID), Semantic(u32, SV_VertexID)) +{ + static const Vec2 unit_quad_verts[4] = { + Vec2(-0.5f, -0.5f), + Vec2(0.5f, -0.5f), + Vec2(0.5f, 0.5f), + Vec2(-0.5f, 0.5f) + }; + StructuredBuffer instances = GpuResourceFromUrid(sig.instances_urid); + K_MaterialInstance instance = instances[SV_InstanceID]; + Vec2 vert = unit_quad_verts[SV_VertexID]; + Vec2 world_pos = mul(instance.xf, Vec3(vert, 1)).xy; + MaterialPS_Input output; + output.SV_Position = mul(sig.projection, Vec4(world_pos, 0, 1)); + output.tex_nurid = instance.tex_nurid; + output.grid_id = instance.grid_id; + output.uv = instance.uv0 + ((vert + 0.5) * (instance.uv1 - instance.uv0)); + output.tint_lin = LinearFromSrgbU32(instance.tint_srgb); + output.emittance_lin = LinearFromSrgbVec4(Vec4(instance.light_emittance_srgb, instance.is_light)); + return output; +} + +//- Pixel shader + +MaterialPS_Output GPU_PixelShaderDef(MaterialPS)(MaterialPS_Input input) +{ + MaterialPS_Output output; + Vec4 albedo = input.tint_lin; + + /* Texture */ + if (input.tex_nurid < 0xFFFFFFFF) + { + Texture2D tex = GpuResourceFromNurid(input.tex_nurid); + albedo *= tex.Sample(s_point_clamp, input.uv); + } + + /* Grid */ + if (input.grid_id < 0xFFFFFFFF) + { + StructuredBuffer grids = GpuResourceFromUrid(sig.grids_urid); + K_MaterialGrid grid = grids[input.grid_id]; + Vec2 grid_pos = input.SV_Position.xy + grid.offset; + float half_thickness = grid.line_thickness / 2; + float spacing = grid.line_spacing; + u32 color_srgb = grid.bg0_srgb; + Vec2 v = abs(round(grid_pos / spacing) * spacing - grid_pos); + float dist = min(v.x, v.y); + if (grid_pos.y <= half_thickness && grid_pos.y >= -half_thickness) + { + color_srgb = grid.x_srgb; + } + else if (grid_pos.x <= half_thickness && grid_pos.x >= -half_thickness) + { + color_srgb = grid.y_srgb; + } + else if (dist < half_thickness) + { + color_srgb = grid.line_srgb; + } + else + { + bool checker = 0; + u32 cell_x = (u32)(abs(grid_pos.x) / spacing) + (grid_pos.x < 0); + u32 cell_y = (u32)(abs(grid_pos.y) / spacing) + (grid_pos.y < 0); + if (cell_x % 2 == 0) + { + checker = cell_y % 2 == 0; + } + else + { + checker = cell_y % 2 == 1; + } + if (checker) + { + color_srgb = grid.bg1_srgb; + } + } + albedo = LinearFromSrgbU32(color_srgb); + } + + Vec4 emittance = input.emittance_lin * albedo.a; + + output.SV_Target0 = albedo; + output.SV_Target1 = emittance; + return output; +} + +//////////////////////////////// +//~ Flood + +//- Compute shader + +[numthreads(8, 8, 1)] +void GPU_ComputeShaderDef(FloodCS)(Semantic(uint3, SV_DispatchThreadID)) +{ + uint2 id = SV_DispatchThreadID.xy; + uint2 tex_size = uint2(sig.tex_width, sig.tex_height); + if (id.x < tex_size.x && id.y < tex_size.y) + { + Texture2D emittance_tex = GpuResourceFromUrid(sig.emittance_tex_urid); + RWTexture2D read_flood_tex = GpuResourceFromUrid(sig.read_flood_tex_urid); + RWTexture2D target_flood_tex = GpuResourceFromUrid(sig.target_flood_tex_urid); + int step_len = sig.step_len; + if (step_len == -1) + { + /* Seed */ + Vec4 emittance = emittance_tex[id]; + uint2 seed = uint2(0xFFFF, 0xFFFF); + if (emittance.a > 0) + { + seed = id; + } + target_flood_tex[id] = seed; + } + else + { + /* Flood */ + Vec2I32 read_coords[9] = { + (Vec2I32)id + Vec2I32(-step_len, -step_len), /* top left */ + (Vec2I32)id + Vec2I32(0, -step_len), /* top center */ + (Vec2I32)id + Vec2I32(+step_len, -step_len), /* top right */ + (Vec2I32)id + Vec2I32(-step_len, 0), /* center left */ + (Vec2I32)id + Vec2I32(0, 0), /* center center */ + (Vec2I32)id + Vec2I32(+step_len, 0), /* center right */ + (Vec2I32)id + Vec2I32(-step_len, +step_len), /* bottom left */ + (Vec2I32)id + Vec2I32(0, +step_len), /* bottom center */ + (Vec2I32)id + Vec2I32(+step_len, +step_len) /* bottom right */ + }; + uint2 closest_seed = uint2(0xFFFF, 0xFFFF); + u32 closest_seed_len_sq = 0xFFFFFFFF; + for (int i = 0; i < 9; ++i) + { + Vec2I32 coord = read_coords[i]; + if (coord.x >= 0 && coord.x < (int)tex_size.x && coord.y >= 0 && coord.y < (int)tex_size.y) + { + uint2 seed = read_flood_tex[coord]; + Vec2I32 dist_vec = (Vec2I32)id - (Vec2I32)seed; + u32 dist_len_sq = dot(dist_vec, dist_vec); + if (dist_len_sq < closest_seed_len_sq) + { + closest_seed = seed; + closest_seed_len_sq = dist_len_sq; + } + } + } + target_flood_tex[id] = closest_seed; + } + } +} + +//////////////////////////////// +//~ Shade + +#define LightSamples 16 +#define LightMarches 16 +#define LightEdgeFalloff 100 + +float rand_angle(uint2 pos, u32 ray_index) +{ + Texture3D noise_tex = GpuResourceFromUrid(K_BLUE_NOISE_TEX_ID); + + Vec3I32 noise_coord = Vec3I32(1, 1, 1); + noise_coord += Vec3I32(pos.xy, ray_index); + noise_coord.xyz += sig.frame_seed.xyz; + // noise_coord.xy -= sig.camera_offset; + + u32 noise = noise_tex[noise_coord % uint3(K_BLUE_NOISE_TEX_WIDTH, K_BLUE_NOISE_TEX_HEIGHT, K_BLUE_NOISE_TEX_DEPTH)]; + return ((float)noise / (float)0xFFFF) * Tau; +} + +Vec3 get_light_in_dir(uint2 ray_start, Vec2 ray_dir) +{ + Texture2D flood_tex = GpuResourceFromUrid(sig.emittance_flood_tex_urid); + Texture2D emittance_tex = GpuResourceFromUrid(sig.emittance_tex_urid); + + Vec3 result = Vec3(0, 0, 0); + Vec2 at_float = ray_start; + uint2 at_uint = ray_start; + for (u32 i = 0; i < LightMarches; ++i) + { + uint2 flood = flood_tex[at_uint]; + Vec2 dist_vec = at_float - (Vec2)flood; + float dist = length(dist_vec); + if (dist < 1) + { + /* Scale light by distance from edge so that offscreen-lights fade in/out rather than popping in */ + float dist_x = min(abs(sig.tex_width - at_float.x), at_float.x); + float dist_y = min(abs(sig.tex_height - at_float.y), at_float.y); + float dist_scale = min(min(dist_x, dist_y) / LightEdgeFalloff, 1); + result = emittance_tex[flood].rgb * dist_scale; + break; + } + else + { + at_float += ray_dir * dist; + at_uint = round(at_float); + if (at_uint.x < 0 || at_uint.x >= sig.tex_width || at_uint.y < 0 || at_uint.y >= sig.tex_height) + { + /* Ray hit edge of screen */ + break; + } + } + } + return result; +} + +Vec3 get_light_at_pos(uint2 pos) +{ + Vec3 result = 0; + for (u32 i = 0; i < LightSamples; ++i) + { + float angle = rand_angle(pos, i); + Vec2 dir = Vec2(cos(angle), sin(angle)); + Vec3 light_in_dir = get_light_in_dir(pos, dir); + result += light_in_dir; + } + result /= LightSamples; + return result; +} + +//- Compute shader + +[numthreads(8, 8, 1)] +void GPU_ComputeShaderDef(ShadeCS)(Semantic(uint3, SV_DispatchThreadID)) +{ + uint2 id = SV_DispatchThreadID.xy; + if (id.x < sig.tex_width && id.y < sig.tex_height) + { + Texture2D albedo_tex = GpuResourceFromUrid(sig.albedo_tex_urid); + Texture2D read_tex = GpuResourceFromUrid(sig.read_tex_urid); + RWTexture2D target_tex = GpuResourceFromUrid(sig.target_tex_urid); + Vec4 color = Vec4(1, 1, 1, 1); + + /* Apply albedo */ + color *= albedo_tex[id]; + + /* Apply lighting */ + if (!(sig.flags & K_SHADE_FLAG_DISABLE_EFFECTS)) + { + color.rgb *= get_light_at_pos(id); + } + + /* Apply temporal accumulation */ + float hysterisis = 0; + // hysterisis = 0.2; + // hysterisis = 0.4; + // hysterisis = 0.5; + // hysterisis = 0.9; + color.rgb = lerp(color.rgb, read_tex[id].rgb, hysterisis); + + target_tex[id] = color; + } +} + +//////////////////////////////// +//~ Ui Blit + +Struct(UiBlitPS_Input) +{ + Semantic(Vec4, SV_Position); + Semantic(Vec2, uv); +}; + +Struct(UiBlitPS_Output) +{ + Semantic(Vec4, SV_Target); +}; + +//- ACES + +/* ACES approximation by Krzysztof Narkowicz + * https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ */ +Vec3 tone_map(Vec3 v) +{ + return saturate((v * (2.51f * v + 0.03f)) / (v * (2.43f * v + 0.59f) + 0.14f)); +} + +//- Vertex shader + +UiBlitPS_Input GT_VertexShaderDef(UiBlitVS)(Semantic(u32, SV_VertexID)) +{ + static const Vec2 unit_quad_verts[4] = { + Vec2(-0.5f, -0.5f), + Vec2(0.5f, -0.5f), + Vec2(0.5f, 0.5f), + Vec2(-0.5f, 0.5f) + }; + + Vec2 vert = unit_quad_verts[SV_VertexID]; + + UiBlitPS_Input output; + output.SV_Position = mul(sig.projection, Vec4(vert, 0, 1)); + output.uv = vert + 0.5; + return output; +} + +//- Pixel shader + +UiBlitPS_Output GT_PixelShaderDef(UiBlitPS)(UiBlitPS_Input input) +{ + UiBlitPS_Output output; + Texture2D tex = GpuResourceFromUrid(sig.tex_urid); + Vec4 color = tex.Sample(s_point_clamp, input.uv); + + /* Apply tone map */ + if (sig.flags & K_BLIT_FLAG_TONE_MAP) + { + /* TODO: Dynamic exposure based on average scene luminance */ + color.rgb *= sig.exposure; + color.rgb = tone_map(color.rgb); + } + + /* Apply gamma correction */ + if (sig.flags & K_BLIT_FLAG_GAMMA_CORRECT) + { + color = pow(abs(color), 1/sig.gamma); + } + + output.SV_Target = color; + return output; +} + +//////////////////////////////// +//~ Ui rect + +Struct(UiRectPS_Input) +{ + nointerpolation Semantic(u32, tex_nurid); + Semantic(Vec2, uv); + Semantic(Vec4, tint_srgb); + Semantic(Vec4, SV_Position); +}; + +Struct(UiRectPS_Output) +{ + Semantic(Vec4, SV_Target0); +}; + +//- Vertex shader + +UiRectPS_Input GT_VertexShaderDef(UiRectVS)(Semantic(u32, SV_InstanceID), Semantic(u32, SV_VertexID)) +{ + static const Vec2 unit_quad_verts[4] = { + Vec2(-0.5f, -0.5f), + Vec2(0.5f, -0.5f), + Vec2(0.5f, 0.5f), + Vec2(-0.5f, 0.5f) + }; + + StructuredBuffer instances = GpuResourceFromUrid(sig.instances_urid); + K_UiInstance instance = instances[SV_InstanceID]; + Vec2 vert = unit_quad_verts[SV_VertexID]; + Vec2 world_pos = mul(instance.xf, Vec3(vert, 1)).xy; + + UiRectPS_Input output; + output.SV_Position = mul(sig.projection, Vec4(world_pos, 0, 1)); + output.tex_nurid = instance.tex_nurid; + output.uv = instance.uv0 + ((vert + 0.5) * (instance.uv1 - instance.uv0)); + output.tint_srgb = Vec4NormFromU32(instance.tint_srgb); + return output; +} + +//- Pixel shader + +UiRectPS_Output GT_PixelShaderDef(UiRectPS)(PSInput input) +{ + UiRectPS_Output output; + Vec4 color = input.tint_srgb; + + /* Texture */ + if (input.tex_nurid < 0xFFFFFFFF) + { + Texture2D tex = GpuResourceFromNurid(input.tex_nurid); + color *= tex.Sample(s_point_clamp, input.uv); + } + + output.SV_Target0 = color; + return output; +} + +//////////////////////////////// +//~ Ui shape + +Struct(UiShapePS_Input) +{ + Semantic(Vec4, SV_Position); + Semantic(Vec4, color_srgb); +}; + +Struct(UiShapePS_Output) +{ + Semantic(Vec4, SV_Target); +}; + +//- Vertex shader + +UiShapePS_Input GT_VertexShaderDef(UiShapeVS)(Semantic(u32, SV_VertexID)) +{ + StructuredBuffer verts = GpuResourceFromUrid(sig.verts_urid); + UiShapeVert vert = verts[SV_VertexID]; + UiShapePS_Input output; + output.SV_Position = mul(sig.projection, Vec4(vert.pos.xy, 0, 1)); + output.color_srgb = Vec4NormFromU32(vert.color_srgb); + return output; +} + +//- Pixel shader + +UiShapePS_Output GT_PixelShaderDef(UiShapePS)(PSInput input) +{ + UiShapePS_Output output; + output.SV_Target = input.color_srgb; + return output; +} diff --git a/src/pp/pp_draw.h b/src/pp/pp_draw.h new file mode 100644 index 00000000..d7671229 --- /dev/null +++ b/src/pp/pp_draw.h @@ -0,0 +1,180 @@ +//////////////////////////////// +//~ Material types + +Struct(MaterialSig) +{ + /* ----------------------------------------------------- */ + Mat4x4 projection; /* 16 consts */ + /* ----------------------------------------------------- */ + u32 instances_urid; /* 01 consts */ + u32 grids_urid; /* 01 consts */ + u32 _pad0; /* 01 consts (padding) */ + u32 _pad1; /* 01 consts (padding) */ + /* ----------------------------------------------------- */ +}; +AssertRootConst(MaterialSig, 20); + +Struct(MaterialInstance) +{ + u32 tex_nurid; + u32 grid_id; + Xform xf; + Vec2 uv0; + Vec2 uv1; + u32 tint_srgb; + u32 is_light; + Vec3 light_emittance_srgb; +}; + +Struct(MaterialGrid) +{ + f32 line_thickness; + f32 line_spacing; + Vec2 offset; + u32 bg0_srgb; + u32 bg1_srgb; + u32 line_srgb; + u32 x_srgb; + u32 y_srgb; +}; + +//////////////////////////////// +//~ Flood types + +Struct(FloodSig) +{ + /* ----------------------------------------------------- */ + i32 step_len; /* 01 consts */ + u32 emittance_tex_urid; /* 01 consts */ + u32 read_flood_tex_urid; /* 01 consts */ + u32 target_flood_tex_urid; /* 01 consts */ + /* ----------------------------------------------------- */ + u32 tex_width; /* 01 consts */ + u32 tex_height; /* 01 consts */ + u32 _pad0; /* 01 consts (padding) */ + u32 _pad1; /* 01 consts (padding) */ + /* ----------------------------------------------------- */ +}; +AssertRootConst(FloodSig, 8); + +//////////////////////////////// +//~ Shade types + +#define K_SHADE_FLAG_NONE (0 << 0) +#define K_SHADE_FLAG_DISABLE_EFFECTS (1 << 0) + +Struct(ShadeSig) +{ + /* ----------------------------------------------------- */ + Vec4I32 frame_seed; /* 04 consts */ + /* ----------------------------------------------------- */ + u32 flags; /* 01 consts */ + u32 _pad0; /* 01 consts (padding) */ + u32 tex_width; /* 01 consts */ + u32 tex_height; /* 01 consts */ + /* ----------------------------------------------------- */ + Vec2 camera_offset; /* 02 consts */ + u32 frame_index; /* 01 consts */ + u32 albedo_tex_urid; /* 01 consts */ + /* ----------------------------------------------------- */ + u32 emittance_tex_urid; /* 01 consts */ + u32 emittance_flood_tex_urid; /* 01 consts */ + u32 read_tex_urid; /* 01 consts */ + u32 target_tex_urid; /* 01 consts */ + /* ----------------------------------------------------- */ +}; +AssertRootConst(ShadeSig, 16); + +//////////////////////////////// +//~ Ui blit types + +#define UiBlitFlag_None (0) +#define UiBlitFlag_ToneMap (1 << 0) +#define UiBlitFlag_GammaCorrect (1 << 1) + +Struct(UiBlitSig) +{ + /* ----------------------------------------------------- */ + Mat4x4 projection; /* 16 consts */ + /* ----------------------------------------------------- */ + u32 flags; /* 01 consts */ + u32 tex_urid; /* 01 consts */ + f32 exposure; /* 01 consts */ + f32 gamma; /* 01 consts */ + /* ----------------------------------------------------- */ +}; +AssertRootConst(UiBlitSig, 20); + + +//////////////////////////////// +//~ Ui rect types + +Struct(UiRectSig) +{ + /* ----------------------------------------------------- */ + Mat4x4 projection; /* 16 consts */ + /* ----------------------------------------------------- */ + u32 instances_urid; /* 01 consts */ + u32 _pad0; /* 01 consts (padding) */ + u32 _pad1; /* 01 consts (padding) */ + u32 _pad2; /* 01 consts (padding) */ + /* ----------------------------------------------------- */ +}; +AssertRootConst(UiRectSig, 20); + +Struct(UiRectInstance) +{ + u32 tex_nurid; + u32 grid_id; + Xform xf; + Vec2 uv0; + Vec2 uv1; + u32 tint_srgb; +}; + +//////////////////////////////// +//~ Ui shape types + +Struct(UiShapeSig) +{ + /* ----------------------------------------------------- */ + Mat4x4 projection; /* 16 consts */ + /* ----------------------------------------------------- */ + u32 verts_urid; /* 01 consts */ + u32 _pad0; /* 01 consts (padding) */ + u32 _pad1; /* 01 consts (padding) */ + u32 _pad2; /* 01 consts (padding) */ + /* ----------------------------------------------------- */ +}; +AssertRootConst(UiShapeSig, 20); + +Struct(UiShapeVert) +{ + Vec2 pos; + u32 color_srgb; +}; + +//////////////////////////////// +//~ Shaders + +//- Material +GT_ShaderDecl(MaterialVS); +GT_ShaderDecl(MaterialPS); + +//- Flood +GT_ShaderDecl(FloodCS); + +//- Shade +GT_ShaderDecl(ShadeCS); + +//- Ui blit +GT_ShaderDecl(UiBlitVS); +GT_ShaderDecl(UiBlitPS); + +//- Ui rect +GT_ShaderDecl(UiRectVS); +GT_ShaderDecl(UiRectPS); + +//- Ui shape +GT_ShaderDecl(UiShapeVS); +GT_ShaderDecl(UiShapePS); diff --git a/src/pp/pp_ent.c b/src/pp/pp_ent.c index 9d2e3800..336bde5f 100644 --- a/src/pp/pp_ent.c +++ b/src/pp/pp_ent.c @@ -742,9 +742,6 @@ void SyncEntity(Entity *local, Entity *remote) EnableProp(local, Prop_SyncDst); } -//////////////////////////////// -//~ Encode / decode - #if 1 //////////////////////////////// @@ -755,7 +752,7 @@ void EncodeEntity(BB_Writer *bw, Entity *e0, Entity *e1) Snapshot *ss = e1->ss; /* FIXME: Things like xforms need to be retreived manually rather than memcopied. */ - /* TODO: Granular delta encoding */ + /* TODO: Granular delta encoding */ u64 pos = 0; e1->ss = e0->ss; diff --git a/src/pp/pp_sim.c b/src/pp/pp_sim.c index ef8c6f97..b269187e 100644 --- a/src/pp/pp_sim.c +++ b/src/pp/pp_sim.c @@ -55,7 +55,7 @@ void StartupSim(void) /* Nil ent */ g->nil_ent = PushStruct(g->nil_arena, Entity); - g->nil_ent->ss = sim_snapshot_nil(); + g->nil_ent->ss = NilSnapshot(); g->nil_ent->valid = 0; g->nil_ent->id = NilEntityId; g->nil_ent->_local_xform = XformIdentity; @@ -270,7 +270,7 @@ Snapshot *AcquireSnapshot(Client *client, Snapshot *src, u64 tick) { if (tick == 0) { - return sim_snapshot_nil(); + return NilSnapshot(); } Snapshot *ss; @@ -531,7 +531,7 @@ void ReleaseSnapshotsInRange(Client *client, u64 start, u64 end) Snapshot *SnapshotFromTick(Client *client, u64 tick) { - Snapshot *ss = sim_snapshot_nil(); + Snapshot *ss = NilSnapshot(); if (tick > 0) { u64 bin_index = tick % client->num_snapshot_lookup_bins; diff --git a/src/pp/pp_sim.h b/src/pp/pp_sim.h index 537d873c..1972e81d 100644 --- a/src/pp/pp_sim.h +++ b/src/pp/pp_sim.h @@ -220,7 +220,7 @@ Struct(Snapshot) u32 num_ents_reserved; }; -Inline Snapshot *sim_snapshot_nil(void) +Inline Snapshot *NilSnapshot(void) { extern Readonly Snapshot **_g_sim_snapshot_nil; return *_g_sim_snapshot_nil; @@ -250,7 +250,7 @@ extern Readonly ClientStore **_g_sim_client_store_nil; /* Accessed via `NilClient()` */ extern Readonly Client **_g_sim_client_nil; -/* Accessed via `sim_snapshot_nil()` */ +/* Accessed via `NilSnapshot()` */ extern Readonly Snapshot **_g_sim_snapshot_nil; extern Readonly struct Entity **_g_sim_ent_nil; diff --git a/src/pp/pp_step.c b/src/pp/pp_step.c index 657de63b..5730c2b8 100644 --- a/src/pp/pp_step.c +++ b/src/pp/pp_step.c @@ -996,7 +996,6 @@ void StepSim(SimStepCtx *ctx) } } - //- Release entities at beginning of frame ReleaseAllWithProp(world, Prop_Release); @@ -1021,7 +1020,6 @@ void StepSim(SimStepCtx *ctx) } } - //- Process player cmds for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) @@ -1197,7 +1195,6 @@ void StepSim(SimStepCtx *ctx) } } - //- Update entity control from player control for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) @@ -1252,7 +1249,6 @@ void StepSim(SimStepCtx *ctx) } } - //- Update entities from sprite for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) @@ -1361,7 +1357,6 @@ void StepSim(SimStepCtx *ctx) #endif } - //- Update attachments for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) @@ -1386,7 +1381,6 @@ void StepSim(SimStepCtx *ctx) SetLocalXform(ent, xf); } - //- Process ent control for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) @@ -1421,7 +1415,6 @@ void StepSim(SimStepCtx *ctx) } } - //- Process triggered entities for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) @@ -1600,7 +1593,6 @@ void StepSim(SimStepCtx *ctx) } } - //- Create & update motor joints from control move for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) @@ -1639,7 +1631,6 @@ void StepSim(SimStepCtx *ctx) } } - //- Create & update motor joints from control focus (aim) #if SIM_PLAYER_AIM @@ -1743,7 +1734,6 @@ void StepSim(SimStepCtx *ctx) } #endif - //- Create motor joints from ground friction (gravity) #if 1 @@ -1776,7 +1766,6 @@ void StepSim(SimStepCtx *ctx) } #endif - //- Create mouse joints from client debug drag if (is_master) @@ -1842,7 +1831,6 @@ void StepSim(SimStepCtx *ctx) } } - //- Physics step { @@ -1852,7 +1840,6 @@ void StepSim(SimStepCtx *ctx) StepPhys(&phys, sim_dt); } - //- Update explosions for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) @@ -1865,7 +1852,6 @@ void StepSim(SimStepCtx *ctx) DisableProp(ent, Prop_Sensor); } - //- Update tracers for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) @@ -1890,7 +1876,6 @@ void StepSim(SimStepCtx *ctx) ent->tracer_gradient_end = gradient_end; } - //- Initialize bullet kinematics from sources for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) @@ -1951,7 +1936,6 @@ void StepSim(SimStepCtx *ctx) } } - //- Update cameras for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) @@ -2012,7 +1996,6 @@ void StepSim(SimStepCtx *ctx) SetXform(ent, xf); } - //- Update quakes for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) @@ -2028,7 +2011,6 @@ void StepSim(SimStepCtx *ctx) } } - //- Update relative layers { @@ -2059,7 +2041,6 @@ void StepSim(SimStepCtx *ctx) EndTempArena(temp); } - //- Release entities at end of frame ReleaseAllWithProp(world, Prop_Release); @@ -2092,7 +2073,6 @@ void StepSim(SimStepCtx *ctx) pub_world->local_player = world->local_player; } - //- End frame S_EndScope(sprite_frame_scope); diff --git a/src/sound/sound_core.c b/src/sound/sound_core.c index 276d9059..2f105225 100644 --- a/src/sound/sound_core.c +++ b/src/sound/sound_core.c @@ -108,7 +108,7 @@ AC_Asset *SND_LoadAsset(String path, SND_SoundFlag flags, b32 wait) RunJobEx((GenericJobDesc *)desc); if (wait) { - AC_WaitOnAssetReady(asset); + AC_YieldOnAssetReady(asset); } } @@ -128,7 +128,7 @@ SND_Sound *SND_LoadSoundWait(String path, SND_SoundFlag flags) { __prof; AC_Asset *asset = SND_LoadAsset(path, flags, 1); - AC_WaitOnAssetReady(asset); + AC_YieldOnAssetReady(asset); SND_Sound *sound = (SND_Sound *)AC_DataFromStore(asset); return sound; } diff --git a/src/sprite/sprite.h b/src/sprite/sprite.h index cbde6ec1..f7a455f0 100644 --- a/src/sprite/sprite.h +++ b/src/sprite/sprite.h @@ -6,7 +6,7 @@ #include "../base/base.h" #include "../platform/platform.h" -#include "../gpu/gpu.h" +#include "../gtest/gtest.h" #include "../ase/ase.h" #include "../resource/resource.h" #include "../watch/watch.h" @@ -14,7 +14,7 @@ inline void S_StartupDeps(void) { BaseMain(); P_Main(); - GPU_Main(); + GT_Main(); ASE_Main(); RES_Main(); W_Main(); diff --git a/src/sprite/sprite_core.c b/src/sprite/sprite_core.c index 4cc8fefa..b637a377 100644 --- a/src/sprite/sprite_core.c +++ b/src/sprite/sprite_core.c @@ -17,10 +17,13 @@ void S_StartupCore(void) g->nil_texture->loaded = 1; { TempArena scratch = BeginScratchNoConflict(); - u32 width = 64; - u32 height = 64; - u32 *pixels = S_GeneratePurpleBlackImage(scratch.arena, width, height); - g->nil_texture->gp_texture = GPU_AcquireTexture(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, VEC2I32(width, height), pixels); + GT_ResourceDesc desc = ZI; + desc.kind = GT_ResourceKind_Texture2D; + desc.texture.format = GT_Format_R8G8B8A8_Unorm; + desc.texture.size = VEC3I32(64, 64, 1); + g->nil_texture->gpu_resource = GT_AcquireResource(desc); + u32 *pixels = S_GeneratePurpleBlackImage(scratch.arena, desc.texture.size.x, desc.texture.size.y); + GT_PushString(0, g->nil_texture->gpu_resource, STRING(desc.texture.size.x * desc.texture.size.y * 4, (u8 *)pixels)); EndScratch(scratch); } @@ -64,8 +67,8 @@ ExitFuncDef(S_Shutdown) SignalCv(&g->evictor_scheduler_shutdown_cv, I32Max); Unlock(&lock); } - /* Wait for evictor shutdown */ - WaitOnCounter(&g->shutdown_counter); + /* Yield for evictor shutdown */ + YieldOnCounter(&g->shutdown_counter); } //////////////////////////////// @@ -491,12 +494,20 @@ void S_LoadCacheEntryTexture(S_CacheEntryRef ref, S_Tag tag) if (decoded.success) { /* Initialize */ + GT_ResourceDesc gpu_desc = ZI; + gpu_desc.kind = GT_ResourceKind_Texture2D; + gpu_desc.texture.size = VEC3I32(decoded.width, decoded.height, 1); + gpu_desc.texture.format = GT_Format_R8G8B8A8_Unorm_Srgb; e->texture = PushStruct(e->arena, S_Texture); e->texture->width = decoded.width; e->texture->height = decoded.height; e->texture->valid = 1; e->texture->loaded = 1; - e->texture->gp_texture = GPU_AcquireTexture(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB, 0, VEC2I32(decoded.width, decoded.height), decoded.pixels); + e->texture->gpu_resource = GT_AcquireResource(gpu_desc); + { + u64 size = decoded.width * decoded.height * 4; + GT_PushString(0, e->texture->gpu_resource, STRING(size, (u8 *)decoded.pixels)); + } /* TODO: Query gpu for more accurate texture size in VRAM */ memory_size += (decoded.width * decoded.height) * sizeof(*decoded.pixels); success = 1; @@ -1283,12 +1294,13 @@ JobDef(S_EvictorJob, UNUSED sig, UNUSED job_id) /* Release evicted node memory */ { __profn("Evictor memory release"); + GT_Fence gpu_fence = GT_GetGlobalFence(); for (S_EvictorNode *en = first_evicted; en; en = en->next_evicted) { S_CacheEntry *n = en->cache_entry; if (n->kind == S_CacheEntryKind_Texture && n->texture->valid) { - GPU_ReleaseResourceFenced(n->texture->gp_texture); + GT_ReleaseResource(n->texture->gpu_resource, gpu_fence, GT_ReleaseFlag_None); } ReleaseArena(n->arena); } @@ -1318,7 +1330,7 @@ JobDef(S_EvictorJob, UNUSED sig, UNUSED job_id) { if (!g->evictor_scheduler_shutdown) { - WaitOnCvTime(&g->evictor_scheduler_shutdown_cv, &lock, S_EvictorCycleIntervalNs); + YieldOnCvTime(&g->evictor_scheduler_shutdown_cv, &lock, S_EvictorCycleIntervalNs); } shutdown = g->evictor_scheduler_shutdown; } diff --git a/src/sprite/sprite_core.h b/src/sprite/sprite_core.h index ade54f04..980fc767 100644 --- a/src/sprite/sprite_core.h +++ b/src/sprite/sprite_core.h @@ -14,7 +14,7 @@ Struct(S_Texture) { b32 loaded; b32 valid; - GPU_Resource *gp_texture; + GT_Resource *gpu_resource; u32 width; u32 height; }; @@ -171,7 +171,7 @@ Struct(S_CacheEntryRef) }; //////////////////////////////// -//~ Scope +//~ Scope types /* A cache reference whose lifetime is bound to the scope it was retrieved from */ Struct(S_ScopeCacheEntryRef) @@ -189,7 +189,7 @@ Struct(S_Scope) }; //////////////////////////////// -//~ Evictor +//~ Evictor types Struct(S_EvictorNode) { diff --git a/src/watch/watch_core.c b/src/watch/watch_core.c index 3dd93416..059fe5a6 100644 --- a/src/watch/watch_core.c +++ b/src/watch/watch_core.c @@ -26,7 +26,7 @@ ExitFuncDef(W_Shutdown) P_WakeWatch(g->watch); Unlock(&lock); } - WaitOnCounter(&g->watch_jobs_counter); + YieldOnCounter(&g->watch_jobs_counter); } //////////////////////////////// @@ -137,7 +137,7 @@ JobDef(W_DispatcherJob, UNUSED sig, UNUSED job_id) /* Delay so that duplicate events pile up */ { __profn("Delay"); - FutexWait(0, 0, 0, NsFromSeconds(W_DispatcherDelaySeconds)); + FutexYield(0, 0, 0, NsFromSeconds(W_DispatcherDelaySeconds)); } /* Pull watch events from queue */ @@ -198,7 +198,7 @@ JobDef(W_DispatcherJob, UNUSED sig, UNUSED job_id) { Counter counter = ZI; RunJob(num_callbacks, W_RunCallbacksJob, JobPool_Background, JobPriority_Low, &counter, .name = e->name, .callbacks = callbacks); - WaitOnCounter(&counter); + YieldOnCounter(&counter); } } } @@ -206,13 +206,13 @@ JobDef(W_DispatcherJob, UNUSED sig, UNUSED job_id) EndScratch(scratch); } - /* Wait for event */ + /* Yield for event */ Lock lock = LockS(&g->watch_dispatcher_mutex); { shutdown = Atomic32Fetch(&g->W_Shutdown); while (!shutdown && !g->first_watch_event) { - WaitOnCv(&g->watch_dispatcher_cv, &lock); + YieldOnCv(&g->watch_dispatcher_cv, &lock); shutdown = Atomic32Fetch(&g->W_Shutdown); } }