conservative d3d12 sync
This commit is contained in:
parent
a772094154
commit
707755e503
@ -795,6 +795,8 @@ Inline u64 MixU64s(u64 seed_a, u64 seed_b)
|
|||||||
#if IsCpu
|
#if IsCpu
|
||||||
StringList GetRawCommandline(void);
|
StringList GetRawCommandline(void);
|
||||||
String GetAppName(void);
|
String GetAppName(void);
|
||||||
|
String GetEngineDirectory(void);
|
||||||
|
String GetLibsDirectory(void);
|
||||||
String GetAppDirectory(void);
|
String GetAppDirectory(void);
|
||||||
void Echo(String msg);
|
void Echo(String msg);
|
||||||
b32 Panic(String msg);
|
b32 Panic(String msg);
|
||||||
|
|||||||
@ -18,7 +18,7 @@ Struct(LogEvent)
|
|||||||
Struct(LogEventsArray)
|
Struct(LogEventsArray)
|
||||||
{
|
{
|
||||||
u64 count;
|
u64 count;
|
||||||
LogEvent *logs;
|
LogEvent *events;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -45,44 +45,6 @@ Struct(LogEventsArray)
|
|||||||
#define LogLevel_Trace 6
|
#define LogLevel_Trace 6
|
||||||
#define LogLevel_COUNT 7
|
#define LogLevel_COUNT 7
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Log level types
|
|
||||||
|
|
||||||
Struct(LogLevelSettings)
|
|
||||||
{
|
|
||||||
String shorthand;
|
|
||||||
};
|
|
||||||
|
|
||||||
Global Readonly LogLevelSettings log_settings[LogLevel_COUNT] = {
|
|
||||||
[LogLevel_Critical] = {
|
|
||||||
CompLit("CRITICAL"),
|
|
||||||
},
|
|
||||||
|
|
||||||
[LogLevel_Error] = {
|
|
||||||
CompLit("ERROR"),
|
|
||||||
},
|
|
||||||
|
|
||||||
[LogLevel_Warning] = {
|
|
||||||
CompLit("WARNING"),
|
|
||||||
},
|
|
||||||
|
|
||||||
[LogLevel_Success] = {
|
|
||||||
CompLit("SUCCESS"),
|
|
||||||
},
|
|
||||||
|
|
||||||
[LogLevel_Info] = {
|
|
||||||
CompLit("INFO"),
|
|
||||||
},
|
|
||||||
|
|
||||||
[LogLevel_Debug] = {
|
|
||||||
CompLit("DEBUG"),
|
|
||||||
},
|
|
||||||
|
|
||||||
[LogLevel_Trace] = {
|
|
||||||
CompLit("TRACE"),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Compile-time logging macros
|
//~ Compile-time logging macros
|
||||||
|
|
||||||
|
|||||||
@ -48,6 +48,21 @@ String GetAppName(void)
|
|||||||
return W32.app_name;
|
return W32.app_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String GetEngineDirectory(void)
|
||||||
|
{
|
||||||
|
return W32.engine_dir_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
String GetLibsDirectory(void)
|
||||||
|
{
|
||||||
|
return W32.libs_dir_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
String GetAppDirectory(void)
|
||||||
|
{
|
||||||
|
return W32.app_dir_path;
|
||||||
|
}
|
||||||
|
|
||||||
void Echo(String msg)
|
void Echo(String msg)
|
||||||
{
|
{
|
||||||
HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
@ -233,11 +248,6 @@ void SleepSeconds(f64 seconds)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String GetAppDirectory(void)
|
|
||||||
{
|
|
||||||
return W32.appdir_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ @hookimpl Swap
|
//~ @hookimpl Swap
|
||||||
|
|
||||||
@ -323,89 +333,107 @@ void ExitNow(i32 code)
|
|||||||
ExitProcess(code);
|
ExitProcess(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Error
|
||||||
|
|
||||||
|
String W32_StringFromError(Arena *arena, i32 code)
|
||||||
|
{
|
||||||
|
String result = Lit("Unknown error");
|
||||||
|
{
|
||||||
|
wchar_t *msg_wstr = 0;
|
||||||
|
i64 msg_len = FormatMessageW(
|
||||||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
0,
|
||||||
|
code,
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
(LPWSTR)&msg_wstr,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
result = StringFromWstr(arena, msg_wstr, msg_len);
|
||||||
|
if (msg_wstr)
|
||||||
|
{
|
||||||
|
LocalFree(msg_wstr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Log
|
//~ Log
|
||||||
|
|
||||||
void W32_BootstrapLogs(void)
|
void W32_LogEventToFile(LogEvent *ev, HANDLE file)
|
||||||
{
|
{
|
||||||
Arena *perm = PermArena();
|
Struct(LogLevelSettings)
|
||||||
W32.logs_arena = AcquireArena(Gibi(64));
|
{
|
||||||
W32.log_msgs_arena = AcquireArena(Gibi(64));
|
String shorthand;
|
||||||
W32.readable_log_events = ArenaNext(W32.logs_arena, LogEvent);
|
};
|
||||||
String logfile_path = StringF(perm, "%F/log.log", FmtString(GetAppDirectory()));
|
PERSIST Readonly LogLevelSettings level_settings[LogLevel_COUNT] = {
|
||||||
wchar_t *path_wstr = WstrFromString(perm, logfile_path);
|
[LogLevel_Critical] = { CompLit("CRITICAL") },
|
||||||
W32.logfile = CreateFileW(
|
[LogLevel_Error] = { CompLit("ERROR") },
|
||||||
path_wstr,
|
[LogLevel_Warning] = { CompLit("WARNING") },
|
||||||
FILE_APPEND_DATA,
|
[LogLevel_Success] = { CompLit("SUCCESS") },
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
[LogLevel_Info] = { CompLit("INFO") },
|
||||||
0,
|
[LogLevel_Debug] = { CompLit("DEBUG") },
|
||||||
CREATE_ALWAYS,
|
[LogLevel_Trace] = { CompLit("TRACE") },
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
};
|
||||||
0
|
|
||||||
);
|
TempArena scratch = BeginScratchNoConflict();
|
||||||
Atomic32Set(&W32.logs_initialized, 1);
|
{
|
||||||
LogInfoF("Log file path: %F", FmtString(logfile_path));
|
LogLevelSettings settings = level_settings[ev->level];
|
||||||
|
String shorthand = settings.shorthand;
|
||||||
|
String msg_formatted = StringF(
|
||||||
|
scratch.arena,
|
||||||
|
"[%F:%F:%F.%F] <%F> [%F] %F\n",
|
||||||
|
|
||||||
|
// Time
|
||||||
|
FmtUint(ev->datetime.hour, .z = 2),
|
||||||
|
FmtUint(ev->datetime.minute, .z = 2),
|
||||||
|
FmtUint(ev->datetime.second, .z = 2),
|
||||||
|
FmtUint(ev->datetime.milliseconds, .z = 3),
|
||||||
|
|
||||||
|
// Thread id
|
||||||
|
FmtUint(ev->thread_id, .z = 5),
|
||||||
|
|
||||||
|
// Level
|
||||||
|
FmtString(shorthand),
|
||||||
|
|
||||||
|
// Message
|
||||||
|
FmtString(ev->msg)
|
||||||
|
);
|
||||||
|
WriteFile(file, msg_formatted.text, msg_formatted.len, 0, 0);
|
||||||
|
}
|
||||||
|
EndScratch(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void W32_Log(i32 level, String msg)
|
void W32_Log(i32 level, String msg)
|
||||||
{
|
{
|
||||||
TempArena scratch = BeginScratchNoConflict();
|
level = ClampI32(level, 0, LogLevel_COUNT - 1);
|
||||||
if (Atomic32Fetch(&W32.logs_initialized))
|
|
||||||
|
DateTime datetime = LocalDateTime();
|
||||||
|
i64 now_ns = TimeNs();
|
||||||
|
i32 thread_id = GetCurrentThreadId();
|
||||||
|
|
||||||
|
LogEvent *ev = 0;
|
||||||
|
LockTicketMutex(&W32.logs_tm);
|
||||||
{
|
{
|
||||||
LogLevelSettings settings = log_settings[level];
|
// Get staged data
|
||||||
if (level < 0 || level >= LogLevel_COUNT)
|
ev = PushStruct(W32.logs_arena, LogEvent);
|
||||||
{
|
ev->msg = PushString(W32.log_events_arena, msg);
|
||||||
Panic(Lit("Invalid log level"));
|
ev->datetime = datetime;
|
||||||
}
|
ev->time_ns = now_ns;
|
||||||
|
ev->level = level;
|
||||||
DateTime datetime = LocalDateTime();
|
ev->thread_id = thread_id;
|
||||||
i64 now_ns = TimeNs();
|
ev->id = W32.logs_count++;
|
||||||
i32 thread_id = GetCurrentThreadId();
|
ev->level_id = W32.log_level_counts[level]++;
|
||||||
|
Atomic64Set(&W32.readable_logs_count, W32.logs_count);
|
||||||
// TODO: Log asynchronously
|
}
|
||||||
|
UnlockTicketMutex(&W32.logs_tm);
|
||||||
//- Log message to file
|
|
||||||
{
|
if (W32.logfile)
|
||||||
String shorthand = settings.shorthand;
|
{
|
||||||
String msg_formatted = StringF(
|
W32_LogEventToFile(ev, W32.logfile);
|
||||||
scratch.arena,
|
|
||||||
"[%F:%F:%F.%F] <%F> [%F] %F\n",
|
|
||||||
|
|
||||||
// Time
|
|
||||||
FmtUint(datetime.hour, .z = 2),
|
|
||||||
FmtUint(datetime.minute, .z = 2),
|
|
||||||
FmtUint(datetime.second, .z = 2),
|
|
||||||
FmtUint(datetime.milliseconds, .z = 3),
|
|
||||||
|
|
||||||
// Thread id
|
|
||||||
FmtUint(thread_id, .z = 5),
|
|
||||||
|
|
||||||
// Level
|
|
||||||
FmtString(shorthand),
|
|
||||||
|
|
||||||
// Message
|
|
||||||
FmtString(msg)
|
|
||||||
);
|
|
||||||
WriteFile(W32.logfile, msg_formatted.text, msg_formatted.len, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Log message to queue
|
|
||||||
LockTicketMutex(&W32.logs_tm);
|
|
||||||
{
|
|
||||||
// Get staged data
|
|
||||||
LogEvent *ev = PushStruct(W32.logs_arena, LogEvent);
|
|
||||||
ev->msg = PushString(W32.log_msgs_arena, msg);
|
|
||||||
ev->datetime = datetime;
|
|
||||||
ev->time_ns = now_ns;
|
|
||||||
ev->level = level;
|
|
||||||
ev->thread_id = thread_id;
|
|
||||||
ev->id = W32.logs_count++;
|
|
||||||
ev->level_id = W32.log_level_counts[level]++;
|
|
||||||
Atomic64Set(&W32.readable_logs_count, W32.logs_count);
|
|
||||||
}
|
|
||||||
UnlockTicketMutex(&W32.logs_tm);
|
|
||||||
}
|
}
|
||||||
EndScratch(scratch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -415,7 +443,7 @@ void W32_Log(i32 level, String msg)
|
|||||||
// immediately writing to log file.
|
// immediately writing to log file.
|
||||||
void LogPanic(String msg)
|
void LogPanic(String msg)
|
||||||
{
|
{
|
||||||
if (Atomic32Fetch(&W32.logs_initialized))
|
if (W32.logfile)
|
||||||
{
|
{
|
||||||
String beg = Lit("******** PANICKING ********\n");
|
String beg = Lit("******** PANICKING ********\n");
|
||||||
String end = Lit("\n***************************\n");
|
String end = Lit("\n***************************\n");
|
||||||
@ -432,18 +460,15 @@ void Log_(i32 level, String msg)
|
|||||||
|
|
||||||
void LogF_(i32 level, String fmt, ...)
|
void LogF_(i32 level, String fmt, ...)
|
||||||
{
|
{
|
||||||
if (Atomic32Fetch(&W32.logs_initialized))
|
TempArena scratch = BeginScratchNoConflict();
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
{
|
{
|
||||||
TempArena scratch = BeginScratchNoConflict();
|
String msg = FormatString(scratch.arena, fmt, FmtArgsFromVaList(scratch.arena, args));
|
||||||
va_list args;
|
W32_Log(level, msg);
|
||||||
va_start(args, fmt);
|
|
||||||
{
|
|
||||||
String msg = FormatString(scratch.arena, fmt, FmtArgsFromVaList(scratch.arena, args));
|
|
||||||
W32_Log(level, msg);
|
|
||||||
}
|
|
||||||
va_end(args);
|
|
||||||
EndScratch(scratch);
|
|
||||||
}
|
}
|
||||||
|
va_end(args);
|
||||||
|
EndScratch(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogEventsArray GetLogEvents(void)
|
LogEventsArray GetLogEvents(void)
|
||||||
@ -452,7 +477,7 @@ LogEventsArray GetLogEvents(void)
|
|||||||
result.count = Atomic64Fetch(&W32.readable_logs_count);
|
result.count = Atomic64Fetch(&W32.readable_logs_count);
|
||||||
if (result.count > 0)
|
if (result.count > 0)
|
||||||
{
|
{
|
||||||
result.logs = W32.readable_log_events;
|
result.events = W32.readable_log_events;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -498,6 +523,11 @@ i32 W32_Main(void)
|
|||||||
// Query system info
|
// Query system info
|
||||||
GetSystemInfo(&W32.info);
|
GetSystemInfo(&W32.info);
|
||||||
|
|
||||||
|
// Setup logging memory
|
||||||
|
W32.logs_arena = AcquireArena(Gibi(64));
|
||||||
|
W32.log_events_arena = AcquireArena(Gibi(64));
|
||||||
|
W32.readable_log_events = ArenaNext(W32.logs_arena, LogEvent);
|
||||||
|
|
||||||
// Init main thread
|
// Init main thread
|
||||||
W32_InitCurrentThread(Lit("Main"));
|
W32_InitCurrentThread(Lit("Main"));
|
||||||
|
|
||||||
@ -534,96 +564,141 @@ i32 W32_Main(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Bootstrap
|
//- Bootstrap tweak vars
|
||||||
|
|
||||||
// Bootstrap tweak vars
|
|
||||||
BootstrapTweakVars();
|
BootstrapTweakVars();
|
||||||
|
|
||||||
// Bootstrap command line
|
//////////////////////////////
|
||||||
|
//- Bootstrap command line
|
||||||
|
|
||||||
BootstrapCmdline();
|
BootstrapCmdline();
|
||||||
|
|
||||||
// Init app directory
|
//////////////////////////////
|
||||||
String appdir_error = Zi;
|
//- Initialize app directories
|
||||||
{
|
|
||||||
String appdir_path = Zi;
|
|
||||||
CommandlineArg appdir_arg = CommandlineArgFromName(Lit("appdir"));
|
|
||||||
CommandlineArg app_name_arg = CommandlineArgFromName(Lit("app_name"));
|
|
||||||
if (appdir_arg.exists && appdir_arg.value.len > 0)
|
|
||||||
{
|
|
||||||
appdir_path = appdir_arg.value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
String app_name = Lit(Stringize(DefaultAppName));
|
|
||||||
if (app_name_arg.exists && app_name_arg.value.len > 0)
|
|
||||||
{
|
|
||||||
app_name = app_name_arg.value;
|
|
||||||
}
|
|
||||||
W32.app_name = app_name;
|
|
||||||
|
|
||||||
wchar_t *path_wstr = 0;
|
{
|
||||||
HRESULT hr = SHGetKnownFolderPath(&FOLDERID_LocalAppData, 0, 0, &path_wstr);
|
String app_name = CommandlineArgFromName(Lit("app_name")).value;
|
||||||
|
if (!app_name.len)
|
||||||
|
{
|
||||||
|
app_name = StringFromCstrNoLimit(Stringize(DefaultAppName));
|
||||||
|
}
|
||||||
|
W32.app_name = app_name;
|
||||||
|
|
||||||
|
String appdata_path = Zi;
|
||||||
|
{
|
||||||
|
wchar_t *appdata_path_wstr = 0;
|
||||||
|
HRESULT hr = SHGetKnownFolderPath(&FOLDERID_LocalAppData, 0, 0, &appdata_path_wstr);
|
||||||
if (!SUCCEEDED(hr))
|
if (!SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
Panic(Lit("Failed to locate AppData directory"));
|
Panic(Lit("Failed to locate AppData/Local directory"));
|
||||||
}
|
}
|
||||||
appdir_path = StringFromWstrNoLimit(perm, path_wstr);
|
appdata_path = PathFromString(perm, StringFromWstrNoLimit(perm, appdata_path_wstr), '/');
|
||||||
CoTaskMemFree(path_wstr);
|
CoTaskMemFree(appdata_path_wstr);
|
||||||
appdir_path = PathFromString(perm, StringF(perm, "%F\\Cabin\\%F\\", FmtString(appdir_path), FmtString(app_name)), '/');
|
|
||||||
}
|
}
|
||||||
// Create app dir
|
|
||||||
|
W32.engine_dir_path = StringF(perm, "%F/Cabin/", FmtString(appdata_path));
|
||||||
|
W32.libs_dir_path = StringF(perm, "%F/libs/", FmtString(W32.engine_dir_path));
|
||||||
|
W32.app_dir_path = StringF(perm, "%F/%F/", FmtString(W32.engine_dir_path), FmtString(app_name));
|
||||||
|
|
||||||
|
// Initialize engine/app dir
|
||||||
{
|
{
|
||||||
String path = PathFromString(perm, appdir_path, '\\');
|
String path = PathFromString(perm, W32.app_dir_path, '\\');
|
||||||
wchar_t *path_wstr = WstrFromString(perm, path);
|
wchar_t *path_wstr = WstrFromString(perm, path);
|
||||||
i32 err_code = SHCreateDirectoryExW(0, path_wstr, 0);
|
i32 err = SHCreateDirectoryExW(0, path_wstr, 0);
|
||||||
String err = StringF(perm, "Error code %F", FmtSint(err_code));
|
if (err != ERROR_SUCCESS && err != ERROR_ALREADY_EXISTS && err != ERROR_FILE_EXISTS)
|
||||||
switch (err_code)
|
|
||||||
{
|
{
|
||||||
default: break;
|
String msg = StringF(
|
||||||
case ERROR_BAD_PATHNAME:
|
|
||||||
{
|
|
||||||
err = Lit("Bad path name");
|
|
||||||
} break;
|
|
||||||
case ERROR_FILENAME_EXCED_RANGE:
|
|
||||||
{
|
|
||||||
err = Lit("Path name too long");
|
|
||||||
} break;
|
|
||||||
case ERROR_CANCELLED:
|
|
||||||
{
|
|
||||||
err = Lit("User canceled the operation");
|
|
||||||
} break;
|
|
||||||
case ERROR_PATH_NOT_FOUND:
|
|
||||||
{
|
|
||||||
err = Lit("The system cannot find the path specified.");
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
if (err_code != ERROR_SUCCESS && err_code != ERROR_ALREADY_EXISTS && err_code != ERROR_FILE_EXISTS)
|
|
||||||
{
|
|
||||||
appdir_error = StringF(
|
|
||||||
perm,
|
perm,
|
||||||
"Failed to initialize app directory at \"%F\": %F",
|
"Failed to initialize app directory at \"%F\": %F",
|
||||||
FmtString(path),
|
FmtString(path),
|
||||||
FmtString(err)
|
FmtString(W32_StringFromError(perm, err))
|
||||||
);
|
);
|
||||||
wchar_t *msg_wstr = WstrFromString(perm, appdir_error);
|
LogError(msg);
|
||||||
MessageBoxExW(0, msg_wstr, L"Warning", MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST, 0);
|
MessageBoxExW(0, WstrFromString(perm, msg), L"Warning", MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
W32.appdir_path = appdir_path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bootstrap log system
|
// Initialize libs dir
|
||||||
W32_BootstrapLogs();
|
{
|
||||||
|
String path = PathFromString(perm, W32.libs_dir_path, '\\');
|
||||||
|
wchar_t *path_wstr = WstrFromString(perm, path);
|
||||||
|
i32 err = SHCreateDirectoryExW(0, path_wstr, 0);
|
||||||
|
if (err != ERROR_SUCCESS && err != ERROR_ALREADY_EXISTS && err != ERROR_FILE_EXISTS)
|
||||||
|
{
|
||||||
|
String msg = StringF(
|
||||||
|
perm,
|
||||||
|
"Failed to initialize libs directory at \"%F\": %F",
|
||||||
|
FmtString(path),
|
||||||
|
FmtString(W32_StringFromError(perm, err))
|
||||||
|
);
|
||||||
|
LogError(msg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
|
||||||
|
if (err != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
LogErrorF(
|
||||||
|
"Failed call to SetDefaultDllDirectories: %F",
|
||||||
|
FmtString(W32_StringFromError(perm, err))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
String libs_path = PathFromString(perm, StringF(perm, "%F/libs/", FmtString(W32.engine_dir_path)), '\\');
|
||||||
|
wchar_t *libs_path_wstr = WstrFromString(perm, libs_path);
|
||||||
|
DLL_DIRECTORY_COOKIE cookie = AddDllDirectory(libs_path_wstr);
|
||||||
|
err = GetLastError();
|
||||||
|
if (!cookie || err != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
LogErrorF(
|
||||||
|
"Failed to add libs directory to dll search path at \"%F\": %F",
|
||||||
|
FmtString(path),
|
||||||
|
FmtString(W32_StringFromError(perm, err))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- Initialize log file
|
||||||
|
|
||||||
|
{
|
||||||
|
String logfile_path = StringF(perm, "%F/log.log", FmtString(GetAppDirectory()));
|
||||||
|
wchar_t *path_wstr = WstrFromString(perm, logfile_path);
|
||||||
|
LogInfoF("Log file path: %F", FmtString(logfile_path));
|
||||||
|
W32.logfile = CreateFileW(
|
||||||
|
path_wstr,
|
||||||
|
FILE_APPEND_DATA,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
0,
|
||||||
|
CREATE_ALWAYS,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
if (W32.logfile)
|
||||||
|
{
|
||||||
|
LogEventsArray unwritten_log_events = GetLogEvents();
|
||||||
|
for (u64 ev_idx = 0; ev_idx < unwritten_log_events.count; ++ev_idx)
|
||||||
|
{
|
||||||
|
LogEvent *ev = &unwritten_log_events.events[ev_idx];
|
||||||
|
W32_LogEventToFile(ev, W32.logfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogErrorF("Failed to create log file at path: %F", FmtString(logfile_path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LogInfoF("Command line: [%F]", FmtString(cmdline_str));
|
LogInfoF("Command line: [%F]", FmtString(cmdline_str));
|
||||||
if (W32.wine_version.len > 0)
|
if (W32.wine_version.len > 0)
|
||||||
{
|
{
|
||||||
LogInfoF("Wine version: \"%F\"", FmtString(W32.wine_version));
|
LogInfoF("Wine version: \"%F\"", FmtString(W32.wine_version));
|
||||||
}
|
}
|
||||||
if (appdir_error.len > 0)
|
|
||||||
{
|
|
||||||
LogError(appdir_error);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bootstrap resource system
|
// Bootstrap resource system
|
||||||
{
|
{
|
||||||
W32_FindEmbeddedDataCtx ctx = Zi;
|
W32_FindEmbeddedDataCtx ctx = Zi;
|
||||||
@ -631,10 +706,14 @@ i32 W32_Main(void)
|
|||||||
BootstrapResources(ctx.embedded_strings_count, ctx.embedded_strings);
|
BootstrapResources(ctx.embedded_strings_count, ctx.embedded_strings);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bootstrap async
|
//////////////////////////////
|
||||||
|
//- Bootstrap async
|
||||||
|
|
||||||
BootstrapAsync();
|
BootstrapAsync();
|
||||||
|
|
||||||
// Bootstrap layers
|
//////////////////////////////
|
||||||
|
//- Bootstrap layers
|
||||||
|
|
||||||
if (!Atomic32Fetch(&W32.panicking))
|
if (!Atomic32Fetch(&W32.panicking))
|
||||||
{
|
{
|
||||||
BootstrapLayers();
|
BootstrapLayers();
|
||||||
|
|||||||
@ -6,32 +6,25 @@
|
|||||||
#define COBJMACROS
|
#define COBJMACROS
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#define UNICODE
|
#define UNICODE
|
||||||
// #pragma warning(push, 0)
|
#include <Windows.h>
|
||||||
#include <Windows.h>
|
#include <combaseapi.h>
|
||||||
#include <combaseapi.h>
|
#include <dcommon.h>
|
||||||
#include <dcommon.h>
|
#include <initguid.h>
|
||||||
#include <initguid.h>
|
#include <unknwn.h>
|
||||||
#include <unknwn.h>
|
#include <objbase.h>
|
||||||
#include <objbase.h>
|
#include <uuids.h>
|
||||||
#include <uuids.h>
|
#include <Knownfolders.h>
|
||||||
#include <Knownfolders.h>
|
#include <WinSock2.h>
|
||||||
#include <WinSock2.h>
|
#include <Mswsock.h>
|
||||||
#include <Mswsock.h>
|
#include <TlHelp32.h>
|
||||||
#include <TlHelp32.h>
|
#include <WS2tcpip.h>
|
||||||
#include <WS2tcpip.h>
|
#include <windowsx.h>
|
||||||
#include <windowsx.h>
|
#include <ShlObj_core.h>
|
||||||
#include <ShlObj_core.h>
|
#include <fileapi.h>
|
||||||
#include <fileapi.h>
|
#include <dwmapi.h>
|
||||||
#include <dwmapi.h>
|
#include <avrt.h>
|
||||||
#include <avrt.h>
|
#include <shellapi.h>
|
||||||
#include <shellapi.h>
|
#include <compressapi.h>
|
||||||
#include <compressapi.h>
|
|
||||||
// #pragma warning(pop)
|
|
||||||
|
|
||||||
#ifndef BCRYPT_RNG_ALG_HANDLE
|
|
||||||
#define BCRYPT_RNG_ALG_HANDLE ((void *)0x00000081)
|
|
||||||
u32 BCryptGenRandom(void *algorithm, u8 *buffer, u32 buffer_size, u32 flags);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//- Windows libs
|
//- Windows libs
|
||||||
|
|
||||||
@ -49,21 +42,16 @@
|
|||||||
#pragma comment(lib, "ws2_32.lib")
|
#pragma comment(lib, "ws2_32.lib")
|
||||||
#pragma comment(lib, "advapi32.lib")
|
#pragma comment(lib, "advapi32.lib")
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
//- Windows API
|
||||||
//~ Embedded data iter types
|
|
||||||
|
|
||||||
Struct(W32_FindEmbeddedDataCtx)
|
|
||||||
{
|
|
||||||
u64 embedded_strings_count;
|
|
||||||
String embedded_strings[64];
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ API types
|
|
||||||
|
|
||||||
typedef char *W32_WineVersionFunc(void);
|
typedef char *W32_WineVersionFunc(void);
|
||||||
typedef BOOL W32_IsWindowArrangedFunc(HWND hwnd);
|
typedef BOOL W32_IsWindowArrangedFunc(HWND hwnd);
|
||||||
|
|
||||||
|
#ifndef BCRYPT_RNG_ALG_HANDLE
|
||||||
|
#define BCRYPT_RNG_ALG_HANDLE ((void *)0x00000081)
|
||||||
|
u32 BCryptGenRandom(void *algorithm, u8 *buffer, u32 buffer_size, u32 flags);
|
||||||
|
#endif
|
||||||
|
|
||||||
Struct(W32_Api)
|
Struct(W32_Api)
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
@ -79,6 +67,15 @@ Struct(W32_Api)
|
|||||||
} func;
|
} func;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Embedded data iter types
|
||||||
|
|
||||||
|
Struct(W32_FindEmbeddedDataCtx)
|
||||||
|
{
|
||||||
|
u64 embedded_strings_count;
|
||||||
|
String embedded_strings[64];
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ State types
|
//~ State types
|
||||||
|
|
||||||
@ -96,7 +93,9 @@ Struct(W32_Ctx)
|
|||||||
|
|
||||||
StringList raw_command_line;
|
StringList raw_command_line;
|
||||||
String app_name;
|
String app_name;
|
||||||
String appdir_path;
|
String engine_dir_path;
|
||||||
|
String libs_dir_path;
|
||||||
|
String app_dir_path;
|
||||||
|
|
||||||
//- Application control flow
|
//- Application control flow
|
||||||
|
|
||||||
@ -113,11 +112,10 @@ Struct(W32_Ctx)
|
|||||||
//- Logs
|
//- Logs
|
||||||
|
|
||||||
HANDLE logfile;
|
HANDLE logfile;
|
||||||
Atomic32 logs_initialized;
|
|
||||||
|
|
||||||
TicketMutex logs_tm;
|
TicketMutex logs_tm;
|
||||||
Arena *log_msgs_arena;
|
|
||||||
Arena *logs_arena;
|
Arena *logs_arena;
|
||||||
|
Arena *log_events_arena;
|
||||||
|
|
||||||
u64 logs_count;
|
u64 logs_count;
|
||||||
u64 log_level_counts[LogLevel_COUNT];
|
u64 log_level_counts[LogLevel_COUNT];
|
||||||
@ -133,10 +131,15 @@ extern W32_Ctx W32;
|
|||||||
#define W32_EmbeddedDataPrefix EMBEDDED_RESOURCE_DATA__
|
#define W32_EmbeddedDataPrefix EMBEDDED_RESOURCE_DATA__
|
||||||
BOOL W32_FindEmbeddedRcData(HMODULE module, LPCWSTR type, LPWSTR wstr_entry_name, LONG_PTR udata);
|
BOOL W32_FindEmbeddedRcData(HMODULE module, LPCWSTR type, LPWSTR wstr_entry_name, LONG_PTR udata);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Error
|
||||||
|
|
||||||
|
String W32_StringFromError(Arena *arena, i32 code);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Log
|
//~ Log
|
||||||
|
|
||||||
void W32_BootstrapLogs(void);
|
void W32_LogEventToFile(LogEvent *ev, HANDLE file);
|
||||||
void W32_Log(i32 level, String msg);
|
void W32_Log(i32 level, String msg);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -572,6 +572,26 @@ u32 G_PushRef(G_ArenaHandle arena, G_ResourceHandle resource, G_RefDesc desc);
|
|||||||
G_CommandListHandle G_PrepareCommandList(G_QueueKind queue);
|
G_CommandListHandle G_PrepareCommandList(G_QueueKind queue);
|
||||||
i64 G_CommitCommandList(G_CommandListHandle cl);
|
i64 G_CommitCommandList(G_CommandListHandle cl);
|
||||||
|
|
||||||
|
//- Constant
|
||||||
|
|
||||||
|
void G_SetConstantEx(G_CommandListHandle cl, i32 slot, void *src_32bit, u32 size);
|
||||||
|
|
||||||
|
#define G_SetConstant(cl, name, value) do { \
|
||||||
|
CAT(name, __shaderconstanttype) __src; \
|
||||||
|
__src.v = value; \
|
||||||
|
G_SetConstantEx((cl), (name), &__src, sizeof(__src)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
//- Barrier
|
||||||
|
|
||||||
|
void G_Sync(G_CommandListHandle cl);
|
||||||
|
void G_SyncLayout(G_CommandListHandle cl, G_ResourceHandle resource, G_Layout layout);
|
||||||
|
|
||||||
|
//- Event
|
||||||
|
|
||||||
|
void G_BeginEvent(G_CommandListHandle cl, String name);
|
||||||
|
void G_EndEvent(G_CommandListHandle cl);
|
||||||
|
|
||||||
//- Cpu -> Gpu staged copy
|
//- Cpu -> Gpu staged copy
|
||||||
|
|
||||||
void G_CopyCpuToBuffer(G_CommandListHandle cl, G_ResourceHandle dst, u64 dst_offset, void *src, RngU64 src_copy_range);
|
void G_CopyCpuToBuffer(G_CommandListHandle cl, G_ResourceHandle dst, u64 dst_offset, void *src, RngU64 src_copy_range);
|
||||||
@ -584,21 +604,6 @@ void G_CopyBufferToTexture(G_CommandListHandle cl_handle, G_ResourceHandle dst_h
|
|||||||
void G_CopyTextureToTexture(G_CommandListHandle cl, G_ResourceHandle dst, Vec3I32 dst_offset, G_ResourceHandle src, Rng3I32 src_copy_range);
|
void G_CopyTextureToTexture(G_CommandListHandle cl, G_ResourceHandle dst, Vec3I32 dst_offset, G_ResourceHandle src, Rng3I32 src_copy_range);
|
||||||
void G_CopyTextureToBuffer(G_CommandListHandle cl, G_ResourceHandle dst, Vec3I32 dst_offset, G_ResourceHandle src, Rng3I32 src_copy_range);
|
void G_CopyTextureToBuffer(G_CommandListHandle cl, G_ResourceHandle dst, Vec3I32 dst_offset, G_ResourceHandle src, Rng3I32 src_copy_range);
|
||||||
|
|
||||||
//- Constant
|
|
||||||
|
|
||||||
void G_SetConstantEx(G_CommandListHandle cl, i32 slot, void *src_32bit, u32 size);
|
|
||||||
|
|
||||||
#define G_SetConstant(cl, name, value) do { \
|
|
||||||
CAT(name, __shaderconstanttype) __src; \
|
|
||||||
__src.v = value; \
|
|
||||||
G_SetConstantEx((cl), (name), &__src, sizeof(__src)); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
//- Sync
|
|
||||||
|
|
||||||
void G_Sync(G_CommandListHandle cl);
|
|
||||||
void G_SyncLayout(G_CommandListHandle cl, G_ResourceHandle resource, G_Layout layout);
|
|
||||||
|
|
||||||
//- Compute
|
//- Compute
|
||||||
|
|
||||||
void G_ComputeEx(G_CommandListHandle cl, ComputeShaderDesc cs, Vec3I32 threads);
|
void G_ComputeEx(G_CommandListHandle cl, ComputeShaderDesc cs, Vec3I32 threads);
|
||||||
|
|||||||
@ -13,17 +13,47 @@ void G_Bootstrap(void)
|
|||||||
G_D12.independent_devices_enabled = !CommandlineArgFromName(Lit("no-d3d12-independent-devices")).exists;
|
G_D12.independent_devices_enabled = !CommandlineArgFromName(Lit("no-d3d12-independent-devices")).exists;
|
||||||
G_D12.validation_layer_enabled = CommandlineArgFromName(Lit("gpu-debug-validation")).exists;
|
G_D12.validation_layer_enabled = CommandlineArgFromName(Lit("gpu-debug-validation")).exists;
|
||||||
G_D12.debug_layer_enabled = G_D12.validation_layer_enabled || CommandlineArgFromName(Lit("gpu-debug")).exists;
|
G_D12.debug_layer_enabled = G_D12.validation_layer_enabled || CommandlineArgFromName(Lit("gpu-debug")).exists;
|
||||||
|
G_D12.events_enabled = IsDeveloperModeEnabled;
|
||||||
|
|
||||||
if (G_D12.independent_devices_enabled && IsRunningInWine())
|
if (G_D12.independent_devices_enabled && IsRunningInWine())
|
||||||
{
|
{
|
||||||
|
// NOTE: Independent devices only supported in newer versions of Proton, which just ignores them anyway
|
||||||
LogInfoF("Wine detected, disabling D3D12 independent devices");
|
LogInfoF("Wine detected, disabling D3D12 independent devices");
|
||||||
G_D12.independent_devices_enabled = 0;
|
G_D12.independent_devices_enabled = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfoF("D3D12 independent devices enabled: %F", FmtSint(G_D12.independent_devices_enabled));
|
LogInfoF("D3D12 independent devices enabled: %F", FmtSint(G_D12.independent_devices_enabled));
|
||||||
|
LogInfoF("D3D12 events enabled: %F", FmtSint(G_D12.events_enabled));
|
||||||
LogInfoF("D3D12 debug layer enabled: %F", FmtSint(G_D12.debug_layer_enabled));
|
LogInfoF("D3D12 debug layer enabled: %F", FmtSint(G_D12.debug_layer_enabled));
|
||||||
LogInfoF("D3D12 validation layer enabled: %F", FmtSint(G_D12.validation_layer_enabled));
|
LogInfoF("D3D12 validation layer enabled: %F", FmtSint(G_D12.validation_layer_enabled));
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- Load pix event runtime
|
||||||
|
|
||||||
|
if (G_D12.events_enabled)
|
||||||
|
{
|
||||||
|
HMODULE pix = LoadLibraryW(L"WinPixEventRuntime");
|
||||||
|
if (pix)
|
||||||
|
{
|
||||||
|
G_D12_PixBeginEventOnCommandList = (G_D12_PixBeginEventOnCommandListFunc *)GetProcAddress(pix, "PIXBeginEventOnCommandList");
|
||||||
|
G_D12_PixEndEventOnCommandList = (G_D12_PixEndEventOnCommandListFunc *)GetProcAddress(pix, "PIXEndEventOnCommandList");
|
||||||
|
G_D12_PixSetMarkerOnCommandList = (G_D12_PixSetMarkerOnCommandListFunc *)GetProcAddress(pix, "PIXSetMarkerOnCommandList");
|
||||||
|
if (!G_D12_PixBeginEventOnCommandList && !G_D12_PixEndEventOnCommandList && !G_D12_PixSetMarkerOnCommandList)
|
||||||
|
{
|
||||||
|
LogErrorF("Failed to retrieve pix procedures");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogInfoF("Pix enabled");
|
||||||
|
G_D12.pix_enabled = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogInfoF("Pix event runtime not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Initialize independent device factory with Agility SDK
|
//- Initialize independent device factory with Agility SDK
|
||||||
|
|
||||||
@ -32,11 +62,11 @@ void G_Bootstrap(void)
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Extract agility SDK
|
//- Extract agility SDK
|
||||||
|
|
||||||
String appdir = GetAppDirectory();
|
String libs_dir = GetLibsDirectory();
|
||||||
|
|
||||||
u32 sdk_ver_num = 619;
|
u32 sdk_ver_num = 619;
|
||||||
String sdk_ver_str = Lit("1.619.0");
|
String sdk_ver_str = Lit("1.619.0");
|
||||||
String sdk_dir_path = StringF(scratch.arena, "%Fd3d12/%F/", FmtString(appdir), FmtString(sdk_ver_str));
|
String sdk_dir_path = StringF(scratch.arena, "%Fd3d12/%F/", FmtString(libs_dir), FmtString(sdk_ver_str));
|
||||||
{
|
{
|
||||||
LogInfoF("D3D12 agility sdk path: \"%F\"", FmtString(sdk_dir_path));
|
LogInfoF("D3D12 agility sdk path: \"%F\"", FmtString(sdk_dir_path));
|
||||||
String core_path = StringF(scratch.arena, "%FD3D12Core.dll", FmtString(sdk_dir_path));
|
String core_path = StringF(scratch.arena, "%FD3D12Core.dll", FmtString(sdk_dir_path));
|
||||||
@ -48,9 +78,9 @@ void G_Bootstrap(void)
|
|||||||
ResourceKey layers_key = ResourceKeyFromStore(&G_D12_Resources, Lit("AgilitySDK/1.619.0/d3d12SDKLayers.dat"));
|
ResourceKey layers_key = ResourceKeyFromStore(&G_D12_Resources, Lit("AgilitySDK/1.619.0/d3d12SDKLayers.dat"));
|
||||||
String core_data = PLT_Decompress(scratch.arena, DataFromResource(core_key), PLT_CompressionLevel_3);
|
String core_data = PLT_Decompress(scratch.arena, DataFromResource(core_key), PLT_CompressionLevel_3);
|
||||||
String layers_data = PLT_Decompress(scratch.arena, DataFromResource(layers_key), PLT_CompressionLevel_3);
|
String layers_data = PLT_Decompress(scratch.arena, DataFromResource(layers_key), PLT_CompressionLevel_3);
|
||||||
PLT_MkDir(StringF(scratch.arena, "%Fd3d12/", FmtString(appdir)));
|
PLT_MkDir(StringF(scratch.arena, "%Fd3d12/", FmtString(libs_dir)));
|
||||||
PLT_MkDir(StringF(scratch.arena, "%Fd3d12/", FmtString(appdir)));
|
PLT_MkDir(StringF(scratch.arena, "%Fd3d12/", FmtString(libs_dir)));
|
||||||
PLT_MkDir(StringF(scratch.arena, "%Fd3d12/%F/", FmtString(appdir), FmtString(sdk_ver_str)));
|
PLT_MkDir(StringF(scratch.arena, "%Fd3d12/%F/", FmtString(libs_dir), FmtString(sdk_ver_str)));
|
||||||
{
|
{
|
||||||
PLT_File file = PLT_OpenFileWrite(core_path);
|
PLT_File file = PLT_OpenFileWrite(core_path);
|
||||||
PLT_WriteFile(file, core_data);
|
PLT_WriteFile(file, core_data);
|
||||||
@ -302,8 +332,8 @@ void G_Bootstrap(void)
|
|||||||
{
|
{
|
||||||
Panic(Lit("Failed to retrieve DXGI debug interface"));
|
Panic(Lit("Failed to retrieve DXGI debug interface"));
|
||||||
}
|
}
|
||||||
// IDXGIInfoQueue_SetBreakOnSeverity(dxgi_info, DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, 1);
|
IDXGIInfoQueue_SetBreakOnSeverity(dxgi_info, DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, 1);
|
||||||
// IDXGIInfoQueue_SetBreakOnSeverity(dxgi_info, DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, 1);
|
IDXGIInfoQueue_SetBreakOnSeverity(dxgi_info, DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,26 +618,16 @@ DXGI_FORMAT G_D12_DxgiFormatFromGpuFormat(G_Format format)
|
|||||||
return (DXGI_FORMAT)format;
|
return (DXGI_FORMAT)format;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D12_BARRIER_LAYOUT G_D12_BarrierLayoutFromUsageKind(G_QueueKind queue_kind, G_D12_TrackedUsageKind usage_kind)
|
D3D12_BARRIER_LAYOUT G_D12_CommonLayoutFromQueueKind(G_QueueKind queue_kind)
|
||||||
{
|
{
|
||||||
D3D12_BARRIER_LAYOUT untracked_layout;
|
D3D12_BARRIER_LAYOUT result = D3D12_BARRIER_LAYOUT_COMMON;
|
||||||
switch (queue_kind)
|
if (queue_kind == G_QueueKind_Direct)
|
||||||
{
|
{
|
||||||
default: untracked_layout = D3D12_BARRIER_LAYOUT_COMMON; break;
|
result = D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COMMON;
|
||||||
case G_QueueKind_Direct: untracked_layout = D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COMMON; break;
|
|
||||||
case G_QueueKind_AsyncCompute: untracked_layout = D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COMMON; break;
|
|
||||||
}
|
}
|
||||||
|
else if (queue_kind == G_QueueKind_AsyncCompute)
|
||||||
D3D12_BARRIER_LAYOUT result;
|
|
||||||
switch(usage_kind)
|
|
||||||
{
|
{
|
||||||
default:
|
result = D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COMMON;
|
||||||
case G_D12_TrackedUsageKind_Untracked: result = untracked_layout; break;
|
|
||||||
case G_D12_TrackedUsageKind_RenderTarget: result = D3D12_BARRIER_LAYOUT_RENDER_TARGET; break;
|
|
||||||
case G_D12_TrackedUsageKind_DepthStencilRead: result = D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_GENERIC_READ; break;
|
|
||||||
case G_D12_TrackedUsageKind_DepthStencilReadWrite: result = D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE; break;
|
|
||||||
case G_D12_TrackedUsageKind_MakeCommon: result = D3D12_BARRIER_LAYOUT_COMMON; break;
|
|
||||||
case G_D12_TrackedUsageKind_MakeExclusive: result = untracked_layout; break;
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -2077,6 +2097,9 @@ G_D12_StagingRegionNode *G_D12_PushStagingRegion(G_D12_CmdList *cl, u64 size)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Tracking
|
||||||
|
|
||||||
void G_D12_UpdateTrackedUsage(Arena *arena, G_D12_CmdBatch *batch, G_D12_Resource *resource, RngI32 mips, G_D12_TrackedUsageKind usage_kind)
|
void G_D12_UpdateTrackedUsage(Arena *arena, G_D12_CmdBatch *batch, G_D12_Resource *resource, RngI32 mips, G_D12_TrackedUsageKind usage_kind)
|
||||||
{
|
{
|
||||||
b32 should_track = !AnyBit(resource->d3d_desc.Flags, D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS);
|
b32 should_track = !AnyBit(resource->d3d_desc.Flags, D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS);
|
||||||
@ -2107,6 +2130,7 @@ void G_D12_UpdateTrackedUsage(Arena *arena, G_D12_CmdBatch *batch, G_D12_Resourc
|
|||||||
tmp = PushStruct(arena, G_D12_TrackedResourceNode);
|
tmp = PushStruct(arena, G_D12_TrackedResourceNode);
|
||||||
tmp->resource = resource;
|
tmp->resource = resource;
|
||||||
tmp->hash = hash;
|
tmp->hash = hash;
|
||||||
|
++batch->tracked_resources_count;
|
||||||
SllQueuePush(batch->first_tracked_resource, batch->last_tracked_resource, tmp);
|
SllQueuePush(batch->first_tracked_resource, batch->last_tracked_resource, tmp);
|
||||||
SllStackPushN(bin->first, tmp, next_in_bin);
|
SllStackPushN(bin->first, tmp, next_in_bin);
|
||||||
}
|
}
|
||||||
@ -2154,15 +2178,15 @@ void G_D12_UpdateTrackedUsage(Arena *arena, G_D12_CmdBatch *batch, G_D12_Resourc
|
|||||||
mip->usage = usage_kind;
|
mip->usage = usage_kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (usage_kind == G_D12_TrackedUsageKind_MakeExclusive)
|
if (usage_kind == G_D12_TrackedUsageKind_Acquire)
|
||||||
{
|
{
|
||||||
mip->prev_usage = G_D12_TrackedUsageKind_MakeCommon;
|
mip->prev_usage = G_D12_TrackedUsageKind_Release;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (usage_kind == G_D12_TrackedUsageKind_MakeCommon)
|
if (usage_kind == G_D12_TrackedUsageKind_Release)
|
||||||
{
|
{
|
||||||
mip->next_usage = G_D12_TrackedUsageKind_MakeCommon;
|
mip->next_usage = G_D12_TrackedUsageKind_Release;
|
||||||
}
|
}
|
||||||
if (prev_mip)
|
if (prev_mip)
|
||||||
{
|
{
|
||||||
@ -2179,6 +2203,109 @@ void G_D12_UpdateTrackedUsage(Arena *arena, G_D12_CmdBatch *batch, G_D12_Resourc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
G_D12_BarrierInfo G_D12_BarrierInfoFromBatch(G_D12_CmdBatch *batch, G_QueueKind queue_kind)
|
||||||
|
{
|
||||||
|
G_D12_BarrierInfo result = Zi;
|
||||||
|
|
||||||
|
if (batch->contains_compute_shader)
|
||||||
|
{
|
||||||
|
result.sync |= D3D12_BARRIER_SYNC_COMPUTE_SHADING;
|
||||||
|
result.access |= D3D12_BARRIER_ACCESS_UNORDERED_ACCESS | D3D12_BARRIER_ACCESS_SHADER_RESOURCE;
|
||||||
|
}
|
||||||
|
if (batch->contains_draw_shader)
|
||||||
|
{
|
||||||
|
result.sync |= D3D12_BARRIER_SYNC_VERTEX_SHADING | D3D12_BARRIER_SYNC_PIXEL_SHADING;
|
||||||
|
result.access |= D3D12_BARRIER_ACCESS_UNORDERED_ACCESS | D3D12_BARRIER_ACCESS_SHADER_RESOURCE;
|
||||||
|
}
|
||||||
|
if (batch->contains_indirect)
|
||||||
|
{
|
||||||
|
result.sync |= D3D12_BARRIER_SYNC_EXECUTE_INDIRECT;
|
||||||
|
result.access |= D3D12_BARRIER_ACCESS_INDIRECT_ARGUMENT;
|
||||||
|
}
|
||||||
|
if (batch->contains_rtv)
|
||||||
|
{
|
||||||
|
result.sync |= D3D12_BARRIER_SYNC_RENDER_TARGET;
|
||||||
|
result.access |= D3D12_BARRIER_ACCESS_RENDER_TARGET;
|
||||||
|
}
|
||||||
|
if (batch->contains_dsv_read)
|
||||||
|
{
|
||||||
|
result.sync |= D3D12_BARRIER_SYNC_DEPTH_STENCIL;
|
||||||
|
result.access |= D3D12_BARRIER_ACCESS_DEPTH_STENCIL_READ;
|
||||||
|
}
|
||||||
|
if (batch->contains_dsv_write)
|
||||||
|
{
|
||||||
|
result.sync |= D3D12_BARRIER_SYNC_DEPTH_STENCIL;
|
||||||
|
result.access |= D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE;
|
||||||
|
}
|
||||||
|
if (batch->contains_copy)
|
||||||
|
{
|
||||||
|
result.sync |= D3D12_BARRIER_SYNC_COPY;
|
||||||
|
result.access |= D3D12_BARRIER_ACCESS_COPY_DEST | D3D12_BARRIER_ACCESS_COPY_SOURCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_D12_BarrierInfo G_D12_BarrierInfoFromUsageKind(G_D12_TrackedUsageKind usage_kind, G_D12_Resource *resource, G_D12_BarrierInfo global, G_QueueKind queue_kind)
|
||||||
|
{
|
||||||
|
G_D12_BarrierInfo result = Zi;
|
||||||
|
|
||||||
|
{
|
||||||
|
if (usage_kind == G_D12_TrackedUsageKind_RenderTarget)
|
||||||
|
{
|
||||||
|
result.layout = D3D12_BARRIER_LAYOUT_RENDER_TARGET;
|
||||||
|
result.sync |= D3D12_BARRIER_SYNC_RENDER_TARGET;
|
||||||
|
result.access |= D3D12_BARRIER_ACCESS_RENDER_TARGET;
|
||||||
|
}
|
||||||
|
else if (usage_kind == G_D12_TrackedUsageKind_DepthStencilRead)
|
||||||
|
{
|
||||||
|
result.layout = D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_GENERIC_READ;
|
||||||
|
|
||||||
|
result.sync |= D3D12_BARRIER_SYNC_DEPTH_STENCIL;
|
||||||
|
result.sync |= (global.sync & D3D12_BARRIER_SYNC_COPY);
|
||||||
|
result.sync |= (global.sync & D3D12_BARRIER_SYNC_VERTEX_SHADING);
|
||||||
|
result.sync |= (global.sync & D3D12_BARRIER_SYNC_PIXEL_SHADING);
|
||||||
|
result.sync |= (global.sync & D3D12_BARRIER_SYNC_COMPUTE_SHADING);
|
||||||
|
|
||||||
|
result.access |= D3D12_BARRIER_ACCESS_DEPTH_STENCIL_READ;
|
||||||
|
result.access |= (global.access & D3D12_BARRIER_ACCESS_COPY_SOURCE);
|
||||||
|
result.access |= (global.access & D3D12_BARRIER_ACCESS_SHADER_RESOURCE);
|
||||||
|
}
|
||||||
|
else if (usage_kind == G_D12_TrackedUsageKind_DepthStencilReadWrite)
|
||||||
|
{
|
||||||
|
result.layout = D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE;
|
||||||
|
result.sync |= D3D12_BARRIER_SYNC_DEPTH_STENCIL;
|
||||||
|
result.access |= D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (usage_kind == G_D12_TrackedUsageKind_Release)
|
||||||
|
{
|
||||||
|
result.layout = D3D12_BARRIER_LAYOUT_COMMON;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.layout = G_D12_CommonLayoutFromQueueKind(queue_kind);
|
||||||
|
if (resource->d3d_desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS)
|
||||||
|
{
|
||||||
|
result.access |= (global.access & D3D12_BARRIER_ACCESS_UNORDERED_ACCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.sync |= D3D12_BARRIER_SYNC_VERTEX_SHADING;
|
||||||
|
result.sync |= D3D12_BARRIER_SYNC_PIXEL_SHADING;
|
||||||
|
result.sync |= D3D12_BARRIER_SYNC_COMPUTE_SHADING;
|
||||||
|
result.sync |= (global.sync & D3D12_BARRIER_SYNC_COPY);
|
||||||
|
|
||||||
|
result.access |= D3D12_BARRIER_ACCESS_SHADER_RESOURCE;
|
||||||
|
result.access |= (global.access & D3D12_BARRIER_ACCESS_COPY_SOURCE);
|
||||||
|
result.access |= (global.access & D3D12_BARRIER_ACCESS_COPY_DEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ @hookimpl Command
|
//~ @hookimpl Command
|
||||||
|
|
||||||
@ -2259,7 +2386,11 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
|
|||||||
G_D12_Cmd *cmd = &cmds[cmd_idx];
|
G_D12_Cmd *cmd = &cmds[cmd_idx];
|
||||||
G_D12_CmdKind cmd_kind = cmd->kind;
|
G_D12_CmdKind cmd_kind = cmd->kind;
|
||||||
|
|
||||||
if (cmd_kind != G_D12_CmdKind_Barrier && cmd_kind != G_D12_CmdKind_Constant)
|
if (
|
||||||
|
cmd_kind != G_D12_CmdKind_Barrier &&
|
||||||
|
cmd_kind != G_D12_CmdKind_Constant &&
|
||||||
|
cmd_kind != G_D12_CmdKind_Event
|
||||||
|
)
|
||||||
{
|
{
|
||||||
batch->contains_hazard = 1;
|
batch->contains_hazard = 1;
|
||||||
}
|
}
|
||||||
@ -2305,7 +2436,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
|
|||||||
}
|
}
|
||||||
else if (is_dsv)
|
else if (is_dsv)
|
||||||
{
|
{
|
||||||
batch->contains_dsv = 1;
|
batch->contains_dsv_write = 1;
|
||||||
G_D12_UpdateTrackedUsage(scratch.arena, batch, resource, RNGI32(0, resource->texture_mips - 1), G_D12_TrackedUsageKind_DepthStencilReadWrite);
|
G_D12_UpdateTrackedUsage(scratch.arena, batch, resource, RNGI32(0, resource->texture_mips - 1), G_D12_TrackedUsageKind_DepthStencilReadWrite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2327,13 +2458,13 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
|
|||||||
G_D12_Resource *resource = cmd->barrier.resource;
|
G_D12_Resource *resource = cmd->barrier.resource;
|
||||||
if (resource)
|
if (resource)
|
||||||
{
|
{
|
||||||
if (cmd->barrier.to_exclusive)
|
if (cmd->barrier.acquire)
|
||||||
{
|
{
|
||||||
G_D12_UpdateTrackedUsage(scratch.arena, batch, resource, RNGI32(0, resource->texture_mips - 1), G_D12_TrackedUsageKind_MakeExclusive);
|
G_D12_UpdateTrackedUsage(scratch.arena, batch, resource, RNGI32(0, resource->texture_mips - 1), G_D12_TrackedUsageKind_Acquire);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
G_D12_UpdateTrackedUsage(scratch.arena, batch, resource, RNGI32(0, resource->texture_mips - 1), G_D12_TrackedUsageKind_MakeCommon);
|
G_D12_UpdateTrackedUsage(scratch.arena, batch, resource, RNGI32(0, resource->texture_mips - 1), G_D12_TrackedUsageKind_Release);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2467,32 +2598,26 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
|
|||||||
u64 texture_barriers_count = batch->transitions_count;
|
u64 texture_barriers_count = batch->transitions_count;
|
||||||
D3D12_TEXTURE_BARRIER *texture_barriers = PushStructs(scratch.arena, D3D12_TEXTURE_BARRIER, texture_barriers_count);
|
D3D12_TEXTURE_BARRIER *texture_barriers = PushStructs(scratch.arena, D3D12_TEXTURE_BARRIER, texture_barriers_count);
|
||||||
|
|
||||||
// TODO: Granular
|
|
||||||
D3D12_BARRIER_SYNC sync_before = D3D12_BARRIER_SYNC_ALL;
|
|
||||||
D3D12_BARRIER_SYNC sync_after = D3D12_BARRIER_SYNC_ALL;
|
|
||||||
D3D12_BARRIER_ACCESS access_before = D3D12_BARRIER_ACCESS_COMMON;
|
|
||||||
D3D12_BARRIER_ACCESS access_after = D3D12_BARRIER_ACCESS_COMMON;
|
|
||||||
|
|
||||||
b32 is_transition_batch = batch->cmds_count == 0;
|
b32 is_transition_batch = batch->cmds_count == 0;
|
||||||
|
|
||||||
|
G_D12_BarrierInfo global_after = G_D12_BarrierInfoFromBatch(batch, queue_kind);
|
||||||
|
G_D12_BarrierInfo global_before = Zi;
|
||||||
|
if (batch->prev)
|
||||||
|
{
|
||||||
|
global_before = G_D12_BarrierInfoFromBatch(batch->prev, queue_kind);
|
||||||
|
}
|
||||||
|
|
||||||
if (batch == first_batch)
|
if (batch == first_batch)
|
||||||
{
|
{
|
||||||
is_transition_batch = 1;
|
is_transition_batch = 1;
|
||||||
sync_before = D3D12_BARRIER_SYNC_NONE;
|
global_before.sync = D3D12_BARRIER_SYNC_NONE;
|
||||||
access_before = D3D12_BARRIER_ACCESS_NO_ACCESS;
|
global_before.access = D3D12_BARRIER_ACCESS_NO_ACCESS;
|
||||||
}
|
}
|
||||||
if (batch == last_batch)
|
if (batch == last_batch)
|
||||||
{
|
{
|
||||||
is_transition_batch = 1;
|
is_transition_batch = 1;
|
||||||
sync_after = D3D12_BARRIER_SYNC_NONE;
|
global_after.sync = D3D12_BARRIER_SYNC_NONE;
|
||||||
access_after = D3D12_BARRIER_ACCESS_NO_ACCESS;
|
global_after.access = D3D12_BARRIER_ACCESS_NO_ACCESS;
|
||||||
}
|
|
||||||
|
|
||||||
D3D12_GLOBAL_BARRIER global_barrier = Zi;
|
|
||||||
{
|
|
||||||
global_barrier.SyncBefore = sync_before;
|
|
||||||
global_barrier.SyncAfter = sync_after;
|
|
||||||
global_barrier.AccessBefore = access_before;
|
|
||||||
global_barrier.AccessAfter = access_after;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push transition barriers
|
// Push transition barriers
|
||||||
@ -2501,27 +2626,39 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
|
|||||||
for (G_D12_TransitionNode *tn = batch->first_transition; tn; tn = tn->next)
|
for (G_D12_TransitionNode *tn = batch->first_transition; tn; tn = tn->next)
|
||||||
{
|
{
|
||||||
G_D12_Resource *resource = tn->resource;
|
G_D12_Resource *resource = tn->resource;
|
||||||
D3D12_BARRIER_LAYOUT old_layout = G_D12_BarrierLayoutFromUsageKind(queue_kind, tn->old);
|
G_D12_TrackedUsageKind old_usage = tn->old;
|
||||||
D3D12_BARRIER_LAYOUT new_layout = G_D12_BarrierLayoutFromUsageKind(queue_kind, tn->new);
|
G_D12_TrackedUsageKind new_usage = tn->new;
|
||||||
|
G_D12_BarrierInfo resource_before = G_D12_BarrierInfoFromUsageKind(old_usage, resource, global_before, queue_kind);
|
||||||
|
G_D12_BarrierInfo resource_after = G_D12_BarrierInfoFromUsageKind(new_usage, resource, global_after, queue_kind);
|
||||||
|
// D3D12_BARRIER_LAYOUT layout_before = G_D12_BarrierLayoutFromUsageKind(old_usage, queue_kind);
|
||||||
|
// D3D12_BARRIER_LAYOUT layout_after = G_D12_BarrierLayoutFromUsageKind(new_usage, queue_kind);
|
||||||
|
|
||||||
D3D12_TEXTURE_BARRIER *barrier = &texture_barriers[barrier_idx];
|
D3D12_TEXTURE_BARRIER *barrier = &texture_barriers[barrier_idx];
|
||||||
barrier->SyncBefore = sync_before;
|
{
|
||||||
barrier->SyncAfter = sync_after;
|
barrier->SyncBefore = resource_before.sync;
|
||||||
barrier->AccessBefore = access_before;
|
barrier->SyncAfter = resource_after.sync;
|
||||||
barrier->AccessAfter = access_after;
|
barrier->AccessBefore = resource_before.access;
|
||||||
barrier->LayoutBefore = old_layout;
|
barrier->AccessAfter = resource_after.access;
|
||||||
barrier->LayoutAfter = new_layout;
|
barrier->LayoutBefore = resource_before.layout;
|
||||||
barrier->pResource = resource->d3d_resource;
|
barrier->LayoutAfter = resource_after.layout;
|
||||||
barrier->Subresources.NumArraySlices = 1;
|
barrier->pResource = resource->d3d_resource;
|
||||||
barrier->Subresources.NumPlanes = 1;
|
barrier->Subresources.NumArraySlices = 1;
|
||||||
barrier->Subresources.IndexOrFirstMipLevel = tn->mips.min;
|
barrier->Subresources.NumPlanes = 1;
|
||||||
barrier->Subresources.NumMipLevels = tn->mips.max - tn->mips.min + 1;
|
barrier->Subresources.IndexOrFirstMipLevel = tn->mips.min;
|
||||||
|
barrier->Subresources.NumMipLevels = tn->mips.max - tn->mips.min + 1;
|
||||||
|
}
|
||||||
++barrier_idx;
|
++barrier_idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dispatch barriers
|
// Dispatch barriers
|
||||||
{
|
{
|
||||||
|
D3D12_GLOBAL_BARRIER global_barrier = Zi;
|
||||||
|
global_barrier.SyncBefore = global_before.sync;
|
||||||
|
global_barrier.SyncAfter = global_before.sync;
|
||||||
|
global_barrier.AccessBefore = global_before.access;
|
||||||
|
global_barrier.AccessAfter = global_before.access;
|
||||||
|
|
||||||
u32 barrier_groups_count = 0;
|
u32 barrier_groups_count = 0;
|
||||||
D3D12_BARRIER_GROUP barrier_groups[2] = Zi;
|
D3D12_BARRIER_GROUP barrier_groups[2] = Zi;
|
||||||
if (!is_transition_batch)
|
if (!is_transition_batch)
|
||||||
@ -3012,6 +3149,51 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
|
|||||||
return completion_target;
|
return completion_target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- Constant
|
||||||
|
|
||||||
|
void G_SetConstantEx(G_CommandListHandle cl_handle, i32 slot, void *src_32bit, u32 size)
|
||||||
|
{
|
||||||
|
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
|
||||||
|
G_D12_Cmd *cmd = G_D12_PushCmd(cl);
|
||||||
|
cmd->kind = G_D12_CmdKind_Constant;
|
||||||
|
cmd->constant.slot = slot;
|
||||||
|
CopyBytes(&cmd->constant.value, src_32bit, MinU32(size, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Barrier
|
||||||
|
|
||||||
|
void G_Sync(G_CommandListHandle cl_handle)
|
||||||
|
{
|
||||||
|
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
|
||||||
|
G_D12_Cmd *cmd = G_D12_PushCmd(cl);
|
||||||
|
cmd->kind = G_D12_CmdKind_Barrier;
|
||||||
|
}
|
||||||
|
|
||||||
|
void G_SyncLayout(G_CommandListHandle cl_handle, G_ResourceHandle resource_handle, G_Layout layout)
|
||||||
|
{
|
||||||
|
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
|
||||||
|
G_D12_Cmd *cmd = G_D12_PushCmd(cl);
|
||||||
|
cmd->kind = G_D12_CmdKind_Barrier;
|
||||||
|
cmd->barrier.resource = G_D12_ResourceFromHandle(resource_handle);
|
||||||
|
cmd->barrier.acquire = layout == G_Layout_Exclusive;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Event
|
||||||
|
|
||||||
|
void G_BeginEvent(G_CommandListHandle cl_handle, String name)
|
||||||
|
{
|
||||||
|
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
|
||||||
|
G_D12_Cmd *cmd = G_D12_PushCmd(cl);
|
||||||
|
cmd->kind = G_D12_CmdKind_Event;
|
||||||
|
}
|
||||||
|
|
||||||
|
void G_EndEvent(G_CommandListHandle cl_handle)
|
||||||
|
{
|
||||||
|
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
|
||||||
|
G_D12_Cmd *cmd = G_D12_PushCmd(cl);
|
||||||
|
cmd->kind = G_D12_CmdKind_Event;
|
||||||
|
}
|
||||||
|
|
||||||
//- Cpu -> Gpu staged copy
|
//- Cpu -> Gpu staged copy
|
||||||
|
|
||||||
void G_CopyCpuToBuffer(G_CommandListHandle cl_handle, G_ResourceHandle dst_handle, u64 dst_offset, void *src, RngU64 src_copy_range)
|
void G_CopyCpuToBuffer(G_CommandListHandle cl_handle, G_ResourceHandle dst_handle, u64 dst_offset, void *src, RngU64 src_copy_range)
|
||||||
@ -3217,35 +3399,6 @@ void G_CopyTextureToBuffer(G_CommandListHandle cl_handle, G_ResourceHandle dst_h
|
|||||||
Assert(0);
|
Assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Constant
|
|
||||||
|
|
||||||
void G_SetConstantEx(G_CommandListHandle cl_handle, i32 slot, void *src_32bit, u32 size)
|
|
||||||
{
|
|
||||||
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
|
|
||||||
G_D12_Cmd *cmd = G_D12_PushCmd(cl);
|
|
||||||
cmd->kind = G_D12_CmdKind_Constant;
|
|
||||||
cmd->constant.slot = slot;
|
|
||||||
CopyBytes(&cmd->constant.value, src_32bit, MinU32(size, 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Barrier
|
|
||||||
|
|
||||||
void G_Sync(G_CommandListHandle cl_handle)
|
|
||||||
{
|
|
||||||
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
|
|
||||||
G_D12_Cmd *cmd = G_D12_PushCmd(cl);
|
|
||||||
cmd->kind = G_D12_CmdKind_Barrier;
|
|
||||||
}
|
|
||||||
|
|
||||||
void G_SyncLayout(G_CommandListHandle cl_handle, G_ResourceHandle resource_handle, G_Layout layout)
|
|
||||||
{
|
|
||||||
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
|
|
||||||
G_D12_Cmd *cmd = G_D12_PushCmd(cl);
|
|
||||||
cmd->kind = G_D12_CmdKind_Barrier;
|
|
||||||
cmd->barrier.resource = G_D12_ResourceFromHandle(resource_handle);
|
|
||||||
cmd->barrier.to_exclusive = layout == G_Layout_Exclusive;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Compute
|
//- Compute
|
||||||
|
|
||||||
void G_ComputeEx(G_CommandListHandle cl_handle, ComputeShaderDesc cs, Vec3I32 threads)
|
void G_ComputeEx(G_CommandListHandle cl_handle, ComputeShaderDesc cs, Vec3I32 threads)
|
||||||
@ -3477,7 +3630,7 @@ G_ResourceHandle G_PrepareBackbuffer(G_SwapchainHandle swapchain_handle, G_Forma
|
|||||||
desc.Height = size.y;
|
desc.Height = size.y;
|
||||||
desc.SampleDesc.Count = 1;
|
desc.SampleDesc.Count = 1;
|
||||||
desc.SampleDesc.Quality = 0;
|
desc.SampleDesc.Quality = 0;
|
||||||
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT;
|
||||||
desc.BufferCount = G_D12_SwapchainBufferCount;
|
desc.BufferCount = G_D12_SwapchainBufferCount;
|
||||||
desc.Scaling = DXGI_SCALING_NONE;
|
desc.Scaling = DXGI_SCALING_NONE;
|
||||||
desc.Flags = G_D12_SwapchainFlags;
|
desc.Flags = G_D12_SwapchainFlags;
|
||||||
|
|||||||
@ -10,6 +10,14 @@
|
|||||||
#pragma comment(lib, "d3d12")
|
#pragma comment(lib, "d3d12")
|
||||||
#pragma comment(lib, "dxgi")
|
#pragma comment(lib, "dxgi")
|
||||||
|
|
||||||
|
//- Pix
|
||||||
|
typedef void(WINAPI* G_D12_PixBeginEventOnCommandListFunc)(ID3D12GraphicsCommandList* commandList, UINT64 color, _In_ PCSTR formatString);
|
||||||
|
typedef void(WINAPI* G_D12_PixEndEventOnCommandListFunc)(ID3D12GraphicsCommandList* commandList);
|
||||||
|
typedef void(WINAPI* G_D12_PixSetMarkerOnCommandListFunc)(ID3D12GraphicsCommandList* commandList, UINT64 color, _In_ PCSTR formatString);
|
||||||
|
G_D12_PixBeginEventOnCommandListFunc *G_D12_PixBeginEventOnCommandList;
|
||||||
|
G_D12_PixEndEventOnCommandListFunc *G_D12_PixEndEventOnCommandList;
|
||||||
|
G_D12_PixSetMarkerOnCommandListFunc *G_D12_PixSetMarkerOnCommandList;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Tweakable definitions
|
//~ Tweakable definitions
|
||||||
|
|
||||||
@ -300,8 +308,9 @@ Struct(G_D12_ReleasableList)
|
|||||||
Enum(G_D12_CmdKind)
|
Enum(G_D12_CmdKind)
|
||||||
{
|
{
|
||||||
G_D12_CmdKind_None,
|
G_D12_CmdKind_None,
|
||||||
G_D12_CmdKind_Barrier,
|
|
||||||
G_D12_CmdKind_Constant,
|
G_D12_CmdKind_Constant,
|
||||||
|
G_D12_CmdKind_Barrier,
|
||||||
|
G_D12_CmdKind_Event,
|
||||||
G_D12_CmdKind_CopyBytes,
|
G_D12_CmdKind_CopyBytes,
|
||||||
G_D12_CmdKind_CopyTexels,
|
G_D12_CmdKind_CopyTexels,
|
||||||
G_D12_CmdKind_Compute,
|
G_D12_CmdKind_Compute,
|
||||||
@ -324,7 +333,7 @@ Struct(G_D12_Cmd)
|
|||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
G_D12_Resource *resource;
|
G_D12_Resource *resource;
|
||||||
b32 to_exclusive;
|
b32 acquire;
|
||||||
} barrier;
|
} barrier;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
@ -411,11 +420,11 @@ Struct(G_D12_CmdList)
|
|||||||
Enum(G_D12_TrackedUsageKind)
|
Enum(G_D12_TrackedUsageKind)
|
||||||
{
|
{
|
||||||
G_D12_TrackedUsageKind_Untracked,
|
G_D12_TrackedUsageKind_Untracked,
|
||||||
G_D12_TrackedUsageKind_MakeExclusive,
|
G_D12_TrackedUsageKind_Acquire,
|
||||||
G_D12_TrackedUsageKind_DepthStencilRead,
|
G_D12_TrackedUsageKind_DepthStencilRead,
|
||||||
G_D12_TrackedUsageKind_DepthStencilReadWrite,
|
G_D12_TrackedUsageKind_DepthStencilReadWrite,
|
||||||
G_D12_TrackedUsageKind_RenderTarget,
|
G_D12_TrackedUsageKind_RenderTarget,
|
||||||
G_D12_TrackedUsageKind_MakeCommon,
|
G_D12_TrackedUsageKind_Release,
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(G_D12_TransitionNode)
|
Struct(G_D12_TransitionNode)
|
||||||
@ -456,6 +465,13 @@ Struct(G_D12_BatchedCmdNode)
|
|||||||
G_D12_Cmd *cmd;
|
G_D12_Cmd *cmd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Struct(G_D12_BarrierInfo)
|
||||||
|
{
|
||||||
|
D3D12_BARRIER_SYNC sync;
|
||||||
|
D3D12_BARRIER_ACCESS access;
|
||||||
|
D3D12_BARRIER_LAYOUT layout;
|
||||||
|
};
|
||||||
|
|
||||||
Struct(G_D12_CmdBatch)
|
Struct(G_D12_CmdBatch)
|
||||||
{
|
{
|
||||||
G_D12_CmdBatch *next;
|
G_D12_CmdBatch *next;
|
||||||
@ -478,7 +494,8 @@ Struct(G_D12_CmdBatch)
|
|||||||
b32 contains_compute_shader;
|
b32 contains_compute_shader;
|
||||||
b32 contains_draw_shader;
|
b32 contains_draw_shader;
|
||||||
b32 contains_rtv;
|
b32 contains_rtv;
|
||||||
b32 contains_dsv;
|
b32 contains_dsv_read;
|
||||||
|
b32 contains_dsv_write;
|
||||||
b32 contains_indirect;
|
b32 contains_indirect;
|
||||||
b32 contains_copy;
|
b32 contains_copy;
|
||||||
};
|
};
|
||||||
@ -517,6 +534,8 @@ Struct(G_D12_Ctx)
|
|||||||
b32 independent_devices_enabled;
|
b32 independent_devices_enabled;
|
||||||
b32 debug_layer_enabled;
|
b32 debug_layer_enabled;
|
||||||
b32 validation_layer_enabled;
|
b32 validation_layer_enabled;
|
||||||
|
b32 events_enabled;
|
||||||
|
b32 pix_enabled;
|
||||||
|
|
||||||
// Stats
|
// Stats
|
||||||
Atomic64 arenas_count;
|
Atomic64 arenas_count;
|
||||||
@ -591,7 +610,7 @@ G_D12_Resource *G_D12_ResourceFromHandle(G_ResourceHandle handle);
|
|||||||
G_D12_Swapchain *G_D12_SwapchainFromHandle(G_SwapchainHandle handle);
|
G_D12_Swapchain *G_D12_SwapchainFromHandle(G_SwapchainHandle handle);
|
||||||
|
|
||||||
DXGI_FORMAT G_D12_DxgiFormatFromGpuFormat(G_Format format);
|
DXGI_FORMAT G_D12_DxgiFormatFromGpuFormat(G_Format format);
|
||||||
D3D12_BARRIER_LAYOUT G_D12_BarrierLayoutFromUsageKind(G_QueueKind queue_kind, G_D12_TrackedUsageKind usage_kind);
|
D3D12_BARRIER_LAYOUT G_D12_CommonLayoutFromQueueKind(G_QueueKind queue_kind);
|
||||||
|
|
||||||
void G_D12_InitRtv(G_D12_Resource *resource, D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle, i32 mip);
|
void G_D12_InitRtv(G_D12_Resource *resource, D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle, i32 mip);
|
||||||
|
|
||||||
@ -632,7 +651,13 @@ G_D12_Descriptor *G_D12_PushDescriptor(G_D12_Arena *gpu_arena, G_D12_DescriptorH
|
|||||||
G_D12_Cmd *G_D12_PushCmd(G_D12_CmdList *cl);
|
G_D12_Cmd *G_D12_PushCmd(G_D12_CmdList *cl);
|
||||||
G_D12_Cmd *G_D12_PushConstCmd(G_D12_CmdList *cl, i32 slot, void *v);
|
G_D12_Cmd *G_D12_PushConstCmd(G_D12_CmdList *cl, i32 slot, void *v);
|
||||||
G_D12_StagingRegionNode *G_D12_PushStagingRegion(G_D12_CmdList *cl, u64 size);
|
G_D12_StagingRegionNode *G_D12_PushStagingRegion(G_D12_CmdList *cl, u64 size);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Tracking
|
||||||
|
|
||||||
void G_D12_UpdateTrackedUsage(Arena *arena, G_D12_CmdBatch *batch, G_D12_Resource *resource, RngI32 mips, G_D12_TrackedUsageKind usage_kind);
|
void G_D12_UpdateTrackedUsage(Arena *arena, G_D12_CmdBatch *batch, G_D12_Resource *resource, RngI32 mips, G_D12_TrackedUsageKind usage_kind);
|
||||||
|
G_D12_BarrierInfo G_D12_BarrierInfoFromBatch(G_D12_CmdBatch *batch, G_QueueKind queue_kind);
|
||||||
|
G_D12_BarrierInfo G_D12_BarrierInfoFromUsageKind(G_D12_TrackedUsageKind usage_kind, G_D12_Resource *resource, G_D12_BarrierInfo global, G_QueueKind queue_kind);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Debug
|
//~ Debug
|
||||||
|
|||||||
@ -1,31 +1,3 @@
|
|||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Win32 helpers
|
|
||||||
|
|
||||||
String W32_StringFromError(Arena *arena, DWORD err)
|
|
||||||
{
|
|
||||||
String result = Zi;
|
|
||||||
char *msg_cstr = 0;
|
|
||||||
i64 len = FormatMessageA(
|
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
||||||
0,
|
|
||||||
err,
|
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
||||||
(LPSTR)&msg_cstr,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
if (len > 0)
|
|
||||||
{
|
|
||||||
result = PushString(arena, TrimWhitespace(StringFromCstr(msg_cstr, len)));
|
|
||||||
LocalFree(msg_cstr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = StringF(arena, "Unknown win32 error - %F", FmtHex(err));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ @hookimpl Bootstrap
|
//~ @hookimpl Bootstrap
|
||||||
|
|
||||||
|
|||||||
@ -3,8 +3,3 @@
|
|||||||
|
|
||||||
#pragma comment(lib, "kernel32")
|
#pragma comment(lib, "kernel32")
|
||||||
#pragma comment(lib, "user32")
|
#pragma comment(lib, "user32")
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Win32 helpers
|
|
||||||
|
|
||||||
String W32_StringFromError(Arena *arena, DWORD err);
|
|
||||||
|
|||||||
@ -4843,10 +4843,10 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
{
|
{
|
||||||
max = 5;
|
max = 5;
|
||||||
}
|
}
|
||||||
LogEventsArray logs = GetLogEvents();
|
LogEventsArray log_events = GetLogEvents();
|
||||||
for (u64 i = logs.count; i-- > 0 && display_count < max && !done;)
|
for (u64 i = log_events.count; i-- > 0 && display_count < max && !done;)
|
||||||
{
|
{
|
||||||
LogEvent ev = logs.logs[i];
|
LogEvent ev = log_events.events[i];
|
||||||
if (ev.time_ns > (frame->time_ns - max_time_ns))
|
if (ev.time_ns > (frame->time_ns - max_time_ns))
|
||||||
{
|
{
|
||||||
if (ev.level <= console_level)
|
if (ev.level <= console_level)
|
||||||
@ -5279,6 +5279,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Initialization pass
|
//- Initialization pass
|
||||||
|
|
||||||
|
G_BeginEvent(cl, Lit("Testing"));
|
||||||
{
|
{
|
||||||
// Prepare shade
|
// Prepare shade
|
||||||
G_Compute2D(cl, V_PrepareShadeCS, frame->shade_dims);
|
G_Compute2D(cl, V_PrepareShadeCS, frame->shade_dims);
|
||||||
@ -5323,6 +5324,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
|
|
||||||
G_Sync(cl);
|
G_Sync(cl);
|
||||||
}
|
}
|
||||||
|
G_EndEvent(cl);
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Quads & emitters pass
|
//- Quads & emitters pass
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user