conservative d3d12 sync

This commit is contained in:
jacob 2026-03-06 12:15:36 -08:00
parent a772094154
commit 707755e503
10 changed files with 584 additions and 386 deletions

View File

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

View File

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

View File

@ -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
@ -324,77 +334,92 @@ void ExitNow(i32 code)
}
////////////////////////////////////////////////////////////
//~ Log
//~ Error
void W32_BootstrapLogs(void)
String W32_StringFromError(Arena *arena, i32 code)
{
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,
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,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0
);
Atomic32Set(&W32.logs_initialized, 1);
LogInfoF("Log file path: %F", FmtString(logfile_path));
result = StringFromWstr(arena, msg_wstr, msg_len);
if (msg_wstr)
{
LocalFree(msg_wstr);
}
}
return result;
}
void W32_Log(i32 level, String msg)
////////////////////////////////////////////////////////////
//~ Log
void W32_LogEventToFile(LogEvent *ev, HANDLE file)
{
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();
if (Atomic32Fetch(&W32.logs_initialized))
{
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
{
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(datetime.hour, .z = 2),
FmtUint(datetime.minute, .z = 2),
FmtUint(datetime.second, .z = 2),
FmtUint(datetime.milliseconds, .z = 3),
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(thread_id, .z = 5),
FmtUint(ev->thread_id, .z = 5),
// Level
FmtString(shorthand),
// Message
FmtString(msg)
FmtString(ev->msg)
);
WriteFile(W32.logfile, msg_formatted.text, msg_formatted.len, 0, 0);
WriteFile(file, msg_formatted.text, msg_formatted.len, 0, 0);
}
EndScratch(scratch);
}
//- Log message to queue
void W32_Log(i32 level, String msg)
{
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);
{
// Get staged data
LogEvent *ev = PushStruct(W32.logs_arena, LogEvent);
ev->msg = PushString(W32.log_msgs_arena, msg);
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;
@ -404,8 +429,11 @@ void W32_Log(i32 level, String msg)
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,8 +460,6 @@ 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);
@ -443,7 +469,6 @@ void LogF_(i32 level, String fmt, ...)
}
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;
//////////////////////////////
//- 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)
String app_name = CommandlineArgFromName(Lit("app_name")).value;
if (!app_name.len)
{
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;
app_name = StringFromCstrNoLimit(Stringize(DefaultAppName));
}
W32.app_name = app_name;
wchar_t *path_wstr = 0;
HRESULT hr = SHGetKnownFolderPath(&FOLDERID_LocalAppData, 0, 0, &path_wstr);
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();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3,8 +3,3 @@
#pragma comment(lib, "kernel32")
#pragma comment(lib, "user32")
////////////////////////////////////////////////////////////
//~ Win32 helpers
String W32_StringFromError(Arena *arena, DWORD err);

View File

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