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
|
||||
StringList GetRawCommandline(void);
|
||||
String GetAppName(void);
|
||||
String GetEngineDirectory(void);
|
||||
String GetLibsDirectory(void);
|
||||
String GetAppDirectory(void);
|
||||
void Echo(String msg);
|
||||
b32 Panic(String msg);
|
||||
|
||||
@ -18,7 +18,7 @@ Struct(LogEvent)
|
||||
Struct(LogEventsArray)
|
||||
{
|
||||
u64 count;
|
||||
LogEvent *logs;
|
||||
LogEvent *events;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -45,44 +45,6 @@ Struct(LogEventsArray)
|
||||
#define LogLevel_Trace 6
|
||||
#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
|
||||
|
||||
|
||||
@ -48,6 +48,21 @@ String GetAppName(void)
|
||||
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)
|
||||
{
|
||||
HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
@ -233,11 +248,6 @@ void SleepSeconds(f64 seconds)
|
||||
}
|
||||
}
|
||||
|
||||
String GetAppDirectory(void)
|
||||
{
|
||||
return W32.appdir_path;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ @hookimpl Swap
|
||||
|
||||
@ -323,89 +333,107 @@ void ExitNow(i32 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
|
||||
|
||||
void W32_BootstrapLogs(void)
|
||||
void W32_LogEventToFile(LogEvent *ev, HANDLE file)
|
||||
{
|
||||
Arena *perm = PermArena();
|
||||
W32.logs_arena = AcquireArena(Gibi(64));
|
||||
W32.log_msgs_arena = AcquireArena(Gibi(64));
|
||||
W32.readable_log_events = ArenaNext(W32.logs_arena, LogEvent);
|
||||
String logfile_path = StringF(perm, "%F/log.log", FmtString(GetAppDirectory()));
|
||||
wchar_t *path_wstr = WstrFromString(perm, logfile_path);
|
||||
W32.logfile = CreateFileW(
|
||||
path_wstr,
|
||||
FILE_APPEND_DATA,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
0,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
0
|
||||
);
|
||||
Atomic32Set(&W32.logs_initialized, 1);
|
||||
LogInfoF("Log file path: %F", FmtString(logfile_path));
|
||||
Struct(LogLevelSettings)
|
||||
{
|
||||
String shorthand;
|
||||
};
|
||||
PERSIST Readonly LogLevelSettings level_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") },
|
||||
};
|
||||
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
{
|
||||
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)
|
||||
{
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
if (Atomic32Fetch(&W32.logs_initialized))
|
||||
level = ClampI32(level, 0, LogLevel_COUNT - 1);
|
||||
|
||||
DateTime datetime = LocalDateTime();
|
||||
i64 now_ns = TimeNs();
|
||||
i32 thread_id = GetCurrentThreadId();
|
||||
|
||||
LogEvent *ev = 0;
|
||||
LockTicketMutex(&W32.logs_tm);
|
||||
{
|
||||
LogLevelSettings settings = log_settings[level];
|
||||
if (level < 0 || level >= LogLevel_COUNT)
|
||||
{
|
||||
Panic(Lit("Invalid log level"));
|
||||
}
|
||||
|
||||
DateTime datetime = LocalDateTime();
|
||||
i64 now_ns = TimeNs();
|
||||
i32 thread_id = GetCurrentThreadId();
|
||||
|
||||
// TODO: Log asynchronously
|
||||
|
||||
//- Log message to file
|
||||
{
|
||||
String shorthand = settings.shorthand;
|
||||
String msg_formatted = StringF(
|
||||
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);
|
||||
// Get staged data
|
||||
ev = PushStruct(W32.logs_arena, LogEvent);
|
||||
ev->msg = PushString(W32.log_events_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);
|
||||
|
||||
if (W32.logfile)
|
||||
{
|
||||
W32_LogEventToFile(ev, W32.logfile);
|
||||
}
|
||||
EndScratch(scratch);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -415,7 +443,7 @@ void W32_Log(i32 level, String msg)
|
||||
// immediately writing to log file.
|
||||
void LogPanic(String msg)
|
||||
{
|
||||
if (Atomic32Fetch(&W32.logs_initialized))
|
||||
if (W32.logfile)
|
||||
{
|
||||
String beg = Lit("******** PANICKING ********\n");
|
||||
String end = Lit("\n***************************\n");
|
||||
@ -432,18 +460,15 @@ void Log_(i32 level, String msg)
|
||||
|
||||
void LogF_(i32 level, String fmt, ...)
|
||||
{
|
||||
if (Atomic32Fetch(&W32.logs_initialized))
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
{
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
{
|
||||
String msg = FormatString(scratch.arena, fmt, FmtArgsFromVaList(scratch.arena, args));
|
||||
W32_Log(level, msg);
|
||||
}
|
||||
va_end(args);
|
||||
EndScratch(scratch);
|
||||
String msg = FormatString(scratch.arena, fmt, FmtArgsFromVaList(scratch.arena, args));
|
||||
W32_Log(level, msg);
|
||||
}
|
||||
va_end(args);
|
||||
EndScratch(scratch);
|
||||
}
|
||||
|
||||
LogEventsArray GetLogEvents(void)
|
||||
@ -452,7 +477,7 @@ LogEventsArray GetLogEvents(void)
|
||||
result.count = Atomic64Fetch(&W32.readable_logs_count);
|
||||
if (result.count > 0)
|
||||
{
|
||||
result.logs = W32.readable_log_events;
|
||||
result.events = W32.readable_log_events;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -498,6 +523,11 @@ i32 W32_Main(void)
|
||||
// Query system 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
|
||||
W32_InitCurrentThread(Lit("Main"));
|
||||
|
||||
@ -534,96 +564,141 @@ i32 W32_Main(void)
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//- Bootstrap
|
||||
//- Bootstrap tweak vars
|
||||
|
||||
// Bootstrap tweak vars
|
||||
BootstrapTweakVars();
|
||||
|
||||
// Bootstrap command line
|
||||
//////////////////////////////
|
||||
//- Bootstrap command line
|
||||
|
||||
BootstrapCmdline();
|
||||
|
||||
// Init app directory
|
||||
String appdir_error = Zi;
|
||||
{
|
||||
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;
|
||||
//////////////////////////////
|
||||
//- Initialize app directories
|
||||
|
||||
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))
|
||||
{
|
||||
Panic(Lit("Failed to locate AppData directory"));
|
||||
Panic(Lit("Failed to locate AppData/Local directory"));
|
||||
}
|
||||
appdir_path = StringFromWstrNoLimit(perm, path_wstr);
|
||||
CoTaskMemFree(path_wstr);
|
||||
appdir_path = PathFromString(perm, StringF(perm, "%F\\Cabin\\%F\\", FmtString(appdir_path), FmtString(app_name)), '/');
|
||||
appdata_path = PathFromString(perm, StringFromWstrNoLimit(perm, appdata_path_wstr), '/');
|
||||
CoTaskMemFree(appdata_path_wstr);
|
||||
}
|
||||
// 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);
|
||||
i32 err_code = SHCreateDirectoryExW(0, path_wstr, 0);
|
||||
String err = StringF(perm, "Error code %F", FmtSint(err_code));
|
||||
switch (err_code)
|
||||
i32 err = SHCreateDirectoryExW(0, path_wstr, 0);
|
||||
if (err != ERROR_SUCCESS && err != ERROR_ALREADY_EXISTS && err != ERROR_FILE_EXISTS)
|
||||
{
|
||||
default: break;
|
||||
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(
|
||||
String msg = StringF(
|
||||
perm,
|
||||
"Failed to initialize app directory at \"%F\": %F",
|
||||
FmtString(path),
|
||||
FmtString(err)
|
||||
FmtString(W32_StringFromError(perm, err))
|
||||
);
|
||||
wchar_t *msg_wstr = WstrFromString(perm, appdir_error);
|
||||
MessageBoxExW(0, msg_wstr, L"Warning", MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST, 0);
|
||||
LogError(msg);
|
||||
MessageBoxExW(0, WstrFromString(perm, msg), L"Warning", MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST, 0);
|
||||
}
|
||||
}
|
||||
W32.appdir_path = appdir_path;
|
||||
}
|
||||
|
||||
// Bootstrap log system
|
||||
W32_BootstrapLogs();
|
||||
// Initialize libs dir
|
||||
{
|
||||
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));
|
||||
if (W32.wine_version.len > 0)
|
||||
{
|
||||
LogInfoF("Wine version: \"%F\"", FmtString(W32.wine_version));
|
||||
}
|
||||
if (appdir_error.len > 0)
|
||||
{
|
||||
LogError(appdir_error);
|
||||
}
|
||||
|
||||
// Bootstrap resource system
|
||||
{
|
||||
W32_FindEmbeddedDataCtx ctx = Zi;
|
||||
@ -631,10 +706,14 @@ i32 W32_Main(void)
|
||||
BootstrapResources(ctx.embedded_strings_count, ctx.embedded_strings);
|
||||
}
|
||||
|
||||
// Bootstrap async
|
||||
//////////////////////////////
|
||||
//- Bootstrap async
|
||||
|
||||
BootstrapAsync();
|
||||
|
||||
// Bootstrap layers
|
||||
//////////////////////////////
|
||||
//- Bootstrap layers
|
||||
|
||||
if (!Atomic32Fetch(&W32.panicking))
|
||||
{
|
||||
BootstrapLayers();
|
||||
|
||||
@ -6,32 +6,25 @@
|
||||
#define COBJMACROS
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define UNICODE
|
||||
// #pragma warning(push, 0)
|
||||
#include <Windows.h>
|
||||
#include <combaseapi.h>
|
||||
#include <dcommon.h>
|
||||
#include <initguid.h>
|
||||
#include <unknwn.h>
|
||||
#include <objbase.h>
|
||||
#include <uuids.h>
|
||||
#include <Knownfolders.h>
|
||||
#include <WinSock2.h>
|
||||
#include <Mswsock.h>
|
||||
#include <TlHelp32.h>
|
||||
#include <WS2tcpip.h>
|
||||
#include <windowsx.h>
|
||||
#include <ShlObj_core.h>
|
||||
#include <fileapi.h>
|
||||
#include <dwmapi.h>
|
||||
#include <avrt.h>
|
||||
#include <shellapi.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
|
||||
#include <Windows.h>
|
||||
#include <combaseapi.h>
|
||||
#include <dcommon.h>
|
||||
#include <initguid.h>
|
||||
#include <unknwn.h>
|
||||
#include <objbase.h>
|
||||
#include <uuids.h>
|
||||
#include <Knownfolders.h>
|
||||
#include <WinSock2.h>
|
||||
#include <Mswsock.h>
|
||||
#include <TlHelp32.h>
|
||||
#include <WS2tcpip.h>
|
||||
#include <windowsx.h>
|
||||
#include <ShlObj_core.h>
|
||||
#include <fileapi.h>
|
||||
#include <dwmapi.h>
|
||||
#include <avrt.h>
|
||||
#include <shellapi.h>
|
||||
#include <compressapi.h>
|
||||
|
||||
//- Windows libs
|
||||
|
||||
@ -49,21 +42,16 @@
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
#pragma comment(lib, "advapi32.lib")
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Embedded data iter types
|
||||
|
||||
Struct(W32_FindEmbeddedDataCtx)
|
||||
{
|
||||
u64 embedded_strings_count;
|
||||
String embedded_strings[64];
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ API types
|
||||
//- Windows API
|
||||
|
||||
typedef char *W32_WineVersionFunc(void);
|
||||
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
|
||||
@ -79,6 +67,15 @@ Struct(W32_Api)
|
||||
} func;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Embedded data iter types
|
||||
|
||||
Struct(W32_FindEmbeddedDataCtx)
|
||||
{
|
||||
u64 embedded_strings_count;
|
||||
String embedded_strings[64];
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ State types
|
||||
|
||||
@ -96,7 +93,9 @@ Struct(W32_Ctx)
|
||||
|
||||
StringList raw_command_line;
|
||||
String app_name;
|
||||
String appdir_path;
|
||||
String engine_dir_path;
|
||||
String libs_dir_path;
|
||||
String app_dir_path;
|
||||
|
||||
//- Application control flow
|
||||
|
||||
@ -113,11 +112,10 @@ Struct(W32_Ctx)
|
||||
//- Logs
|
||||
|
||||
HANDLE logfile;
|
||||
Atomic32 logs_initialized;
|
||||
|
||||
TicketMutex logs_tm;
|
||||
Arena *log_msgs_arena;
|
||||
Arena *logs_arena;
|
||||
Arena *log_events_arena;
|
||||
|
||||
u64 logs_count;
|
||||
u64 log_level_counts[LogLevel_COUNT];
|
||||
@ -133,10 +131,15 @@ extern W32_Ctx W32;
|
||||
#define W32_EmbeddedDataPrefix EMBEDDED_RESOURCE_DATA__
|
||||
BOOL W32_FindEmbeddedRcData(HMODULE module, LPCWSTR type, LPWSTR wstr_entry_name, LONG_PTR udata);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Error
|
||||
|
||||
String W32_StringFromError(Arena *arena, i32 code);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Log
|
||||
|
||||
void W32_BootstrapLogs(void);
|
||||
void W32_LogEventToFile(LogEvent *ev, HANDLE file);
|
||||
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);
|
||||
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
|
||||
|
||||
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_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
|
||||
|
||||
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.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.events_enabled = IsDeveloperModeEnabled;
|
||||
|
||||
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");
|
||||
G_D12.independent_devices_enabled = 0;
|
||||
}
|
||||
|
||||
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 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
|
||||
|
||||
@ -32,11 +62,11 @@ void G_Bootstrap(void)
|
||||
//////////////////////////////
|
||||
//- Extract agility SDK
|
||||
|
||||
String appdir = GetAppDirectory();
|
||||
String libs_dir = GetLibsDirectory();
|
||||
|
||||
u32 sdk_ver_num = 619;
|
||||
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));
|
||||
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"));
|
||||
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);
|
||||
PLT_MkDir(StringF(scratch.arena, "%Fd3d12/", FmtString(appdir)));
|
||||
PLT_MkDir(StringF(scratch.arena, "%Fd3d12/", FmtString(appdir)));
|
||||
PLT_MkDir(StringF(scratch.arena, "%Fd3d12/%F/", FmtString(appdir), FmtString(sdk_ver_str)));
|
||||
PLT_MkDir(StringF(scratch.arena, "%Fd3d12/", FmtString(libs_dir)));
|
||||
PLT_MkDir(StringF(scratch.arena, "%Fd3d12/", FmtString(libs_dir)));
|
||||
PLT_MkDir(StringF(scratch.arena, "%Fd3d12/%F/", FmtString(libs_dir), FmtString(sdk_ver_str)));
|
||||
{
|
||||
PLT_File file = PLT_OpenFileWrite(core_path);
|
||||
PLT_WriteFile(file, core_data);
|
||||
@ -302,8 +332,8 @@ void G_Bootstrap(void)
|
||||
{
|
||||
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_ERROR, 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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -588,26 +618,16 @@ DXGI_FORMAT G_D12_DxgiFormatFromGpuFormat(G_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;
|
||||
switch (queue_kind)
|
||||
D3D12_BARRIER_LAYOUT result = D3D12_BARRIER_LAYOUT_COMMON;
|
||||
if (queue_kind == G_QueueKind_Direct)
|
||||
{
|
||||
default: untracked_layout = D3D12_BARRIER_LAYOUT_COMMON; break;
|
||||
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;
|
||||
result = D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COMMON;
|
||||
}
|
||||
|
||||
D3D12_BARRIER_LAYOUT result;
|
||||
switch(usage_kind)
|
||||
else if (queue_kind == G_QueueKind_AsyncCompute)
|
||||
{
|
||||
default:
|
||||
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;
|
||||
result = D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COMMON;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -2077,6 +2097,9 @@ G_D12_StagingRegionNode *G_D12_PushStagingRegion(G_D12_CmdList *cl, u64 size)
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Tracking
|
||||
|
||||
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);
|
||||
@ -2107,6 +2130,7 @@ void G_D12_UpdateTrackedUsage(Arena *arena, G_D12_CmdBatch *batch, G_D12_Resourc
|
||||
tmp = PushStruct(arena, G_D12_TrackedResourceNode);
|
||||
tmp->resource = resource;
|
||||
tmp->hash = hash;
|
||||
++batch->tracked_resources_count;
|
||||
SllQueuePush(batch->first_tracked_resource, batch->last_tracked_resource, tmp);
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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
|
||||
|
||||
@ -2259,7 +2386,11 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
|
||||
G_D12_Cmd *cmd = &cmds[cmd_idx];
|
||||
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;
|
||||
}
|
||||
@ -2305,7 +2436,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -2327,13 +2458,13 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
|
||||
G_D12_Resource *resource = cmd->barrier.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
|
||||
{
|
||||
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;
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
is_transition_batch = 1;
|
||||
sync_before = D3D12_BARRIER_SYNC_NONE;
|
||||
access_before = D3D12_BARRIER_ACCESS_NO_ACCESS;
|
||||
global_before.sync = D3D12_BARRIER_SYNC_NONE;
|
||||
global_before.access = D3D12_BARRIER_ACCESS_NO_ACCESS;
|
||||
}
|
||||
if (batch == last_batch)
|
||||
{
|
||||
is_transition_batch = 1;
|
||||
sync_after = D3D12_BARRIER_SYNC_NONE;
|
||||
access_after = 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;
|
||||
global_after.sync = D3D12_BARRIER_SYNC_NONE;
|
||||
global_after.access = D3D12_BARRIER_ACCESS_NO_ACCESS;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
G_D12_Resource *resource = tn->resource;
|
||||
D3D12_BARRIER_LAYOUT old_layout = G_D12_BarrierLayoutFromUsageKind(queue_kind, tn->old);
|
||||
D3D12_BARRIER_LAYOUT new_layout = G_D12_BarrierLayoutFromUsageKind(queue_kind, tn->new);
|
||||
G_D12_TrackedUsageKind old_usage = tn->old;
|
||||
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];
|
||||
barrier->SyncBefore = sync_before;
|
||||
barrier->SyncAfter = sync_after;
|
||||
barrier->AccessBefore = access_before;
|
||||
barrier->AccessAfter = access_after;
|
||||
barrier->LayoutBefore = old_layout;
|
||||
barrier->LayoutAfter = new_layout;
|
||||
barrier->pResource = resource->d3d_resource;
|
||||
barrier->Subresources.NumArraySlices = 1;
|
||||
barrier->Subresources.NumPlanes = 1;
|
||||
barrier->Subresources.IndexOrFirstMipLevel = tn->mips.min;
|
||||
barrier->Subresources.NumMipLevels = tn->mips.max - tn->mips.min + 1;
|
||||
{
|
||||
barrier->SyncBefore = resource_before.sync;
|
||||
barrier->SyncAfter = resource_after.sync;
|
||||
barrier->AccessBefore = resource_before.access;
|
||||
barrier->AccessAfter = resource_after.access;
|
||||
barrier->LayoutBefore = resource_before.layout;
|
||||
barrier->LayoutAfter = resource_after.layout;
|
||||
barrier->pResource = resource->d3d_resource;
|
||||
barrier->Subresources.NumArraySlices = 1;
|
||||
barrier->Subresources.NumPlanes = 1;
|
||||
barrier->Subresources.IndexOrFirstMipLevel = tn->mips.min;
|
||||
barrier->Subresources.NumMipLevels = tn->mips.max - tn->mips.min + 1;
|
||||
}
|
||||
++barrier_idx;
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
D3D12_BARRIER_GROUP barrier_groups[2] = Zi;
|
||||
if (!is_transition_batch)
|
||||
@ -3012,6 +3149,51 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
|
||||
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
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
//- 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
|
||||
|
||||
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.SampleDesc.Count = 1;
|
||||
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.Scaling = DXGI_SCALING_NONE;
|
||||
desc.Flags = G_D12_SwapchainFlags;
|
||||
|
||||
@ -10,6 +10,14 @@
|
||||
#pragma comment(lib, "d3d12")
|
||||
#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
|
||||
|
||||
@ -300,8 +308,9 @@ Struct(G_D12_ReleasableList)
|
||||
Enum(G_D12_CmdKind)
|
||||
{
|
||||
G_D12_CmdKind_None,
|
||||
G_D12_CmdKind_Barrier,
|
||||
G_D12_CmdKind_Constant,
|
||||
G_D12_CmdKind_Barrier,
|
||||
G_D12_CmdKind_Event,
|
||||
G_D12_CmdKind_CopyBytes,
|
||||
G_D12_CmdKind_CopyTexels,
|
||||
G_D12_CmdKind_Compute,
|
||||
@ -324,7 +333,7 @@ Struct(G_D12_Cmd)
|
||||
struct
|
||||
{
|
||||
G_D12_Resource *resource;
|
||||
b32 to_exclusive;
|
||||
b32 acquire;
|
||||
} barrier;
|
||||
|
||||
struct
|
||||
@ -411,11 +420,11 @@ Struct(G_D12_CmdList)
|
||||
Enum(G_D12_TrackedUsageKind)
|
||||
{
|
||||
G_D12_TrackedUsageKind_Untracked,
|
||||
G_D12_TrackedUsageKind_MakeExclusive,
|
||||
G_D12_TrackedUsageKind_Acquire,
|
||||
G_D12_TrackedUsageKind_DepthStencilRead,
|
||||
G_D12_TrackedUsageKind_DepthStencilReadWrite,
|
||||
G_D12_TrackedUsageKind_RenderTarget,
|
||||
G_D12_TrackedUsageKind_MakeCommon,
|
||||
G_D12_TrackedUsageKind_Release,
|
||||
};
|
||||
|
||||
Struct(G_D12_TransitionNode)
|
||||
@ -456,6 +465,13 @@ Struct(G_D12_BatchedCmdNode)
|
||||
G_D12_Cmd *cmd;
|
||||
};
|
||||
|
||||
Struct(G_D12_BarrierInfo)
|
||||
{
|
||||
D3D12_BARRIER_SYNC sync;
|
||||
D3D12_BARRIER_ACCESS access;
|
||||
D3D12_BARRIER_LAYOUT layout;
|
||||
};
|
||||
|
||||
Struct(G_D12_CmdBatch)
|
||||
{
|
||||
G_D12_CmdBatch *next;
|
||||
@ -478,7 +494,8 @@ Struct(G_D12_CmdBatch)
|
||||
b32 contains_compute_shader;
|
||||
b32 contains_draw_shader;
|
||||
b32 contains_rtv;
|
||||
b32 contains_dsv;
|
||||
b32 contains_dsv_read;
|
||||
b32 contains_dsv_write;
|
||||
b32 contains_indirect;
|
||||
b32 contains_copy;
|
||||
};
|
||||
@ -517,6 +534,8 @@ Struct(G_D12_Ctx)
|
||||
b32 independent_devices_enabled;
|
||||
b32 debug_layer_enabled;
|
||||
b32 validation_layer_enabled;
|
||||
b32 events_enabled;
|
||||
b32 pix_enabled;
|
||||
|
||||
// Stats
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
@ -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_PushConstCmd(G_D12_CmdList *cl, i32 slot, void *v);
|
||||
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);
|
||||
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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -3,8 +3,3 @@
|
||||
|
||||
#pragma comment(lib, "kernel32")
|
||||
#pragma comment(lib, "user32")
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Win32 helpers
|
||||
|
||||
String W32_StringFromError(Arena *arena, DWORD err);
|
||||
|
||||
@ -4843,10 +4843,10 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
{
|
||||
max = 5;
|
||||
}
|
||||
LogEventsArray logs = GetLogEvents();
|
||||
for (u64 i = logs.count; i-- > 0 && display_count < max && !done;)
|
||||
LogEventsArray log_events = GetLogEvents();
|
||||
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.level <= console_level)
|
||||
@ -5279,6 +5279,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
//////////////////////////////
|
||||
//- Initialization pass
|
||||
|
||||
G_BeginEvent(cl, Lit("Testing"));
|
||||
{
|
||||
// Prepare shade
|
||||
G_Compute2D(cl, V_PrepareShadeCS, frame->shade_dims);
|
||||
@ -5323,6 +5324,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
|
||||
G_Sync(cl);
|
||||
}
|
||||
G_EndEvent(cl);
|
||||
|
||||
//////////////////////////////
|
||||
//- Quads & emitters pass
|
||||
|
||||
Loading…
Reference in New Issue
Block a user