gpu refactor progress

This commit is contained in:
jacob 2025-08-11 04:06:34 -05:00
parent fdecaacebd
commit 1d569d293c
43 changed files with 1999 additions and 395 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
.*.swp .*.swp
*.lnk *.lnk
*.rdbg *.rdbg
*.raddbg
*.10x *.10x
*.cap *.cap
*.wpix *.wpix

23
build.c
View File

@ -1051,6 +1051,7 @@ void OnBuild(StringList cli_args)
BuildStepSimpleCommandArg *bs_arg = ArenaPush(&perm, BuildStepSimpleCommandArg); 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->cmd = StringF(&perm, link_args_fmt, FmtStr(link_files_str), FmtStr(executable_file.full_path));
bs_arg->skip_flag = &src_success_flag; bs_arg->skip_flag = &src_success_flag;
bs_arg->delete_file_on_failure = executable_file;
String step_name = Lit("Link"); String step_name = Lit("Link");
AddStep(step_name, &BuildStepSimpleCommand, bs_arg); AddStep(step_name, &BuildStepSimpleCommand, bs_arg);
} }
@ -1102,20 +1103,22 @@ void OnBuild(StringList cli_args)
SH_Print(Lit("No work to do\n")); 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)) if (!D_Exists(executable_file))
{ {
/* Create blank executible if build fails (since Visual Studio can get /* Create blank executible if build fails (since Visual Studio can get
* confused if no build target exists) */ * confused if no build target exists) */
D_ClearWrite(executable_file, Lit("")); D_ClearWrite(executable_file, Lit(""));
} }
#if 0
if (!success)
{
Error(Lit("Build failed\n"));
}
#endif
T_ShutdownWorkers();
D_WriteStoreToHistFile(&store, hist_path);
} }

View File

@ -18,7 +18,8 @@ String InitializeAppWriteDirectory(Arena *arena, String write_dir)
); );
/* Create write dir if not present */ /* Create write dir if not present */
if (!P_IsDir(write_path)) { if (!P_IsDir(write_path))
{
P_MkDir(write_path); P_MkDir(write_path);
/* TODO: handle failure */ /* TODO: handle failure */
} }
@ -41,19 +42,20 @@ P_WindowSettings GetDefaultAppWindowSettings(P_Window *window)
{ {
__prof; __prof;
Vec2 monitor_size = P_GetWindowMonitorSize(window); Vec2I32 monitor_size = P_GetWindowMonitorSize(window);
i32 width = 1280; i32 width = 1280;
i32 height = RoundF32ToI32(width / (f32)(DEFAULT_CAMERA_WIDTH / DEFAULT_CAMERA_HEIGHT)); i32 height = RoundF32ToI32(width / (f32)(DEFAULT_CAMERA_WIDTH / DEFAULT_CAMERA_HEIGHT));
i32 x = RoundF32ToI32(monitor_size.x / 2.f - width / 2); i32 x = RoundF32ToI32(monitor_size.x / 2.f - width / 2);
i32 y = RoundF32ToI32(monitor_size.y / 2.f - height / 2); i32 y = RoundF32ToI32(monitor_size.y / 2.f - height / 2);
return (P_WindowSettings) { return (P_WindowSettings)
{
.title = WINDOW_TITLE, .title = WINDOW_TITLE,
.floating_x = x, .floating_x = x,
.floating_y = y, .floating_y = y,
.floating_width = width, .floating_width = width,
.floating_height = height .floating_height = height
}; };
} }
@ -70,12 +72,15 @@ AppArgList ParseAppArgs(Arena *arena, String args_str)
i64 key_end = -1; i64 key_end = -1;
i64 value_start = -1; i64 value_start = -1;
i64 value_end = -1; i64 value_end = -1;
while (i < (i64)args_str.len) { while (i < (i64)args_str.len)
{
u8 c = args_str.text[i]; u8 c = args_str.text[i];
switch (mode) { switch (mode)
{
case 0: case 0:
{ {
if (c == '-') { if (c == '-')
{
mode = 1; mode = 1;
key_start = i + 1; key_start = i + 1;
} }
@ -84,7 +89,8 @@ AppArgList ParseAppArgs(Arena *arena, String args_str)
case 1: case 1:
{ {
if (c == '=') { if (c == '=')
{
key_end = i; key_end = i;
value_start = i + 1; value_start = i + 1;
mode = 2; mode = 2;
@ -94,21 +100,29 @@ AppArgList ParseAppArgs(Arena *arena, String args_str)
case 2: case 2:
{ {
if (c == '-' || i == (i64)args_str.len - 1) { if (c == '-' || i == (i64)args_str.len - 1)
if (c == '-') { {
if (c == '-')
{
value_end = i; value_end = i;
} else { }
else
{
value_end = i + 1; 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 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)); String value = PushString(arena, STRING(value_end - value_start, args_str.text + value_start));
AppArg *arg = PushStruct(arena, AppArg); AppArg *arg = PushStruct(arena, AppArg);
arg->key = key; arg->key = key;
arg->value = value; arg->value = value;
if (result.last) { if (result.last)
{
result.last->next = arg; result.last->next = arg;
} else { }
else
{
result.first = arg; result.first = arg;
} }
result.last = arg; result.last = arg;
@ -139,14 +153,20 @@ void Startup(void)
String logfile_name = Lit("log.log"); String logfile_name = Lit("log.log");
String settings_file_name = Lit("settings.txt"); String settings_file_name = Lit("settings.txt");
String connect_address = ZI; 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 key = arg->key;
String value = arg->value; String value = arg->value;
if (EqString(key, Lit("log"))) { if (EqString(key, Lit("log")))
{
logfile_name = value; logfile_name = value;
} else if (EqString(key, Lit("settings"))) { }
else if (EqString(key, Lit("settings")))
{
settings_file_name = value; settings_file_name = value;
} else if (EqString(key, Lit("connect"))) { }
else if (EqString(key, Lit("connect")))
{
connect_address = value; connect_address = value;
} }
} }
@ -185,7 +205,8 @@ void Startup(void)
EndTempArena(temp); EndTempArena(temp);
} }
P_LogInfoF("App started with args \"%F\" (%F parsed)", FmtString(args_str), FmtUint(args.count)); 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)); P_LogInfoF("Parsed arg: key = \"%F\", value = \"%F\"", FmtString(arg->key), FmtString(arg->value));
} }
#endif #endif
@ -198,7 +219,8 @@ void Startup(void)
P_WindowSettings window_settings = ZI; P_WindowSettings window_settings = ZI;
String settings_path = CatAppWritePath(temp.arena, settings_file_name); String settings_path = CatAppWritePath(temp.arena, settings_file_name);
P_LogInfoF("Looking for settings file \"%F\"", FmtString(settings_path)); 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_LogInfoF("Settings file found");
P_File settings_file = P_OpenFileRead(settings_path); P_File settings_file = P_OpenFileRead(settings_path);
String file_data = P_ReadFile(temp.arena, settings_file); 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)); P_LogInfoF("Deserializing settings file data: %F", FmtString(file_data));
String error = ZI; String error = ZI;
P_WindowSettings *deser = SETTINGS_WindowSettingsFromString(temp.arena, file_data, &error); 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)); P_LogInfoF("Failed to load settings file with error - %F", FmtString(error));
String msg = StringFormat(temp.arena, String msg = StringFormat(temp.arena,
Lit( Lit(
"Failed to loading settings file \"%F\":\n" "Failed to loading settings file \"%F\":\n"
"------------\n" "------------\n"
"%F\n" "%F\n"
"------------\n" "------------\n"
"To stop this error from appearing, either fix the issue above or delete the file from the system." "To stop this error from appearing, either fix the issue above or delete the file from the system."
), ),
FmtString(settings_path), FmtString(settings_path),
FmtString(error)); FmtString(error));
Panic(msg); Panic(msg);
} }
P_LogInfoF("Settings file loaded successfully"); P_LogInfoF("Settings file loaded successfully");
window_settings = *deser; window_settings = *deser;
} else { }
else
{
P_LogInfoF("Settings file not found, loading default"); P_LogInfoF("Settings file not found, loading default");
window_settings = GetDefaultAppWindowSettings(window); window_settings = GetDefaultAppWindowSettings(window);
} }

View File

@ -168,9 +168,9 @@ void AC_MarkReady(AC_Asset *asset, void *store_data)
AddCounter(&asset->counter, -1); AddCounter(&asset->counter, -1);
} }
void AC_WaitOnAssetReady(AC_Asset *asset) void AC_YieldOnAssetReady(AC_Asset *asset)
{ {
WaitOnCounter(&asset->counter); YieldOnCounter(&asset->counter);
} }
//////////////////////////////// ////////////////////////////////

View File

@ -84,7 +84,7 @@ AC_Asset *AC_TouchCache(String key, u64 hash, b32 *is_first_touch);
void AC_MarkLoading(AC_Asset *asset); void AC_MarkLoading(AC_Asset *asset);
void AC_MarkReady(AC_Asset *asset, void *store_data); void AC_MarkReady(AC_Asset *asset, void *store_data);
void AC_WaitOnAssetReady(AC_Asset *asset); void AC_YieldOnAssetReady(AC_Asset *asset);
//////////////////////////////// ////////////////////////////////
//~ Store operations //~ Store operations

View File

@ -134,9 +134,10 @@ Inline void *AlignArena(Arena *arena, u64 align)
} }
} }
Inline void ResetArena(Arena *arena) Inline void *ResetArena(Arena *arena)
{ {
PopTo(arena, 0); PopTo(arena, 0);
return (void *)ArenaBase(arena);
} }
//////////////////////////////// ////////////////////////////////

View File

@ -41,7 +41,7 @@ void StartupBaseJobs(void);
//~ @hookdecl Futex //~ @hookdecl Futex
/* Futex-like wait & wake */ /* 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); void FutexWake(void *addr, i32 count);
//////////////////////////////// ////////////////////////////////

View File

@ -52,40 +52,37 @@ void SetMemoryReadWrite(void *address, u64 size)
#endif #endif
//////////////////////////////// ////////////////////////////////
//~ Crtlib memory.h stubs //~ Memory operations
#if !CrtlibIsEnabled void *CopyBytes(void *dst, void *src, u64 count)
//- memcpy
__attribute((section(".text.memcpy")))
void *memcpy(void *__restrict dst, const void *__restrict src, u64 n)
{ {
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; return dst;
} }
//- memset void *SetBytes(void *dst, u8 c, u64 count)
__attribute((section(".text.memset")))
void *memset(void *dst, i32 c, u64 n)
{ {
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; return dst;
} }
//- memcmp i32 CmpBytes(void *p1, void *p2, u64 count)
__attribute((section(".text.memcmp")))
i32 memcmp(const void *p1, const void *p2, u64 n)
{ {
i32 result = 0; 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) if (result != 0)
{ {
break; break;
@ -94,4 +91,30 @@ i32 memcmp(const void *p1, const void *p2, u64 n)
return result; 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 */ #endif /* !CrtlibIsEnabled */

View File

@ -16,21 +16,21 @@ void SetMemoryReadWrite(void *address, u64 size);
//////////////////////////////// ////////////////////////////////
//~ Memory operations //~ Memory operations
//- Wrappers
#define ZeroStruct(ptr) ZeroBytes((ptr), sizeof(*(ptr))) #define ZeroStruct(ptr) ZeroBytes((ptr), sizeof(*(ptr)))
#define ZeroArray(a) Assert(IsArray(a)); ZeroBytes((a), sizeof((a))) #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 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 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 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 #if CrtlibIsEnabled
# include <memory.h> # include <memory.h>
#else #else

View File

@ -1,7 +1,8 @@
//////////////////////////////// ////////////////////////////////
//~ Rand types //~ 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 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; u64 counter;
}; };

View File

@ -49,7 +49,7 @@ Lock LockSpinE(Mutex *m, i32 spin)
} }
else else
{ {
FutexWait(&m->v, &v, 4, I64Max); FutexYield(&m->v, &v, 4, I64Max);
spin_cnt = 0; spin_cnt = 0;
} }
} }
@ -96,7 +96,7 @@ Lock LockSpinS(Mutex *m, i32 spin)
} }
else else
{ {
FutexWait(&m->v, &v, 4, I64Max); FutexYield(&m->v, &v, 4, I64Max);
spin_cnt = 0; spin_cnt = 0;
} }
} }
@ -138,12 +138,12 @@ void Unlock(Lock *l)
//////////////////////////////// ////////////////////////////////
//~ Condition variable //~ 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); u64 old_wake_gen = Atomic64Fetch(&cv->wake_gen);
Mutex *mutex = l->mutex; Mutex *mutex = l->mutex;
@ -151,7 +151,7 @@ void WaitOnCvTime(Cv *cv, Lock *l, i64 timeout_ns)
{ {
Unlock(l); 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) 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); i64 v = Atomic64Fetch(&counter->v);
while (v > 0) while (v > 0)
{ {
FutexWait(&counter->v, &v, sizeof(v), I64Max); FutexYield(&counter->v, &v, sizeof(v), I64Max);
v = Atomic64Fetch(&counter->v); v = Atomic64Fetch(&counter->v);
} }
} }

View File

@ -72,12 +72,12 @@ void Unlock(Lock *lock);
//////////////////////////////// ////////////////////////////////
//~ Condition variable operations //~ Condition variable operations
void WaitOnCv(Cv *cv, Lock *lock); void YieldOnCv(Cv *cv, Lock *lock);
void WaitOnCvTime(Cv *cv, Lock *l, i64 timeout_ns); void YieldOnCvTime(Cv *cv, Lock *l, i64 timeout_ns);
void SignalCv(Cv *cv, i32 count); void SignalCv(Cv *cv, i32 count);
//////////////////////////////// ////////////////////////////////
//~ Counter operations //~ Counter operations
void AddCounter(Counter *counter, i64 x); void AddCounter(Counter *counter, i64 x);
void WaitOnCounter(Counter *counter); void YieldOnCounter(Counter *counter);

View File

@ -10,7 +10,7 @@ String StringFromChar(Arena *arena, char c)
return (String) return (String)
{ {
.len = 1, .len = 1,
.text = dst .text = dst
}; };
} }
@ -51,7 +51,7 @@ String StringFromU64(Arena *arena, u64 n, u64 base, u64 zfill)
return (String) return (String)
{ {
.len = len, .len = len,
.text = final_text .text = final_text
}; };
} }
@ -73,7 +73,7 @@ String StringFromI64(Arena *arena, i64 n, u64 base, u64 zfill)
return (String) return (String)
{ {
.len = len + uint_str.len, .len = len + uint_str.len,
.text = final_text .text = final_text
}; };
} }
@ -86,7 +86,7 @@ String StringFromPtr(Arena *arena, void *ptr)
return (String) return (String)
{ {
.len = prepend.len + uint_str.len, .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) return (String)
{ {
.len = final_len, .len = final_len,
.text = final_text .text = final_text
}; };
} }
@ -230,7 +230,7 @@ String RepeatString(Arena *arena, String src, u64 count)
return (String) return (String)
{ {
.text = final_text, .text = final_text,
.len = final_len .len = final_len
}; };
} }
@ -320,7 +320,7 @@ String IndentString(Arena *arena, String str, u32 indent)
return (String) return (String)
{ {
.len = final_len, .len = final_len,
.text = final_text .text = final_text
}; };
} }
@ -599,7 +599,7 @@ String StringFormatV(Arena *arena, String fmt, va_list args)
return (String) return (String)
{ {
.len = final_len, .len = final_len,
.text = final_text .text = final_text
}; };
} }
@ -815,7 +815,7 @@ String StringFromCstrNoLimit(char *cstr)
return (String) return (String)
{ {
.len = len, .len = len,
.text = (u8 *)cstr .text = (u8 *)cstr
}; };
} }
@ -825,7 +825,7 @@ String StringFromCstr(char *cstr, u64 limit)
return (String) return (String)
{ {
.text = (u8 *)cstr, .text = (u8 *)cstr,
.len = len .len = len
}; };
} }
@ -896,7 +896,7 @@ String16 String16FromWstrNoLimit(wchar_t *wstr)
return (String16) return (String16)
{ {
.len = len, .len = len,
.text = (u16 *)wstr .text = (u16 *)wstr
}; };
} }
@ -906,6 +906,6 @@ String16 String16FromWstr(wchar_t *wstr, u64 limit)
return (String16) return (String16)
{ {
.len = len, .len = len,
.text = (u16 *)wstr .text = (u16 *)wstr
}; };
} }

7
src/base/build.bat Normal file
View File

@ -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

7
src/base/build.sh Normal file
View File

@ -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

View File

@ -63,7 +63,7 @@ void Panic(String msg)
WstrLen += countof(prefix) - 1; WstrLen += countof(prefix) - 1;
/* Perform manual string encode to avoid any implicit memory /* Perform manual string encode to avoid any implicit memory
* allocation (in case allocation is unreliable) */ * allocation (in case allocation is unreliable) */
String str8 = msg; String str8 = msg;
u64 pos8 = 0; u64 pos8 = 0;
while (pos8 < str8.len) while (pos8 < str8.len)
@ -102,7 +102,6 @@ void Panic(String msg)
} }
} }
//////////////////////////////// ////////////////////////////////
//~ Winmain //~ Winmain
@ -116,7 +115,6 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
__profthread("Main thread", PROF_THREAD_GROUP_MAIN); __profthread("Main thread", PROF_THREAD_GROUP_MAIN);
W32_SharedEntryCtx *g = &W32_shared_entry_ctx; W32_SharedEntryCtx *g = &W32_shared_entry_ctx;
#if ProfilingIsEnabled #if ProfilingIsEnabled
/* Start profiler */ /* Start profiler */
{ {

View File

@ -1355,7 +1355,7 @@ W32_ThreadDef(W32_JobSchedulerEntryFunc, UNUSED arg)
//////////////////////////////// ////////////////////////////////
//~ @hookdef Futex //~ @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()); W32_Fiber *fiber = W32_FiberFromId(FiberId());
i16 parent_id = fiber->parent_id; i16 parent_id = fiber->parent_id;

View File

@ -46,6 +46,7 @@ CLD_SupportPoint CLD_SupportPointFromDirEx(CLD_Shape *shape, Xform xf, Vec2 dir,
Vec2 furthest = ZI; Vec2 furthest = ZI;
u32 furthest_index = 0; u32 furthest_index = 0;
f32 furthest_dot = -F32Infinity; f32 furthest_dot = -F32Infinity;
for (u32 i = 0; i < count; ++i) for (u32 i = 0; i < count; ++i)
{ {
if ((i32)i == ignore) if ((i32)i == ignore)

View File

@ -120,7 +120,7 @@ AC_Asset *F_LoadAsset(String path, f32 point_size, b32 wait)
RunJobEx((GenericJobDesc *)desc); RunJobEx((GenericJobDesc *)desc);
if (wait) if (wait)
{ {
AC_WaitOnAssetReady(asset); AC_YieldOnAssetReady(asset);
} }
} }
@ -140,7 +140,7 @@ F_Font *F_LoadFontWait(String path, f32 point_size)
{ {
__prof; __prof;
AC_Asset *asset = F_LoadAsset(path, point_size, 1); AC_Asset *asset = F_LoadAsset(path, point_size, 1);
AC_WaitOnAssetReady(asset); AC_YieldOnAssetReady(asset);
F_Font *f = (F_Font *)AC_DataFromStore(asset); F_Font *f = (F_Font *)AC_DataFromStore(asset);
return f; return f;
} }

View File

@ -14,9 +14,8 @@ GPU_D12_SharedState GPU_D12_shared_state = ZI;
# pragma comment(lib, "advapi32") # pragma comment(lib, "advapi32")
#endif #endif
/* ========================== * ////////////////////////////////
* Startup //~ Startup
* ========================== */
void GPU_StartupCore(void) void GPU_StartupCore(void)
{ {
@ -97,12 +96,11 @@ ExitFuncDef(GPU_D12_Shutdown)
SignalCv(&g->evictor_wake_cv, I32Max); SignalCv(&g->evictor_wake_cv, I32Max);
Unlock(&lock); Unlock(&lock);
} }
WaitOnCounter(&g->evictor_job_counter); YieldOnCounter(&g->evictor_job_counter);
} }
/* ========================== * ////////////////////////////////
* Dx12 device initialization //~ Dx12 device initialization
* ========================== */
void GPU_D12_PushInitError(String error) void GPU_D12_PushInitError(String error)
{ {
@ -290,9 +288,8 @@ void GPU_D12_InitDevice(void)
EndScratch(scratch); EndScratch(scratch);
} }
/* ========================== * ////////////////////////////////
* Dx12 object initialization //~ Dx12 object initialization
* ========================== */
void GPU_D12_InitObjects(void) void GPU_D12_InitObjects(void)
{ {
@ -325,7 +322,7 @@ void GPU_D12_InitObjects(void)
{ {
Counter counter = ZI; Counter counter = ZI;
RunJob(DX12_NUM_QUEUES, GPU_D12_AcquireCommandQueueJob, JobPool_Inherit, JobPriority_Low, &counter, .descs_in = params, .cqs_out = g->command_queues); 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 #if ProfilingIsEnabled
{ {
@ -343,9 +340,8 @@ void GPU_D12_InitObjects(void)
} }
} }
/* ========================== * ////////////////////////////////
* Dx12 pipeline initialization //~ Dx12 pipeline initialization
* ========================== */
void GPU_InitPipelines(void) void GPU_InitPipelines(void)
{ {
@ -417,7 +413,7 @@ void GPU_InitPipelines(void)
__profn("Acquire pipelines"); __profn("Acquire pipelines");
Counter counter = ZI; Counter counter = ZI;
RunJob(num_pipelines, GPU_D12_AcquirePipelineJob, JobPool_Inherit, JobPriority_Inherit, &counter, .descs_in = descs, .pipelines_out = pipelines); 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) for (u32 i = 0; i < num_pipelines; ++i)
{ {
@ -444,9 +440,8 @@ void GPU_InitPipelines(void)
EndScratch(scratch); EndScratch(scratch);
} }
/* ========================== * ////////////////////////////////
* Noise texture initialization //~ Noise texture initialization
* ========================== */
void GPU_D12_InitNoise(void) void GPU_D12_InitNoise(void)
{ {
@ -497,7 +492,7 @@ void GPU_D12_InitNoise(void)
{ {
Counter counter = ZI; Counter counter = ZI;
RunJob(1, GPU_D12_UploadJob, JobPool_Inherit, JobPriority_Low, &counter, .resource = r, .data = data.text); 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); EndScratch(scratch);
} }
/* ========================== * ////////////////////////////////
* Shader compilation //~ Shader compilation
* ========================== */
#if RESOURCE_RELOADING #if RESOURCE_RELOADING
@ -563,9 +557,8 @@ JobDef(GPU_D12_CompileShaderJob, sig, id)
#endif #endif
/* ========================== * ////////////////////////////////
* Pipeline //~ Pipeline
* ========================== */
JobDef(GPU_D12_AcquirePipelineJob, sig, id) JobDef(GPU_D12_AcquirePipelineJob, sig, id)
{ {
@ -910,9 +903,8 @@ void GPU_D12_ReleasePipelineNow(GPU_D12_Pipeline *pipeline)
Unlock(&lock); Unlock(&lock);
} }
/* ========================== * ////////////////////////////////
* Pipeline cache //~ Pipeline cache
* ========================== */
GPU_D12_PipelineScope *GPU_D12_BeginPipelineScope(void) GPU_D12_PipelineScope *GPU_D12_BeginPipelineScope(void)
{ {
@ -1109,7 +1101,7 @@ W_CallbackFuncDef(GPU_D12_WatchPipelineCallback, name)
job_desc->count = num_shaders; job_desc->count = num_shaders;
job_desc->counter = &counter; job_desc->counter = &counter;
RunJobEx((GenericJobDesc *)job_desc); RunJobEx((GenericJobDesc *)job_desc);
WaitOnCounter(&counter); YieldOnCounter(&counter);
} }
} }
P_CloseFIle(file); P_CloseFIle(file);
@ -1170,7 +1162,7 @@ W_CallbackFuncDef(GPU_D12_WatchPipelineCallback, name)
{ {
Counter counter = ZI; Counter counter = ZI;
RunJob(num_pipelines, GPU_D12_AcquirePipelineJob, JobPool_Inherit, JobPriority_Low, &counter, .descs_in = pipeline_descs, .pipelines_out = pipelines); 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); Lock lock = LockS(&g->pipelines_mutex);
@ -1214,9 +1206,8 @@ W_CallbackFuncDef(GPU_D12_WatchPipelineCallback, name)
} }
#endif #endif
/* ========================== * ////////////////////////////////
* Descriptor //~ Descriptor
* ========================== */
GPU_D12_Descriptor *GPU_D12_AcquireDescriptor(GPU_D12_CpuDescriptorHeap *dh) GPU_D12_Descriptor *GPU_D12_AcquireDescriptor(GPU_D12_CpuDescriptorHeap *dh)
{ {
@ -1263,9 +1254,8 @@ void GPU_D12_ReleaseDescriptor(GPU_D12_Descriptor *descriptor)
Unlock(&lock); Unlock(&lock);
} }
/* ========================== * ////////////////////////////////
* CPU descriptor heap //~ CPU descriptor heap
* ========================== */
GPU_D12_CpuDescriptorHeap *GPU_D12_AcquireCpuDescriptorHeap(enum D3D12_DESCRIPTOR_HEAP_TYPE type) 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 #endif
/* ========================== * ////////////////////////////////
* Fenced release //~ Fenced release
* ========================== */
void GPU_D12_ReleaseDataFenced(void *data, GPU_D12_FencedReleaseKind kind) 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) 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); 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) 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); EndScratch(scratch);
} }
/* ========================== * ////////////////////////////////
* Command queue //~ Command queue
* ========================== */
GPU_D12_CommandListPool *GPU_D12_AcquireCommandListPool(GPU_D12_CommandQueue *cq); 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); //ID3D12CommandQueue_Release(cq->cq);
} }
/* ========================== * ////////////////////////////////
* Command list //~ Command list
* ========================== */
GPU_D12_CommandListPool *GPU_D12_AcquireCommandListPool(GPU_D12_CommandQueue *cq) 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; 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) 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; return cdh;
} }
/* ========================== * ////////////////////////////////
* Command buffer //~ Command buffer
* ========================== */
u64 GPU_D12_CommandBufferHashFromSize(u64 size) u64 GPU_D12_CommandBufferHashFromSize(u64 size)
{ {
@ -1864,8 +1847,7 @@ u64 GPU_D12_CommandBufferHashFromSize(u64 size)
return hash; 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_PushCommandBufferEx(GPU_D12_CommandList *cl, u64 data_len, void *data, u64 data_stride)
GPU_D12_CommandBuffer *GPU_D12__PushCommandBuffer(GPU_D12_CommandList *cl, u64 data_len, void *data, u64 data_stride)
{ {
__prof; __prof;
GPU_D12_SharedState *g = &GPU_D12_shared_state; 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; return cb;
} }
/* ========================== * ////////////////////////////////
* Wait job //~ Wait job
* ========================== */
JobDef(GPU_D12_WaitOnFenceJob, sig, UNUSED id) 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) 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 */ /* TODO: Make wait optional */
Counter counter = ZI; Counter counter = ZI;
RunJob(1, GPU_D12_UploadJob, JobPool_Inherit, JobPriority_Inherit, &counter, .resource = r, .data = initial_data); RunJob(1, GPU_D12_UploadJob, JobPool_Inherit, JobPriority_Inherit, &counter, .resource = r, .data = initial_data);
WaitOnCounter(&counter); YieldOnCounter(&counter);
} }
return (GPU_Resource *)r; return (GPU_Resource *)r;
@ -2099,9 +2079,8 @@ Vec2I32 GPU_GetTextureSize(GPU_Resource *resource)
return r->texture_size; return r->texture_size;
} }
/* ========================== * ////////////////////////////////
* Upload //~ Upload
* ========================== */
JobDef(GPU_D12_UploadJob, sig, UNUSED id) 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); 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) if (ID3D12Fence_GetCompletedValue(cq->submit_fence) < fence_target)
{ {
Counter counter = ZI; Counter counter = ZI;
RunJob(1, GPU_D12_WaitOnFenceJob, JobPool_Floating, JobPriority_Inherit, &counter, .fence = cq->submit_fence, .target = fence_target); 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 */ /* 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) 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; return result;
} }
/* ========================== * ////////////////////////////////
* Render sig //~ Render sig
* ========================== */
GPU_D12_RenderSig *GPU_D12_AcquireRenderSig(void) GPU_D12_RenderSig *GPU_D12_AcquireRenderSig(void)
{ {
@ -2466,9 +2444,8 @@ u32 GPU_PushRenderCmd(GPU_RenderSig *render_sig, GPU_RenderCmdDesc *cmd_desc)
return ret; return ret;
} }
/* ========================== * ////////////////////////////////
* Render //~ Render
* ========================== */
GPU_Resource *GPU_RunRender(GPU_RenderSig *gp_render_sig, GPU_RenderParams params) 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; return (GPU_Resource *)rsig->ui_target;
} }
/* ========================== * ////////////////////////////////
* Memory info //~ Memory info
* ========================== */
GPU_MemoryInfo GPU_QueryMemoryInfo(void) GPU_MemoryInfo GPU_QueryMemoryInfo(void)
{ {
@ -2984,9 +2960,8 @@ GPU_MemoryInfo GPU_QueryMemoryInfo(void)
return result; return result;
} }
/* ========================== * ////////////////////////////////
* Swapchain //~ Swapchain
* ========================== */
void GPU_D12_InitSwapchainResources(GPU_D12_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]; return &swapchain->buffers[backbuffer_index];
} }
/* ========================== * ////////////////////////////////
* Present //~ Present
* ========================== */
void GPU_D12_BlitToSwapchain(GPU_D12_SwapchainBuffer *dst, GPU_D12_Resource *src, Xform src_xf) 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 #endif
} }
/* ========================== * ////////////////////////////////
* Evictor job //~ Evictor job
* ========================== */
JobDef(GPU_D12_EvictorJob, UNUSED sig, UNUSED id) JobDef(GPU_D12_EvictorJob, UNUSED sig, UNUSED id)
{ {
@ -3343,7 +3316,7 @@ JobDef(GPU_D12_EvictorJob, UNUSED sig, UNUSED id)
Unlock(&lock); Unlock(&lock);
} }
/* Wait until fences reach target */ /* Yield until fences reach target */
{ {
__profn("Check fences"); __profn("Check fences");
for (u32 i = 0; i < countof(targets); ++i) 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); completed_targets[i] = ID3D12Fence_GetCompletedValue(cq->submit_fence);
if (completed_targets[i] < targets[i]) if (completed_targets[i] < targets[i])
{ {
__profn("Wait on fence"); __profn("Yield on fence");
{ {
Counter counter = ZI; Counter counter = ZI;
RunJob(1, GPU_D12_WaitOnFenceJob, JobPool_Floating, JobPriority_Inherit, &counter, .fence = cq->submit_fence, .target = targets[i]); 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) 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; shutdown = g->evictor_shutdown;
g->evictor_wake_gen = 0; g->evictor_wake_gen = 0;

View File

@ -47,9 +47,8 @@
# define DX12_DEBUG 0 # define DX12_DEBUG 0
#endif #endif
/* ========================== * ////////////////////////////////
* structs //~ structs
* ========================== */
Struct(GPU_D12_Descriptor) 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 */ enum D3D12_RESOURCE_STATES new_state; /* 0 if type != D3D12_RESOURCE_BARRIER_TYPE_TRANSITION */
}; };
/* ========================== * ////////////////////////////////
* Shared state //~ Shared state
* ========================== */
Struct(GPU_D12_SharedState) Struct(GPU_D12_SharedState)
{ {
@ -421,55 +419,47 @@ Struct(GPU_D12_SharedState)
extern GPU_D12_SharedState GPU_D12_shared_state; extern GPU_D12_SharedState GPU_D12_shared_state;
/* ========================== * ////////////////////////////////
* Startup //~ Startup
* ========================== */
ExitFuncDef(GPU_D12_Shutdown); ExitFuncDef(GPU_D12_Shutdown);
/* ========================== * ////////////////////////////////
* Dx12 device initialization //~ Dx12 device initialization
* ========================== */
void GPU_D12_PushInitError(String error); void GPU_D12_PushInitError(String error);
void GPU_D12_InitDevice(void); void GPU_D12_InitDevice(void);
/* ========================== * ////////////////////////////////
* Dx12 object initialization //~ Dx12 object initialization
* ========================== */
void GPU_D12_InitObjects(void); void GPU_D12_InitObjects(void);
/* ========================== * ////////////////////////////////
* Dx12 pipeline initialization //~ Dx12 pipeline initialization
* ========================== */
void GPU_InitPipelines(void); void GPU_InitPipelines(void);
/* ========================== * ////////////////////////////////
* Noise texture initialization //~ Noise texture initialization
* ========================== */
void GPU_D12_InitNoise(void); void GPU_D12_InitNoise(void);
/* ========================== * ////////////////////////////////
* Shader compilation //~ Shader compilation
* ========================== */
JobDecl(GPU_D12_CompileShaderJob, { Arena *arena; GPU_D12_ShaderDesc *descs; GPU_D12_CompiledShaderResult *results; }); 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; }); JobDecl(GPU_D12_AcquirePipelineJob, { GPU_D12_PipelineDesc *descs_in; GPU_D12_Pipeline **pipelines_out; });
void GPU_D12_ReleasePipelineNow(GPU_D12_Pipeline *pipeline); void GPU_D12_ReleasePipelineNow(GPU_D12_Pipeline *pipeline);
/* ========================== * ////////////////////////////////
* Pipeline cache //~ Pipeline cache
* ========================== */
GPU_D12_PipelineScope *GPU_D12_BeginPipelineScope(void); 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); W_CallbackFuncDef(GPU_D12_WatchPipelineCallback, name);
/* ========================== * ////////////////////////////////
* Descriptor //~ Descriptor
* ========================== */
GPU_D12_Descriptor *GPU_D12_AcquireDescriptor(GPU_D12_CpuDescriptorHeap *dh); GPU_D12_Descriptor *GPU_D12_AcquireDescriptor(GPU_D12_CpuDescriptorHeap *dh);
void GPU_D12_ReleaseDescriptor(GPU_D12_Descriptor *descriptor); 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); 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); 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); 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); void GPU_ReleaseResourceFenced(GPU_Resource *resource);
/* ========================== * ////////////////////////////////
* Resource barrier //~ Resource barrier
* ========================== */
void GPU_D12_InsertBarrier(ID3D12GraphicsCommandList *cl, i32 num_descs, GPU_D12_ResourceBarrierDesc *descs); 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; }); JobDecl(GPU_D12_AcquireCommandQueueJob, { GPU_D12_CommandQueueDesc *descs_in; GPU_D12_CommandQueue **cqs_out; });
void GPU_D12_ReleaseCommandQueue(GPU_D12_CommandQueue *cq); void GPU_D12_ReleaseCommandQueue(GPU_D12_CommandQueue *cq);
/* ========================== * ////////////////////////////////
* Command list //~ Command list
* ========================== */
GPU_D12_CommandListPool *GPU_D12_AcquireCommandListPool(GPU_D12_CommandQueue *cq); 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 */ /* TODO: Allow multiple command list submissions */
u64 GPU_D12_EndCommandList(GPU_D12_CommandList *cl); 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); 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); 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) #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__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);
/* ========================== * ////////////////////////////////
* Wait job //~ Wait job
* ========================== */
JobDecl(GPU_D12_WaitOnFenceJob, { ID3D12Fence *fence; u64 target; }); JobDecl(GPU_D12_WaitOnFenceJob, { ID3D12Fence *fence; u64 target; });
/* ========================== * ////////////////////////////////
* Upload //~ Upload
* ========================== */
JobDecl(GPU_D12_UploadJob, { GPU_D12_Resource *resource; void *data; }); 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); 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); 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); GPU_D12_RenderSig *GPU_D12_AcquireRenderSig(void);
@ -595,22 +572,19 @@ void GPU_D12_ResetRenderSig(GPU_D12_RenderSig *sig);
GPU_RenderSig *GPU_AcquireRenderSig(void); GPU_RenderSig *GPU_AcquireRenderSig(void);
/* ========================== * ////////////////////////////////
* Swapchain //~ Swapchain
* ========================== */
void GPU_D12_InitSwapchainResources(GPU_D12_Swapchain *swapchain); void GPU_D12_InitSwapchainResources(GPU_D12_Swapchain *swapchain);
GPU_D12_SwapchainBuffer *GPU_D12_UpdateSwapchain(GPU_D12_Swapchain *swapchain, Vec2I32 resolution); 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); void GPU_D12_BlitToSwapchain(GPU_D12_SwapchainBuffer *dst, GPU_D12_Resource *src, Xform src_xf);
/* ========================== * ////////////////////////////////
* Evictor job //~ Evictor job
* ========================== */
JobDecl(GPU_D12_EvictorJob, EmptySig); JobDecl(GPU_D12_EvictorJob, EmptySig);

View File

@ -1,6 +1,206 @@
//////////////////////////////// ////////////////////////////////
//~ Startup //~ @hookdef Startup hook
void GT_StartupCore(void) 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;
}

View File

@ -5,9 +5,11 @@
//~ Layer dependencies //~ Layer dependencies
#include "../base/base.h" #include "../base/base.h"
#include "../platform/platform.h"
inline void GT_StartupDeps(void) inline void GT_StartupDeps(void)
{ {
BaseMain(); BaseMain();
P_Main();
} }
//////////////////////////////// ////////////////////////////////

View File

@ -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 //~ Startup
void GT_StartupCore(void); 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);

View File

@ -803,7 +803,7 @@ void JSON_Parse(Arena *arena, JSON_Parser *p)
{ {
case JSON_TokenKind_Number: 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); f64 value = interpret_number(t_text);
json->type = JSON_Type_Number; json->type = JSON_Type_Number;
json->value.number = value; json->value.number = value;
@ -812,7 +812,7 @@ void JSON_Parse(Arena *arena, JSON_Parser *p)
case JSON_TokenKind_String: 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 error = ZI;
String value = interpret_string(arena, t_text, &error); String value = interpret_string(arena, t_text, &error);
if (error.len > 0) if (error.len > 0)

View File

@ -374,8 +374,8 @@ void P_DisableWindoweCursorClip(P_Window *window);
void P_ToggleWindowTopmost(P_Window *window); void P_ToggleWindowTopmost(P_Window *window);
//- Info //- Info
Vec2 P_GetWindowSize(P_Window *window); Vec2I32 P_GetWindowSize(P_Window *window);
Vec2 P_GetWindowMonitorSize(P_Window *window); Vec2I32 P_GetWindowMonitorSize(P_Window *window);
u64 P_GetInternalWindowHandle(P_Window *window); u64 P_GetInternalWindowHandle(P_Window *window);
//////////////////////////////// ////////////////////////////////

View File

@ -113,7 +113,6 @@ Global Readonly P_LogLevelSettings P_log_settings[P_LogLevel_Count] = {
} }
}; };
//////////////////////////////// ////////////////////////////////
//~ Startup //~ Startup

View File

@ -196,7 +196,7 @@ P_W32_Window *P_W32_AcquireWindow(void)
* the same thread that created the window. */ * the same thread that created the window. */
AddCounter(&window->ready_fence, 1); AddCounter(&window->ready_fence, 1);
window->window_thread = W32_AcquireThread(&P_W32_WindowThreadEntryFunc, window, Lit("Window thread"), PROF_THREAD_GROUP_WINDOW); 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; return window;
} }
@ -1563,16 +1563,16 @@ void P_ToggleWindowTopmost(P_Window *p_window)
} }
//- Window info //- 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; 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; 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) 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) while (now_ns < target_ns - big_sleep - tolerance)
{ {
__profn("Sleep part"); __profn("Sleep part");
FutexWait(0, 0, 0, big_sleep); FutexYield(0, 0, 0, big_sleep);
now_ns = TimeNs(); now_ns = TimeNs();
} }

View File

@ -24,7 +24,7 @@ ExitFuncDef(PB_WSP_Shutdown)
__prof; __prof;
PB_WSP_SharedState *g = &PB_WSP_shared_state; PB_WSP_SharedState *g = &PB_WSP_shared_state;
Atomic32FetchSet(&g->shutdown, 1); Atomic32FetchSet(&g->shutdown, 1);
WaitOnCounter(&g->PB_WSP_PlaybackJob_counter); YieldOnCounter(&g->PB_WSP_PlaybackJob_counter);
} }
void PB_WSP_InitializeWasapi(void) void PB_WSP_InitializeWasapi(void)

View File

@ -36,6 +36,7 @@ inline void StartupPpDeps(void)
#include "pp_space.h" #include "pp_space.h"
#include "pp_ent.h" #include "pp_ent.h"
#include "pp_step.h" #include "pp_step.h"
#include "pp_draw.h"
#include "pp_core.h" #include "pp_core.h"
void PpMain(void); void PpMain(void);

View File

@ -24,23 +24,27 @@ void StartupUser(void)
g->user_client_store = AcquireClientStore(); g->user_client_store = AcquireClientStore();
g->user_unblended_client = AcquireClient(g->user_client_store); g->user_unblended_client = AcquireClient(g->user_client_store);
g->user_blended_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 */ /* Local to user client */
g->local_to_user_client_store = AcquireClientStore(); g->local_to_user_client_store = AcquireClientStore();
g->local_to_user_client = AcquireClient(g->local_to_user_client_store); g->local_to_user_client = AcquireClient(g->local_to_user_client_store);
/* GPU handles */
g->world_to_ui_xf = XformIdentity; g->world_to_ui_xf = XformIdentity;
g->world_to_render_xf = XformIdentity; g->world_to_render_xf = XformIdentity;
g->render_sig = GPU_AcquireRenderSig();
g->console_logs_arena = AcquireArena(Gibi(64)); g->console_logs_arena = AcquireArena(Gibi(64));
//P_RegisterLogCallback(ConsoleLogCallback, P_LogLevel_Success); //P_RegisterLogCallback(ConsoleLogCallback, P_LogLevel_Success);
P_RegisterLogCallback(ConsoleLogCallback, P_LogLevel_Debug); P_RegisterLogCallback(ConsoleLogCallback, P_LogLevel_Debug);
g->window = P_AcquireWindow(); 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); P_ShowWindow(g->window);
/* Start jobs */ /* Start jobs */
@ -57,7 +61,7 @@ ExitFuncDef(ShutdownUser)
__prof; __prof;
SharedUserState *g = &shared_user_state; SharedUserState *g = &shared_user_state;
Atomic32FetchSet(&g->shutdown, 1); Atomic32FetchSet(&g->shutdown, 1);
WaitOnCounter(&g->shutdown_job_counters); YieldOnCounter(&g->shutdown_job_counters);
P_ReleaseWindow(g->window); 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); x_ray = MulVec2(x_ray, ray_scale);
y_ray = MulVec2(y_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, x_ray, thickness, arrowhead_len, color_x);
D_DrawArrowRay(g->render_sig, pos, y_ray, thickness, arrowhead_len, color_y); 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); //u32 color_quad = Rgba32F(0, 1, 1, 0.3);
//Quad quad = QuadFromRect(RectFromScalar(0, 0, 1, -1)); //Quad quad = QuadFromRect(RectFromScalar(0, 0, 1, -1));
@ -105,7 +120,18 @@ void DrawDebugMovement(Entity *ent)
if (Vec2Len(vel_ray) > 0.00001) if (Vec2Len(vel_ray) > 0.00001)
{ {
/* FIXME: Enable this */
#if 0
D_DrawArrowRay(g->render_sig, pos, vel_ray, thickness, arrow_len, color_vel); 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 //- Draw console
void DrawDebugConsole(i32 level, b32 minimized) void DrawDebugConsole(i32 level, b32 minimized)
{ {
/* FIXME: Enable this */
#if 0
__prof; __prof;
SharedUserState *g = &shared_user_state; SharedUserState *g = &shared_user_state;
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
@ -350,6 +378,56 @@ void DrawDebugConsole(i32 level, b32 minimized)
g->console_logs_height = bounds_bottom - bounds_top; g->console_logs_height = bounds_bottom - bounds_top;
} }
EndScratch(scratch); 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 */ /* Get two snapshots nearest to render time */
Snapshot *left_snapshot = sim_snapshot_nil(); Snapshot *left_snapshot = NilSnapshot();
Snapshot *right_snapshot = newest_snapshot; Snapshot *right_snapshot = newest_snapshot;
{ {
Snapshot *ss = SnapshotFromTick(g->user_unblended_client, g->user_unblended_client->first_tick); 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); height = CeilF32(width / aspect_ratio);
} }
g->ui_size = VEC2(width, height); g->ui_size = VEC2I32(width, height);
/* Center ui in window */ /* Center ui in window */
f32 x = RoundF32(g->screen_size.x / 2 - width / 2); f32 x = RoundF32(g->screen_size.x / 2 - width / 2);
@ -839,19 +917,19 @@ void UpdateUser(P_Window *window)
f32 rot = RotationFromXform(xf); f32 rot = RotationFromXform(xf);
/* Scale view into viewport based on camera size */ /* 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); Xform quad_xf = MulXform(xf, local_camera->camera_quad_xform);
Vec2 camera_size = ScaleFromXform(quad_xf); Vec2 camera_size = ScaleFromXform(quad_xf);
if (!IsVec2Zero(camera_size)) if (!IsVec2Zero(camera_size))
{ {
scale = DivVec2Vec2(g->ui_size, camera_size); scale = DivVec2Vec2(scale, camera_size);
} }
} }
scale.x = MinF32(scale.x, scale.y); scale.x = MinF32(scale.x, scale.y);
scale.y = scale.x; 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); Trs trs = TRS(.t = SubVec2(ui_center, world_center), .r = rot, .s = scale);
Vec2 pivot = world_center; Vec2 pivot = world_center;
g->world_to_ui_xf = XformIdentity; 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 //- Update world to render xform from world to ui xform
b32 effects_disabled = 0; 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) if (g->debug_camera)
{ {
@ -879,13 +957,13 @@ void UpdateUser(P_Window *window)
else else
{ {
Xform ui_to_world_xf = InvertXform(g->world_to_ui_xf); 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); Vec2 scale = VEC2(PIXELS_PER_UNIT, PIXELS_PER_UNIT);
Xform xf = XformIdentity; 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 = ScaleXform(xf, scale);
xf = TranslateXform(xf, MulVec2(world_center, -1)); xf = TranslateXform(xf, MulVec2(world_center, -1));
@ -908,7 +986,7 @@ void UpdateUser(P_Window *window)
{ {
Vec2 up = VEC2(0, -1); 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_pos = InvertXformMulV2(g->world_to_ui_xf, ui_center);
Vec2 listener_dir = NormVec2(InvertXformBasisMulV2(g->world_to_ui_xf, up)); Vec2 listener_dir = NormVec2(InvertXformBasisMulV2(g->world_to_ui_xf, up));
MIX_UpdateListener(listener_pos, listener_dir); MIX_UpdateListener(listener_pos, listener_dir);
@ -916,6 +994,8 @@ void UpdateUser(P_Window *window)
//- Draw grid //- Draw grid
/* FIXME: Enable this */
#if 0
{ {
f32 thickness = 2; f32 thickness = 2;
@ -923,11 +1003,13 @@ void UpdateUser(P_Window *window)
f32 spacing = ScaleFromXform(g->world_to_render_xf).x; f32 spacing = ScaleFromXform(g->world_to_render_xf).x;
Vec2 pos = InvertXformMulV2(g->world_to_render_xf, VEC2(0, 0)); 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 color0 = Rgba32F(0.17f, 0.17f, 0.17f, 1.f);
u32 color1 = Rgba32F(0.15f, 0.15f, 0.15f, 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); 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 #if 0
//- Acquire / release tile cache entries //- 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); Entity *chunk_ent_br = sim_ent_from_chunk_pos(chunk_pos_br);
String data = sim_ent_get_chunk_tile_data(chunk_ent); 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); Entity *parent = EntityFromId(g->ss_blended, ent->parent);
Xform xf = XformFromEntity(ent); 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; b32 skip_debug_draw = !g->debug_camera && ent == local_camera;
skip_debug_draw = skip_debug_draw || HasProp(ent, Prop_MotorJoint); 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); b32 skip_debug_draw_transform = HasProp(ent, Prop_Camera);
skip_debug_draw_transform = 1; 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 */ /* Draw tracer */
/* TODO: Enable this */ /* TODO: Enable this */
@ -1147,8 +1227,16 @@ void UpdateUser(P_Window *window)
Vec3 emittance = ent->sprite_emittance; Vec3 emittance = ent->sprite_emittance;
u32 tint = ent->sprite_tint; u32 tint = ent->sprite_tint;
S_Frame frame = S_FrameFromIndex(sheet, ent->animation_frame); 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); 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); 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)]; TileKind tile = ent->tile_chunk_tiles[local_tile_index.x + (local_tile_index.y * SIM_TILES_PER_CHUNK_SQRT)];
//if (tile > -1) { //if (tile > -1) {
/* FIXME: Enable this */
#if 0
if (tile == TileKind_Wall) if (tile == TileKind_Wall)
{ {
Vec2I32 world_tile_index = WorldTileIndexFromLocalTileIndex(chunk_index, local_tile_index); Vec2I32 world_tile_index = WorldTileIndexFromLocalTileIndex(chunk_index, local_tile_index);
Vec2 pos = PosFromWorldTileIndex(world_tile_index); Vec2 pos = PosFromWorldTileIndex(world_tile_index);
Xform tile_xf = XformFromRect(RectFromVec2(pos, VEC2(tile_size, tile_size))); 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); 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 */ /* Draw AABB */
/* FIXME: Enable this */
#if 0
if (ent->local_collider.count > 0) if (ent->local_collider.count > 0)
{ {
Aabb aabb = CLD_AabbFromShape(&ent->local_collider, xf); 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); end = MulXformV2(g->world_to_ui_xf, end);
D_DrawArrowLine(g->render_sig, start, end, 3, 10, Rgba32F(1, 1, 1, 0.5)); D_DrawArrowLine(g->render_sig, start, end, 3, 10, Rgba32F(1, 1, 1, 0.5));
} }
#endif
#if 0 #if 0
/* Draw slices */ /* Draw slices */
@ -1285,6 +1384,8 @@ void UpdateUser(P_Window *window)
#endif #endif
/* Draw mouse joint */ /* Draw mouse joint */
/* FIXME: Enable this */
#if 0
if (HasProp(ent, Prop_MouseJoint)) if (HasProp(ent, Prop_MouseJoint))
{ {
Entity *target = EntityFromId(g->ss_blended, ent->mouse_joint_data.target); 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_DrawArrowLine(g->render_sig, point_start, point_end, 3, 10, color);
D_DrawCircle(g->render_sig, point_start, 4, color, 10); D_DrawCircle(g->render_sig, point_start, 4, color, 10);
} }
#endif
/* Draw collider */ /* Draw collider */
/* FIXME: Enable this */
#if 0
if (ent->local_collider.count > 0) if (ent->local_collider.count > 0)
{ {
CLD_Shape collider = ent->local_collider; CLD_Shape collider = ent->local_collider;
@ -1336,8 +1440,11 @@ void UpdateUser(P_Window *window)
} }
#endif #endif
} }
#endif
/* Draw contact constraint */ /* Draw contact constraint */
/* FIXME: Enable this */
#if 0
if (HasProp(ent, Prop_ContactConstraint)) if (HasProp(ent, Prop_ContactConstraint))
{ {
ContactConstraint *data = &ent->contact_constraint_data; ContactConstraint *data = &ent->contact_constraint_data;
@ -1407,6 +1514,7 @@ void UpdateUser(P_Window *window)
} }
#endif #endif
} }
#endif
/* Draw collision debug */ /* Draw collision debug */
#if COLLIDER_DEBUG #if COLLIDER_DEBUG
@ -1610,6 +1718,8 @@ void UpdateUser(P_Window *window)
#endif #endif
/* Draw hierarchy */ /* Draw hierarchy */
/* FIXME: Enable this */
#if 0
if (HasProp(parent, Prop_Active) && !parent->is_root) if (HasProp(parent, Prop_Active) && !parent->is_root)
{ {
u32 color = Rgba32F(0.6, 0.6, 1, 0.75); 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); D_DrawQuadLine(g->render_sig, quad, thickness, color);
} }
#endif
EndTempArena(temp); EndTempArena(temp);
} }
@ -1640,6 +1751,8 @@ void UpdateUser(P_Window *window)
} }
/* Draw crosshair or show cursor */ /* Draw crosshair or show cursor */
/* FIXME: Enable this */
#if 0
if (!g->debug_camera) if (!g->debug_camera)
{ {
__profn("Draw crosshair"); __profn("Draw crosshair");
@ -1648,8 +1761,9 @@ void UpdateUser(P_Window *window)
S_Texture *t = S_TextureFromTagAsync(sprite_frame_scope, crosshair); S_Texture *t = S_TextureFromTagAsync(sprite_frame_scope, crosshair);
Vec2 size = VEC2(t->width, t->height); Vec2 size = VEC2(t->width, t->height);
Xform xf = XformFromTrs(TRS(.t = crosshair_pos, .s = size)); 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 */ /* FIXME: Enable this */
#if 0 #if 0
@ -1870,7 +1984,8 @@ void UpdateUser(P_Window *window)
} }
//- Draw ent debug info //- Draw ent debug info
/* FIXME: Enable this */
#if 0
if (g->debug_draw && hovered_ent->valid) if (g->debug_draw && hovered_ent->valid)
{ {
Entity *ent = hovered_ent; Entity *ent = hovered_ent;
@ -1889,13 +2004,16 @@ void UpdateUser(P_Window *window)
EndTempArena(temp); EndTempArena(temp);
} }
} }
#endif
//- Query vram //- Query vram
GPU_MemoryInfo vram = GPU_QueryMemoryInfo(); GT_MemoryInfo vram = GT_QueryMemoryInfo();
//- Draw global debug info //- Draw global debug info
/* FIXME: Enable this */
#if 0
if (g->debug_draw) if (g->debug_draw)
{ {
__profn("Draw debug info"); __profn("Draw debug info");
@ -2006,6 +2124,9 @@ void UpdateUser(P_Window *window)
EndTempArena(temp); EndTempArena(temp);
} }
} }
#else
LAX vram;
#endif
{ {
#if DeveloperIsEnabled #if DeveloperIsEnabled
@ -2024,24 +2145,299 @@ void UpdateUser(P_Window *window)
{ {
__profn("Render"); __profn("Render");
Vec2I32 world_resolution = RoundVec2ToVec2I32(g->render_size); Rect ui_viewport = RectFromVec2(VEC2(0, 0), VEC2(g->ui_size.x, g->ui_size.y));
Vec2I32 user_resolution = RoundVec2ToVec2I32(g->ui_size); Rect render_viewport = RectFromVec2(VEC2(0, 0), VEC2(g->render_size.x, g->render_size.y));
Vec2I32 backbuffer_resolution = RoundVec2ToVec2I32(g->screen_size); /* Acquire gbuffers */
if (g->shade_target && !EqVec2I32(g->render_size, GT_GetTextureSize(g->shade_target)))
/* Draw world to user texture */
GPU_Resource *render_texture = 0;
{ {
GPU_RenderParams params = ZI; __profn("Release render resources");
params.ui_size = user_resolution; GT_ReleaseResource(g->albedo, g->render_fence, GT_ReleaseFlag_None);
params.render_size = world_resolution; GT_ReleaseResource(g->emittance, g->render_fence, GT_ReleaseFlag_None);
params.world_to_render_xf = g->world_to_render_xf; GT_ReleaseResource(g->emittance_flood_read, g->render_fence, GT_ReleaseFlag_None);
params.render_to_ui_xf = g->render_to_ui_xf; GT_ReleaseResource(g->emittance_flood_target, g->render_fence, GT_ReleaseFlag_None);
params.effects_disabled = effects_disabled; GT_ReleaseResource(g->shade_read, g->render_fence, GT_ReleaseFlag_None);
render_texture = GPU_RunRender(g->render_sig, params); 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 */ /* Acquire ui buffers */
GPU_PresentSwapchain(g->swapchain, backbuffer_resolution, render_texture, g->ui_to_screen_xf, VSYNC); 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 //- End frame cache scopes
@ -2051,7 +2447,8 @@ void UpdateUser(P_Window *window)
EndScratch(scratch); EndScratch(scratch);
} }
//- User update job ////////////////////////////////
//~ User update job
JobDef(UpdateUserJob, UNUSED sig, UNUSED id) JobDef(UpdateUserJob, UNUSED sig, UNUSED id)
{ {
@ -2064,7 +2461,7 @@ JobDef(UpdateUserJob, UNUSED sig, UNUSED id)
__profn("User sleep"); __profn("User sleep");
{ {
__profn("Swapchain wait"); __profn("Swapchain wait");
GPU_WaitOnSwapchain(g->swapchain); GT_WaitOnSwapchain(g->swapchain);
} }
{ {
__profn("Frame limiter wait"); __profn("Frame limiter wait");
@ -2506,7 +2903,7 @@ JobDef(SimJob, UNUSED sig, UNUSED id)
b32 master_ss_is_blended = 0; 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) */ /* How along are we between master sim ticks (0 = start of tick, 1 = end of tick) */
f64 tick_progress = 0; f64 tick_progress = 0;
@ -2537,7 +2934,7 @@ JobDef(SimJob, UNUSED sig, UNUSED id)
/* Get snapshot nearest to master blend time */ /* Get snapshot nearest to master blend time */
/* TODO: Blend */ /* TODO: Blend */
Snapshot *left_snapshot = sim_snapshot_nil(); Snapshot *left_snapshot = NilSnapshot();
Snapshot *right_snapshot = newest_snapshot; Snapshot *right_snapshot = newest_snapshot;
{ {
Snapshot *ss = SnapshotFromTick(master_client, master_client->first_tick); Snapshot *ss = SnapshotFromTick(master_client, master_client->first_tick);

View File

@ -155,9 +155,7 @@ Struct(SharedUserState)
Atomic32 shutdown; Atomic32 shutdown;
Counter shutdown_job_counters; Counter shutdown_job_counters;
P_Window *window; P_Window *window;
GPU_Swapchain *swapchain; GT_Swapchain *swapchain;
struct sim_ctx *local_sim_ctx;
Arena *arena; Arena *arena;
String connect_address_str; String connect_address_str;
@ -173,8 +171,31 @@ Struct(SharedUserState)
SecondsStat net_bytes_sent; SecondsStat net_bytes_sent;
//- Gpu resources //- 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]; BindState bind_states[BindKind_Count];
//- Debug camera //- Debug camera
@ -230,15 +251,15 @@ Struct(SharedUserState)
//- Per frame //- Per frame
Vec2 screen_size; Vec2I32 screen_size;
Vec2 screen_cursor; Vec2 screen_cursor;
Xform ui_to_screen_xf; Xform ui_to_screen_xf;
Vec2 ui_size; Vec2I32 ui_size;
Vec2 ui_cursor; Vec2 ui_cursor;
Xform render_to_ui_xf; Xform render_to_ui_xf;
Vec2 render_size; Vec2I32 render_size;
Xform world_to_render_xf; Xform world_to_render_xf;
Xform world_to_ui_xf; Xform world_to_ui_xf;
@ -272,6 +293,13 @@ String DebugStringFromEntity(Arena *arena, Entity *ent);
P_LogEventCallbackFuncDef(ConsoleLogCallback, log); P_LogEventCallbackFuncDef(ConsoleLogCallback, log);
void DrawDebugConsole(i32 level, b32 minimized); 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 //~ Entity sorting
@ -281,6 +309,10 @@ MergesortCompareFuncDef(EntitySortCmp, arg_a, arg_b, _);
//~ User update //~ User update
void UpdateUser(P_Window *window); void UpdateUser(P_Window *window);
////////////////////////////////
//~ User update job
JobDecl(UpdateUserJob, EmptySig); JobDecl(UpdateUserJob, EmptySig);
//////////////////////////////// ////////////////////////////////

445
src/pp/pp_draw.gpu Normal file
View File

@ -0,0 +1,445 @@
////////////////////////////////
//~ Signatures
ConstantBuffer<BlitSig> blit_sig : register(b0);
ConstantBuffer<FloodSig> flood_sig : register(b0);
ConstantBuffer<MaterialSig> mat_sig : register(b0);
ConstantBuffer<ShadeSig> shade_sig : register(b0);
ConstantBuffer<UiSig> ui_sig : register(b0);
ConstantBuffer<ShapeSig> 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<K_MaterialInstance> 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<Vec4> tex = GpuResourceFromNurid(input.tex_nurid);
albedo *= tex.Sample(s_point_clamp, input.uv);
}
/* Grid */
if (input.grid_id < 0xFFFFFFFF)
{
StructuredBuffer<K_MaterialGrid> 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<Vec4> emittance_tex = GpuResourceFromUrid(sig.emittance_tex_urid);
RWTexture2D<uint2> read_flood_tex = GpuResourceFromUrid(sig.read_flood_tex_urid);
RWTexture2D<uint2> 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<u32> 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<uint2> flood_tex = GpuResourceFromUrid(sig.emittance_flood_tex_urid);
Texture2D<Vec4> 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<Vec4> albedo_tex = GpuResourceFromUrid(sig.albedo_tex_urid);
Texture2D<Vec4> read_tex = GpuResourceFromUrid(sig.read_tex_urid);
RWTexture2D<Vec4> 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<Vec4> 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<K_UiInstance> 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<Vec4> 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<UiShapeVert> 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;
}

180
src/pp/pp_draw.h Normal file
View File

@ -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);

View File

@ -742,9 +742,6 @@ void SyncEntity(Entity *local, Entity *remote)
EnableProp(local, Prop_SyncDst); EnableProp(local, Prop_SyncDst);
} }
////////////////////////////////
//~ Encode / decode
#if 1 #if 1
//////////////////////////////// ////////////////////////////////
@ -755,7 +752,7 @@ void EncodeEntity(BB_Writer *bw, Entity *e0, Entity *e1)
Snapshot *ss = e1->ss; Snapshot *ss = e1->ss;
/* FIXME: Things like xforms need to be retreived manually rather than memcopied. */ /* FIXME: Things like xforms need to be retreived manually rather than memcopied. */
/* TODO: Granular delta encoding */ /* TODO: Granular delta encoding */
u64 pos = 0; u64 pos = 0;
e1->ss = e0->ss; e1->ss = e0->ss;

View File

@ -55,7 +55,7 @@ void StartupSim(void)
/* Nil ent */ /* Nil ent */
g->nil_ent = PushStruct(g->nil_arena, Entity); 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->valid = 0;
g->nil_ent->id = NilEntityId; g->nil_ent->id = NilEntityId;
g->nil_ent->_local_xform = XformIdentity; g->nil_ent->_local_xform = XformIdentity;
@ -270,7 +270,7 @@ Snapshot *AcquireSnapshot(Client *client, Snapshot *src, u64 tick)
{ {
if (tick == 0) if (tick == 0)
{ {
return sim_snapshot_nil(); return NilSnapshot();
} }
Snapshot *ss; Snapshot *ss;
@ -531,7 +531,7 @@ void ReleaseSnapshotsInRange(Client *client, u64 start, u64 end)
Snapshot *SnapshotFromTick(Client *client, u64 tick) Snapshot *SnapshotFromTick(Client *client, u64 tick)
{ {
Snapshot *ss = sim_snapshot_nil(); Snapshot *ss = NilSnapshot();
if (tick > 0) if (tick > 0)
{ {
u64 bin_index = tick % client->num_snapshot_lookup_bins; u64 bin_index = tick % client->num_snapshot_lookup_bins;

View File

@ -220,7 +220,7 @@ Struct(Snapshot)
u32 num_ents_reserved; u32 num_ents_reserved;
}; };
Inline Snapshot *sim_snapshot_nil(void) Inline Snapshot *NilSnapshot(void)
{ {
extern Readonly Snapshot **_g_sim_snapshot_nil; extern Readonly Snapshot **_g_sim_snapshot_nil;
return *_g_sim_snapshot_nil; return *_g_sim_snapshot_nil;
@ -250,7 +250,7 @@ extern Readonly ClientStore **_g_sim_client_store_nil;
/* Accessed via `NilClient()` */ /* Accessed via `NilClient()` */
extern Readonly Client **_g_sim_client_nil; extern Readonly Client **_g_sim_client_nil;
/* Accessed via `sim_snapshot_nil()` */ /* Accessed via `NilSnapshot()` */
extern Readonly Snapshot **_g_sim_snapshot_nil; extern Readonly Snapshot **_g_sim_snapshot_nil;
extern Readonly struct Entity **_g_sim_ent_nil; extern Readonly struct Entity **_g_sim_ent_nil;

View File

@ -996,7 +996,6 @@ void StepSim(SimStepCtx *ctx)
} }
} }
//- Release entities at beginning of frame //- Release entities at beginning of frame
ReleaseAllWithProp(world, Prop_Release); ReleaseAllWithProp(world, Prop_Release);
@ -1021,7 +1020,6 @@ void StepSim(SimStepCtx *ctx)
} }
} }
//- Process player cmds //- Process player cmds
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) 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 //- Update entity control from player control
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) 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 //- Update entities from sprite
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index)
@ -1361,7 +1357,6 @@ void StepSim(SimStepCtx *ctx)
#endif #endif
} }
//- Update attachments //- Update attachments
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index)
@ -1386,7 +1381,6 @@ void StepSim(SimStepCtx *ctx)
SetLocalXform(ent, xf); SetLocalXform(ent, xf);
} }
//- Process ent control //- Process ent control
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index)
@ -1421,7 +1415,6 @@ void StepSim(SimStepCtx *ctx)
} }
} }
//- Process triggered entities //- Process triggered entities
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) 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 //- Create & update motor joints from control move
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) 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) //- Create & update motor joints from control focus (aim)
#if SIM_PLAYER_AIM #if SIM_PLAYER_AIM
@ -1743,7 +1734,6 @@ void StepSim(SimStepCtx *ctx)
} }
#endif #endif
//- Create motor joints from ground friction (gravity) //- Create motor joints from ground friction (gravity)
#if 1 #if 1
@ -1776,7 +1766,6 @@ void StepSim(SimStepCtx *ctx)
} }
#endif #endif
//- Create mouse joints from client debug drag //- Create mouse joints from client debug drag
if (is_master) if (is_master)
@ -1842,7 +1831,6 @@ void StepSim(SimStepCtx *ctx)
} }
} }
//- Physics step //- Physics step
{ {
@ -1852,7 +1840,6 @@ void StepSim(SimStepCtx *ctx)
StepPhys(&phys, sim_dt); StepPhys(&phys, sim_dt);
} }
//- Update explosions //- Update explosions
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) 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); DisableProp(ent, Prop_Sensor);
} }
//- Update tracers //- Update tracers
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) 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; ent->tracer_gradient_end = gradient_end;
} }
//- Initialize bullet kinematics from sources //- Initialize bullet kinematics from sources
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index)
@ -1951,7 +1936,6 @@ void StepSim(SimStepCtx *ctx)
} }
} }
//- Update cameras //- Update cameras
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index)
@ -2012,7 +1996,6 @@ void StepSim(SimStepCtx *ctx)
SetXform(ent, xf); SetXform(ent, xf);
} }
//- Update quakes //- Update quakes
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index)
@ -2028,7 +2011,6 @@ void StepSim(SimStepCtx *ctx)
} }
} }
//- Update relative layers //- Update relative layers
{ {
@ -2059,7 +2041,6 @@ void StepSim(SimStepCtx *ctx)
EndTempArena(temp); EndTempArena(temp);
} }
//- Release entities at end of frame //- Release entities at end of frame
ReleaseAllWithProp(world, Prop_Release); ReleaseAllWithProp(world, Prop_Release);
@ -2092,7 +2073,6 @@ void StepSim(SimStepCtx *ctx)
pub_world->local_player = world->local_player; pub_world->local_player = world->local_player;
} }
//- End frame //- End frame
S_EndScope(sprite_frame_scope); S_EndScope(sprite_frame_scope);

View File

@ -108,7 +108,7 @@ AC_Asset *SND_LoadAsset(String path, SND_SoundFlag flags, b32 wait)
RunJobEx((GenericJobDesc *)desc); RunJobEx((GenericJobDesc *)desc);
if (wait) if (wait)
{ {
AC_WaitOnAssetReady(asset); AC_YieldOnAssetReady(asset);
} }
} }
@ -128,7 +128,7 @@ SND_Sound *SND_LoadSoundWait(String path, SND_SoundFlag flags)
{ {
__prof; __prof;
AC_Asset *asset = SND_LoadAsset(path, flags, 1); AC_Asset *asset = SND_LoadAsset(path, flags, 1);
AC_WaitOnAssetReady(asset); AC_YieldOnAssetReady(asset);
SND_Sound *sound = (SND_Sound *)AC_DataFromStore(asset); SND_Sound *sound = (SND_Sound *)AC_DataFromStore(asset);
return sound; return sound;
} }

View File

@ -6,7 +6,7 @@
#include "../base/base.h" #include "../base/base.h"
#include "../platform/platform.h" #include "../platform/platform.h"
#include "../gpu/gpu.h" #include "../gtest/gtest.h"
#include "../ase/ase.h" #include "../ase/ase.h"
#include "../resource/resource.h" #include "../resource/resource.h"
#include "../watch/watch.h" #include "../watch/watch.h"
@ -14,7 +14,7 @@ inline void S_StartupDeps(void)
{ {
BaseMain(); BaseMain();
P_Main(); P_Main();
GPU_Main(); GT_Main();
ASE_Main(); ASE_Main();
RES_Main(); RES_Main();
W_Main(); W_Main();

View File

@ -17,10 +17,13 @@ void S_StartupCore(void)
g->nil_texture->loaded = 1; g->nil_texture->loaded = 1;
{ {
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
u32 width = 64; GT_ResourceDesc desc = ZI;
u32 height = 64; desc.kind = GT_ResourceKind_Texture2D;
u32 *pixels = S_GeneratePurpleBlackImage(scratch.arena, width, height); desc.texture.format = GT_Format_R8G8B8A8_Unorm;
g->nil_texture->gp_texture = GPU_AcquireTexture(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, VEC2I32(width, height), pixels); 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); EndScratch(scratch);
} }
@ -64,8 +67,8 @@ ExitFuncDef(S_Shutdown)
SignalCv(&g->evictor_scheduler_shutdown_cv, I32Max); SignalCv(&g->evictor_scheduler_shutdown_cv, I32Max);
Unlock(&lock); Unlock(&lock);
} }
/* Wait for evictor shutdown */ /* Yield for evictor shutdown */
WaitOnCounter(&g->shutdown_counter); YieldOnCounter(&g->shutdown_counter);
} }
//////////////////////////////// ////////////////////////////////
@ -491,12 +494,20 @@ void S_LoadCacheEntryTexture(S_CacheEntryRef ref, S_Tag tag)
if (decoded.success) if (decoded.success)
{ {
/* Initialize */ /* 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 = PushStruct(e->arena, S_Texture);
e->texture->width = decoded.width; e->texture->width = decoded.width;
e->texture->height = decoded.height; e->texture->height = decoded.height;
e->texture->valid = 1; e->texture->valid = 1;
e->texture->loaded = 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 */ /* TODO: Query gpu for more accurate texture size in VRAM */
memory_size += (decoded.width * decoded.height) * sizeof(*decoded.pixels); memory_size += (decoded.width * decoded.height) * sizeof(*decoded.pixels);
success = 1; success = 1;
@ -1283,12 +1294,13 @@ JobDef(S_EvictorJob, UNUSED sig, UNUSED job_id)
/* Release evicted node memory */ /* Release evicted node memory */
{ {
__profn("Evictor memory release"); __profn("Evictor memory release");
GT_Fence gpu_fence = GT_GetGlobalFence();
for (S_EvictorNode *en = first_evicted; en; en = en->next_evicted) for (S_EvictorNode *en = first_evicted; en; en = en->next_evicted)
{ {
S_CacheEntry *n = en->cache_entry; S_CacheEntry *n = en->cache_entry;
if (n->kind == S_CacheEntryKind_Texture && n->texture->valid) 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); ReleaseArena(n->arena);
} }
@ -1318,7 +1330,7 @@ JobDef(S_EvictorJob, UNUSED sig, UNUSED job_id)
{ {
if (!g->evictor_scheduler_shutdown) 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; shutdown = g->evictor_scheduler_shutdown;
} }

View File

@ -14,7 +14,7 @@ Struct(S_Texture)
{ {
b32 loaded; b32 loaded;
b32 valid; b32 valid;
GPU_Resource *gp_texture; GT_Resource *gpu_resource;
u32 width; u32 width;
u32 height; 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 */ /* A cache reference whose lifetime is bound to the scope it was retrieved from */
Struct(S_ScopeCacheEntryRef) Struct(S_ScopeCacheEntryRef)
@ -189,7 +189,7 @@ Struct(S_Scope)
}; };
//////////////////////////////// ////////////////////////////////
//~ Evictor //~ Evictor types
Struct(S_EvictorNode) Struct(S_EvictorNode)
{ {

View File

@ -26,7 +26,7 @@ ExitFuncDef(W_Shutdown)
P_WakeWatch(g->watch); P_WakeWatch(g->watch);
Unlock(&lock); 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 */ /* Delay so that duplicate events pile up */
{ {
__profn("Delay"); __profn("Delay");
FutexWait(0, 0, 0, NsFromSeconds(W_DispatcherDelaySeconds)); FutexYield(0, 0, 0, NsFromSeconds(W_DispatcherDelaySeconds));
} }
/* Pull watch events from queue */ /* Pull watch events from queue */
@ -198,7 +198,7 @@ JobDef(W_DispatcherJob, UNUSED sig, UNUSED job_id)
{ {
Counter counter = ZI; Counter counter = ZI;
RunJob(num_callbacks, W_RunCallbacksJob, JobPool_Background, JobPriority_Low, &counter, .name = e->name, .callbacks = callbacks); 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); EndScratch(scratch);
} }
/* Wait for event */ /* Yield for event */
Lock lock = LockS(&g->watch_dispatcher_mutex); Lock lock = LockS(&g->watch_dispatcher_mutex);
{ {
shutdown = Atomic32Fetch(&g->W_Shutdown); shutdown = Atomic32Fetch(&g->W_Shutdown);
while (!shutdown && !g->first_watch_event) while (!shutdown && !g->first_watch_event)
{ {
WaitOnCv(&g->watch_dispatcher_cv, &lock); YieldOnCv(&g->watch_dispatcher_cv, &lock);
shutdown = Atomic32Fetch(&g->W_Shutdown); shutdown = Atomic32Fetch(&g->W_Shutdown);
} }
} }