From 014b8e84c31baa516860b34b116a9c4495243e3a Mon Sep 17 00:00:00 2001 From: jacob Date: Tue, 12 Aug 2025 08:38:13 -0500 Subject: [PATCH] meta layer progress --- build.bat | 2 +- src/app/app.lay | 2 +- src/ase/ase.lay | 2 +- src/asset_cache/asset_cache.lay | 2 +- src/base/base.lay | 46 +- src/base/base_arena.h | 26 +- src/base/base_core.h | 57 +- src/bitbuff/bitbuff.lay | 2 +- src/collider/collider.lay | 2 +- src/collider/collider_core.h | 3 +- src/draw/draw.lay | 2 +- src/dxc/dxc.lay | 14 - src/dxc/dxc_core.h | 13 - src/dxc/win32/dxc_win32.cpp | 97 - src/font/font.lay | 2 +- src/gpu/dx12/gpu_dx12.c | 3403 +---------------- src/gpu/dx12/gpu_dx12.h | 590 --- src/gpu/gpu.lay | 10 +- src/gpu/gpu_core.h | 376 +- src/gtest/dx12/gtest_dx12.c | 206 - src/gtest/dx12/gtest_dx12.h | 0 src/gtest/gtest.lay | 20 - src/gtest/gtest_core.h | 349 -- src/inc/inc.lay | 2 +- src/json/json.lay | 2 +- src/kernel/kernel.lay | 4 +- src/kernel/kernel_core.h | 2 +- src/meta/meta.c | 400 +- src/meta/meta_arena.h | 26 +- src/meta/meta_core.h | 49 +- src/meta/meta_math.c | 3 +- src/mixer/mixer.lay | 2 +- src/mp3/mmf/mp3_mmf.c | 16 +- src/mp3/mp3.lay | 4 +- src/net/net.lay | 2 +- src/platform/platform.lay | 6 +- src/playback/playback.lay | 4 +- src/pp/pp.lay | 16 +- src/pp/pp_core.c | 222 +- src/pp/pp_core.h | 24 +- src/pp/pp_draw.gpu | 12 +- src/pp/pp_draw.h | 20 +- src/prof/prof.lay | 6 - src/rendertest/rendertest.lay | 2 +- src/resource/resource.lay | 2 +- src/settings/settings.lay | 2 +- src/sound/sound.lay | 2 +- src/sprite/sprite.lay | 4 +- src/sprite/sprite_core.c | 24 +- src/sprite/sprite_core.h | 2 +- src/tar/tar.lay | 2 +- .../dwrite/{ttf_dwrite.cpp => ttf_dwrite.c} | 0 src/ttf/ttf.lay | 2 +- src/watch/watch.lay | 2 +- 54 files changed, 1077 insertions(+), 5015 deletions(-) delete mode 100644 src/dxc/dxc.lay delete mode 100644 src/dxc/dxc_core.h delete mode 100644 src/dxc/win32/dxc_win32.cpp delete mode 100644 src/gtest/dx12/gtest_dx12.c delete mode 100644 src/gtest/dx12/gtest_dx12.h delete mode 100644 src/gtest/gtest.lay delete mode 100644 src/gtest/gtest_core.h delete mode 100644 src/prof/prof.lay rename src/ttf/dwrite/{ttf_dwrite.cpp => ttf_dwrite.c} (100%) diff --git a/build.bat b/build.bat index 981736cd..648d026d 100644 --- a/build.bat +++ b/build.bat @@ -47,7 +47,7 @@ if "%meta%" == "1" ( if "%pp%" == "1" ( echo [Building power play] - "build/meta.exe" pp.lay + "build/meta.exe" pp if not "!errorlevel!" == "0" ( echo. diff --git a/src/app/app.lay b/src/app/app.lay index f54ee3f6..957d354f 100644 --- a/src/app/app.lay +++ b/src/app/app.lay @@ -23,4 +23,4 @@ //////////////////////////////// //~ Api -@CpuApi app_core +@ApiC app_core diff --git a/src/ase/ase.lay b/src/ase/ase.lay index aad7f87c..cc024a10 100644 --- a/src/ase/ase.lay +++ b/src/ase/ase.lay @@ -9,4 +9,4 @@ //////////////////////////////// //~ Api -@CpuApi ase_core +@ApiC ase_core diff --git a/src/asset_cache/asset_cache.lay b/src/asset_cache/asset_cache.lay index 2283585e..a6987d73 100644 --- a/src/asset_cache/asset_cache.lay +++ b/src/asset_cache/asset_cache.lay @@ -9,7 +9,7 @@ //////////////////////////////// //~ Api -@CpuApi asset_cache_core +@ApiC asset_cache_core //////////////////////////////// //~ Init diff --git a/src/base/base.lay b/src/base/base.lay index 8493f3cf..07e1b5af 100644 --- a/src/base/base.lay +++ b/src/base/base.lay @@ -1,37 +1,31 @@ @Layer base -//////////////////////////////// -//~ Deps - -@Dep prof - //////////////////////////////// //~ Api -@CpuApi base_core -@GpuApi base_core +@ApiC base_core +@ApiC base_intrinsics +@ApiC base_memory +@ApiC base_arena +@ApiC base_snc +@ApiC base_job +@ApiC base_uid +@ApiC base_string +@ApiC base_uni +@ApiC base_gstat +@ApiC base_buddy +@ApiC base_math +@ApiC base_rand +@ApiC base_util +@ApiC base_incbin +@ApiC base_entry -@CpuApi base_intrinsics -@CpuApi base_memory -@CpuApi base_arena -@CpuApi base_snc -@CpuApi base_job -@CpuApi base_uid -@CpuApi base_string -@CpuApi base_uni -@CpuApi base_gstat -@CpuApi base_buddy -@CpuApi base_math -@CpuApi base_rand -@CpuApi base_util -@CpuApi base_incbin -@CpuApi base_entry - -@GpuApi base_math_gpu +@ApiGpu base_core +@ApiGpu base_math_gpu //- Win32 -@CpuApiWindows win32/base_win32_job -@CpuApiWindows win32/base_win32_entry +@ApiCWindows win32/base_win32_job +@ApiCWindows win32/base_win32_entry //////////////////////////////// //~ Init diff --git a/src/base/base_arena.h b/src/base/base_arena.h index df70a906..9a2fca12 100644 --- a/src/base/base_arena.h +++ b/src/base/base_arena.h @@ -14,7 +14,8 @@ Struct(Arena) #endif }; -Struct(TempArena) { +Struct(TempArena) +{ Arena *arena; u64 start_pos; @@ -118,16 +119,22 @@ void SetArenaReadWrite(Arena *arena); Inline void *AlignArena(Arena *arena, u64 align) { Assert(!arena->readonly); - if (align > 0) { + if (align > 0) + { u64 aligned_start_pos = (arena->pos + (align - 1)); aligned_start_pos -= aligned_start_pos % align; u64 align_bytes = aligned_start_pos - (u64)arena->pos; - if (align_bytes > 0) { + if (align_bytes > 0) + { return (void *)PushStructsNoZero(arena, u8, align_bytes); - } else { + } + else + { return (void *)(ArenaBase(arena) + arena->pos); } - } else { + } + else + { /* 0 alignment */ Assert(0); return (void *)(ArenaBase(arena) + arena->pos); @@ -163,9 +170,11 @@ Inline ArenaCtx *ArenaCtxFromFiberId(i16 fiber_id) { SharedArenaCtx *shared = &shared_arena_ctx; ArenaCtx *ctx = &shared->arena_contexts[fiber_id]; - if (!ctx->scratch_arenas[0]) { + if (!ctx->scratch_arenas[0]) + { __profn("Initialize fiber arena ctx"); - for (i32 i = 0; i < (i32)countof(ctx->scratch_arenas); ++i) { + for (i32 i = 0; i < (i32)countof(ctx->scratch_arenas); ++i) + { ctx->scratch_arenas[i] = AcquireArena(Gibi(64)); } ctx->perm_arena = AcquireArena(Gibi(64)); @@ -196,7 +205,8 @@ Inline TempArena _BeginScratch(Arena *potential_conflict) ArenaCtx *ctx = ArenaCtxFromFiberId(FiberId()); Arena *scratch_arena = ctx->scratch_arenas[0]; - if (potential_conflict && scratch_arena == potential_conflict) { + if (potential_conflict && scratch_arena == potential_conflict) + { scratch_arena = ctx->scratch_arenas[1]; } TempArena temp = BeginTempArena(scratch_arena); diff --git a/src/base/base_core.h b/src/base/base_core.h index 8430b817..eea569ac 100644 --- a/src/base/base_core.h +++ b/src/base/base_core.h @@ -59,16 +59,10 @@ extern "C" { #endif //- Language -#if defined(__cplusplus) -# define LanguageIsCpp 1 -# define LanguageIsC 0 -# define LanguageIsGpu 0 -#elif defined(__STDC_VERSION__) -# define LanguageIsCpp 0 +#if defined(__STDC_VERSION__) # define LanguageIsC 1 # define LanguageIsGpu 0 #elif defined(__HLSL_VERSION) -# define LanguageIsCpp 0 # define LanguageIsC 0 # define LanguageIsGpu 1 #else @@ -173,13 +167,6 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t); //////////////////////////////// //~ Common utility macros -//- Initlist compatibility -#if CompilerIsMsvc && LanguageIsCpp -# define CppCompatInitListType(type) -#else -# define CppCompatInitListType(type) (type) -#endif - //- ZeroStruct initialization macro #if LanguageIsC # define ZI { 0 } @@ -248,16 +235,10 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t); #define LAX (void) //- Fallthrough -#if CompilerIsMsvc -# if LanguageIsCpp -# define FALLTHROUGH [[fallthrough]] -# else -# define FALLTHROUGH -# endif -#elif CompilerIsClang -# define FALLTHROUGH __attribute((fallthrough)) +#if CompilerIsClang +# define FALLTHROUGH #else -# define FALLTHROUGH +# define FALLTHROUGH __attribute((fallthrough)) #endif //- Preprocessor concatenation @@ -281,18 +262,6 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t); //////////////////////////////// //~ Type helper macros -//- typeof -#if CompilerIsMsvc -/* Typeof not supported in MSVC */ -# define TypeofIsDefined 0 -# define typeof(type) Assert(0) -#else -# define TypeofIsDefined 1 -# if LanguageIsCpp || (__STDC_VERSION__ < 202311L) -# define typeof(type) __typeof__(type) -# endif -#endif - //- alignof #if (CompilerIsMsvc && LanguageIsC) || (LanguageIsC && (__STDC_VERSION__ < 202311L)) # define alignof(type) __alignof(type) @@ -383,7 +352,7 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t); //////////////////////////////// //~ Intrinsic headers -#if !LanguageIsGpu +#if LanguageIsC /* Intrinsic header info: * ((void *)__readgsqword(32)); -#else i16 *v = (void *)__readgsqword(32); -#endif return *v; } # else diff --git a/src/bitbuff/bitbuff.lay b/src/bitbuff/bitbuff.lay index c06f88f6..e58dfb25 100644 --- a/src/bitbuff/bitbuff.lay +++ b/src/bitbuff/bitbuff.lay @@ -8,4 +8,4 @@ //////////////////////////////// //~ Api -@CpuApi bitbuff_core +@ApiC bitbuff_core diff --git a/src/collider/collider.lay b/src/collider/collider.lay index 2ec0d1aa..da3a9f28 100644 --- a/src/collider/collider.lay +++ b/src/collider/collider.lay @@ -8,4 +8,4 @@ //////////////////////////////// //~ Api -@CpuApi collider_core +@ApiC collider_core diff --git a/src/collider/collider_core.h b/src/collider/collider_core.h index 6f51a3ac..be79f68c 100644 --- a/src/collider/collider_core.h +++ b/src/collider/collider_core.h @@ -143,7 +143,8 @@ void CLD_DebugBreakable(void); if (dbg_step >= GetGstat(GSTAT_DEBUG_STEPS)) \ { \ goto abort; \ - } else if (dbg_step >= GetGstat(GSTAT_DEBUG_STEPS) - 1) \ + } \ + else if (dbg_step >= GetGstat(GSTAT_DEBUG_STEPS) - 1) \ { \ CLD_DebugBreakable(); \ } (void)0 diff --git a/src/draw/draw.lay b/src/draw/draw.lay index 95f5e9ea..a5f7a4b1 100644 --- a/src/draw/draw.lay +++ b/src/draw/draw.lay @@ -12,7 +12,7 @@ //////////////////////////////// //~ Api -@CpuApi draw_core +@ApiC draw_core //////////////////////////////// //~ Init diff --git a/src/dxc/dxc.lay b/src/dxc/dxc.lay deleted file mode 100644 index 9888ebe2..00000000 --- a/src/dxc/dxc.lay +++ /dev/null @@ -1,14 +0,0 @@ -@Layer dxc - -//////////////////////////////// -//~ Dependencies - -@Dep base - -//////////////////////////////// -//~ Api - -@CpuApi dxc_core - -//- Win32 -@CpuApiWindows win32/dxc_win32 diff --git a/src/dxc/dxc_core.h b/src/dxc/dxc_core.h deleted file mode 100644 index 835caafa..00000000 --- a/src/dxc/dxc_core.h +++ /dev/null @@ -1,13 +0,0 @@ -//////////////////////////////// -//~ Dxc types - -Struct(DXC_Result) { - String dxc; - String errors; - b32 success; -}; - -//////////////////////////////// -//~ Dxc operations - -DXC_Result DXC_Compile(Arena *arena, String shader_source, i32 num_args, String *args); diff --git a/src/dxc/win32/dxc_win32.cpp b/src/dxc/win32/dxc_win32.cpp deleted file mode 100644 index 96fafcc4..00000000 --- a/src/dxc/win32/dxc_win32.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#if !RESOURCE_RELOADING - -DXC_Result DXC_Compile(Arena *arena, String shader_source, i32 num_args, String *args) -{ - LAX arena; - LAX shader_source; - LAX num_args; - LAX args; - DXC_Result result = ZI; - return result; -} - -#else - -#if CompilerIsClang -# pragma clang diagnostic ignored "-Wlanguage-extension-token" -#endif - -//////////////////////////////// -//~ Windows headers - -#pragma warning(push, 0) -# define WIN32_LEAN_AND_MEAN -# define UNICODE -# include -# include -# include -# include -#pragma warning(pop) - -#pragma comment(lib, "d3dcompiler") -#pragma comment(lib, "dxcompiler") - -//////////////////////////////// -//~ Compile - -/* https://github.com/microsoft/DirectXShaderCompiler/wiki/Using-dxc.exe-and-dxcompiler.dll */ -DXC_Result DXC_Compile(Arena *arena, String shader_source, i32 num_args, String *args) -{ - __prof; - TempArena scratch = BeginScratch(arena); - DXC_Result result = ZI; - - wchar_t **wstr_args = PushStructs(scratch.arena, wchar_t *, num_args); - for (i32 i = 0; i < num_args; ++i) { - wstr_args[i] = WstrFromString(scratch.arena, args[i]); - } - - DxcBuffer dxc_src_buffer = ZI; - dxc_src_buffer.Ptr = shader_source.text; - dxc_src_buffer.Size = shader_source.len; - dxc_src_buffer.Encoding = DXC_CP_UTF8; - - //- Init compiler - CComPtr dxc_utils; - CComPtr dxc_compiler; - CComPtr dxc_include_handler; - DxcCreateInstance(CLSID_DxcUtils, IID_PPV_ARGS(&dxc_utils)); - DxcCreateInstance(CLSID_DxcCompiler, IID_PPV_ARGS(&dxc_compiler)); - dxc_utils->CreateDefaultIncludeHandler(&dxc_include_handler); - - //- Compile - CComPtr compile_results = 0; - dxc_compiler->Compile(&dxc_src_buffer, (LPCWSTR *)wstr_args, (u32)num_args, dxc_include_handler, IID_PPV_ARGS(&compile_results)); - - //- Copy errors - CComPtr dxc_errors = 0; - compile_results->GetOutput(DXC_OUT_ERRORS, IID_PPV_ARGS(&dxc_errors), 0); - if (dxc_errors != 0) { - String blob_str = ZI; - blob_str.len = dxc_errors->GetBufferSize(); - blob_str.text = (u8 *)dxc_errors->GetBufferPointer(); - result.errors = PushString(arena, blob_str); - } - - //- Get status - HRESULT dxc_hr = 0; - compile_results->GetStatus(&dxc_hr); - result.success = SUCCEEDED(dxc_hr); - - //- Copy shader output - if (result.success) { - CComPtr dxc_shader = 0; - compile_results->GetOutput(DXC_OUT_OBJECT, IID_PPV_ARGS(&dxc_shader), 0); - if (dxc_shader != 0) { - String blob_str = ZI; - blob_str.len = dxc_shader->GetBufferSize(); - blob_str.text = (u8 *)dxc_shader->GetBufferPointer(); - result.dxc = PushString(arena, blob_str); - } - } - - EndScratch(scratch); - return result; -} - -#endif diff --git a/src/font/font.lay b/src/font/font.lay index 9769f9f8..6a3e5db2 100644 --- a/src/font/font.lay +++ b/src/font/font.lay @@ -12,4 +12,4 @@ //////////////////////////////// //~ Api -@CpuApi font_core +@ApiC font_core diff --git a/src/gpu/dx12/gpu_dx12.c b/src/gpu/dx12/gpu_dx12.c index c1e9dbb5..f3563982 100644 --- a/src/gpu/dx12/gpu_dx12.c +++ b/src/gpu/dx12/gpu_dx12.c @@ -1,3379 +1,206 @@ -GPU_D12_SharedState GPU_D12_shared_state = ZI; - //////////////////////////////// -//~ Windows libs - -#pragma comment(lib, "d3d12") -#pragma comment(lib, "dxgi") -#pragma comment(lib, "dxguid") -#pragma comment(lib, "d3dcompiler") - -#if ProfilingGpu -/* For RegOpenKeyEx */ -# include -# pragma comment(lib, "advapi32") -#endif - -//////////////////////////////// -//~ Startup +//~ @hookdef Startup hook void GPU_StartupCore(void) { - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - if (Atomic32FetchTestSet(&g->initialized, 0, 1) != 0) - { - Panic(Lit("GP layer already initialized")); - } - - /* Initialize command descriptor heaps pool */ - g->command_descriptor_heaps_arena = AcquireArena(Gibi(64)); - - /* Initialize command buffers pool */ - g->command_buffers_arena = AcquireArena(Gibi(64)); - g->command_buffers_dict = InitDict(g->command_buffers_arena, 4096); - - /* Initialize resources pool */ - g->resources_arena = AcquireArena(Gibi(64)); - - /* Initialize swapchains pool */ - g->swapchains_arena = AcquireArena(Gibi(64)); - - /* Initialize pipeline cache */ - g->pipelines_arena = AcquireArena(Gibi(64)); - g->pipeline_descs = InitDict(g->pipelines_arena, 1024); - g->top_pipelines = InitDict(g->pipelines_arena, 1024); - g->top_successful_pipelines = InitDict(g->pipelines_arena, 1024); - - /* Initialize fenced releases queue */ - g->fenced_releases_arena = AcquireArena(Gibi(64)); - - /* Initialize embedded shader archive */ - String embedded_data = INC_GetDxcTar(); - if (embedded_data.len <= 0) - { - Panic(Lit("No embedded shaders found")); - } - g->dxc_archive = TAR_ArchiveFromString(g->pipelines_arena, embedded_data, Lit("")); - - /* Initialize dx12 */ - /* TODO: Parallelize phases */ - GPU_D12_InitDevice(); - GPU_D12_InitObjects(); - GPU_InitPipelines(); - GPU_D12_InitNoise(); - - /* Register callbacks */ -#if RESOURCE_RELOADING - W_RegisterCallback(GPU_D12_WatchPipelineCallback); -#endif - OnExit(GPU_D12_Shutdown); - - /* Start evictor job */ - RunJob(1, GPU_D12_EvictorJob, JobPool_Background, JobPriority_Low, &g->evictor_job_counter, 0); -} - -ExitFuncDef(GPU_D12_Shutdown) -{ - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; -#if 0 - /* Release objects to make live object reporting less noisy */ - //IDXGISwapChain3_Release(g->swapchain); - for (u32 i = 0; i < countof(g->command_queues); ++i) - { - GPU_D12_CommandQueue *cq = g->command_queues[i]; - cmomand_queue_release(cq); - } - ID3D12Device_Release(g->device); -#else - LAX GPU_D12_ReleaseCommandQueue; -#endif - - { - Lock lock = LockE(&g->evictor_wake_mutex); - g->evictor_shutdown = 1; - SignalCv(&g->evictor_wake_cv, I32Max); - Unlock(&lock); - } - YieldOnCounter(&g->evictor_job_counter); } //////////////////////////////// -//~ Dx12 device initialization +//~ @hookdef Rasterizer helper hooks -void GPU_D12_PushInitError(String error) +GPU_Viewport GPU_ViewportFromRect(Rect rect) { - TempArena scratch = BeginScratchNoConflict(); - String msg = StringFormat(scratch.arena, Lit("Failed to initialize DirectX 12.\n\n%F"), FmtString(error)); - Panic(msg); - EndScratch(scratch); + LAX rect; + return (GPU_Viewport) ZI; } -void GPU_D12_InitDevice(void) +GPU_Scissor GPU_ScissorFromRect(Rect rect) { - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - TempArena scratch = BeginScratchNoConflict(); - HRESULT hr = 0; - - /* Enable debug layer */ - u32 dxgi_factory_flags = 0; -#if DX12_DEBUG - { - __profn("Enable debug layer"); - ID3D12Debug *debug_controller0 = 0; - hr = D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug_controller0); - if (FAILED(hr)) - { - GPU_D12_PushInitError(Lit("Failed to create ID3D12Debug0")); - } - - ID3D12Debug1 *debug_controller1 = 0; - hr = ID3D12Debug_QueryInterface(debug_controller0, &IID_ID3D12Debug1, (void **)&debug_controller1); - if (FAILED(hr)) - { - GPU_D12_PushInitError(Lit("Failed to create ID3D12Debug1")); - } - - ID3D12Debug_EnableDebugLayer(debug_controller0); - - /* FIXME: Enable this */ - //ID3D12Debug1_SetEnableGPUBasedValidation(debug_controller1, 1); - - ID3D12Debug_Release(debug_controller1); - ID3D12Debug_Release(debug_controller0); - dxgi_factory_flags |= DXGI_CREATE_FACTORY_DEBUG; - } -#endif - - /* Create factory */ - { - __profn("Create factory"); - hr = CreateDXGIFactory2(dxgi_factory_flags, &IID_IDXGIFactory6, (void **)&g->factory); - if (FAILED(hr)) - { - GPU_D12_PushInitError(Lit("Failed to initialize DXGI factory")); - } - } - - /* Create device */ - { - __profn("Create device"); - IDXGIAdapter1 *adapter = 0; - ID3D12Device *device = 0; - String error = Lit("Could not initialize GPU device."); - String first_gpu_name = ZI; - u32 adapter_index = 0; - b32 skip = 0; /* For debugging iGPU */ - for (;;) - { - { - hr = IDXGIFactory6_EnumAdapterByGpuPreference(g->factory, adapter_index, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, &IID_IDXGIAdapter1, (void **)&adapter); - } - if (SUCCEEDED(hr)) - { - DXGI_ADAPTER_DESC1 desc; - IDXGIAdapter1_GetDesc1(adapter, &desc); - if (first_gpu_name.len == 0) - { - first_gpu_name = StringFromWstrNoLimit(scratch.arena, desc.Description); - } - { - hr = D3D12CreateDevice((IUnknown *)adapter, D3D_FEATURE_LEVEL_12_0, &IID_ID3D12Device, (void **)&device); - } - if (SUCCEEDED(hr) && !skip) - { - break; - } - skip = 0; - ID3D12Device_Release(device); - IDXGIAdapter1_Release(adapter); - adapter = 0; - device = 0; - ++adapter_index; - } - else - { - break; - } - } - if (!device) - { - if (first_gpu_name.len > 0) - { - String fmt = Lit("Could not initialize device '%F' with D3D_FEATURE_LEVEL_12_0. Ensure that the device is capable and drivers are up to date."); - error = StringFormat(scratch.arena, fmt, FmtString(first_gpu_name)); - } - GPU_D12_PushInitError(error); - } - g->adapter = adapter; - g->device = device; - } - -#if DX12_DEBUG - /* Enable D3D12 Debug break */ - { - __profn("Enable d3d12 debug break"); - ID3D12InfoQueue *info = 0; - hr = ID3D12Device_QueryInterface(g->device, &IID_ID3D12InfoQueue, (void **)&info); - if (FAILED(hr)) - { - GPU_D12_PushInitError(Lit("Failed to query ID3D12Device interface")); - } - ID3D12InfoQueue_SetBreakOnSeverity(info, D3D12_MESSAGE_SEVERITY_CORRUPTION, 1); - ID3D12InfoQueue_SetBreakOnSeverity(info, D3D12_MESSAGE_SEVERITY_ERROR, 1); - ID3D12InfoQueue_Release(info); - } - - /* Enable DXGI Debug break */ - { - __profn("Enable dxgi debug break"); - IDXGIInfoQueue *dxgi_info = 0; - hr = DXGIGetDebugInterface1(0, &IID_IDXGIInfoQueue, (void **)&dxgi_info); - if (FAILED(hr)) - { - GPU_D12_PushInitError(Lit("Failed to get 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_Release(dxgi_info); - } -#endif - -#if ProfilingGpu && ProfilingGpuStablePowerState - /* Enable stable power state */ - { - __profn("Set stable power state"); - b32 success = 1; - HKEY key = 0; - success = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock", 0, KEY_READ, &key) == ERROR_SUCCESS; - if (success) - { - DWORD value = ZI; - DWORD dword_size = sizeof(DWORD); - success = RegQueryValueExW(key, L"AllowDevelopmentWithoutDevLicense", 0, 0, (LPBYTE)&value, &dword_size) == ERROR_SUCCESS; - RegCloseKey(key); - if (success) - { - success = value != 0; - } - } - P_LogInfoF("D3D12 profiling is enabled, attempting to set stable power state (this will increase GPU timing stability at the cost of performance)"); - if (success) - { - P_LogInfoF("Machine is in developer mode, calling ID3D12Device::SetStablePowerState"); - hr = ID3D12Device_SetStablePowerState(g->device, 1); - if (SUCCEEDED(hr)) - { - P_LogInfoF("ID3D12Device::SetStablePowerState succeeded"); - } - else - { - success = 0; - P_LogErrorF("ID3D12Device::SetStablePowerState failed"); - } - } - else - { - P_LogWarningF("Machine is not in developer mode, cannot call ID3D12Device::SetStablePowerState"); - } - if (!success) - { - P_LogWarningF("Profiling is enabled, but ID3D12Device::SetStablePowerState could not be called. This means that GPU timing may be unreliable."); - } - } -#endif - - EndScratch(scratch); + LAX rect; + return (GPU_Scissor) ZI; } //////////////////////////////// -//~ Dx12 object initialization +//~ @hookdef Fence hooks -void GPU_D12_InitObjects(void) +GPU_Fence GPU_GetGlobalFence(void) { - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - - /* Initialize desc sizes */ - g->desc_sizes[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV] = ID3D12Device_GetDescriptorHandleIncrementSize(g->device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - g->desc_sizes[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER] = ID3D12Device_GetDescriptorHandleIncrementSize(g->device, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); - g->desc_sizes[D3D12_DESCRIPTOR_HEAP_TYPE_RTV] = ID3D12Device_GetDescriptorHandleIncrementSize(g->device, D3D12_DESCRIPTOR_HEAP_TYPE_RTV); - g->desc_sizes[D3D12_DESCRIPTOR_HEAP_TYPE_DSV] = ID3D12Device_GetDescriptorHandleIncrementSize(g->device, D3D12_DESCRIPTOR_HEAP_TYPE_DSV); - - /* Initialize desc counts */ - g->desc_counts[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV] = DX12_NUM_CBV_SRV_UAV_DESCRIPTORS; - g->desc_counts[D3D12_DESCRIPTOR_HEAP_TYPE_RTV] = DX12_NUM_RTV_DESCRIPTORS; - - /* Create global descriptor heaps */ - g->cbv_srv_uav_heap = GPU_D12_AcquireCpuDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - g->rtv_heap = GPU_D12_AcquireCpuDescriptorHeap(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); - - /* Create command queues */ - { - __profn("Acquire command queues"); - GPU_D12_CommandQueueDesc params[] = { - {.type = D3D12_COMMAND_LIST_TYPE_DIRECT, .priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, .dbg_name = Lit("Direct queue") }, - {.type = D3D12_COMMAND_LIST_TYPE_COMPUTE, .priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, .dbg_name = Lit("Compute queue") }, - {.type = D3D12_COMMAND_LIST_TYPE_COPY, .priority = D3D12_COMMAND_QUEUE_PRIORITY_HIGH, .dbg_name = Lit("Copy queue") }, - {.type = D3D12_COMMAND_LIST_TYPE_COPY, .priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, .dbg_name = Lit("Background copy queue") } - }; - { - Counter counter = ZI; - RunJob(DX12_NUM_QUEUES, GPU_D12_AcquireCommandQueueJob, JobPool_Inherit, JobPriority_Low, &counter, .descs_in = params, .cqs_out = g->command_queues); - YieldOnCounter(&counter); - } -#if ProfilingIsEnabled - { - /* Initialize serially for consistent order in profiler */ - __profn("Initialize command queue profiling contexts"); - for (i32 i = 0; i < DX12_NUM_QUEUES; ++i) - { - GPU_D12_CommandQueue *cq = g->command_queues[i]; - String dbg_name = params[i].dbg_name; - __prof_dx12_ctx_acquire(cq->prof, g->device, cq->cq, dbg_name.text, dbg_name.len); - LAX dbg_name; - } - } -#endif - } + return (GPU_Fence) ZI; } //////////////////////////////// -//~ Dx12 pipeline initialization +//~ @hookdef Resource hooks -void GPU_InitPipelines(void) +GPU_Resource *GPU_AcquireResource(GPU_ResourceDesc desc) { - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - TempArena scratch = BeginScratchNoConflict(); - - /* Register pipeline descs */ - { - /* Material pipeline */ - { - GPU_D12_PipelineDesc *desc = PushStruct(g->pipelines_arena, GPU_D12_PipelineDesc); - desc->name = Lit("kernel_material"); - desc->rtvs[0].format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc->rtvs[0].blending = 1; - desc->rtvs[1].format = DXGI_FORMAT_R16G16B16A16_FLOAT; - desc->rtvs[1].blending = 1; - SetDictValue(g->pipelines_arena, g->pipeline_descs, HashFnv64(Fnv64Basis, desc->name), (u64)desc); - } - /* Flood pipeline */ - { - GPU_D12_PipelineDesc *desc = PushStruct(g->pipelines_arena, GPU_D12_PipelineDesc); - desc->name = Lit("kernel_flood"); - SetDictValue(g->pipelines_arena, g->pipeline_descs, HashFnv64(Fnv64Basis, desc->name), (u64)desc); - } - /* Shade pipeline */ - { - GPU_D12_PipelineDesc *desc = PushStruct(g->pipelines_arena, GPU_D12_PipelineDesc); - desc->name = Lit("kernel_shade"); - SetDictValue(g->pipelines_arena, g->pipeline_descs, HashFnv64(Fnv64Basis, desc->name), (u64)desc); - } - /* Shape pipeline */ - { - GPU_D12_PipelineDesc *desc = PushStruct(g->pipelines_arena, GPU_D12_PipelineDesc); - desc->name = Lit("kernel_shape"); - desc->rtvs[0].format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc->rtvs[0].blending = 1; - SetDictValue(g->pipelines_arena, g->pipeline_descs, HashFnv64(Fnv64Basis, desc->name), (u64)desc); - } - /* UI pipeline */ - { - GPU_D12_PipelineDesc *desc = PushStruct(g->pipelines_arena, GPU_D12_PipelineDesc); - desc->name = Lit("kernel_ui"); - desc->rtvs[0].format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc->rtvs[0].blending = 1; - SetDictValue(g->pipelines_arena, g->pipeline_descs, HashFnv64(Fnv64Basis, desc->name), (u64)desc); - } - /* Blit pipeilne */ - { - GPU_D12_PipelineDesc *desc = PushStruct(g->pipelines_arena, GPU_D12_PipelineDesc); - desc->name = Lit("kernel_blit"); - desc->rtvs[0].format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc->rtvs[0].blending = 1; - SetDictValue(g->pipelines_arena, g->pipeline_descs, HashFnv64(Fnv64Basis, desc->name), (u64)desc); - } - } - - /* Compile pipelines */ - u32 num_pipelines = 0; - GPU_D12_PipelineDesc *descs = PushDry(scratch.arena, GPU_D12_PipelineDesc); - for (DictEntry *entry = g->pipeline_descs->first; entry; entry = entry->next) - { - GPU_D12_PipelineDesc *desc = (GPU_D12_PipelineDesc *)entry->value; - *PushStruct(scratch.arena, GPU_D12_PipelineDesc) = *desc; - ++num_pipelines; - } - GPU_D12_Pipeline **pipelines = PushStructs(scratch.arena, GPU_D12_Pipeline *, num_pipelines); - { - __profn("Acquire pipelines"); - Counter counter = ZI; - RunJob(num_pipelines, GPU_D12_AcquirePipelineJob, JobPool_Inherit, JobPriority_Inherit, &counter, .descs_in = descs, .pipelines_out = pipelines); - YieldOnCounter(&counter); - } - for (u32 i = 0; i < num_pipelines; ++i) - { - GPU_D12_Pipeline *pipeline = pipelines[i]; - if (pipeline->success) - { - P_LogSuccessF("Successfully compiled pipeline \"%F\" in %F seconds", FmtString(pipeline->name), FmtFloat(SecondsFromNs(pipeline->compilation_time_ns))); - if (pipeline->error.len) - { - String msg = StringFormat(scratch.arena, Lit("Warning while compiling pipeline \"%F\":\n%F"), FmtString(pipeline->name), FmtString(pipeline->error)); - P_LogWarning(msg); - } - } - else - { - String error = pipeline->error.len > 0 ? pipeline->error : Lit("Unknown error"); - String msg = StringFormat(scratch.arena, Lit("Error initializing pipeline \"%F\":\n\n%F"), FmtString(pipeline->name), FmtString(error)); - P_LogError(msg); - P_MessageBox(P_MessageBoxKind_Warning, msg); - } - } - GPU_D12_RegisterPipeline(num_pipelines, pipelines); - - EndScratch(scratch); + LAX desc; + return (GPU_Resource *)0; } -//////////////////////////////// -//~ Noise texture initialization - -void GPU_D12_InitNoise(void) +void GPU_ReleaseResource(GPU_Resource *resource, GPU_Fence fence, GPU_ReleaseFlag flags) { - GPU_D12_SharedState *g = &GPU_D12_shared_state; - TempArena scratch = BeginScratchNoConflict(); - - { - String noise_res_name = Lit("noise_128x128x64_16.dat"); - RES_Resource noise_res = RES_OpenResource(noise_res_name); - DXGI_FORMAT format = DXGI_FORMAT_R16_UINT; - //u32 expected_size = K_BLUE_NOISE_TEX_WIDTH * K_BLUE_NOISE_TEX_HEIGHT * K_BLUE_NOISE_TEX_DEPTH * 2; - u32 expected_size = K_BLUE_NOISE_TEX_WIDTH * K_BLUE_NOISE_TEX_HEIGHT * K_BLUE_NOISE_TEX_DEPTH * 2; - if (RES_ResourceExists(&noise_res)) - { - String data = RES_GetResourceData(&noise_res); - if (data.len != expected_size) - { - Panic(StringFormat(scratch.arena, - Lit("Noise texture has unexpected size for a %Fx%Fx%F texture (expected %F, got %F)"), - FmtUint(K_BLUE_NOISE_TEX_WIDTH), FmtUint(K_BLUE_NOISE_TEX_HEIGHT), FmtUint(K_BLUE_NOISE_TEX_DEPTH), - FmtUint(expected_size), FmtUint(data.len))); - } - { - D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_DEFAULT }; - heap_props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; - heap_props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; - - D3D12_HEAP_FLAGS heap_flags = D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; - - D3D12_RESOURCE_DESC desc = ZI; - desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE3D; - - desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; - desc.Format = format; - desc.Alignment = 0; - desc.Width = K_BLUE_NOISE_TEX_WIDTH; - desc.Height = K_BLUE_NOISE_TEX_HEIGHT; - desc.DepthOrArraySize = K_BLUE_NOISE_TEX_DEPTH; - desc.MipLevels = 1; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - - GPU_D12_Resource *r = GPU_D12_AcquireResource(heap_props, heap_flags, desc, D3D12_RESOURCE_STATE_COPY_DEST); - r->srv_descriptor = GPU_D12_AcquireDescriptor(g->cbv_srv_uav_heap); - ID3D12Device_CreateShaderResourceView(g->device, r->resource, 0, r->srv_descriptor->handle); - - /* Upload texture */ - { - Counter counter = ZI; - RunJob(1, GPU_D12_UploadJob, JobPool_Inherit, JobPriority_Low, &counter, .resource = r, .data = data.text); - YieldOnCounter(&counter); - } - } - } - else - { - Panic(StringFormat(scratch.arena, Lit("Noise resource \"%F\" not found"), FmtString(noise_res_name))); - } - RES_CloseResource(&noise_res); - } - - EndScratch(scratch); + LAX resource; + LAX fence; + LAX flags; } -//////////////////////////////// -//~ Shader compilation - -#if RESOURCE_RELOADING - -JobDef(GPU_D12_CompileShaderJob, sig, id) +u32 GPU_GetResourceId(GPU_Resource *resource) { - __prof; - Arena *arena = sig->arena; - GPU_D12_ShaderDesc *desc = &sig->descs[id]; - GPU_D12_CompiledShaderResult *result = &sig->results[id]; - - TempArena scratch = BeginScratch(arena); - { - i64 start_ns = TimeNs(); - DXC_Result dxc_result = ZI; - { - __profn("Compile shader"); - P_LogInfoF("Compiling shader \"%F:%F\"", FmtString(desc->friendly_name), FmtString(desc->entry)); - /* NOTE: `DXC_ARGS` is supplied by build system at compile time */ - char *dxc_args_cstr = Stringize(DXC_ARGS); - String dxc_args_str = StringFromCstrNoLimit(dxc_args_cstr); - StringArray dxc_args_array = SplitString(scratch.arena, dxc_args_str, Lit(" ")); - String shader_args[] = { - desc->friendly_name, - Lit("-E"), desc->entry, - Lit("-T"), desc->target, - }; - u32 num_args = countof(shader_args) + dxc_args_array.count; - String *args = PushStructs(scratch.arena, String, num_args); - for (u32 i = 0; i < countof(shader_args); ++i) - { - args[i] = shader_args[i]; - } - for (u32 i = 0; i < dxc_args_array.count; ++i) - { - args[i + countof(shader_args)] = dxc_args_array.strings[i]; - } - dxc_result = DXC_Compile(arena, desc->src, num_args, args); - } - result->success = dxc_result.success; - result->dxc = dxc_result.dxc; - result->errors = dxc_result.errors; - result->elapsed_ns = TimeNs() - start_ns; - - } - EndScratch(scratch); -} - -#endif - -//////////////////////////////// -//~ Pipeline - -JobDef(GPU_D12_AcquirePipelineJob, sig, id) -{ - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - GPU_D12_PipelineDesc *desc = &sig->descs_in[id]; - GPU_D12_Pipeline **pipelines_out = sig->pipelines_out; - - GPU_D12_Pipeline *pipeline = 0; - { - Lock lock = LockE(&g->pipelines_mutex); - if (g->first_free_pipeline) - { - pipeline = g->first_free_pipeline; - g->first_free_pipeline = pipeline->next; - } - else - { - pipeline = PushStructNoZero(g->pipelines_arena, GPU_D12_Pipeline); - } - Unlock(&lock); - } - ZeroStruct(pipeline); - pipelines_out[id] = pipeline; - pipeline->desc = *desc; - pipeline->name = desc->name; - pipeline->hash = HashFnv64(Fnv64Basis, pipeline->name); - - TempArena scratch = BeginScratchNoConflict(); - { - i64 start_ns = TimeNs(); - String pipeline_name = pipeline->name; - P_LogInfoF("Loading pipeline \"%F\"", FmtString(pipeline_name)); - b32 success = 1; - HRESULT hr = 0; - - String error_str = ZI; - - String vs_dxc = desc->vs_dxc.len > 0 ? desc->vs_dxc : TAR_EntryFromName(&g->dxc_archive, CatString(scratch.arena, pipeline_name, Lit(".vs")))->data; - String ps_dxc = desc->ps_dxc.len > 0 ? desc->ps_dxc : TAR_EntryFromName(&g->dxc_archive, CatString(scratch.arena, pipeline_name, Lit(".ps")))->data; - String cs_dxc = desc->cs_dxc.len > 0 ? desc->cs_dxc : TAR_EntryFromName(&g->dxc_archive, CatString(scratch.arena, pipeline_name, Lit(".cs")))->data; - if (success && vs_dxc.len > 0 && ps_dxc.len <= 0) - { - error_str = Lit("Pipeline has vertex shader without pixel shader"); - success = 0; - } - if (success && vs_dxc.len <= 0 && ps_dxc.len > 0) - { - error_str = Lit("Pipeline has pixel shader without vertex shader"); - success = 0; - } - if (success && cs_dxc.len > 0 && (vs_dxc.len > 0 || ps_dxc.len > 0)) - { - error_str = Lit("Pipeline has a compute shader with a vertex/pixel shader"); - success = 0; - } - if (success && cs_dxc.len <= 0 && vs_dxc.len <= 0 && ps_dxc.len <= 0) - { - error_str = Lit("Pipeline has no shaders"); - success = 0; - } - - ID3D10Blob *vs_blob = 0; - ID3D10Blob *ps_blob = 0; - ID3D10Blob *cs_blob = 0; - if (success && vs_dxc.len > 0) - { - hr = D3DCreateBlob(vs_dxc.len, &vs_blob); - if (SUCCEEDED(hr)) - { - CopyBytes(ID3D10Blob_GetBufferPointer(vs_blob), vs_dxc.text, vs_dxc.len); - } - else - { - error_str = Lit("Failed to create vertex shader blob"); - success = 0; - } - } - if (success && ps_dxc.len > 0) - { - hr = D3DCreateBlob(ps_dxc.len, &ps_blob); - if (SUCCEEDED(hr)) - { - CopyBytes(ID3D10Blob_GetBufferPointer(ps_blob), ps_dxc.text, ps_dxc.len); - } - else - { - error_str = Lit("Failed to create pixel shader blob"); - success = 0; - } - } - if (success && cs_dxc.len > 0) - { - hr = D3DCreateBlob(cs_dxc.len, &cs_blob); - if (SUCCEEDED(hr)) - { - CopyBytes(ID3D10Blob_GetBufferPointer(cs_blob), cs_dxc.text, cs_dxc.len); - } - else - { - error_str = Lit("Failed to create compute shader blob"); - success = 0; - } - } - - /* Get root signature blob - * NOTE: This isn't necessary for creating the root signature (since it - * could reuse the shader blob), however we'd like to verify that the - * root signature exists and matches between vs & ps shaders. */ - ID3D10Blob *rootsig_blob = 0; - if (success) - { - __profn("Validate root signatures"); - if (cs_dxc.len > 0) - { - u32 cs_rootsig_data_len = 0; - ID3D10Blob *cs_rootsig_blob = 0; - D3DGetBlobPart(ID3D10Blob_GetBufferPointer(cs_blob), ID3D10Blob_GetBufferSize(cs_blob), D3D_BLOB_ROOT_SIGNATURE, 0, &cs_rootsig_blob); - if (cs_rootsig_blob) - { - cs_rootsig_data_len = ID3D10Blob_GetBufferSize(cs_rootsig_blob); - } - if (cs_rootsig_data_len == 0) - { - success = 0; - error_str = Lit("Compute shader is missing root signature"); - } - else - { - rootsig_blob = cs_rootsig_blob; - } - } - else - { - char *vs_rootsig_data = 0; - char *ps_rootsig_data = 0; - u32 vs_rootsig_data_len = 0; - u32 ps_rootsig_data_len = 0; - ID3D10Blob *vs_rootsig_blob = 0; - ID3D10Blob *ps_rootsig_blob = 0; - D3DGetBlobPart(ID3D10Blob_GetBufferPointer(vs_blob), ID3D10Blob_GetBufferSize(vs_blob), D3D_BLOB_ROOT_SIGNATURE, 0, &vs_rootsig_blob); - D3DGetBlobPart(ID3D10Blob_GetBufferPointer(ps_blob), ID3D10Blob_GetBufferSize(ps_blob), D3D_BLOB_ROOT_SIGNATURE, 0, &ps_rootsig_blob); - if (vs_rootsig_blob) - { - vs_rootsig_data = ID3D10Blob_GetBufferPointer(vs_rootsig_blob); - vs_rootsig_data_len = ID3D10Blob_GetBufferSize(vs_rootsig_blob); - } - if (ps_rootsig_blob) - { - ps_rootsig_data = ID3D10Blob_GetBufferPointer(ps_rootsig_blob); - ps_rootsig_data_len = ID3D10Blob_GetBufferSize(ps_rootsig_blob); - } - if (vs_rootsig_data_len == 0) - { - success = 0; - error_str = Lit("Vertex shader is missing root signature"); - } - else if (ps_rootsig_data_len == 0) - { - success = 0; - error_str = Lit("Pixel shader is missing root signature"); - } - else if (vs_rootsig_data_len != ps_rootsig_data_len || !EqBytes(vs_rootsig_data, ps_rootsig_data, vs_rootsig_data_len)) - { - success = 0; - error_str = Lit("Root signature mismatch between vertex and pixel shader"); - } - else - { - rootsig_blob = vs_rootsig_blob; - } - if (ps_rootsig_blob) - { - ID3D10Blob_Release(ps_rootsig_blob); - } - } - } - - /* Create root signature */ - ID3D12RootSignature *rootsig = 0; - if (success) - { - __profn("Create root signature"); - hr = ID3D12Device_CreateRootSignature(g->device, 0, ID3D10Blob_GetBufferPointer(rootsig_blob), ID3D10Blob_GetBufferSize(rootsig_blob), &IID_ID3D12RootSignature, (void **)&rootsig); - if (FAILED(hr)) - { - error_str = Lit("Failed to create root signature"); - success = 0; - } - } - - /* Create PSO */ - ID3D12PipelineState *pso = 0; - if (success) - { - if (cs_dxc.len > 0) - { - __profn("Create compute PSO"); - D3D12_COMPUTE_PIPELINE_STATE_DESC pso_desc = { 0 }; - pso_desc.pRootSignature = rootsig; - pso_desc.CS.pShaderBytecode = ID3D10Blob_GetBufferPointer(cs_blob); - pso_desc.CS.BytecodeLength = ID3D10Blob_GetBufferSize(cs_blob); - hr = ID3D12Device_CreateComputePipelineState(g->device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso); - } - else - { - __profn("Create graphics PSO"); - - /* Default rasterizer state */ - D3D12_RASTERIZER_DESC raster_desc = { - .FillMode = D3D12_FILL_MODE_SOLID, - .CullMode = D3D12_CULL_MODE_NONE, - .FrontCounterClockwise = 0, - .DepthBias = D3D12_DEFAULT_DEPTH_BIAS, - .DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP, - .SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS, - .DepthClipEnable = 1, - .MultisampleEnable = 0, - .AntialiasedLineEnable = 0, - .ForcedSampleCount = 0, - .ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF - }; - - /* Empty input layout */ - D3D12_INPUT_LAYOUT_DESC input_layout_desc = ZI; - - /* Blend state */ - D3D12_BLEND_DESC blend_desc = { - .AlphaToCoverageEnable = 0, - .IndependentBlendEnable = 1 - }; - for (i32 i = 0; i < (i32)countof(desc->rtvs); ++i) - { - StaticAssert(countof(blend_desc.RenderTarget) <= countof(desc->rtvs)); - if (desc->rtvs[i].format != DXGI_FORMAT_UNKNOWN) - { - b32 blending_enabled = desc->rtvs[i].blending; - blend_desc.RenderTarget[i].BlendEnable = blending_enabled; - blend_desc.RenderTarget[i].SrcBlend = D3D12_BLEND_SRC_ALPHA; - blend_desc.RenderTarget[i].DestBlend = D3D12_BLEND_INV_SRC_ALPHA; - blend_desc.RenderTarget[i].BlendOp = D3D12_BLEND_OP_ADD; - blend_desc.RenderTarget[i].SrcBlendAlpha = D3D12_BLEND_ONE; - blend_desc.RenderTarget[i].DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA; - blend_desc.RenderTarget[i].BlendOpAlpha = D3D12_BLEND_OP_ADD; - blend_desc.RenderTarget[i].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; - } - else - { - break; - } - } - - /* Disable depth stencil */ - D3D12_DEPTH_STENCIL_DESC depth_stencil_desc = { - .DepthEnable = 0, - .StencilEnable = 0 - }; - - /* PSO */ - D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc = { 0 }; - pso_desc.pRootSignature = rootsig; - pso_desc.VS.pShaderBytecode = ID3D10Blob_GetBufferPointer(vs_blob); - pso_desc.VS.BytecodeLength = ID3D10Blob_GetBufferSize(vs_blob); - pso_desc.PS.pShaderBytecode = ID3D10Blob_GetBufferPointer(ps_blob); - pso_desc.PS.BytecodeLength = ID3D10Blob_GetBufferSize(ps_blob); - pso_desc.BlendState = blend_desc; - pso_desc.SampleMask = UINT_MAX; - pso_desc.RasterizerState = raster_desc; - pso_desc.DepthStencilState = depth_stencil_desc; - pso_desc.InputLayout = input_layout_desc; - pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; - for (i32 i = 0; i < (i32)countof(desc->rtvs); ++i) - { - StaticAssert(countof(pso_desc.RTVFormats) <= countof(desc->rtvs)); - DXGI_FORMAT format = desc->rtvs[i].format; - if (format != DXGI_FORMAT_UNKNOWN) - { - pso_desc.RTVFormats[pso_desc.NumRenderTargets++] = format; - } - else - { - break; - } - } - pso_desc.SampleDesc.Count = 1; - pso_desc.SampleDesc.Quality = 0; - hr = ID3D12Device_CreateGraphicsPipelineState(g->device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso); - } - if (FAILED(hr)) - { - error_str = Lit("Failed to create pipeline state object"); - success = 0; - } - } - - /* Parse errors */ - if (!success && error_str.len <= 0) - { - error_str = Lit("Unknown error"); - } - - pipeline->pso = pso; - pipeline->rootsig = rootsig; - pipeline->compilation_time_ns = TimeNs() - start_ns; - pipeline->success = success; - pipeline->is_gfx = cs_dxc.len == 0; - pipeline->error = error_str; - - if (rootsig_blob) - { - ID3D10Blob_Release(rootsig_blob); - } - if (vs_blob) - { - ID3D10Blob_Release(vs_blob); - } - if (ps_blob) - { - ID3D10Blob_Release(ps_blob); - } - if (cs_blob) - { - ID3D10Blob_Release(cs_blob); - } - } - EndScratch(scratch); -} - -void GPU_D12_ReleasePipelineNow(GPU_D12_Pipeline *pipeline) -{ - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - if (pipeline->pso) - { - ID3D12PipelineState_Release(pipeline->pso); - } - Lock lock = LockE(&g->pipelines_mutex); - { - pipeline->next = g->first_free_pipeline; - g->first_free_pipeline = pipeline; - } - Unlock(&lock); -} - -//////////////////////////////// -//~ Pipeline cache - -GPU_D12_PipelineScope *GPU_D12_BeginPipelineScope(void) -{ - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - GPU_D12_PipelineScope *scope = 0; - { - Lock lock = LockE(&g->pipelines_mutex); - if (g->first_free_pipeline_scope) - { - scope = g->first_free_pipeline_scope; - g->first_free_pipeline_scope = scope->next_free; - } - Unlock(&lock); - } - Arena *arena = 0; - if (scope) - { - arena = scope->arena; - } - else - { - arena = AcquireArena(Mebi(64)); - } - ResetArena(arena); - scope = PushStruct(arena, GPU_D12_PipelineScope); - scope->arena = arena; - scope->refs = InitDict(scope->arena, 64); - return scope; -} - -void GPU_D12_EndPipelineScope(GPU_D12_PipelineScope *scope) -{ - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - Lock lock = LockE(&g->pipelines_mutex); - { - for (DictEntry *entry = scope->refs->first; entry; entry = entry->next) - { - GPU_D12_Pipeline *pipeline = (GPU_D12_Pipeline *)entry->value; - if (--pipeline->refcount <= 0) - { - GPU_D12_ReleaseDataFenced(pipeline, GPU_D12_FencedReleaseKind_Pipeline); - } - } - scope->next_free = g->first_free_pipeline_scope; - g->first_free_pipeline_scope = scope; - } - Unlock(&lock); -} - -Readonly GPU_D12_Pipeline GPU_D12_nil_pipeline = ZI; -GPU_D12_Pipeline *GPU_D12_PipelineFromName(GPU_D12_PipelineScope *scope, String name) -{ - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - GPU_D12_Pipeline *result = &GPU_D12_nil_pipeline; - u64 hash = HashFnv64(Fnv64Basis, name); - - GPU_D12_Pipeline *tmp = (GPU_D12_Pipeline *)DictValueFromHash(scope->refs, hash); - if (tmp) - { - result = tmp; - } - else - { - { - Lock lock = LockE(&g->pipelines_mutex); - tmp = (GPU_D12_Pipeline *)DictValueFromHash(g->top_successful_pipelines, hash); - if (tmp) - { - ++tmp->refcount; - } - Unlock(&lock); - } - if (tmp) - { - SetDictValue(scope->arena, scope->refs, hash, (u64)tmp); - result = tmp; - } - } - - return result; -} - -void GPU_D12_RegisterPipeline(u64 num_pipelines, GPU_D12_Pipeline **pipelines) -{ - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - Lock lock = LockE(&g->pipelines_mutex); - { - for (u64 i = 0; i < num_pipelines; ++i) - { - GPU_D12_Pipeline *pipeline = pipelines[i]; - u64 hash = pipeline->hash; - /* Insert into top dict */ - { - GPU_D12_Pipeline *old_pipeline = (GPU_D12_Pipeline *)DictValueFromHash(g->top_pipelines, hash); - if (old_pipeline && --old_pipeline->refcount <= 0) - { - GPU_D12_ReleaseDataFenced(old_pipeline, GPU_D12_FencedReleaseKind_Pipeline); - } - SetDictValue(g->pipelines_arena, g->top_pipelines, hash, (u64)pipeline); - ++pipeline->refcount; - } - /* Insert into success dict */ - if (pipeline->success) - { - GPU_D12_Pipeline *old_pipeline = (GPU_D12_Pipeline *)DictValueFromHash(g->top_successful_pipelines, hash); - if (old_pipeline && --old_pipeline->refcount <= 0) - { - GPU_D12_ReleaseDataFenced(old_pipeline, GPU_D12_FencedReleaseKind_Pipeline); - } - SetDictValue(g->pipelines_arena, g->top_successful_pipelines, hash, (u64)pipeline); - ++pipeline->refcount; - } - } - } - Unlock(&lock); -} - -#if RESOURCE_RELOADING -W_CallbackFuncDef(GPU_D12_WatchPipelineCallback, name) -{ - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - TempArena scratch = BeginScratchNoConflict(); - - String rst_extension = Lit(".rst"); - String knl_extension = Lit(".knl"); - - b32 is_src = StringStartsWith(name, Lit("src/")); - b32 is_rs = is_src && StringEndsWith(name, rst_extension); - b32 is_cs = is_src && !is_rs && StringEndsWith(name, knl_extension); - b32 success = 0; - - /* Recompile shaders */ - String pipeline_name = ZI; - String friendly_name = ZI; - i32 num_shaders = 0; - GPU_D12_ShaderDesc *shader_descs = 0; - GPU_D12_CompiledShaderResult *shader_results = 0; - if (is_rs || is_cs) - { - P_LogDebugF("Change detected in shader source file \"%F\", recompiling...", FmtString(name)); - success = 1; - P_File file = P_OpenFileReadWait(name); - String data = P_ReadFile(scratch.arena, file); - { - friendly_name = name; - StringArray split = SplitString(scratch.arena, friendly_name, Lit("src/")); - friendly_name = split.count > 0 ? CatString(scratch.arena, Lit("src/"), split.strings[split.count - 1]) : friendly_name; - } - { - pipeline_name = name; - StringArray split = SplitString(scratch.arena, pipeline_name, Lit("/")); - pipeline_name = split.count > 0 ? split.strings[split.count - 1] : pipeline_name; - split = SplitString(scratch.arena, pipeline_name, Lit(".")); - pipeline_name = split.count > 1 ? split.strings[split.count - 2] : pipeline_name; - } - { - GPU_D12_CompileShaderJob_Desc *job_desc = PushJobDesc(GPU_D12_CompileShaderJob, .count = 0); - job_desc->sig->arena = scratch.arena; - if (is_rs) - { - num_shaders = 2; - shader_descs = PushStructs(scratch.arena, GPU_D12_ShaderDesc, num_shaders); - shader_results = PushStructs(scratch.arena, GPU_D12_CompiledShaderResult, num_shaders); - job_desc->sig->descs = shader_descs; - job_desc->sig->results = shader_results; - job_desc->sig->descs[0].src = data; - job_desc->sig->descs[0].friendly_name = friendly_name; - job_desc->sig->descs[0].entry = Lit("vs"); - job_desc->sig->descs[0].target = Lit("vs_6_6"); - job_desc->sig->descs[1].src = data; - job_desc->sig->descs[1].friendly_name = friendly_name; - job_desc->sig->descs[1].entry = Lit("ps"); - job_desc->sig->descs[1].target = Lit("ps_6_6"); - } - else if (is_cs) - { - num_shaders = 1; - shader_descs = PushStructs(scratch.arena, GPU_D12_ShaderDesc, num_shaders); - shader_results = PushStructs(scratch.arena, GPU_D12_CompiledShaderResult, num_shaders); - job_desc->sig->descs = shader_descs; - job_desc->sig->results = shader_results; - job_desc->sig->descs[0].src = data; - job_desc->sig->descs[0].friendly_name = friendly_name; - job_desc->sig->descs[0].entry = Lit("cs"); - job_desc->sig->descs[0].target = Lit("cs_6_6"); - } - { - Counter counter = ZI; - job_desc->count = num_shaders; - job_desc->counter = &counter; - RunJobEx((GenericJobDesc *)job_desc); - YieldOnCounter(&counter); - } - } - P_CloseFIle(file); - } - - - for (i32 i = 0; i < num_shaders; ++i) - { - GPU_D12_ShaderDesc *desc = &shader_descs[i]; - GPU_D12_CompiledShaderResult *result = &shader_results[i]; - if (result->success) - { - P_LogSuccessF("Finished compiling shader \"%F:%F\" in %F seconds", FmtString(desc->friendly_name), FmtString(desc->entry), FmtFloat(SecondsFromNs(result->elapsed_ns))); - if (result->errors.len > 0) - { - String msg = result->errors; - P_LogWarning(msg); - } - } - else - { - String msg = result->errors; - P_LogError(msg); - success = 0; - } - } - - if (success) - { - /* Create pipeline descs */ - u32 num_pipelines = 0; - GPU_D12_PipelineDesc *pipeline_descs = PushDry(scratch.arena, GPU_D12_PipelineDesc); - for (DictEntry *entry = g->pipeline_descs->first; entry; entry = entry->next) - { - GPU_D12_PipelineDesc *pipeline_desc = (GPU_D12_PipelineDesc *)entry->value; - GPU_D12_PipelineDesc new_pipeline_desc = *pipeline_desc; - if (EqString(pipeline_desc->name, pipeline_name)) - { - if (is_rs) - { - new_pipeline_desc.vs_dxc = shader_results[0].dxc; - new_pipeline_desc.ps_dxc = shader_results[1].dxc; - } - else if (is_cs) - { - new_pipeline_desc.cs_dxc = shader_results[0].dxc; - } - *PushStructNoZero(scratch.arena, GPU_D12_PipelineDesc) = new_pipeline_desc; - ++num_pipelines; - } - } - - /* Recompile dirty pipelines */ - if (num_pipelines > 0) - { - __profn("Compile dirty pipelines"); - GPU_D12_Pipeline **pipelines = PushStructs(scratch.arena, GPU_D12_Pipeline *, num_pipelines); - { - Counter counter = ZI; - RunJob(num_pipelines, GPU_D12_AcquirePipelineJob, JobPool_Inherit, JobPriority_Low, &counter, .descs_in = pipeline_descs, .pipelines_out = pipelines); - YieldOnCounter(&counter); - } - { - Lock lock = LockS(&g->pipelines_mutex); - for (u32 i = 0; i < num_pipelines; ++i) - { - GPU_D12_Pipeline *pipeline = pipelines[i]; - if (pipeline->success) - { - P_LogSuccessF("Successfully compiled pipeline \"%F\" in %F seconds", FmtString(pipeline->name), FmtFloat(SecondsFromNs(pipeline->compilation_time_ns))); - if (pipeline->error.len > 0) - { - String msg = StringFormat(scratch.arena, Lit("Warning while compiling pipeline \"%F\":\n%F"), FmtString(pipeline->name), FmtString(pipeline->error)); - P_LogWarning(msg); - } - } - else - { - { - String error = pipeline->error.len > 0 ? pipeline->error : Lit("Unknown error"); - String msg = StringFormat(scratch.arena, Lit("Error compiling pipeline \"%F\":\n%F"), FmtString(pipeline->name), FmtString(error)); - P_LogError(msg); - } - GPU_D12_Pipeline *old_pipeline = (GPU_D12_Pipeline *)DictValueFromHash(g->top_successful_pipelines, pipeline->hash); - if (!old_pipeline) - { - /* If no previously successful pipeline exists, then show a message box rather than logging since logs may not be visible to user */ - String error = pipeline->error.len > 0 ? pipeline->error : Lit("Unknown error"); - String msg = StringFormat(scratch.arena, Lit("Error compiling pipeline \"%F\":\n\n%F"), FmtString(pipeline->name), FmtString(error)); - P_MessageBox(P_MessageBoxKind_Warning, msg); - } - - } - } - Unlock(&lock); - } - GPU_D12_RegisterPipeline(num_pipelines, pipelines); - } - } - - EndScratch(scratch); -} -#endif - -//////////////////////////////// -//~ Descriptor - -GPU_D12_Descriptor *GPU_D12_AcquireDescriptor(GPU_D12_CpuDescriptorHeap *dh) -{ - __prof; - GPU_D12_Descriptor *d = 0; - u32 index = 0; - D3D12_CPU_DESCRIPTOR_HANDLE handle = ZI; - { - Lock lock = LockE(&dh->mutex); - if (dh->first_free_descriptor) - { - d = dh->first_free_descriptor; - dh->first_free_descriptor = d->next_free; - handle = d->handle; - index = d->index; - } - else - { - if (dh->num_descriptors_reserved >= dh->num_descriptors_capacity) - { - Panic(Lit("Max descriptors reached in heap")); - } - d = PushStructNoZero(dh->arena, GPU_D12_Descriptor); - index = dh->num_descriptors_reserved++; - handle.ptr = dh->handle.ptr + (index * dh->descriptor_size); - } - Unlock(&lock); - } - ZeroStruct(d); - d->heap = dh; - d->handle = handle; - d->index = index; - return d; -} - -void GPU_D12_ReleaseDescriptor(GPU_D12_Descriptor *descriptor) -{ - GPU_D12_CpuDescriptorHeap *dh = descriptor->heap; - Lock lock = LockE(&dh->mutex); - { - descriptor->next_free = dh->first_free_descriptor; - dh->first_free_descriptor = descriptor; - } - Unlock(&lock); -} - -//////////////////////////////// -//~ CPU descriptor heap - -GPU_D12_CpuDescriptorHeap *GPU_D12_AcquireCpuDescriptorHeap(enum D3D12_DESCRIPTOR_HEAP_TYPE type) -{ - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - GPU_D12_CpuDescriptorHeap *dh = 0; - { - Arena *arena = AcquireArena(Mebi(64)); - dh = PushStruct(arena, GPU_D12_CpuDescriptorHeap); - dh->arena = arena; - } - - u32 num_descriptors = 0; - u32 descriptor_size = 0; - if (type < (i32)countof(g->desc_counts) && type < (i32)countof(g->desc_sizes)) - { - num_descriptors = g->desc_counts[type]; - descriptor_size = g->desc_sizes[type]; - } - if (num_descriptors == 0 || descriptor_size == 0) - { - Panic(Lit("Unsupported CPU descriptor type")); - } - dh->num_descriptors_capacity = num_descriptors; - dh->descriptor_size = descriptor_size; - - D3D12_DESCRIPTOR_HEAP_DESC desc = ZI; - desc.Type = type; - desc.NumDescriptors = num_descriptors; - HRESULT hr = ID3D12Device_CreateDescriptorHeap(g->device, &desc, &IID_ID3D12DescriptorHeap, (void **)&dh->heap); - if (FAILED(hr)) - { - Panic(Lit("Failed to create CPU descriptor heap")); - } - ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(dh->heap, &dh->handle); - - return dh; -} - -#if 0 -void cpu_descriptor_heap_release(GPU_D12_CpuDescriptorHeap *dh) -{ - /* TODO */ - LAX dh; -} -#endif - -//////////////////////////////// -//~ Fenced release - -void GPU_D12_ReleaseDataFenced(void *data, GPU_D12_FencedReleaseKind kind) -{ - GPU_D12_SharedState *g = &GPU_D12_shared_state; - GPU_D12_FencedReleaseData fr = ZI; - fr.kind = kind; - fr.ptr = data; - - u64 fr_targets[countof(g->fenced_release_targets)] = ZI; - - /* Read current fence target values from command queues */ - for (u32 i = 0; i < countof(g->command_queues); ++i) - { - GPU_D12_CommandQueue *cq = g->command_queues[i]; - Lock lock = LockS(&cq->submit_fence_mutex); - { - fr_targets[i] = cq->submit_fence_target; - } - Unlock(&lock); - } - - /* Push data to release queue */ - { - Lock lock = LockE(&g->fenced_releases_mutex); - { - *PushStruct(g->fenced_releases_arena, GPU_D12_FencedReleaseData) = fr; - CopyBytes(g->fenced_release_targets, fr_targets, sizeof(fr_targets)); - } - Unlock(&lock); - } - - /* Wake evictor */ - { - Lock lock = LockE(&g->evictor_wake_mutex); - { - ++g->evictor_wake_gen; - SignalCv(&g->evictor_wake_cv, I32Max); - } - Unlock(&lock); - } -} - -//////////////////////////////// -//~ Resource - -GPU_D12_Resource *GPU_D12_AcquireResource(D3D12_HEAP_PROPERTIES heap_props, D3D12_HEAP_FLAGS heap_flags, D3D12_RESOURCE_DESC desc, D3D12_RESOURCE_STATES initial_state) -{ - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - GPU_D12_Resource *r = 0; - { - Lock lock = LockE(&g->resources_mutex); - if (g->first_free_resource) - { - r = g->first_free_resource; - g->first_free_resource = r->next_free; - } - else - { - r = PushStructNoZero(g->resources_arena, GPU_D12_Resource); - } - Unlock(&lock); - } - ZeroStruct(r); - - D3D12_CLEAR_VALUE clear_value = { .Format = desc.Format, .Color = { 0 } }; - D3D12_CLEAR_VALUE *clear_value_ptr = desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET ? &clear_value : 0; - HRESULT hr = ID3D12Device_CreateCommittedResource(g->device, &heap_props, heap_flags, &desc, initial_state, clear_value_ptr, &IID_ID3D12Resource, (void **)&r->resource); - if (FAILED(hr)) - { - /* TODO: Don't panic */ - Panic(Lit("Failed to create resource")); - } - - r->state = initial_state; - - if (desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - r->gpu_address = ID3D12Resource_GetGPUVirtualAddress(r->resource); - } - - return r; -} - -void GPU_D12_ReleaseResourceNow(GPU_D12_Resource *t) -{ - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - - /* Release descriptors */ - /* TODO: Batch lock heaps */ - if (t->cbv_descriptor) - { - GPU_D12_ReleaseDescriptor(t->cbv_descriptor); - } - if (t->srv_descriptor) - { - GPU_D12_ReleaseDescriptor(t->srv_descriptor); - } - if (t->uav_descriptor) - { - GPU_D12_ReleaseDescriptor(t->uav_descriptor); - } - if (t->rtv_descriptor) - { - GPU_D12_ReleaseDescriptor(t->rtv_descriptor); - } - - /* Release resource */ - ID3D12Resource_Release(t->resource); - - /* Add to free list */ - Lock lock = LockE(&g->resources_mutex); - t->next_free = g->first_free_resource; - g->first_free_resource = t; - Unlock(&lock); -} - -void GPU_ReleaseResourceFenced(GPU_Resource *resource) -{ - GPU_D12_Resource *r = (GPU_D12_Resource *)resource; - GPU_D12_ReleaseDataFenced(r, GPU_D12_FencedReleaseKind_Resource); -} - -//////////////////////////////// -//~ Resource barrier - -void GPU_D12_InsertBarrier(ID3D12GraphicsCommandList *cl, i32 num_descs, GPU_D12_ResourceBarrierDesc *descs) -{ - __prof; - TempArena scratch = BeginScratchNoConflict(); - - i32 num_rbs = 0; - struct D3D12_RESOURCE_BARRIER *rbs = PushStructsNoZero(scratch.arena, struct D3D12_RESOURCE_BARRIER, num_descs); - for (i32 i = 0; i < num_descs; ++i) - { - GPU_D12_ResourceBarrierDesc *desc = &descs[i]; - GPU_D12_Resource *resource = desc->resource; - enum D3D12_RESOURCE_BARRIER_TYPE type = desc->type; - if (type == D3D12_RESOURCE_BARRIER_TYPE_TRANSITION) - { - enum D3D12_RESOURCE_STATES old_state = resource->state; - enum D3D12_RESOURCE_STATES new_state = desc->new_state; - if (new_state != old_state) - { - struct D3D12_RESOURCE_BARRIER *rb = &rbs[num_rbs++]; - ZeroStruct(rb); - rb->Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - rb->Flags = 0; - rb->Transition.pResource = resource->resource; - rb->Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - rb->Transition.StateBefore = old_state; - rb->Transition.StateAfter = new_state; - resource->state = new_state; - } - } - else if (type == D3D12_RESOURCE_BARRIER_TYPE_UAV) - { - struct D3D12_RESOURCE_BARRIER *rb = &rbs[num_rbs++]; - ZeroStruct(rb); - rb->Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; - rb->Flags = 0; - rb->UAV.pResource = resource->resource; - } - else - { - /* Unknown barrier type */ - Assert(0); - } - } - - if (num_rbs > 0) - { - ID3D12GraphicsCommandList_ResourceBarrier(cl, num_rbs, rbs); - } - - EndScratch(scratch); -} - -//////////////////////////////// -//~ Command queue - -GPU_D12_CommandListPool *GPU_D12_AcquireCommandListPool(GPU_D12_CommandQueue *cq); - -JobDef(GPU_D12_AcquireCommandQueueJob, sig, id) -{ - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - GPU_D12_CommandQueueDesc *desc = &sig->descs_in[id]; - { - GPU_D12_CommandQueue *cq = 0; - { - Arena *arena = AcquireArena(Gibi(64)); - cq = PushStruct(arena, GPU_D12_CommandQueue); - cq->arena = arena; - } - cq->desc = *desc; - - D3D12_COMMAND_QUEUE_DESC dx12_desc = ZI; - dx12_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; - dx12_desc.Type = desc->type; - dx12_desc.Priority = desc->priority; - HRESULT hr = ID3D12Device_CreateCommandQueue(g->device, &dx12_desc, &IID_ID3D12CommandQueue, (void **)&cq->cq); - if (FAILED(hr)) - { - Panic(Lit("Failed to create command queue")); - } - - hr = ID3D12Device_CreateFence(g->device, 0, 0, &IID_ID3D12Fence, (void **)&cq->submit_fence); - if (FAILED(hr)) - { - Panic(Lit("Failed to create command queue fence")); - } - - cq->cl_pool = GPU_D12_AcquireCommandListPool(cq); - - sig->cqs_out[id] = cq; - } -} - -void GPU_D12_ReleaseCommandQueue(GPU_D12_CommandQueue *cq) -{ - __prof; - /* TODO */ - LAX cq; - //ID3D12CommandQueue_Release(cq->cq); -} - -//////////////////////////////// -//~ Command list - -GPU_D12_CommandListPool *GPU_D12_AcquireCommandListPool(GPU_D12_CommandQueue *cq) -{ - GPU_D12_CommandListPool *pool = 0; - { - Arena *arena = AcquireArena(Gibi(64)); - pool = PushStruct(arena, GPU_D12_CommandListPool); - pool->arena = arena; - } - pool->cq = cq; - return pool; -} - -GPU_D12_CommandList *GPU_D12_BeginCommandList(GPU_D12_CommandListPool *pool) -{ - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - GPU_D12_CommandQueue *cq = pool->cq; - u64 completed_fence_value = ID3D12Fence_GetCompletedValue(cq->submit_fence); - - GPU_D12_CommandList *cl = 0; - struct ID3D12GraphicsCommandList *old_cl = 0; - struct ID3D12CommandAllocator *old_ca = 0; - { - Lock lock = LockE(&pool->mutex); - /* Find first command list ready for reuse */ - for (GPU_D12_CommandList *tmp = pool->first_submitted_command_list; tmp; tmp = tmp->next_submitted) - { - if (completed_fence_value >= tmp->submitted_fence_target) - { - cl = tmp; - break; - } - } - if (cl) - { - /* Remove from submitted list */ - old_cl = cl->cl; - old_ca = cl->ca; - GPU_D12_CommandList *prev = cl->prev_submitted; - GPU_D12_CommandList *next = cl->next_submitted; - if (prev) - { - prev->next_submitted = next; - } - else - { - pool->first_submitted_command_list = next; - } - if (next) - { - next->prev_submitted = prev; - } - else - { - pool->last_submitted_command_list = prev; - } - } - else - { - cl = PushStructNoZero(pool->arena, GPU_D12_CommandList); - } - Unlock(&lock); - } - ZeroStruct(cl); - cl->cq = cq; - cl->pool = pool; - cl->global_record_lock = LockS(&g->global_command_list_record_mutex); - - HRESULT hr = 0; - if (old_cl) - { - cl->cl = old_cl; - cl->ca = old_ca; - } - else - { - hr = ID3D12Device_CreateCommandAllocator(g->device, cq->desc.type, &IID_ID3D12CommandAllocator, (void **)&cl->ca); - if (FAILED(hr)) - { - Panic(Lit("Failed to create command allocator")); - } - - hr = ID3D12Device_CreateCommandList(g->device, 0, cq->desc.type, cl->ca, 0, &IID_ID3D12GraphicsCommandList, (void **)&cl->cl); - if (FAILED(hr)) - { - Panic(Lit("Failed to create command list")); - } - - hr = ID3D12GraphicsCommandList_Close(cl->cl); - if (FAILED(hr)) - { - Panic(Lit("Failed to close command list during initialization")); - } - } - - /* Reset */ - hr = ID3D12CommandAllocator_Reset(cl->ca); - if (FAILED(hr)) - { - Panic(Lit("Failed to reset command allocator")); - } - - hr = ID3D12GraphicsCommandList_Reset(cl->cl, cl->ca, 0); - if (FAILED(hr)) - { - Panic(Lit("Failed to reset command list")); - } - - return cl; -} - -/* TODO: Allow multiple command list submissions */ -u64 GPU_D12_EndCommandList(GPU_D12_CommandList *cl) -{ - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - GPU_D12_CommandQueue *cq = cl->cq; - GPU_D12_CommandListPool *pool = cl->pool; - - /* Close */ - { - __profn("Close DX12 command list"); - HRESULT hr = ID3D12GraphicsCommandList_Close(cl->cl); - if (FAILED(hr)) - { - /* TODO: Don't panic */ - Panic(Lit("Failed to close command list before execution")); - } - } - - /* Submit */ - u64 submit_fence_target = 0; - { - __profn("Execute"); - Lock submit_lock = LockS(&g->global_submit_mutex); - Lock fence_lock = LockE(&cq->submit_fence_mutex); - { - submit_fence_target = ++cq->submit_fence_target; - ID3D12CommandQueue_ExecuteCommandLists(cq->cq, 1, (ID3D12CommandList **)&cl->cl); - ID3D12CommandQueue_Signal(cq->cq, cq->submit_fence, submit_fence_target); - } - Unlock(&fence_lock); - Unlock(&submit_lock); - } - - /* Add descriptor heaps to submitted list */ - { - Lock lock = LockE(&g->command_descriptor_heaps_mutex); - for (GPU_D12_CommandDescriptorHeap *cdh = cl->first_command_descriptor_heap; cdh; cdh = cdh->next_in_command_list) - { - cdh->submitted_cq = cq; - cdh->submitted_fence_target = submit_fence_target; - if (g->last_submitted_command_descriptor_heap) - { - g->last_submitted_command_descriptor_heap->next_submitted = cdh; - } - else - { - g->first_submitted_command_descriptor_heap = cdh; - } - g->last_submitted_command_descriptor_heap = cdh; - } - Unlock(&lock); - } - - /* Add command buffers to submitted list */ - { - Lock lock = LockE(&g->command_buffers_mutex); - for (GPU_D12_CommandBuffer *cb = cl->first_command_buffer; cb; cb = cb->next_in_command_list) - { - GPU_D12_CommandBufferGroup *group = cb->group; - cb->submitted_cq = cq; - cb->submitted_fence_target = submit_fence_target; - if (group->last_submitted) - { - group->last_submitted->next_submitted = cb; - } - else - { - group->first_submitted = cb; - } - group->last_submitted = cb; - } - Unlock(&lock); - } - - /* Add command list to pool submitted list */ - Unlock(&cl->global_record_lock); - cl->submitted_fence_target = submit_fence_target; - { - Lock lock = LockE(&pool->mutex); - if (pool->last_submitted_command_list) - { - pool->last_submitted_command_list->next_submitted = cl; - } - else - { - pool->first_submitted_command_list = cl; - } - pool->last_submitted_command_list = cl; - Unlock(&lock); - } - - return submit_fence_target; -} - -//////////////////////////////// -//~ Command descriptor heap (GPU / shader visible descriptor heap) - -GPU_D12_CommandDescriptorHeap *GPU_D12_PushDescriptorHeap(GPU_D12_CommandList *cl, GPU_D12_CpuDescriptorHeap *dh_cpu) -{ - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - Assert(dh_cpu->type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); /* Src heap must have expected type */ - - /* Acquire GPU heap */ - GPU_D12_CommandDescriptorHeap *cdh = 0; - ID3D12DescriptorHeap *old_heap = 0; - D3D12_CPU_DESCRIPTOR_HANDLE old_start_cpu_handle = ZI; - D3D12_GPU_DESCRIPTOR_HANDLE old_start_gpu_handle = ZI; - { - Lock lock = LockE(&g->command_descriptor_heaps_mutex); - /* Find first heap ready for reuse */ - for (GPU_D12_CommandDescriptorHeap *tmp = g->first_submitted_command_descriptor_heap; tmp; tmp = tmp->next_submitted) - { - /* TODO: Cache completed fence values */ - u64 completed_fence_value = ID3D12Fence_GetCompletedValue(tmp->submitted_cq->submit_fence); - if (completed_fence_value >= tmp->submitted_fence_target) - { - cdh = tmp; - break; - } - } - if (cdh) - { - /* Remove from submitted list */ - old_heap = cdh->heap; - old_start_cpu_handle = cdh->start_cpu_handle; - old_start_gpu_handle = cdh->start_gpu_handle; - GPU_D12_CommandDescriptorHeap *prev = cdh->prev_submitted; - GPU_D12_CommandDescriptorHeap *next = cdh->next_submitted; - if (prev) - { - prev->next_submitted = next; - } - else - { - g->first_submitted_command_descriptor_heap = next; - } - if (next) - { - next->prev_submitted = prev; - } - else - { - g->last_submitted_command_descriptor_heap = prev; - } - } - else - { - /* No available heap available for reuse, allocate new */ - cdh = PushStructNoZero(g->command_descriptor_heaps_arena, GPU_D12_CommandDescriptorHeap); - } - Unlock(&lock); - } - ZeroStruct(cdh); - - if (old_heap) - { - cdh->heap = old_heap; - cdh->start_cpu_handle = old_start_cpu_handle; - cdh->start_gpu_handle = old_start_gpu_handle; - } - else - { - D3D12_DESCRIPTOR_HEAP_DESC desc = ZI; - desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - desc.NumDescriptors = DX12_NUM_CBV_SRV_UAV_DESCRIPTORS; - desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - HRESULT hr = ID3D12Device_CreateDescriptorHeap(g->device, &desc, &IID_ID3D12DescriptorHeap, (void **)&cdh->heap); - if (FAILED(hr)) - { - Panic(Lit("Failed to create GPU descriptor heap")); - } - ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(cdh->heap, &cdh->start_cpu_handle); - ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(cdh->heap, &cdh->start_gpu_handle); - } - - /* Copy CPU heap */ - { - Lock lock = LockS(&dh_cpu->mutex); - ID3D12Device_CopyDescriptorsSimple(g->device, dh_cpu->num_descriptors_reserved, cdh->start_cpu_handle, dh_cpu->handle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - Unlock(&lock); - } - - /* Insert into command list */ - cdh->next_in_command_list = cl->first_command_descriptor_heap; - cl->first_command_descriptor_heap = cdh; - - return cdh; -} - -//////////////////////////////// -//~ Command buffer - -u64 GPU_D12_CommandBufferHashFromSize(u64 size) -{ - u64 hash = RandU64FromSeed(size); - return hash; -} - -GPU_D12_CommandBuffer *GPU_D12_PushCommandBufferEx(GPU_D12_CommandList *cl, u64 data_len, void *data, u64 data_stride) -{ - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - - /* Data length should be a multiple of stride */ - Assert(data_len % data_stride == 0); - - /* Determine size */ - u64 size = MaxU64(DX12_COMMAND_BUFFER_MIN_SIZE, AlignU64Pow2(data_len)); - - /* Acquire buffer */ - GPU_D12_CommandBufferGroup *cb_group = 0; - GPU_D12_CommandBuffer *cb = 0; - GPU_D12_Resource *r = 0; - { - Lock lock = LockE(&g->command_buffers_mutex); - - { - u64 group_hash = GPU_D12_CommandBufferHashFromSize(size); - DictEntry *cb_group_entry = EnsureDictEntry(g->command_buffers_arena, g->command_buffers_dict, group_hash); - cb_group = (GPU_D12_CommandBufferGroup *)cb_group_entry->value; - if (!cb_group) - { - /* Create group */ - cb_group = PushStruct(g->command_buffers_arena, GPU_D12_CommandBufferGroup); - cb_group_entry->value = (u64)cb_group; - } - } - /* Find first command buffer ready for reuse */ - for (GPU_D12_CommandBuffer *tmp = cb_group->first_submitted; tmp; tmp = tmp->next_submitted) - { - /* TODO: Cache completed fence values */ - u64 completed_fence_value = ID3D12Fence_GetCompletedValue(tmp->submitted_cq->submit_fence); - if (completed_fence_value >= tmp->submitted_fence_target) - { - cb = tmp; - break; - } - } - if (cb) - { - /* Remove from submitted list */ - r = cb->resource; - GPU_D12_CommandBuffer *prev = cb->prev_submitted; - GPU_D12_CommandBuffer *next = cb->next_submitted; - if (prev) - { - prev->next_submitted = next; - } - else - { - cb_group->first_submitted = next; - } - if (next) - { - next->prev_submitted = prev; - } - else - { - cb_group->last_submitted = prev; - } - } - else - { - /* Acquire new */ - cb = PushStructNoZero(g->command_buffers_arena, GPU_D12_CommandBuffer); - } - Unlock(&lock); - } - ZeroStruct(cb); - cb->group = cb_group; - cb->size = data_len; - - /* Create upload heap */ - if (!r) - { - D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_UPLOAD }; - heap_props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; - heap_props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; - - D3D12_HEAP_FLAGS heap_flags = D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; - - D3D12_RESOURCE_DESC desc = ZI; - desc.Flags = 0; - desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - desc.Format = DXGI_FORMAT_UNKNOWN; - desc.Alignment = 0; - desc.Width = size; - desc.Height = 1; - desc.DepthOrArraySize = 1; - desc.MipLevels = 1; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - D3D12_RESOURCE_STATES initial_state = D3D12_RESOURCE_STATE_GENERIC_READ; - - r = GPU_D12_AcquireResource(heap_props, heap_flags, desc, initial_state); - r->srv_descriptor = GPU_D12_AcquireDescriptor(g->cbv_srv_uav_heap); - } - cb->resource = r; - - { - struct D3D12_SHADER_RESOURCE_VIEW_DESC desc = ZI; - desc.Format = DXGI_FORMAT_UNKNOWN; - desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; - desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - desc.Buffer.FirstElement = 0; - desc.Buffer.NumElements = MaxU32(data_len / data_stride, 1); - desc.Buffer.StructureByteStride = data_stride; - desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE; - ID3D12Device_CreateShaderResourceView(g->device, r->resource, &desc, r->srv_descriptor->handle); - } - - /* Write data to resource */ - { - D3D12_RANGE read_range = ZI; - void *dst = 0; - HRESULT hr = ID3D12Resource_Map(cb->resource->resource, 0, &read_range, &dst); - if (FAILED(hr) || !dst) - { - /* TODO: Don't panic */ - Panic(Lit("Failed to map command buffer resource")); - } - CopyBytes(dst, data, data_len); - ID3D12Resource_Unmap(cb->resource->resource, 0, 0); - } - - /* Insert into command list */ - cb->next_in_command_list = cl->first_command_buffer; - cl->first_command_buffer = cb; - - return cb; -} - -//////////////////////////////// -//~ Wait job - -JobDef(GPU_D12_WaitOnFenceJob, sig, UNUSED id) -{ - __prof; - ID3D12Fence *fence = sig->fence; - u64 target = sig->target; - if (ID3D12Fence_GetCompletedValue(fence) < target) - { - /* TODO: Pool events */ - HANDLE event = CreateEvent(0, 0, 0, 0); - ID3D12Fence_SetEventOnCompletion(sig->fence, sig->target, event); - WaitForSingleObject(event, INFINITE); - CloseHandle(event); - } -} - -//////////////////////////////// -//~ Texture - -GPU_Resource *GPU_AcquireTexture(GPU_TextureFormat format, u32 flags, Vec2I32 size, void *initial_data) -{ - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - if (size.x <= 0 || size.y <= 0) - { - Panic(Lit("Tried to create texture with dimension <= 0")); - } - LocalPersist const DXGI_FORMAT formats[] = { - [GP_TEXTURE_FORMAT_R8_UNORM] = DXGI_FORMAT_R8_UNORM, - [GP_TEXTURE_FORMAT_R8G8B8A8_UNORM] = DXGI_FORMAT_R8G8B8A8_UNORM, - [GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB] = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - [GP_TEXTURE_FORMAT_R16G16B16A16_FLOAT] = DXGI_FORMAT_R16G16B16A16_FLOAT - }; - - DXGI_FORMAT dxgi_format = ZI; - if (format >= 0 && format < (i32)countof(formats)) - { - dxgi_format = formats[format]; - } - if (format == 0) - { - Panic(Lit("Tried to create texture with unknown format")); - } - - D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_DEFAULT }; - heap_props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; - heap_props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; - - D3D12_HEAP_FLAGS heap_flags = D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; - - D3D12_RESOURCE_DESC desc = ZI; - desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; - desc.Format = dxgi_format; - desc.Alignment = 0; - desc.Width = size.x; - desc.Height = size.y; - desc.DepthOrArraySize = 1; - desc.MipLevels = 1; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - - D3D12_RESOURCE_STATES initial_state = D3D12_RESOURCE_STATE_COPY_DEST; - - GPU_D12_Resource *r = GPU_D12_AcquireResource(heap_props, heap_flags, desc, initial_state); - r->texture_size = size; - r->srv_descriptor = GPU_D12_AcquireDescriptor(g->cbv_srv_uav_heap); - ID3D12Device_CreateShaderResourceView(g->device, r->resource, 0, r->srv_descriptor->handle); - if (flags & GP_TEXTURE_FLAG_TARGETABLE) - { - desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; - r->uav_descriptor = GPU_D12_AcquireDescriptor(g->cbv_srv_uav_heap); - r->rtv_descriptor = GPU_D12_AcquireDescriptor(g->rtv_heap); - ID3D12Device_CreateUnorderedAccessView(g->device, r->resource, 0, 0, r->uav_descriptor->handle); - ID3D12Device_CreateRenderTargetView(g->device, r->resource, 0, r->rtv_descriptor->handle); - } - - /* Upload texture */ - if (initial_data) - { - /* TODO: Make wait optional */ - Counter counter = ZI; - RunJob(1, GPU_D12_UploadJob, JobPool_Inherit, JobPriority_Inherit, &counter, .resource = r, .data = initial_data); - YieldOnCounter(&counter); - } - - return (GPU_Resource *)r; + LAX resource; + return 0; } Vec2I32 GPU_GetTextureSize(GPU_Resource *resource) { - GPU_D12_Resource *r = (GPU_D12_Resource *)resource; - return r->texture_size; + LAX resource; + return VEC2I32(0, 0); } //////////////////////////////// -//~ Upload +//~ @hookdef Command list hooks -JobDef(GPU_D12_UploadJob, sig, UNUSED id) +GPU_CommandList *GPU_BeginCommandList(void) { - GPU_D12_SharedState *g = &GPU_D12_shared_state; - GPU_D12_Resource *r = sig->resource; - void *data = sig->data; + return 0; +} - Assert(r->state == D3D12_RESOURCE_STATE_COPY_DEST); +GPU_Fence GPU_EndCommandList(GPU_CommandList *cl) +{ + LAX cl; + return (GPU_Fence) ZI; +} - D3D12_RESOURCE_DESC desc = ZI; - ID3D12Resource_GetDesc(r->resource, &desc); - - { - u64 upload_size = 0; - u64 upload_row_size = 0; - u32 upload_num_rows = 0; - D3D12_PLACED_SUBRESOURCE_FOOTPRINT placed_footprint = ZI; - ID3D12Device_GetCopyableFootprints(g->device, &desc, 0, 1, 0, &placed_footprint, &upload_num_rows, &upload_row_size, &upload_size); - D3D12_SUBRESOURCE_FOOTPRINT footprint = placed_footprint.Footprint; - - /* Create upload heap */ - GPU_D12_Resource *upload = 0; - { - D3D12_HEAP_PROPERTIES upload_heap_props = { .Type = D3D12_HEAP_TYPE_UPLOAD }; - upload_heap_props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; - upload_heap_props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; - - D3D12_HEAP_FLAGS upload_heap_flags = D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; - - D3D12_RESOURCE_DESC upload_desc = ZI; - upload_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - upload_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - upload_desc.Format = DXGI_FORMAT_UNKNOWN; - upload_desc.Alignment = 0; - upload_desc.Width = upload_size; - upload_desc.Height = 1; - upload_desc.DepthOrArraySize = 1; - upload_desc.MipLevels = 1; - upload_desc.SampleDesc.Count = 1; - upload_desc.SampleDesc.Quality = 0; - D3D12_RESOURCE_STATES upload_initial_state = D3D12_RESOURCE_STATE_GENERIC_READ; - - upload = GPU_D12_AcquireResource(upload_heap_props, upload_heap_flags, upload_desc, upload_initial_state); - } - - GPU_D12_CommandQueue *cq = g->command_queues[DX12_QUEUE_COPY_BACKGROUND]; - GPU_D12_CommandList *cl = GPU_D12_BeginCommandList(cq->cl_pool); - { - /* Copy to upload heap */ - { - D3D12_RANGE read_range = ZI; - void *mapped = 0; - HRESULT hr = ID3D12Resource_Map(upload->resource, 0, &read_range, &mapped); - if (FAILED(hr) || !mapped) - { - /* TODO: Don't panic */ - Panic(Lit("Failed to map texture upload resource")); - } - u8 *dst = (u8 *)mapped + placed_footprint.Offset; - u8 *src = data; - - u32 z_size = upload_row_size * upload_num_rows; - - for (u32 z = 0; z < desc.DepthOrArraySize; ++z) - { - u32 z_offset = z * z_size; - for (u32 y = 0; y < upload_num_rows; ++y) - { - CopyBytes(dst + y * footprint.RowPitch + z_offset, src + y * upload_row_size + z_offset, upload_row_size); - } - } - ID3D12Resource_Unmap(upload->resource, 0, 0); - } - - /* Copy from upload heap to texture */ - { - __profnc_dx12(cl->cq->prof, cl->cl, "Upload texture", Rgb32F(0.2, 0.5, 0.2)); - D3D12_TEXTURE_COPY_LOCATION dst_loc = { - .pResource = r->resource, - .Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, - .SubresourceIndex = 0, - }; - - D3D12_TEXTURE_COPY_LOCATION src_loc = { - .pResource = upload->resource, - .Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT, - .PlacedFootprint = placed_footprint, - }; - - ID3D12GraphicsCommandList_CopyTextureRegion(cl->cl, &dst_loc, 0, 0, 0, &src_loc, 0); - } - } - u64 fence_target = GPU_D12_EndCommandList(cl); - - /* Yield on fence so we know it's safe to release upload heap */ - if (ID3D12Fence_GetCompletedValue(cq->submit_fence) < fence_target) - { - Counter counter = ZI; - RunJob(1, GPU_D12_WaitOnFenceJob, JobPool_Floating, JobPriority_Inherit, &counter, .fence = cq->submit_fence, .target = fence_target); - YieldOnCounter(&counter); - } - - /* Release upload heap now */ - GPU_D12_ReleaseResourceNow(upload); - } +void GPU_ProfileDF(GPU_CommandList *cl, String zone_name) +{ + LAX cl; + LAX zone_name; } //////////////////////////////// -//~ Run utils +//~ @hookdef Resource transition hooks -void GPU_D12_SetPipeline(GPU_D12_CommandList *cl, GPU_D12_Pipeline *pipeline) +void GPU_TransitionToSrv(GPU_CommandList *cl, GPU_Resource *resource) { - ID3D12GraphicsCommandList_SetPipelineState(cl->cl, pipeline->pso); - if (pipeline->is_gfx) - { - ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, pipeline->rootsig); - } - else - { - ID3D12GraphicsCommandList_SetComputeRootSignature(cl->cl, pipeline->rootsig); - } - cl->cur_pipeline = pipeline; + LAX cl; + LAX resource; } -void GPU_D12_SetSig(GPU_D12_CommandList *cl, void *src, u32 size) +void GPU_TransitionToUav(GPU_CommandList *cl, GPU_Resource *resource) { - __prof; - Assert(size % 16 == 0); /* Root constant structs must pad to 16 bytes */ - Assert(size <= 256); /* Only 64 32-bit root constants allowed in signature */ - u32 num32bit = size / 4; - b32 is_gfx = cl->cur_pipeline->is_gfx; - /* FIXME: Enable this */ -#if 0 - if (is_gfx) - { - ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(cl->cl, 0, num32bit, src, 0); - } - else - { - ID3D12GraphicsCommandList_SetComputeRoot32BitConstants(cl->cl, 0, num32bit, src, 0); - } -#else - for (u32 i = 0; i < num32bit; ++i) - { - u32 val = 0; - CopyBytes(&val, (((u32 *)src) + i), 4); - if (is_gfx) - { - ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstant(cl->cl, 0, val, i); - } - else - { - ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(cl->cl, 0, val, i); - } - } -#endif - + LAX cl; + LAX resource; } -struct D3D12_VIEWPORT GPU_D12_ViewportFromRect(Rect r) +void GPU_TransitionToRtv(GPU_CommandList *cl, GPU_Resource *resource) { - struct D3D12_VIEWPORT viewport = ZI; - viewport.TopLeftX = r.x; - viewport.TopLeftY = r.y; - viewport.Width = r.width; - viewport.Height = r.height; - viewport.MinDepth = 0.0f; - viewport.MaxDepth = 1.0f; - return viewport; + LAX cl; + LAX resource; } -D3D12_RECT GPU_D12_ScissorRectFromRect(Rect r) +void GPU_Flush(GPU_CommandList *cl, GPU_Resource *resource) { - D3D12_RECT scissor = ZI; - scissor.left = r.x; - scissor.top = r.y; - scissor.right = r.x + r.width; - scissor.bottom = r.y + r.height; - return scissor; -} - -D3D12_VERTEX_BUFFER_VIEW GPU_D12_VbvFromCommandBuffer(GPU_D12_CommandBuffer *cb, u32 vertex_size) -{ - D3D12_VERTEX_BUFFER_VIEW vbv = ZI; - vbv.BufferLocation = cb->resource->gpu_address; - vbv.SizeInBytes = cb->size; - vbv.StrideInBytes = vertex_size; - return vbv; -} - -D3D12_INDEX_BUFFER_VIEW GPU_D12_IbvFromCommandBuffer(GPU_D12_CommandBuffer *cb, DXGI_FORMAT format) -{ - D3D12_INDEX_BUFFER_VIEW ibv = ZI; - ibv.BufferLocation = cb->resource->gpu_address; - ibv.Format = format; - ibv.SizeInBytes = cb->size; - return ibv; -} - -GPU_D12_Resource *GPU_D12_AcquireGbuff(DXGI_FORMAT format, Vec2I32 size, D3D12_RESOURCE_STATES initial_state) -{ - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_DEFAULT }; - heap_props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; - heap_props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; - - D3D12_HEAP_FLAGS heap_flags = D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; - - D3D12_RESOURCE_DESC desc = ZI; - desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; - desc.Format = format; - desc.Alignment = 0; - desc.Width = size.x; - desc.Height = size.y; - desc.DepthOrArraySize = 1; - desc.MipLevels = 1; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; - - GPU_D12_Resource *r = GPU_D12_AcquireResource(heap_props, heap_flags, desc, initial_state); - r->srv_descriptor = GPU_D12_AcquireDescriptor(g->cbv_srv_uav_heap); - r->uav_descriptor = GPU_D12_AcquireDescriptor(g->cbv_srv_uav_heap); - r->rtv_descriptor = GPU_D12_AcquireDescriptor(g->rtv_heap); - ID3D12Device_CreateShaderResourceView(g->device, r->resource, 0, r->srv_descriptor->handle); - ID3D12Device_CreateUnorderedAccessView(g->device, r->resource, 0, 0, r->uav_descriptor->handle); - ID3D12Device_CreateRenderTargetView(g->device, r->resource, 0, r->rtv_descriptor->handle); - - r->texture_size = size; - return r; -} - -D3D12_GPU_DESCRIPTOR_HANDLE GPU_D12_GpuHandleFromDescriptor(GPU_D12_Descriptor *descriptor, GPU_D12_CommandDescriptorHeap *cdh) -{ - GPU_D12_SharedState *g = &GPU_D12_shared_state; - struct D3D12_GPU_DESCRIPTOR_HANDLE result = ZI; - result.ptr = cdh->start_gpu_handle.ptr + descriptor->index * g->desc_sizes[descriptor->heap->type]; - return result; + LAX cl; + LAX resource; } //////////////////////////////// -//~ Render sig +//~ @hookdef Dispatch hooks -GPU_D12_RenderSig *GPU_D12_AcquireRenderSig(void) +void GPU_DispatchClear(GPU_CommandList *cl, GPU_Resource *resource) { - __prof; - GPU_D12_RenderSig *sig = 0; - { - Arena *arena = AcquireArena(Mebi(64)); - sig = PushStruct(arena, GPU_D12_RenderSig); - sig->arena = arena; - } - - sig->material_instance_descs_arena = AcquireArena(Gibi(1)); - sig->material_grid_descs_arena = AcquireArena(Gibi(1)); - sig->ui_rect_instance_descs_arena = AcquireArena(Gibi(1)); - sig->ui_shape_verts_arena = AcquireArena(Gibi(1)); - sig->ui_shape_indices_arena = AcquireArena(Gibi(1)); - - return sig; + LAX cl; + LAX resource; } -void GPU_D12_ResetRenderSig(GPU_D12_RenderSig *sig) +void GPU_DispatchRasterize(GPU_CommandList *cl, + GPU_ShaderDesc vs, + GPU_ShaderDesc ps, + void *sig, + u32 rts_count, + GPU_Resource **rts, + u32 viewports_count, + GPU_Viewport *viewports, + u32 scissors_count, + GPU_Scissor *scissors, + u32 instances_count, + GPU_Resource *index_buffer, + GPU_RasterizeMode mode) { - __prof; - - /* Reset material instances */ - sig->num_material_instance_descs = 0; - ResetArena(sig->material_instance_descs_arena); - - /* Reset UI rect instances */ - sig->num_ui_rect_instance_descs = 0; - ResetArena(sig->ui_rect_instance_descs_arena); - - /* Reset shapes */ - ResetArena(sig->ui_shape_verts_arena); - ResetArena(sig->ui_shape_indices_arena); - - /* Reset grids */ - sig->num_material_grid_descs = 0; - ResetArena(sig->material_grid_descs_arena); + LAX cl; + LAX vs; + LAX ps; + LAX sig; + LAX rts_count; + LAX rts; + LAX viewports_count; + LAX *viewports; + LAX scissors_count; + LAX scissors; + LAX instances_count; + LAX index_buffer; + LAX mode; } -GPU_RenderSig *GPU_AcquireRenderSig(void) +void GPU_DispatchCompute(GPU_CommandList *cl, GPU_ShaderDesc cs, void *sig, u32 num_threads_x, u32 num_threads_y, u32 num_threads_z) { - __prof; - GPU_D12_RenderSig *sig = GPU_D12_AcquireRenderSig(); - return (GPU_RenderSig *)sig; -} - -u32 GPU_PushRenderCmd(GPU_RenderSig *render_sig, GPU_RenderCmdDesc *cmd_desc) -{ - u32 ret = 0; - GPU_D12_RenderSig *sig = (GPU_D12_RenderSig *)render_sig; - if (sig) - { - switch (cmd_desc->kind) - { - default: break; - - case GP_RENDER_CMD_KIND_DRAW_MATERIAL: - { - GPU_D12_Resource *texture = (GPU_D12_Resource *)cmd_desc->material.texture; - GPU_D12_MaterialInstanceDesc *instance_desc = PushStruct(sig->material_instance_descs_arena, GPU_D12_MaterialInstanceDesc); - instance_desc->xf = cmd_desc->material.xf; - instance_desc->texture_id = texture ? texture->srv_descriptor->index : 0xFFFFFFFF; - instance_desc->clip = cmd_desc->material.clip; - instance_desc->tint = cmd_desc->material.tint; - instance_desc->is_light = cmd_desc->material.is_light; - instance_desc->light_emittance = cmd_desc->material.light_emittance; - instance_desc->grid_id = cmd_desc->material.grid_cmd_id - 1; - ret = ++sig->num_material_instance_descs; - } break; - - case GP_RENDER_CMD_KIND_DRAW_UI_RECT: - { - GPU_D12_Resource *texture = (GPU_D12_Resource *)cmd_desc->ui_rect.texture; - GPU_D12_UiRectInstanceDesc *instance_desc = PushStruct(sig->ui_rect_instance_descs_arena, GPU_D12_UiRectInstanceDesc); - instance_desc->xf = cmd_desc->ui_rect.xf; - instance_desc->texture_id = texture ? texture->srv_descriptor->index : 0xFFFFFFFF; - instance_desc->clip = cmd_desc->ui_rect.clip; - instance_desc->tint = cmd_desc->ui_rect.tint; - ret = ++sig->num_ui_rect_instance_descs; - } break; - - case GP_RENDER_CMD_KIND_DRAW_UI_SHAPE: - { - u32 color = cmd_desc->ui_shape.color; - K_ShapeVert *verts = PushStructsNoZero(sig->ui_shape_verts_arena, K_ShapeVert, cmd_desc->ui_shape.vertices.count); - u32 *indices = PushStructsNoZero(sig->ui_shape_indices_arena, u32, cmd_desc->ui_shape.indices.count); - for (u32 i = 0; i < cmd_desc->ui_shape.vertices.count; ++i) - { - K_ShapeVert *v = &verts[i]; - v->pos = cmd_desc->ui_shape.vertices.points[i]; - v->color_srgb = color; - } - u32 vert_offset = verts - (K_ShapeVert *)ArenaBase(sig->ui_shape_verts_arena); - for (u32 i = 0; i < cmd_desc->ui_shape.indices.count; ++i) - { - indices[i] = cmd_desc->ui_shape.indices.indices[i] + vert_offset; - } - } break; - - case GP_RENDER_CMD_KIND_PUSH_GRID: - { - GPU_D12_MaterialGridDesc *grid_desc = PushStruct(sig->material_grid_descs_arena, GPU_D12_MaterialGridDesc); - grid_desc->line_thickness = cmd_desc->grid.line_thickness; - grid_desc->line_spacing = cmd_desc->grid.line_spacing; - grid_desc->offset = cmd_desc->grid.offset; - grid_desc->bg0_color = cmd_desc->grid.bg0_color; - grid_desc->bg1_color = cmd_desc->grid.bg1_color; - grid_desc->line_color = cmd_desc->grid.line_color; - grid_desc->x_color = cmd_desc->grid.x_color; - grid_desc->y_color = cmd_desc->grid.y_color; - ret = ++sig->num_material_grid_descs; - } break; - } - } - return ret; + LAX cl; + LAX cs; + LAX sig; + LAX num_threads_x; + LAX num_threads_y; + LAX num_threads_z; } //////////////////////////////// -//~ Render +//~ @hookdef Copy hooks -GPU_Resource *GPU_RunRender(GPU_RenderSig *gp_render_sig, GPU_RenderParams params) +void GPU_PushResource(GPU_CommandList *cl, GPU_Resource *dst, GPU_Resource *src) { - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - TempArena scratch = BeginScratchNoConflict(); - GPU_D12_RenderSig *rsig = (GPU_D12_RenderSig *)gp_render_sig; - ++rsig->frame_index; + LAX cl; + LAX dst; + LAX src; +} - Vec2I32 ui_size = VEC2I32(MaxI32(params.ui_size.x, 1), MaxI32(params.ui_size.y, 1)); - Vec2I32 render_size = VEC2I32(MaxI32(params.render_size.x, 1), MaxI32(params.render_size.y, 1)); - Xform world_to_render_xf = params.world_to_render_xf; - Xform render_to_ui_xf = params.render_to_ui_xf; - - Rect ui_viewport = RectFromVec2(VEC2(0, 0), VEC2(ui_size.x, ui_size.y)); - Rect render_viewport = RectFromVec2(VEC2(0, 0), VEC2(render_size.x, render_size.y)); - - - /* Acquire render buffers */ - if (rsig->shade_target && !EqVec2I32(render_size, rsig->shade_target->texture_size)) - { - __profn("Release sig resources"); - GPU_D12_ReleaseDataFenced(rsig->albedo, GPU_D12_FencedReleaseKind_Resource); - GPU_D12_ReleaseDataFenced(rsig->emittance, GPU_D12_FencedReleaseKind_Resource); - GPU_D12_ReleaseDataFenced(rsig->emittance_flood_read, GPU_D12_FencedReleaseKind_Resource); - GPU_D12_ReleaseDataFenced(rsig->emittance_flood_target, GPU_D12_FencedReleaseKind_Resource); - GPU_D12_ReleaseDataFenced(rsig->shade_read, GPU_D12_FencedReleaseKind_Resource); - GPU_D12_ReleaseDataFenced(rsig->shade_target, GPU_D12_FencedReleaseKind_Resource); - rsig->shade_target = 0; - } - if (!rsig->shade_target) - { - __profn("Acquire sig resources"); - rsig->albedo = GPU_D12_AcquireGbuff(DXGI_FORMAT_R8G8B8A8_UNORM, render_size, D3D12_RESOURCE_STATE_RENDER_TARGET); - rsig->emittance = GPU_D12_AcquireGbuff(DXGI_FORMAT_R16G16B16A16_FLOAT, render_size, D3D12_RESOURCE_STATE_RENDER_TARGET); - rsig->emittance_flood_read = GPU_D12_AcquireGbuff(DXGI_FORMAT_R16G16_UINT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - rsig->emittance_flood_target = GPU_D12_AcquireGbuff(DXGI_FORMAT_R16G16_UINT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - rsig->shade_read = GPU_D12_AcquireGbuff(DXGI_FORMAT_R16G16B16A16_FLOAT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - rsig->shade_target = GPU_D12_AcquireGbuff(DXGI_FORMAT_R16G16B16A16_FLOAT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - } - - /* Acquire ui buffers */ - if (rsig->ui_target && !EqVec2I32(ui_size, rsig->ui_target->texture_size)) - { - GPU_D12_ReleaseDataFenced(rsig->ui_target, GPU_D12_FencedReleaseKind_Resource); - rsig->ui_target = 0; - } - if (!rsig->ui_target) - { - rsig->ui_target = GPU_D12_AcquireGbuff(DXGI_FORMAT_R8G8B8A8_UNORM, ui_size, D3D12_RESOURCE_STATE_RENDER_TARGET); - } - - GPU_D12_PipelineScope *pipeline_scope = GPU_D12_BeginPipelineScope(); - GPU_D12_Pipeline *material_pipeline = GPU_D12_PipelineFromName(pipeline_scope, Lit("kernel_material")); - GPU_D12_Pipeline *flood_pipeline = GPU_D12_PipelineFromName(pipeline_scope, Lit("kernel_flood")); - GPU_D12_Pipeline *shade_pipeline = GPU_D12_PipelineFromName(pipeline_scope, Lit("kernel_shade")); - GPU_D12_Pipeline *blit_pipeline = GPU_D12_PipelineFromName(pipeline_scope, Lit("kernel_blit")); - GPU_D12_Pipeline *ui_pipeline = GPU_D12_PipelineFromName(pipeline_scope, Lit("kernel_ui")); - GPU_D12_Pipeline *shape_pipeline = GPU_D12_PipelineFromName(pipeline_scope, Lit("kernel_shape")); - GPU_D12_CommandQueue *cq = g->command_queues[DX12_QUEUE_DIRECT]; - GPU_D12_CommandList *cl = GPU_D12_BeginCommandList(cq->cl_pool); - { - __profn("Run render"); - __profnc_dx12(cl->cq->prof, cl->cl, "Run render", Rgb32F(0.5, 0.2, 0.2)); - Mat4x4 world_to_render_vp_matrix = ProjectMat4x4View(world_to_render_xf, render_viewport.width, render_viewport.height); - Mat4x4 ui_vp_matrix = ProjectMat4x4View(XformIdentity, ui_viewport.width, ui_viewport.height); - Mat4x4 blit_vp_matrix = ZI; - { - Xform xf = render_to_ui_xf; - xf = ScaleXform(xf, VEC2(render_size.x, render_size.y)); - xf = TranslateXform(xf, VEC2(0.5, 0.5)); - blit_vp_matrix = ProjectMat4x4View(xf, ui_viewport.width, ui_viewport.height); - } - - /* Upload dummmy vert & index buffer */ - /* TODO: Make these static */ - /* Dummy vertex buffer */ - LocalPersist u16 quad_indices[6] = { 0, 1, 2, 0, 2, 3 }; - GPU_D12_CommandBuffer *dummy_vertex_buffer = GPU_D12_PushCommandBuffer(cl, 0, (u8 *)0); - GPU_D12_CommandBuffer *quad_index_buffer = GPU_D12_PushCommandBuffer(cl, countof(quad_indices), quad_indices); - - /* Process sig data into uploadable data */ - K_MaterialInstance *material_instances = PushStructsNoZero(scratch.arena, K_MaterialInstance, rsig->num_material_instance_descs); - K_UiInstance *ui_rect_instances = PushStructsNoZero(scratch.arena, K_UiInstance, rsig->num_ui_rect_instance_descs); - K_MaterialGrid *grids = PushStructsNoZero(scratch.arena, K_MaterialGrid, rsig->num_material_grid_descs); - { - __profn("Process sig data"); - - /* Process material instances */ - { - __profn("Process material instances"); - for (u32 i = 0; i < rsig->num_material_instance_descs; ++i) - { - GPU_D12_MaterialInstanceDesc *desc = &((GPU_D12_MaterialInstanceDesc *)ArenaBase(rsig->material_instance_descs_arena))[i]; - K_MaterialInstance *instance = &material_instances[i]; - instance->tex_nurid = desc->texture_id; - instance->grid_id = desc->grid_id; - instance->xf = desc->xf; - instance->uv0 = desc->clip.p0; - instance->uv1 = desc->clip.p1; - instance->tint_srgb = desc->tint; - instance->is_light = desc->is_light; - instance->light_emittance_srgb = desc->light_emittance; - } - } - - /* Process ui rect instances */ - { - __profn("Process ui rect instances"); - for (u32 i = 0; i < rsig->num_ui_rect_instance_descs; ++i) - { - GPU_D12_UiRectInstanceDesc *desc = &((GPU_D12_UiRectInstanceDesc *)ArenaBase(rsig->ui_rect_instance_descs_arena))[i]; - K_UiInstance *instance = &ui_rect_instances[i]; - instance->tex_nurid = desc->texture_id; - instance->xf = desc->xf; - instance->uv0 = desc->clip.p0; - instance->uv1 = desc->clip.p1; - instance->tint_srgb = desc->tint; - } - } - - /* Process grids */ - { - __profn("Process grids"); - for (u32 i = 0; i < rsig->num_material_grid_descs; ++i) - { - GPU_D12_MaterialGridDesc *desc = &((GPU_D12_MaterialGridDesc *)ArenaBase(rsig->material_grid_descs_arena))[i]; - K_MaterialGrid *grid = &grids[i]; - grid->line_thickness = desc->line_thickness; - grid->line_spacing = desc->line_spacing; - grid->offset = desc->offset; - grid->bg0_srgb = desc->bg0_color; - grid->bg1_srgb = desc->bg1_color; - grid->line_srgb = desc->line_color; - grid->x_srgb = desc->x_color; - grid->y_srgb = desc->y_color; - } - } - } - - /* Upload buffers */ - u64 num_ui_shape_verts = rsig->ui_shape_verts_arena->pos / sizeof(K_ShapeVert); - u64 num_ui_shape_indices = rsig->ui_shape_indices_arena->pos / sizeof(u32); - GPU_D12_CommandBuffer *material_instance_buffer = GPU_D12_PushCommandBuffer(cl, rsig->num_material_instance_descs, material_instances); - GPU_D12_CommandBuffer *ui_rect_instance_buffer = GPU_D12_PushCommandBuffer(cl, rsig->num_ui_rect_instance_descs, ui_rect_instances); - GPU_D12_CommandBuffer *ui_shape_verts_buffer = GPU_D12_PushCommandBuffer(cl, num_ui_shape_verts, (K_ShapeVert *)ArenaBase(rsig->ui_shape_verts_arena)); - GPU_D12_CommandBuffer *ui_shape_indices_buffer = GPU_D12_PushCommandBuffer(cl, num_ui_shape_indices, (u32 *)ArenaBase(rsig->ui_shape_indices_arena)); - GPU_D12_CommandBuffer *grid_buffer = GPU_D12_PushCommandBuffer(cl, rsig->num_material_grid_descs, grids); - - /* Upload descriptor heap */ - GPU_D12_CommandDescriptorHeap *descriptor_heap = GPU_D12_PushDescriptorHeap(cl, g->cbv_srv_uav_heap); - ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap }; - ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, countof(heaps), heaps); - - /* Prep for material pass */ - { - /* Barrier */ - { - GPU_D12_ResourceBarrierDesc barriers[] = { - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->albedo, D3D12_RESOURCE_STATE_RENDER_TARGET }, - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->emittance, D3D12_RESOURCE_STATE_RENDER_TARGET } - }; - D3D12_CPU_DESCRIPTOR_HANDLE rtvs[] = { - rsig->albedo->rtv_descriptor->handle, - rsig->emittance->rtv_descriptor->handle, - }; - GPU_D12_InsertBarrier(cl->cl, countof(barriers), barriers); - ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, countof(rtvs), rtvs, 0, 0); - } - /* Clear */ - { - __profn("Clear gbuffers"); - __profnc_dx12(cl->cq->prof, cl->cl, "Clear gbuffers", Rgb32F(0.5, 0.2, 0.2)); - f32 clear_color[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, rsig->albedo->rtv_descriptor->handle, clear_color, 0, 0); - ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, rsig->emittance->rtv_descriptor->handle, clear_color, 0, 0); - } - } - - /* Material pass */ - if (material_pipeline->success) - { - __profn("Material pass"); - __profnc_dx12(cl->cq->prof, cl->cl, "Material pass", Rgb32F(0.5, 0.2, 0.2)); - - /* Bind pipeline */ - GPU_D12_SetPipeline(cl, material_pipeline); - - /* Set Rasterizer State */ - D3D12_VIEWPORT viewport = GPU_D12_ViewportFromRect(render_viewport); - D3D12_RECT scissor = GPU_D12_ScissorRectFromRect(render_viewport); - ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport); - ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor); - - /* Set sig */ - K_MaterialSig sig = ZI; - sig.projection = world_to_render_vp_matrix; - sig.instances_urid = material_instance_buffer->resource->srv_descriptor->index; - sig.grids_urid = grid_buffer->resource->srv_descriptor->index; - GPU_D12_SetSig(cl, &sig, sizeof(sig)); - - /* Draw */ - u32 instance_count = material_instance_buffer->size / sizeof(K_MaterialInstance); - D3D12_VERTEX_BUFFER_VIEW vbv = GPU_D12_VbvFromCommandBuffer(dummy_vertex_buffer, 0); - D3D12_INDEX_BUFFER_VIEW ibv = GPU_D12_IbvFromCommandBuffer(quad_index_buffer, DXGI_FORMAT_R16_UINT); - ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl->cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ID3D12GraphicsCommandList_IASetVertexBuffers(cl->cl, 0, 1, &vbv); - ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &ibv); - ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, 6, instance_count, 0, 0, 0); - } - - /* Prep for flood pass */ - { - /* Barrier */ - { - GPU_D12_ResourceBarrierDesc barriers[] = { - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->emittance, D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE }, - - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->emittance_flood_read, D3D12_RESOURCE_STATE_UNORDERED_ACCESS }, - { D3D12_RESOURCE_BARRIER_TYPE_UAV, rsig->emittance_flood_read, 0 }, - - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->emittance_flood_target, D3D12_RESOURCE_STATE_UNORDERED_ACCESS } - }; - GPU_D12_InsertBarrier(cl->cl, countof(barriers), barriers); - } - } - - /* Flood pass */ - if (flood_pipeline->success && !params.effects_disabled) - { - __profn("Flood pass"); - __profnc_dx12(cl->cq->prof, cl->cl, "Flood pass", Rgb32F(0.5, 0.2, 0.2)); - - /* Bind pipeline */ - GPU_D12_SetPipeline(cl, flood_pipeline); - - i32 step_length = -1; - - /* TODO: Remove this */ - u64 max_steps = GetGstat(GSTAT_DEBUG_STEPS); - u64 step = 0; - while (step_length != 0 && step < max_steps) - { - __profn("Flood step"); - __profnc_dx12(cl->cq->prof, cl->cl, "Flood step", Rgb32F(0.5, 0.2, 0.2)); - - /* UAV barrier */ - { - GPU_D12_ResourceBarrierDesc barriers[] = { - { D3D12_RESOURCE_BARRIER_TYPE_UAV, rsig->emittance_flood_read, 0 } - }; - GPU_D12_InsertBarrier(cl->cl, countof(barriers), barriers); - } - - /* Set sig */ - K_FloodSig sig = ZI; - sig.step_len = step_length; - sig.emittance_tex_urid = rsig->emittance->srv_descriptor->index; - sig.read_flood_tex_urid = rsig->emittance_flood_read->uav_descriptor->index; - sig.target_flood_tex_urid = rsig->emittance_flood_target->uav_descriptor->index; - sig.tex_width = render_size.x; - sig.tex_height = render_size.y; - GPU_D12_SetSig(cl, &sig, sizeof(sig)); - - /* Dispatch */ - ID3D12GraphicsCommandList_Dispatch(cl->cl, (render_size.x + 7) / 8, (render_size.y + 7) / 8, 1); - - /* Swap buffers */ - GPU_D12_Resource *swp = rsig->emittance_flood_read; - rsig->emittance_flood_read = rsig->emittance_flood_target; - rsig->emittance_flood_target = swp; - - /* Update step */ - if (step_length == -1) - { - step_length = MaxI32(render_size.x, render_size.y) / 2; - } - else - { - step_length /= 2; - } - ++step; - } - } - - /* Prep for shade pass */ - { - /* Barrier */ - { - GPU_D12_ResourceBarrierDesc barriers[] = { - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->albedo, D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE }, - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->emittance, D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE }, - - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->emittance_flood_read, D3D12_RESOURCE_STATE_UNORDERED_ACCESS }, - { D3D12_RESOURCE_BARRIER_TYPE_UAV, rsig->emittance_flood_read, 0 }, - - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->shade_read, D3D12_RESOURCE_STATE_UNORDERED_ACCESS }, - { D3D12_RESOURCE_BARRIER_TYPE_UAV, rsig->shade_read, 0 }, - - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->shade_target, D3D12_RESOURCE_STATE_UNORDERED_ACCESS } - }; - GPU_D12_InsertBarrier(cl->cl, countof(barriers), barriers); - } - /* Clear */ - { - __profn("Clear shade target"); - __profnc_dx12(cl->cq->prof, cl->cl, "Clear shade target", Rgb32F(0.5, 0.2, 0.2)); - f32 clear_color[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - ID3D12GraphicsCommandList_ClearUnorderedAccessViewFloat(cl->cl, GPU_D12_GpuHandleFromDescriptor(rsig->shade_target->uav_descriptor, descriptor_heap), rsig->shade_target->uav_descriptor->handle, rsig->shade_target->resource, clear_color, 0, 0); - } - } - - /* Shade pass */ - if (shade_pipeline->success) - { - __profn("Shade pass"); - __profnc_dx12(cl->cq->prof, cl->cl, "Shade pass", Rgb32F(0.5, 0.2, 0.2)); - - /* Bind pipeline */ - GPU_D12_SetPipeline(cl, shade_pipeline); - - u32 shade_flags = K_SHADE_FLAG_NONE; - if (params.effects_disabled) - { - shade_flags |= K_SHADE_FLAG_DISABLE_EFFECTS; - } - - /* Set sig */ - K_ShadeSig sig = ZI; - sig.flags = shade_flags; - sig.tex_width = render_size.x; - sig.tex_height = render_size.y; - sig.frame_seed = VEC4I32((u32)(RandU64FromState(&rsig->rand) & 0xFFFFFFFF), - (u32)(RandU64FromState(&rsig->rand) & 0xFFFFFFFF), - (u32)(RandU64FromState(&rsig->rand) & 0xFFFFFFFF), - (u32)(RandU64FromState(&rsig->rand) & 0xFFFFFFFF)); - sig.frame_index = rsig->frame_index; - sig.camera_offset = world_to_render_xf.og; - sig.albedo_tex_urid = rsig->albedo->srv_descriptor->index; - sig.emittance_tex_urid = rsig->emittance->srv_descriptor->index; - sig.emittance_flood_tex_urid = rsig->emittance_flood_read->srv_descriptor->index; - sig.read_tex_urid = rsig->shade_read->uav_descriptor->index; - sig.target_tex_urid = rsig->shade_target->uav_descriptor->index; - GPU_D12_SetSig(cl, &sig, sizeof(sig)); - - /* Dispatch */ - ID3D12GraphicsCommandList_Dispatch(cl->cl, (render_size.x + 7) / 8, (render_size.y + 7) / 8, 1); - - /* Swap */ - GPU_D12_Resource *swp = rsig->shade_read; - rsig->shade_read = rsig->shade_target; - rsig->shade_target = swp; - } - - /* Prep for UI pass */ - { - /* Barrier */ - { - GPU_D12_ResourceBarrierDesc barriers[] = { - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->shade_read, D3D12_RESOURCE_STATE_UNORDERED_ACCESS }, - { D3D12_RESOURCE_BARRIER_TYPE_UAV, rsig->shade_read, 0 }, - { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, rsig->ui_target, D3D12_RESOURCE_STATE_RENDER_TARGET } - }; - GPU_D12_InsertBarrier(cl->cl, countof(barriers), barriers); - ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, 1, &rsig->ui_target->rtv_descriptor->handle, 0, 0); - } - /* Clear */ - { - __profn("Clear ui target"); - __profnc_dx12(cl->cq->prof, cl->cl, "Clear ui target", Rgb32F(0.5, 0.2, 0.2)); - f32 clear_color[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, rsig->ui_target->rtv_descriptor->handle, clear_color, 0, 0); - } - } - - /* UI blit pass */ - if (blit_pipeline->success) - { - __profn("UI blit pass"); - __profnc_dx12(cl->cq->prof, cl->cl, "UI blit pass", Rgb32F(0.5, 0.2, 0.2)); - - /* Bind pipeline */ - GPU_D12_SetPipeline(cl, blit_pipeline); - - /* Set Rasterizer State */ - D3D12_VIEWPORT viewport = GPU_D12_ViewportFromRect(ui_viewport); - D3D12_RECT scissor = GPU_D12_ScissorRectFromRect(ui_viewport); - ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport); - ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor); - - /* Set sig */ - K_BlitSig sig = ZI; - sig.projection = blit_vp_matrix; - sig.flags = K_BLIT_FLAG_TONE_MAP | K_BLIT_FLAG_GAMMA_CORRECT; - sig.exposure = 2.0; - sig.gamma = (f32)2.2; - sig.tex_urid = rsig->shade_read->uav_descriptor->index; - GPU_D12_SetSig(cl, &sig, sizeof(sig)); - - /* Draw */ - D3D12_VERTEX_BUFFER_VIEW vbv = GPU_D12_VbvFromCommandBuffer(dummy_vertex_buffer, 0); - D3D12_INDEX_BUFFER_VIEW ibv = GPU_D12_IbvFromCommandBuffer(quad_index_buffer, DXGI_FORMAT_R16_UINT); - ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl->cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ID3D12GraphicsCommandList_IASetVertexBuffers(cl->cl, 0, 1, &vbv); - ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &ibv); - ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, 6, 1, 0, 0, 0); - } - - /* UI rect pass */ - if (ui_pipeline->success) - { - __profn("UI rect pass"); - __profnc_dx12(cl->cq->prof, cl->cl, "UI rect pass", Rgb32F(0.5, 0.2, 0.2)); - - /* Bind pipeline */ - GPU_D12_SetPipeline(cl, ui_pipeline); - - /* Set Rasterizer State */ - D3D12_VIEWPORT viewport = GPU_D12_ViewportFromRect(ui_viewport); - D3D12_RECT scissor = GPU_D12_ScissorRectFromRect(ui_viewport); - ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport); - ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor); - - /* Set sig */ - K_UiSig sig = ZI; - sig.projection = ui_vp_matrix; - sig.instances_urid = ui_rect_instance_buffer->resource->srv_descriptor->index; - GPU_D12_SetSig(cl, &sig, sizeof(sig)); - - /* Draw */ - u32 instance_count = ui_rect_instance_buffer->size / sizeof(K_UiInstance); - D3D12_VERTEX_BUFFER_VIEW vbv = GPU_D12_VbvFromCommandBuffer(dummy_vertex_buffer, 0); - D3D12_INDEX_BUFFER_VIEW ibv = GPU_D12_IbvFromCommandBuffer(quad_index_buffer, DXGI_FORMAT_R16_UINT); - ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl->cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ID3D12GraphicsCommandList_IASetVertexBuffers(cl->cl, 0, 1, &vbv); - ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &ibv); - ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, 6, instance_count, 0, 0, 0); - } - - /* UI shape pass */ - if (shape_pipeline->success) - { - __profn("UI shape pass"); - __profnc_dx12(cl->cq->prof, cl->cl, "UI shape pass", Rgb32F(0.5, 0.2, 0.2)); - - /* Bind pipeline */ - GPU_D12_SetPipeline(cl, shape_pipeline); - - /* Set Rasterizer State */ - D3D12_VIEWPORT viewport = GPU_D12_ViewportFromRect(ui_viewport); - D3D12_RECT scissor = GPU_D12_ScissorRectFromRect(ui_viewport); - ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport); - ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor); - - /* Set sig */ - K_ShapeSig sig = ZI; - sig.projection = ui_vp_matrix; - sig.verts_urid = ui_shape_verts_buffer->resource->srv_descriptor->index; - GPU_D12_SetSig(cl, &sig, sizeof(sig)); - - /* Draw */ - u32 index_count = ui_shape_indices_buffer->size / sizeof(u32); - D3D12_VERTEX_BUFFER_VIEW vbv = GPU_D12_VbvFromCommandBuffer(dummy_vertex_buffer, 0); - D3D12_INDEX_BUFFER_VIEW ibv = GPU_D12_IbvFromCommandBuffer(ui_shape_indices_buffer, DXGI_FORMAT_R32_UINT); - ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl->cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ID3D12GraphicsCommandList_IASetVertexBuffers(cl->cl, 0, 1, &vbv); - ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &ibv); - ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, index_count, 1, 0, 0, 0); - } - } - GPU_D12_EndCommandList(cl); - GPU_D12_EndPipelineScope(pipeline_scope); - - GPU_D12_ResetRenderSig(rsig); - EndScratch(scratch); - - return (GPU_Resource *)rsig->ui_target; +void GPU_PushString(GPU_CommandList *cl, GPU_Resource *dst, String src) +{ + LAX cl; + LAX dst; + LAX src; } //////////////////////////////// -//~ Memory info +//~ @hookdef Memory info hooks GPU_MemoryInfo GPU_QueryMemoryInfo(void) { - GPU_D12_SharedState *g = &GPU_D12_shared_state; - GPU_MemoryInfo result = ZI; - - HRESULT hr = 0; - IDXGIAdapter3 *dxgiAdapter3 = 0; - if (SUCCEEDED(hr)) - { - hr = IDXGIAdapter_QueryInterface(g->adapter, &IID_IDXGIAdapter3, (void **)&dxgiAdapter3); - } - if (SUCCEEDED(hr)) - { - struct DXGI_QUERY_VIDEO_MEMORY_INFO info = ZI; - IDXGIAdapter3_QueryVideoMemoryInfo(dxgiAdapter3, 0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &info); - result.local_used = info.CurrentUsage; - result.local_budget = info.Budget; - } - if (SUCCEEDED(hr)) - { - struct DXGI_QUERY_VIDEO_MEMORY_INFO info = ZI; - IDXGIAdapter3_QueryVideoMemoryInfo(dxgiAdapter3, 0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &info); - result.non_local_used = info.CurrentUsage; - result.non_local_budget = info.Budget; - } - if (dxgiAdapter3) - { - IDXGIAdapter_Release(dxgiAdapter3); - } - return result; + return (GPU_MemoryInfo) ZI; } //////////////////////////////// -//~ Swapchain +//~ @hookdef Swapchain hooks -void GPU_D12_InitSwapchainResources(GPU_D12_Swapchain *swapchain) +GPU_Swapchain *GPU_AcquireSwapchain(P_Window *window, Vec2I32 size) { - GPU_D12_SharedState *g = &GPU_D12_shared_state; - for (u32 i = 0; i < countof(swapchain->buffers); ++i) - { - ID3D12Resource *resource = 0; - HRESULT hr = IDXGISwapChain3_GetBuffer(swapchain->swapchain, i, &IID_ID3D12Resource, (void **)&resource); - if (FAILED(hr)) - { - /* TODO: Don't panic */ - Panic(Lit("Failed to get swapchain buffer")); - } - GPU_D12_SwapchainBuffer *sb = &swapchain->buffers[i]; - ZeroStruct(sb); - sb->swapchain = swapchain; - sb->resource = resource; - sb->rtv_descriptor = GPU_D12_AcquireDescriptor(g->rtv_heap); - sb->state = D3D12_RESOURCE_STATE_COMMON; - ID3D12Device_CreateRenderTargetView(g->device, sb->resource, 0, sb->rtv_descriptor->handle); - } + LAX window; + LAX size; + return 0; } -GPU_Swapchain *GPU_AcquireSwapchain(P_Window *window, Vec2I32 resolution) +void GPU_ReleaseSwapchain(GPU_Swapchain *swapchain) { - GPU_D12_SharedState *g = &GPU_D12_shared_state; - HRESULT hr = 0; - HWND hwnd = (HWND)P_GetInternalWindowHandle(window); - GPU_D12_CommandQueue *cq = g->command_queues[DX12_QUEUE_DIRECT]; - - GPU_D12_Swapchain *swapchain = 0; - { - Lock lock = LockE(&g->swapchains_mutex); - if (g->first_free_swapchain) - { - swapchain = g->first_free_swapchain; - g->first_free_swapchain = swapchain->next_free; - } - else - { - swapchain = PushStruct(g->swapchains_arena, GPU_D12_Swapchain); - } - Unlock(&lock); - } - - /* Create swapchain1 */ - IDXGISwapChain1 *swapchain1 = 0; - { - DXGI_SWAP_CHAIN_DESC1 desc = ZI; - desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc.Width = resolution.x; - desc.Height = resolution.y; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.BufferUsage = DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT; - desc.BufferCount = DX12_SWAPCHAIN_BUFFER_COUNT; - desc.Scaling = DXGI_SCALING_NONE; - desc.Flags = DX12_SWAPCHAIN_FLAGS; - desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; - desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - hr = IDXGIFactory2_CreateSwapChainForHwnd(g->factory, (IUnknown *)cq->cq, hwnd, &desc, 0, 0, &swapchain1); - if (FAILED(hr)) - { - Panic(Lit("Failed to create IDXGISwapChain1")); - } - } - - /* Upgrade to swapchain3 */ - hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void **)&swapchain->swapchain); - if (FAILED(hr)) - { - Panic(Lit("Failed to create IDXGISwapChain3")); - } - - /* Create waitable object */ -#if DX12_WAIT_FRAME_LATENCY > 0 - IDXGISwapChain3_SetMaximumFrameLatency(swapchain->swapchain, DX12_WAIT_FRAME_LATENCY); - swapchain->waitable = IDXGISwapChain2_GetFrameLatencyWaitableObject(swapchain->swapchain); - Assert(swapchain->waitable); -#endif - - /* Disable Alt+Enter changing monitor resolution to match window size */ - IDXGIFactory_MakeWindowAssociation(g->factory, hwnd, DXGI_MWA_NO_ALT_ENTER); - - IDXGISwapChain1_Release(swapchain1); - swapchain->hwnd = hwnd; - - GPU_D12_InitSwapchainResources(swapchain); - - return (GPU_Swapchain *)swapchain; + LAX swapchain; } -void GPU_ReleaseSwapchain(GPU_Swapchain *gp_swapchain) +void GPU_WaitOnSwapchain(GPU_Swapchain *swapchain) { - /* TODO */ - LAX gp_swapchain; + LAX swapchain; } -void GPU_WaitOnSwapchain(GPU_Swapchain *gp_swapchain) +void GPU_PresentSwapchain(GPU_Swapchain *swapchain, Vec2I32 backbuffer_resolution, GPU_Resource *texture, Xform texture_xf, i32 vsync) { -#if DX12_WAIT_FRAME_LATENCY > 0 - GPU_D12_Swapchain *swapchain = (GPU_D12_Swapchain *)gp_swapchain; - if (swapchain->waitable) - { - WaitForSingleObjectEx(swapchain->waitable, 1000, 1); - } -#else - LAX gp_swapchain; -#endif -} - -GPU_D12_SwapchainBuffer *GPU_D12_UpdateSwapchain(GPU_D12_Swapchain *swapchain, Vec2I32 resolution) -{ - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - resolution.x = MaxI32(resolution.x, 1); - resolution.y = MaxI32(resolution.y, 1); - b32 should_rebuild = !EqVec2I32(swapchain->resolution, resolution); - if (should_rebuild) - { - HRESULT hr = 0; - GPU_D12_CommandQueue *cq = g->command_queues[DX12_QUEUE_DIRECT]; - /* Lock direct queue submissions (in case any write to backbuffer) */ - /* TODO: Less overkill approach - Only flush GPU_D12_BlitToSwapchain since we know it's the only operation targeting backbuffer */ - Lock lock = LockE(&cq->submit_fence_mutex); - //DEBUGBREAKABLE; - //Lock lock = LockE(&g->global_command_list_record_mutex); - { - /* Flush direct queue */ - //ID3D12CommandQueue_Signal(cq->cq, cq->submit_fence, ++cq->submit_fence_target); - { - HANDLE event = CreateEvent(0, 0, 0, 0); - ID3D12Fence_SetEventOnCompletion(cq->submit_fence, cq->submit_fence_target, event); - WaitForSingleObject(event, INFINITE); - CloseHandle(event); - } - - /* Release buffers */ - for (u32 i = 0; i < countof(swapchain->buffers); ++i) - { - GPU_D12_SwapchainBuffer *sb = &swapchain->buffers[i]; - GPU_D12_ReleaseDescriptor(sb->rtv_descriptor); - ID3D12Resource_Release(sb->resource); - } - - /* Resize buffers */ - hr = IDXGISwapChain_ResizeBuffers(swapchain->swapchain, 0, resolution.x, resolution.y, DXGI_FORMAT_UNKNOWN, DX12_SWAPCHAIN_FLAGS); - if (FAILED(hr)) - { - /* TODO: Don't panic */ - Panic(Lit("Failed to resize swapchain")); - } - } - Unlock(&lock); - - GPU_D12_InitSwapchainResources(swapchain); - - swapchain->resolution = resolution; - } - - u32 backbuffer_index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain->swapchain); - return &swapchain->buffers[backbuffer_index]; -} - -//////////////////////////////// -//~ Present - -void GPU_D12_BlitToSwapchain(GPU_D12_SwapchainBuffer *dst, GPU_D12_Resource *src, Xform src_xf) -{ - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - GPU_D12_PipelineScope *pipeline_scope = GPU_D12_BeginPipelineScope(); - GPU_D12_Pipeline *blit_pipeline = GPU_D12_PipelineFromName(pipeline_scope, Lit("kernel_blit")); - if (blit_pipeline->success) - { - GPU_D12_CommandQueue *cq = g->command_queues[DX12_QUEUE_DIRECT]; - GPU_D12_CommandList *cl = GPU_D12_BeginCommandList(cq->cl_pool); - { - __profn("Present blit"); - __profnc_dx12(cl->cq->prof, cl->cl, "Present blit", Rgb32F(0.5, 0.2, 0.2)); - GPU_D12_Swapchain *swapchain = dst->swapchain; - - /* Upload dummmy vert & index buffer */ - /* TODO: Make these static */ - /* Dummy vertex buffer */ - LocalPersist u16 quad_indices[6] = { 0, 1, 2, 0, 2, 3 }; - GPU_D12_CommandBuffer *dummy_vertex_buffer = GPU_D12_PushCommandBuffer(cl, 0, (u8 *)0); - GPU_D12_CommandBuffer *quad_index_buffer = GPU_D12_PushCommandBuffer(cl, countof(quad_indices), quad_indices); - - /* Upload descriptor heap */ - GPU_D12_CommandDescriptorHeap *descriptor_heap = GPU_D12_PushDescriptorHeap(cl, g->cbv_srv_uav_heap); - ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap }; - ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, countof(heaps), heaps); - - Rect viewport_rect = RectFromVec2(VEC2(0, 0), VEC2(swapchain->resolution.x, swapchain->resolution.y)); - D3D12_VIEWPORT viewport = GPU_D12_ViewportFromRect(viewport_rect); - D3D12_RECT scissor = GPU_D12_ScissorRectFromRect(viewport_rect); - - Mat4x4 vp_matrix = ZI; - { - Xform xf = src_xf; - xf = ScaleXform(xf, VEC2(src->texture_size.x, src->texture_size.y)); - xf = TranslateXform(xf, VEC2(0.5, 0.5)); - vp_matrix = ProjectMat4x4View(xf, viewport.Width, viewport.Height); - } - - /* Transition dst to render target */ - { - struct D3D12_RESOURCE_TRANSITION_BARRIER rtb = ZI; - rtb.pResource = dst->resource; - rtb.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - rtb.StateBefore = dst->state; - rtb.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; - struct D3D12_RESOURCE_BARRIER rb = ZI; - rb.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - rb.Flags = 0; - rb.Transition = rtb; - ID3D12GraphicsCommandList_ResourceBarrier(cl->cl, 1, &rb); - dst->state = rtb.StateAfter; - } - ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, 1, &dst->rtv_descriptor->handle, 0, 0); - - /* Clear */ - f32 clear_color[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, dst->rtv_descriptor->handle, clear_color, 0, 0); - - /* Bind pipeline */ - GPU_D12_SetPipeline(cl, blit_pipeline); - - /* Set Rasterizer State */ - ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport); - ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor); - - /* Set sig */ - K_BlitSig sig = ZI; - sig.projection = vp_matrix; - sig.flags = K_BLIT_FLAG_NONE; - sig.tex_urid = src->srv_descriptor->index; - GPU_D12_SetSig(cl, &sig, sizeof(sig)); - - /* Draw */ - D3D12_VERTEX_BUFFER_VIEW vbv = GPU_D12_VbvFromCommandBuffer(dummy_vertex_buffer, 0); - D3D12_INDEX_BUFFER_VIEW ibv = GPU_D12_IbvFromCommandBuffer(quad_index_buffer, DXGI_FORMAT_R16_UINT); - ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl->cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ID3D12GraphicsCommandList_IASetVertexBuffers(cl->cl, 0, 1, &vbv); - ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &ibv); - ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, 6, 1, 0, 0, 0); - - /* Transition dst to presentable */ - { - struct D3D12_RESOURCE_TRANSITION_BARRIER rtb = ZI; - rtb.pResource = dst->resource; - rtb.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - rtb.StateBefore = dst->state; - rtb.StateAfter = D3D12_RESOURCE_STATE_PRESENT; - struct D3D12_RESOURCE_BARRIER rb = ZI; - rb.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - rb.Flags = 0; - rb.Transition = rtb; - ID3D12GraphicsCommandList_ResourceBarrier(cl->cl, 1, &rb); - dst->state = rtb.StateAfter; - } - } - GPU_D12_EndCommandList(cl); - } - GPU_D12_EndPipelineScope(pipeline_scope); -} - -void GPU_PresentSwapchain(GPU_Swapchain *gp_swapchain, Vec2I32 backbuffer_resolution, GPU_Resource *texture, Xform texture_xf, i32 vsync) -{ - __prof; - GPU_D12_Swapchain *swapchain = (GPU_D12_Swapchain *)gp_swapchain; - GPU_D12_SwapchainBuffer *swapchain_buffer = GPU_D12_UpdateSwapchain(swapchain, backbuffer_resolution); - GPU_D12_Resource *texture_resource = (GPU_D12_Resource *)texture; - - /* Blit */ - GPU_D12_BlitToSwapchain(swapchain_buffer, texture_resource, texture_xf); - - u32 present_flags = 0; - if (vsync == 0) - { - present_flags |= (DXGI_PRESENT_ALLOW_TEARING * DX12_ALLOW_TEARING); - } - - /* Present */ - { - __profn("Present"); - HRESULT hr = IDXGISwapChain3_Present(swapchain->swapchain, vsync, present_flags); - if (!SUCCEEDED(hr)) - { - Assert(0); - } - } - -#if ProfilingGpu - { - GPU_D12_SharedState *g = &GPU_D12_shared_state; - { - __profframe(0); - - __profn("Mark queue frames"); - /* Lock because frame marks shouldn't occur while command lists are recording */ - Lock lock = LockE(&g->global_command_list_record_mutex); - for (u32 i = 0; i < countof(g->command_queues); ++i) - { - { - GPU_D12_CommandQueue *cq = g->command_queues[i]; - __prof_dx12_new_frame(cq->prof); - } - } - Unlock(&lock); - } - { - __profn("Collect queues"); - for (u32 i = 0; i < countof(g->command_queues); ++i) - { - GPU_D12_CommandQueue *cq = g->command_queues[i]; - __prof_dx12_collect(cq->prof); - } - } - } -#endif -} - -//////////////////////////////// -//~ Evictor job - -JobDef(GPU_D12_EvictorJob, UNUSED sig, UNUSED id) -{ - GPU_D12_SharedState *g = &GPU_D12_shared_state; - u64 completed_targets[DX12_NUM_QUEUES] = ZI; - - b32 shutdown = 0; - while (!shutdown) - { - { - __profn("Dx12 evictor run"); - TempArena scratch = BeginScratchNoConflict(); - u64 targets[countof(completed_targets)] = ZI; - - /* Copy queued data */ - u32 num_fenced_releases = 0; - GPU_D12_FencedReleaseData *fenced_releases = 0; - { - __profn("Copy queued releases"); - Lock lock = LockE(&g->fenced_releases_mutex); - num_fenced_releases = g->fenced_releases_arena->pos / sizeof(GPU_D12_FencedReleaseData); - fenced_releases = PushStructsNoZero(scratch.arena, GPU_D12_FencedReleaseData, num_fenced_releases); - CopyBytes(fenced_releases, ArenaBase(g->fenced_releases_arena), g->fenced_releases_arena->pos); - ResetArena(g->fenced_releases_arena); - CopyBytes(targets, g->fenced_release_targets, sizeof(targets)); - Unlock(&lock); - } - - /* Yield until fences reach target */ - { - __profn("Check fences"); - for (u32 i = 0; i < countof(targets); ++i) - { - while (completed_targets[i] < targets[i]) - { - GPU_D12_CommandQueue *cq = g->command_queues[i]; - completed_targets[i] = ID3D12Fence_GetCompletedValue(cq->submit_fence); - if (completed_targets[i] < targets[i]) - { - __profn("Yield on fence"); - { - Counter counter = ZI; - RunJob(1, GPU_D12_WaitOnFenceJob, JobPool_Floating, JobPriority_Inherit, &counter, .fence = cq->submit_fence, .target = targets[i]); - YieldOnCounter(&counter); - } - } - } - } - } - - /* Process releases */ - for (u32 i = 0; i < num_fenced_releases; ++i) - { - GPU_D12_FencedReleaseData *fr = &fenced_releases[i]; - switch (fr->kind) - { - default: - { - /* Unknown handle type */ - Assert(0); - } break; - - case GPU_D12_FencedReleaseKind_Resource: - { - GPU_D12_Resource *resource = (GPU_D12_Resource *)fr->ptr; - GPU_D12_ReleaseResourceNow(resource); - } break; - - case GPU_D12_FencedReleaseKind_Pipeline: - { - GPU_D12_Pipeline *pipeline = (GPU_D12_Pipeline *)fr->ptr; - GPU_D12_ReleasePipelineNow(pipeline); - } break; - } - } - EndScratch(scratch); - } - Lock lock = LockE(&g->evictor_wake_mutex); - { - while (!g->evictor_shutdown && g->evictor_wake_gen == 0) - { - YieldOnCv(&g->evictor_wake_cv, &lock); - } - shutdown = g->evictor_shutdown; - g->evictor_wake_gen = 0; - } - Unlock(&lock); - } + LAX swapchain; + LAX backbuffer_resolution; + LAX texture; + LAX texture_xf; + LAX vsync; } diff --git a/src/gpu/dx12/gpu_dx12.h b/src/gpu/dx12/gpu_dx12.h index bfcf4355..e69de29b 100644 --- a/src/gpu/dx12/gpu_dx12.h +++ b/src/gpu/dx12/gpu_dx12.h @@ -1,590 +0,0 @@ -//////////////////////////////// -//~ D3D12 headers - -#pragma warning(push, 0) -# define UNICODE -# define COBJMACROS -# include -# include -# include -# include -# include -# include -#pragma warning(pop) - -//////////////////////////////// -//~ Dx12 - -#define DX12_ALLOW_TEARING 1 -#define DX12_WAIT_FRAME_LATENCY 1 -#define DX12_SWAPCHAIN_FLAGS (((DX12_ALLOW_TEARING != 0) * DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING) | ((DX12_WAIT_FRAME_LATENCY != 0) * DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT)) -#define DX12_SWAPCHAIN_BUFFER_COUNT (4) - -/* Arbitrary limits */ -#define DX12_NUM_CBV_SRV_UAV_DESCRIPTORS (1024 * 64) -#define DX12_NUM_RTV_DESCRIPTORS (1024 * 1) -#define DX12_COMMAND_BUFFER_MIN_SIZE (1024 * 64) - -#define DX12_MULTI_QUEUE !ProfilingIsEnabled -#if DX12_MULTI_QUEUE -# define DX12_QUEUE_DIRECT 0 -# define DX12_QUEUE_COMPUTE 1 -# define DX12_QUEUE_COPY 2 -# define DX12_QUEUE_COPY_BACKGROUND 3 -# define DX12_NUM_QUEUES 4 -#else -# define DX12_QUEUE_DIRECT 0 -# define DX12_QUEUE_COMPUTE 0 -# define DX12_QUEUE_COPY 0 -# define DX12_QUEUE_COPY_BACKGROUND 0 -# define DX12_NUM_QUEUES 1 -#endif - -#if RtcIsEnabled -//# define DX12_DEBUG 1 -# define DX12_DEBUG 0 -#else -# define DX12_DEBUG 0 -#endif - -//////////////////////////////// -//~ structs - -Struct(GPU_D12_Descriptor) -{ - struct GPU_D12_CpuDescriptorHeap *heap; - - u32 index; - D3D12_CPU_DESCRIPTOR_HANDLE handle; - - GPU_D12_Descriptor *next_free; -}; - -Struct(GPU_D12_Resource) -{ - enum D3D12_RESOURCE_STATES state; - ID3D12Resource *resource; - GPU_D12_Descriptor *cbv_descriptor; - GPU_D12_Descriptor *srv_descriptor; - GPU_D12_Descriptor *uav_descriptor; - GPU_D12_Descriptor *rtv_descriptor; - - D3D12_GPU_VIRTUAL_ADDRESS gpu_address; /* NOTE: 0 for textures */ - - Vec2I32 texture_size; - GPU_D12_Resource *next_free; -}; - -Struct(GPU_D12_RtvDesc) -{ - DXGI_FORMAT format; - b32 blending; -}; - -Struct(GPU_D12_PipelineDesc) -{ - String name; - - /* If a dxc string is set, then it will be used directly instead of looking up dxc from archive using pipeline name */ - String vs_dxc; - String ps_dxc; - String cs_dxc; - - GPU_D12_RtvDesc rtvs[8]; -}; - -Struct(GPU_D12_Pipeline) -{ - String name; - u64 hash; - b32 success; - b32 is_gfx; - String error; - i64 compilation_time_ns; - - /* Lock global pipelines mutex when accessing */ - i64 refcount; - - ID3D12PipelineState *pso; - ID3D12RootSignature *rootsig; - GPU_D12_PipelineDesc desc; - - GPU_D12_Pipeline *next; -}; - -Struct(GPU_D12_PipelineScope) -{ - Arena *arena; - Dict *refs; - GPU_D12_PipelineScope *next_free; -}; - -Struct(GPU_D12_CommandQueueDesc) -{ - enum D3D12_COMMAND_LIST_TYPE type; - enum D3D12_COMMAND_QUEUE_PRIORITY priority; - String dbg_name; -}; - -Struct(GPU_D12_CommandQueue) -{ - GPU_D12_CommandQueueDesc desc; - ID3D12CommandQueue *cq; - Arena *arena; - - Mutex submit_fence_mutex; - u64 submit_fence_target; - ID3D12Fence *submit_fence; - - struct GPU_D12_CommandListPool *cl_pool; - -#if ProfilingGpu - __prof_dx12_ctx(prof); -#endif -}; - -Struct(GPU_D12_CommandListPool) -{ - GPU_D12_CommandQueue *cq; - Arena *arena; - Mutex mutex; - struct GPU_D12_CommandList *first_submitted_command_list; - struct GPU_D12_CommandList *last_submitted_command_list; -}; - -Struct(GPU_D12_CommandDescriptorHeap) -{ - D3D12_DESCRIPTOR_HEAP_TYPE type; - ID3D12DescriptorHeap *heap; - D3D12_CPU_DESCRIPTOR_HANDLE start_cpu_handle; - D3D12_GPU_DESCRIPTOR_HANDLE start_gpu_handle; - - GPU_D12_CommandDescriptorHeap *next_in_command_list; - - u64 submitted_fence_target; - GPU_D12_CommandQueue *submitted_cq; - GPU_D12_CommandDescriptorHeap *prev_submitted; - GPU_D12_CommandDescriptorHeap *next_submitted; -}; - -Struct(GPU_D12_CommandBuffer) -{ - struct GPU_D12_CommandBufferGroup *group; - - u64 size; - GPU_D12_Resource *resource; - D3D12_VERTEX_BUFFER_VIEW vbv; - D3D12_INDEX_BUFFER_VIEW Ibv; - - GPU_D12_CommandBuffer *next_in_command_list; - - u64 submitted_fence_target; - GPU_D12_CommandQueue *submitted_cq; - GPU_D12_CommandBuffer *prev_submitted; - GPU_D12_CommandBuffer *next_submitted; -}; - -Struct(GPU_D12_CommandBufferGroup) -{ - GPU_D12_CommandBuffer *first_submitted; - GPU_D12_CommandBuffer *last_submitted; -}; - -Struct(GPU_D12_CommandList) -{ - GPU_D12_CommandQueue *cq; - GPU_D12_CommandListPool *pool; - struct ID3D12CommandAllocator *ca; - struct ID3D12GraphicsCommandList *cl; - Lock global_record_lock; - - GPU_D12_Pipeline *cur_pipeline; - - GPU_D12_CommandDescriptorHeap *first_command_descriptor_heap; - GPU_D12_CommandBuffer *first_command_buffer; - - u64 submitted_fence_target; - GPU_D12_CommandList *prev_submitted; - GPU_D12_CommandList *next_submitted; -}; - -Struct(GPU_D12_SwapchainBuffer) -{ - struct GPU_D12_Swapchain *swapchain; - ID3D12Resource *resource; - GPU_D12_Descriptor *rtv_descriptor; - D3D12_RESOURCE_STATES state; -}; - -Struct(GPU_D12_Swapchain) -{ - IDXGISwapChain3 *swapchain; - HWND hwnd; - HANDLE waitable; - Vec2I32 resolution; - GPU_D12_SwapchainBuffer buffers[DX12_SWAPCHAIN_BUFFER_COUNT]; - - GPU_D12_Swapchain *next_free; -}; - -Struct(GPU_D12_CpuDescriptorHeap) -{ - enum D3D12_DESCRIPTOR_HEAP_TYPE type; - Arena *arena; - Mutex mutex; - - u32 descriptor_size; - u32 num_descriptors_reserved; - u32 num_descriptors_capacity; - - GPU_D12_Descriptor *first_free_descriptor; - - ID3D12DescriptorHeap *heap; - struct D3D12_CPU_DESCRIPTOR_HANDLE handle; -}; - -typedef i32 GPU_D12_FencedReleaseKind; enum -{ - GPU_D12_FencedReleaseKind_None, - GPU_D12_FencedReleaseKind_Resource, - GPU_D12_FencedReleaseKind_Pipeline -}; - -Struct(GPU_D12_FencedReleaseData) -{ - GPU_D12_FencedReleaseKind kind; - void *ptr; -}; - -Struct(GPU_D12_ShaderDesc) -{ - String src; - String friendly_name; - String entry; - String target; -}; - -Struct(GPU_D12_CompiledShaderResult) -{ - i64 elapsed_ns; - String dxc; - String errors; - b32 success; -}; - -Struct(GPU_D12_RenderSig) -{ - Arena *arena; - RandState rand; - u32 frame_index; - - /* Material instances */ - u32 num_material_instance_descs; - Arena *material_instance_descs_arena; - - /* Ui instances */ - u32 num_ui_rect_instance_descs; - Arena *ui_rect_instance_descs_arena; - - /* UI shapes */ - Arena *ui_shape_verts_arena; - Arena *ui_shape_indices_arena; - - /* Grids */ - u32 num_material_grid_descs; - Arena *material_grid_descs_arena; - - /* Resources */ - GPU_D12_Resource *albedo; - GPU_D12_Resource *emittance; - GPU_D12_Resource *emittance_flood_read; - GPU_D12_Resource *emittance_flood_target; - GPU_D12_Resource *shade_read; - GPU_D12_Resource *shade_target; - GPU_D12_Resource *ui_target; -}; - -Struct(GPU_D12_MaterialInstanceDesc) -{ - Xform xf; - u32 texture_id; - ClipRect clip; - u32 tint; - b32 is_light; - Vec3 light_emittance; - u32 grid_id; -}; - -Struct(GPU_D12_UiRectInstanceDesc) -{ - Xform xf; - u32 texture_id; - ClipRect clip; - u32 tint; -}; - -Struct(GPU_D12_MaterialGridDesc) -{ - f32 line_thickness; - f32 line_spacing; - Vec2 offset; - u32 bg0_color; - u32 bg1_color; - u32 line_color; - u32 x_color; - u32 y_color; -}; - -Struct(GPU_D12_ResourceBarrierDesc) -{ - enum D3D12_RESOURCE_BARRIER_TYPE type; - GPU_D12_Resource *resource; - enum D3D12_RESOURCE_STATES new_state; /* 0 if type != D3D12_RESOURCE_BARRIER_TYPE_TRANSITION */ -}; - -//////////////////////////////// -//~ Shared state - -Struct(GPU_D12_SharedState) -{ - Atomic32 initialized; - - /* Descriptor heaps pool */ - Mutex command_descriptor_heaps_mutex; - Arena *command_descriptor_heaps_arena; - GPU_D12_CommandDescriptorHeap *first_submitted_command_descriptor_heap; - GPU_D12_CommandDescriptorHeap *last_submitted_command_descriptor_heap; - - /* Command buffers pool */ - Mutex command_buffers_mutex; - Arena *command_buffers_arena; - Dict *command_buffers_dict; - - /* Resources pool */ - Mutex resources_mutex; - Arena *resources_arena; - GPU_D12_Resource *first_free_resource; - - /* Swapchains pool */ - Mutex swapchains_mutex; - Arena *swapchains_arena; - GPU_D12_Swapchain *first_free_swapchain; - - /* Shader bytecode archive */ - TAR_Archive dxc_archive; - - /* Pipeline cache */ - Mutex pipelines_mutex; - Arena *pipelines_arena; - GPU_D12_Pipeline *first_free_pipeline; - Dict *pipeline_descs; - Dict *top_pipelines; /* Latest pipelines */ - Dict *top_successful_pipelines; /* Latest pipelines that successfully compiled */ - GPU_D12_PipelineScope *first_free_pipeline_scope; - - /* Fenced release queue */ - Mutex fenced_releases_mutex; - Arena *fenced_releases_arena; - u64 fenced_release_targets[DX12_NUM_QUEUES]; - - /* Factory */ - IDXGIFactory6 *factory; - - /* Adapter */ - IDXGIAdapter1 *adapter; - - /* Device */ - ID3D12Device *device; - - /* Descriptor sizes */ - u32 desc_sizes[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES]; - u32 desc_counts[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES]; - - /* Global descriptor heaps */ - GPU_D12_CpuDescriptorHeap *cbv_srv_uav_heap; - GPU_D12_CpuDescriptorHeap *rtv_heap; - - /* Command queues */ - Mutex global_command_list_record_mutex; - Mutex global_submit_mutex; - GPU_D12_CommandQueue *command_queues[DX12_NUM_QUEUES]; - - /* Evictor job */ - Counter evictor_job_counter; - Cv evictor_wake_cv; - Mutex evictor_wake_mutex; - i64 evictor_wake_gen; - b32 evictor_shutdown; -}; - -extern GPU_D12_SharedState GPU_D12_shared_state; - -//////////////////////////////// -//~ Startup - -ExitFuncDef(GPU_D12_Shutdown); - -//////////////////////////////// -//~ Dx12 device initialization - -void GPU_D12_PushInitError(String error); - -void GPU_D12_InitDevice(void); - -//////////////////////////////// -//~ Dx12 object initialization - -void GPU_D12_InitObjects(void); - -//////////////////////////////// -//~ Dx12 pipeline initialization - -void GPU_InitPipelines(void); - -//////////////////////////////// -//~ Noise texture initialization - -void GPU_D12_InitNoise(void); - -//////////////////////////////// -//~ Shader compilation - -JobDecl(GPU_D12_CompileShaderJob, { Arena *arena; GPU_D12_ShaderDesc *descs; GPU_D12_CompiledShaderResult *results; }); - -//////////////////////////////// -//~ Pipeline - -JobDecl(GPU_D12_AcquirePipelineJob, { GPU_D12_PipelineDesc *descs_in; GPU_D12_Pipeline **pipelines_out; }); - -void GPU_D12_ReleasePipelineNow(GPU_D12_Pipeline *pipeline); - -//////////////////////////////// -//~ Pipeline cache - -GPU_D12_PipelineScope *GPU_D12_BeginPipelineScope(void); - -void GPU_D12_EndPipelineScope(GPU_D12_PipelineScope *scope); - -extern Readonly GPU_D12_Pipeline GPU_D12_nil_pipeline; -GPU_D12_Pipeline *GPU_D12_PipelineFromName(GPU_D12_PipelineScope *scope, String name); - -void GPU_D12_RegisterPipeline(u64 num_pipelines, GPU_D12_Pipeline **pipelines); - -W_CallbackFuncDef(GPU_D12_WatchPipelineCallback, name); - -//////////////////////////////// -//~ Descriptor - -GPU_D12_Descriptor *GPU_D12_AcquireDescriptor(GPU_D12_CpuDescriptorHeap *dh); - -void GPU_D12_ReleaseDescriptor(GPU_D12_Descriptor *descriptor); - -//////////////////////////////// -//~ CPU descriptor heap - -GPU_D12_CpuDescriptorHeap *GPU_D12_AcquireCpuDescriptorHeap(enum D3D12_DESCRIPTOR_HEAP_TYPE type); - -//////////////////////////////// -//~ Fenced release - -void GPU_D12_ReleaseDataFenced(void *data, GPU_D12_FencedReleaseKind kind); - -//////////////////////////////// -//~ Resource - -GPU_D12_Resource *GPU_D12_AcquireResource(D3D12_HEAP_PROPERTIES heap_props, D3D12_HEAP_FLAGS heap_flags, D3D12_RESOURCE_DESC desc, D3D12_RESOURCE_STATES initial_state); - -void GPU_D12_ReleaseResourceNow(GPU_D12_Resource *t); - -void GPU_ReleaseResourceFenced(GPU_Resource *resource); - -//////////////////////////////// -//~ Resource barrier - -void GPU_D12_InsertBarrier(ID3D12GraphicsCommandList *cl, i32 num_descs, GPU_D12_ResourceBarrierDesc *descs); - -//////////////////////////////// -//~ Command queue - -JobDecl(GPU_D12_AcquireCommandQueueJob, { GPU_D12_CommandQueueDesc *descs_in; GPU_D12_CommandQueue **cqs_out; }); - -void GPU_D12_ReleaseCommandQueue(GPU_D12_CommandQueue *cq); - -//////////////////////////////// -//~ Command list - -GPU_D12_CommandListPool *GPU_D12_AcquireCommandListPool(GPU_D12_CommandQueue *cq); - -GPU_D12_CommandList *GPU_D12_BeginCommandList(GPU_D12_CommandListPool *pool); - -/* TODO: Allow multiple command list submissions */ -u64 GPU_D12_EndCommandList(GPU_D12_CommandList *cl); - -//////////////////////////////// -//~ Command descriptor heap (GPU / shader visible descriptor heap) - -GPU_D12_CommandDescriptorHeap *GPU_D12_PushDescriptorHeap(GPU_D12_CommandList *cl, GPU_D12_CpuDescriptorHeap *dh_cpu); - -//////////////////////////////// -//~ Command buffer - -u64 GPU_D12_CommandBufferHashFromSize(u64 size); - -#define GPU_D12_PushCommandBuffer(cl, count, elems) GPU_D12_PushCommandBufferEx((cl), count * ((elems) ? sizeof(*(elems)) : 0), (elems), (elems) ? sizeof(*(elems)) : 1) -GPU_D12_CommandBuffer *GPU_D12_PushCommandBufferEx(GPU_D12_CommandList *cl, u64 data_len, void *data, u64 data_stride); - -//////////////////////////////// -//~ Wait job - -JobDecl(GPU_D12_WaitOnFenceJob, { ID3D12Fence *fence; u64 target; }); - -//////////////////////////////// -//~ Upload - -JobDecl(GPU_D12_UploadJob, { GPU_D12_Resource *resource; void *data; }); - -//////////////////////////////// -//~ Run utils - -void GPU_D12_SetPipeline(GPU_D12_CommandList *cl, GPU_D12_Pipeline *pipeline); - - -void GPU_D12_SetSig(GPU_D12_CommandList *cl, void *src, u32 size); - -struct D3D12_VIEWPORT GPU_D12_ViewportFromRect(Rect r); - -D3D12_RECT GPU_D12_ScissorRectFromRect(Rect r); - -D3D12_VERTEX_BUFFER_VIEW GPU_D12_VbvFromCommandBuffer(GPU_D12_CommandBuffer *cb, u32 vertex_size); - -D3D12_INDEX_BUFFER_VIEW GPU_D12_IbvFromCommandBuffer(GPU_D12_CommandBuffer *cb, DXGI_FORMAT format); - -GPU_D12_Resource *GPU_D12_AcquireGbuff(DXGI_FORMAT format, Vec2I32 size, D3D12_RESOURCE_STATES initial_state); - -D3D12_GPU_DESCRIPTOR_HANDLE GPU_D12_GpuHandleFromDescriptor(GPU_D12_Descriptor *descriptor, GPU_D12_CommandDescriptorHeap *cdh); - -//////////////////////////////// -//~ Render sig - -GPU_D12_RenderSig *GPU_D12_AcquireRenderSig(void); - -void GPU_D12_ResetRenderSig(GPU_D12_RenderSig *sig); - -GPU_RenderSig *GPU_AcquireRenderSig(void); - -//////////////////////////////// -//~ Swapchain - -void GPU_D12_InitSwapchainResources(GPU_D12_Swapchain *swapchain); - -GPU_D12_SwapchainBuffer *GPU_D12_UpdateSwapchain(GPU_D12_Swapchain *swapchain, Vec2I32 resolution); - -//////////////////////////////// -//~ Present - -void GPU_D12_BlitToSwapchain(GPU_D12_SwapchainBuffer *dst, GPU_D12_Resource *src, Xform src_xf); - -//////////////////////////////// -//~ Evictor job - -JobDecl(GPU_D12_EvictorJob, EmptySig); diff --git a/src/gpu/gpu.lay b/src/gpu/gpu.lay index f61ff6a1..e4ec0d17 100644 --- a/src/gpu/gpu.lay +++ b/src/gpu/gpu.lay @@ -5,20 +5,14 @@ @Dep base @Dep platform -@Dep tar -@Dep ase -@Dep dxc -@Dep inc -@Dep resource -@Dep watch //////////////////////////////// //~ Api -@CpuApi gpu_core +@ApiC gpu_core //- Dx12 -@CpuApi dx12/gpu_dx12 +@ApiCWindows dx12/gpu_dx12 //////////////////////////////// //~ Init diff --git a/src/gpu/gpu_core.h b/src/gpu/gpu_core.h index 766ef5f2..22ba53f6 100644 --- a/src/gpu/gpu_core.h +++ b/src/gpu/gpu_core.h @@ -2,109 +2,262 @@ //~ Opaque types Struct(GPU_Resource); -Struct(GPU_RenderSig); +Struct(GPU_CommandList); +Struct(GPU_VertexShader); +Struct(GPU_PixelShader); +Struct(GPU_ComputeShader); Struct(GPU_Swapchain); //////////////////////////////// -//~ Render +//~ Queue types -Struct(GPU_Indices) +#define GPU_MultiQueueEnabled !ProfilingIsEnabled +typedef i32 GPU_QueueKind; +#if GPU_MultiQueueEnabled +# define GPU_QueueKind_Direct 0 +# define GPU_QueueKind_Compute 1 +# define GPU_QueueKind_Copy 2 +# define GPU_QueueKind_BackgroundCopy 3 +# define GPU_NumQueues 4 +#else +# define GPU_QueueKind_Direct 0 +# define GPU_QueueKind_Compute 0 +# define GPU_QueueKind_Copy 0 +# define GPU_QueueKind_BackgroundCopy 0 +# define GPU_NumQueues 1 +#endif + +//////////////////////////////// +//~ Format types + +/* NOTE: Matches DXGI_FORMAT */ +typedef i32 GPU_Format; enum { - u32 count; - u32 *indices; + GPU_Format_Unknown = 0, + GPU_Format_R32G32B32A32_Typeless = 1, + GPU_Format_R32G32B32A32_Float = 2, + GPU_Format_R32G32B32A32_Uint = 3, + GPU_Format_R32G32B32A32_Sint = 4, + GPU_Format_R32G32B32_Typeless = 5, + GPU_Format_R32G32B32_Float = 6, + GPU_Format_R32G32B32_Uint = 7, + GPU_Format_R32G32B32_Sint = 8, + GPU_Format_R16G16B16A16_Typeless = 9, + GPU_Format_R16G16B16A16_Float = 10, + GPU_Format_R16G16B16A16_Unorm = 11, + GPU_Format_R16G16B16A16_Uint = 12, + GPU_Format_R16G16B16A16_Snorm = 13, + GPU_Format_R16G16B16A16_Sint = 14, + GPU_Format_R32G32_Typeless = 15, + GPU_Format_R32G32_Float = 16, + GPU_Format_R32G32_Uint = 17, + GPU_Format_R32G32_Sint = 18, + GPU_Format_R32G8X24_Typeless = 19, + GPU_Format_D32_Float_S8X24_Uint = 20, + GPU_Format_R32_Float_X8X24_Typeless = 21, + GPU_Format_X32_Typeless_G8X24_Uint = 22, + GPU_Format_R10G10B10A2_Typeless = 23, + GPU_Format_R10G10B10A2_Unorm = 24, + GPU_Format_R10G10B10A2_Uint = 25, + GPU_Format_R11G11B10_Float = 26, + GPU_Format_R8G8B8A8_Typeless = 27, + GPU_Format_R8G8B8A8_Unorm = 28, + GPU_Format_R8G8B8A8_Unorm_Srgb = 29, + GPU_Format_R8G8B8A8_Uint = 30, + GPU_Format_R8G8B8A8_Snorm = 31, + GPU_Format_R8G8B8A8_Sint = 32, + GPU_Format_R16G16_Typeless = 33, + GPU_Format_R16G16_Float = 34, + GPU_Format_R16G16_Unorm = 35, + GPU_Format_R16G16_Uint = 36, + GPU_Format_R16G16_Snorm = 37, + GPU_Format_R16G16_Sint = 38, + GPU_Format_R32_Typeless = 39, + GPU_Format_D32_Float = 40, + GPU_Format_R32_Float = 41, + GPU_Format_R32_Uint = 42, + GPU_Format_R32_Sint = 43, + GPU_Format_R24G8_Typeless = 44, + GPU_Format_D24_Unorm_S8_Uint = 45, + GPU_Format_R24_Unorm_X8_Typeless = 46, + GPU_Format_X24_Typeless_G8_Uint = 47, + GPU_Format_R8G8_Typeless = 48, + GPU_Format_R8G8_Unorm = 49, + GPU_Format_R8G8_Uint = 50, + GPU_Format_R8G8_Snorm = 51, + GPU_Format_R8G8_Sint = 52, + GPU_Format_R16_Typeless = 53, + GPU_Format_R16_Float = 54, + GPU_Format_D16_Unorm = 55, + GPU_Format_R16_Unorm = 56, + GPU_Format_R16_Uint = 57, + GPU_Format_R16_Snorm = 58, + GPU_Format_R16_Sint = 59, + GPU_Format_R8_Typeless = 60, + GPU_Format_R8_Unorm = 61, + GPU_Format_R8_Uint = 62, + GPU_Format_R8_Snorm = 63, + GPU_Format_R8_Sint = 64, + GPU_Format_A8_Unorm = 65, + GPU_Format_R1_Unorm = 66, + GPU_Format_R9G9B9E5_SharedXP = 67, + GPU_Format_R8G8_B8G8_Unorm = 68, + GPU_Format_G8R8_G8B8_Unorm = 69, + GPU_Format_BC1_Typeless = 70, + GPU_Format_BC1_Unorm = 71, + GPU_Format_BC1_Unorm_Srgb = 72, + GPU_Format_BC2_Typeless = 73, + GPU_Format_BC2_Unorm = 74, + GPU_Format_BC2_Unorm_Srgb = 75, + GPU_Format_BC3_Typeless = 76, + GPU_Format_BC3_Unorm = 77, + GPU_Format_BC3_Unorm_Srgb = 78, + GPU_Format_BC4_Typeless = 79, + GPU_Format_BC4_Unorm = 80, + GPU_Format_BC4_Snorm = 81, + GPU_Format_BC5_Typeless = 82, + GPU_Format_BC5_Unorm = 83, + GPU_Format_BC5_Snorm = 84, + GPU_Format_B5G6R5_Unorm = 85, + GPU_Format_B5G5R5A1_Unorm = 86, + GPU_Format_B8G8R8A8_Unorm = 87, + GPU_Format_B8G8R8X8_Unorm = 88, + GPU_Format_R10G10B10_XR_BIAS_A2_Unorm = 89, + GPU_Format_B8G8R8A8_Typeless = 90, + GPU_Format_B8G8R8A8_Unorm_Srgb = 91, + GPU_Format_B8G8R8X8_Typeless = 92, + GPU_Format_B8G8R8X8_Unorm_Srgb = 93, + GPU_Format_BC6H_Typeless = 94, + GPU_Format_BC6H_UF16 = 95, + GPU_Format_BC6H_SF16 = 96, + GPU_Format_BC7_Typeless = 97, + GPU_Format_BC7_Unorm = 98, + GPU_Format_BC7_Unorm_Srgb = 99, + GPU_Format_AYUV = 100, + GPU_Format_Y410 = 101, + GPU_Format_Y416 = 102, + GPU_Format_NV12 = 103, + GPU_Format_P010 = 104, + GPU_Format_P016 = 105, + GPU_Format_420_Opaque = 106, + GPU_Format_YUY2 = 107, + GPU_Format_Y210 = 108, + GPU_Format_Y216 = 109, + GPU_Format_NV11 = 110, + GPU_Format_AI44 = 111, + GPU_Format_IA44 = 112, + GPU_Format_P8 = 113, + GPU_Format_A8P8 = 114, + GPU_Format_B4G4R4A4_Unorm = 115, + GPU_Format_P208 = 130, + GPU_Format_V208 = 131, + GPU_Format_V408 = 132, + GPU_Format_SAMPLER_FEEDBACK_MIN_MIP_Opaque = 189, + GPU_Format_SAMPLER_FEEDBACK_MIP_REGION_USED_Opaque = 190, + GPU_Format_A4B4G4R4_Unorm = 191, + GPU_Format_Count = 192 }; -typedef i32 GPU_RenderCmdKind; enum -{ - GP_RENDER_CMD_KIND_NONE, - GP_RENDER_CMD_KIND_DRAW_MATERIAL, - GP_RENDER_CMD_KIND_DRAW_UI_RECT, - GP_RENDER_CMD_KIND_DRAW_UI_SHAPE, - GP_RENDER_CMD_KIND_PUSH_GRID, +//////////////////////////////// +//~ Resource types - NUM_GP_RENDER_CMD_KINDS +typedef i32 GPU_ResourceKind; enum +{ + GPU_ResourceKind_Unknown, + GPU_ResourceKind_Buffer, + GPU_ResourceKind_Texture1D, + GPU_ResourceKind_Texture2D, + GPU_ResourceKind_Texture3D, + GPU_ResourceKind_Sampler }; -Struct(GPU_RenderCmdDesc) +typedef i32 GPU_ResourceFlag; enum { - GPU_RenderCmdKind kind; + GPU_ResourceFlag_None = 0, + GPU_ResourceFlag_AllowSrv = (1 << 0), + GPU_ResourceFlag_AllowUav = (1 << 1), + GPU_ResourceFlag_AllowRtv = (1 << 2) +}; + +typedef i32 GPU_HeapKind; enum +{ + GPU_HeapKind_Default, + GPU_HeapKind_Upload, + GPU_HeapKind_Download +}; + +typedef i32 GPU_ReleaseFlag; enum +{ + GPU_ReleaseFlag_None = 0, + GPU_ReleaseFlag_Reuse = (1 << 0) +}; + +Struct(GPU_ResourceDesc) +{ + GPU_ResourceKind kind; + GPU_ResourceFlag flags; union { struct { - Xform xf; - GPU_Resource *texture; - ClipRect clip; - u32 tint; - b32 is_light; - Vec3 light_emittance; - u32 grid_cmd_id; - } material; + GPU_Format format; + Vec3I32 size; + i32 mip_levels; + } texture; struct { - Xform xf; - GPU_Resource *texture; - ClipRect clip; - u32 tint; - } ui_rect; - struct - { - Vec2Array vertices; - GPU_Indices indices; - u32 color; - } ui_shape; - struct - { - f32 line_thickness; - f32 line_spacing; - Vec2 offset; - u32 bg0_color; - u32 bg1_color; - u32 line_color; - u32 x_color; - u32 y_color; - } grid; + GPU_HeapKind heap_kind; + u32 size; + u32 element_count; + u32 element_size; + } buffer; }; }; -Struct(GPU_RenderParams) +//////////////////////////////// +//~ Shader types + +Struct(GPU_ShaderDesc) { - Vec2I32 ui_size; - Vec2I32 render_size; - Xform world_to_render_xf; - Xform render_to_ui_xf; - b32 effects_disabled; + char *shader_id; +}; + +#define GPU_ShaderDecl(name) static GPU_ShaderDesc name = { .shader_id = #name } + +//////////////////////////////// +//~ Rasterizer types + +typedef i32 GPU_RasterizeMode; enum +{ + GPU_RasterizeMode_None, + GPU_RasterizeMode_TriangleList +}; + +Struct(GPU_Viewport) +{ + i32 _; +}; + +Struct(GPU_Scissor) +{ + i32 _; }; //////////////////////////////// -//~ Texture +//~ Fence types -typedef i32 GPU_TextureFormat; enum +Struct(GPU_Fence) { - GP_TEXTURE_FORMAT_NONE, - GP_TEXTURE_FORMAT_R8_UNORM, - GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, - GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB, - GP_TEXTURE_FORMAT_R16G16B16A16_FLOAT, - - NUM_GP_TEXTURE_FORMATS -}; - -typedef i32 GPU_TextureFlag; enum -{ - GP_TEXTURE_FLAG_NONE = 0, - GP_TEXTURE_FLAG_TARGETABLE = (1 << 0) + u64 targets[GPU_NumQueues]; + u32 num_targets; }; //////////////////////////////// -//~ Memory info +//~ Memory info types Struct(GPU_MemoryInfo) { - u64 local_used; - u64 local_budget; - u64 non_local_used; - u64 non_local_budget; + i32 _; }; //////////////////////////////// @@ -112,50 +265,85 @@ Struct(GPU_MemoryInfo) void GPU_StartupCore(void); +//////////////////////////////// +//~ Rasterizer helpers + +GPU_Viewport GPU_ViewportFromRect(Rect rect); +GPU_Scissor GPU_ScissorFromRect(Rect rect); + +//////////////////////////////// +//~ Fence operations + +GPU_Fence GPU_GetGlobalFence(void); + //////////////////////////////// //~ Resource operations -/* NOTE: Internally, the layer will make sure to not release any resources - * until after any in-flight GPU runs finish using them. However, it is up to - * the caller to make sure the released resources aren't then referenced in - * any runs - */ -void GPU_ReleaseResourceFenced(GPU_Resource *resource); +GPU_Resource *GPU_AcquireResource(GPU_ResourceDesc desc); +void GPU_ReleaseResource(GPU_Resource *resource, GPU_Fence fence, GPU_ReleaseFlag flags); + +u32 GPU_GetResourceId(GPU_Resource *resource); +Vec2I32 GPU_GetTextureSize(GPU_Resource *resource); //////////////////////////////// -//~ Texture operations +//~ Command list operations -GPU_Resource *GPU_AcquireTexture(GPU_TextureFormat format, u32 flags, Vec2I32 size, void *initial_data); +GPU_CommandList *GPU_BeginCommandList(void); +GPU_Fence GPU_EndCommandList(GPU_CommandList *cl); -Vec2I32 GPU_GetTextureSize(GPU_Resource *texture); +void GPU_ProfileDF(GPU_CommandList *cl, String zone_name); //////////////////////////////// -//~ Render operations +//~ Resource transition operations -GPU_RenderSig *GPU_AcquireRenderSig(void); - -/* Returns a cmd id internal to the sig */ -u32 GPU_PushRenderCmd(GPU_RenderSig *render_sig, GPU_RenderCmdDesc *desc); - -GPU_Resource *GPU_RunRender(GPU_RenderSig *gp_render_sig, GPU_RenderParams render_params); +void GPU_TransitionToSrv(GPU_CommandList *cl, GPU_Resource *resource); +void GPU_TransitionToUav(GPU_CommandList *cl, GPU_Resource *resource); +void GPU_TransitionToRtv(GPU_CommandList *cl, GPU_Resource *resource); +void GPU_Flush(GPU_CommandList *cl, GPU_Resource *resource); //////////////////////////////// -//~ Memory query +//~ Dispatch operations + +void GPU_DispatchClear(GPU_CommandList *cl, GPU_Resource *resource); + +void GPU_DispatchRasterize(GPU_CommandList *cl, + GPU_ShaderDesc vs, + GPU_ShaderDesc ps, + void *sig, + u32 rts_count, + GPU_Resource **rts, + u32 viewports_count, + GPU_Viewport *viewports, + u32 scissors_count, + GPU_Scissor *scissors, + u32 instances_count, + GPU_Resource *index_buffer, + GPU_RasterizeMode mode); + +void GPU_DispatchCompute(GPU_CommandList *cl, GPU_ShaderDesc cs, void *sig, u32 num_threads_x, u32 num_threads_y, u32 num_threads_z); + +//////////////////////////////// +//~ Resource copy operations + +void GPU_PushResource(GPU_CommandList *cl, GPU_Resource *dst, GPU_Resource *src); +void GPU_PushString(GPU_CommandList *cl, GPU_Resource *dst, String src); + +//////////////////////////////// +//~ Memory info operations GPU_MemoryInfo GPU_QueryMemoryInfo(void); //////////////////////////////// -//~ Swapchain +//~ Swapchain operations -GPU_Swapchain *GPU_AcquireSwapchain(P_Window *window, Vec2I32 resolution); - -void GPU_ReleaseSwapchain(GPU_Swapchain *gp_swapchain); +GPU_Swapchain *GPU_AcquireSwapchain(P_Window *window, Vec2I32 size); +void GPU_ReleaseSwapchain(GPU_Swapchain *swapchain); /* Waits until a new backbuffer is ready to be written to. * This should be called before rendering for minimum latency. */ -void GPU_WaitOnSwapchain(GPU_Swapchain *gp_swapchain); +void GPU_WaitOnSwapchain(GPU_Swapchain *swapchain); /* 1. Clears the backbuffer and ensures it's at size `backbuffer_resolution` * 2. Blits `texture` to the backbuffer using `texture_xf` * 3. Presents the backbuffer */ -void GPU_PresentSwapchain(GPU_Swapchain *gp_swapchain, Vec2I32 backbuffer_resolution, GPU_Resource *texture, Xform texture_xf, i32 vsync); +void GPU_PresentSwapchain(GPU_Swapchain *swapchain, Vec2I32 backbuffer_resolution, GPU_Resource *texture, Xform texture_xf, i32 vsync); diff --git a/src/gtest/dx12/gtest_dx12.c b/src/gtest/dx12/gtest_dx12.c deleted file mode 100644 index 43a3e51d..00000000 --- a/src/gtest/dx12/gtest_dx12.c +++ /dev/null @@ -1,206 +0,0 @@ -//////////////////////////////// -//~ @hookdef Startup hook - -void GT_StartupCore(void) -{ -} - -//////////////////////////////// -//~ @hookdef Rasterizer helper hooks - -GT_Viewport GT_ViewportFromRect(Rect rect) -{ - LAX rect; - return (GT_Viewport) ZI; -} - -GT_Scissor GT_ScissorRectFromRect(Rect rect) -{ - LAX rect; - return (GT_Scissor) ZI; -} - -//////////////////////////////// -//~ @hookdef Fence hooks - -GT_Fence GT_GetGlobalFence(void) -{ - return (GT_Fence) ZI; -} - -//////////////////////////////// -//~ @hookdef Resource hooks - -GT_Resource *GT_AcquireResource(GT_ResourceDesc desc) -{ - LAX desc; - return (GT_Resource *)0; -} - -void GT_ReleaseResource(GT_Resource *resource, GT_Fence fence, GT_ReleaseFlag flags) -{ - LAX resource; - LAX fence; - LAX flags; -} - -u32 GT_GetResourceId(GT_Resource *resource) -{ - LAX resource; - return 0; -} - -Vec2I32 GT_GetTextureSize(GT_Resource *resource) -{ - LAX resource; - return VEC2I32(0, 0); -} - -//////////////////////////////// -//~ @hookdef Command list hooks - -GT_CommandList *GT_BeginCommandList(void) -{ - return 0; -} - -GT_Fence GT_EndCommandList(GT_CommandList *cl) -{ - LAX cl; - return (GT_Fence) ZI; -} - -void GT_ProfileDF(GT_CommandList *cl, String zone_name) -{ - LAX cl; - LAX zone_name; -} - -//////////////////////////////// -//~ @hookdef Resource transition hooks - -void GT_TransitionToSrv(GT_CommandList *cl, GT_Resource *resource) -{ - LAX cl; - LAX resource; -} - -void GT_TransitionToUav(GT_CommandList *cl, GT_Resource *resource) -{ - LAX cl; - LAX resource; -} - -void GT_TransitionToRtv(GT_CommandList *cl, GT_Resource *resource) -{ - LAX cl; - LAX resource; -} - -void GT_Flush(GT_CommandList *cl, GT_Resource *resource) -{ - LAX cl; - LAX resource; -} - -//////////////////////////////// -//~ @hookdef Dispatch hooks - -void GT_DispatchClear(GT_CommandList *cl, GT_Resource *resource) -{ - LAX cl; - LAX resource; -} - -void GT_DispatchRasterize(GT_CommandList *cl, - GT_ShaderDesc vs, - GT_ShaderDesc ps, - void *sig, - u32 rts_count, - GT_Resource **rts, - u32 viewports_count, - GT_Viewport *viewports, - u32 scissors_count, - GT_Scissor *scissors, - u32 instances_count, - GT_Resource *index_buffer, - GT_RasterizeMode mode) -{ - LAX cl; - LAX vs; - LAX ps; - LAX sig; - LAX rts_count; - LAX rts; - LAX viewports_count; - LAX *viewports; - LAX scissors_count; - LAX scissors; - LAX instances_count; - LAX index_buffer; - LAX mode; -} - -void GT_DispatchCompute(GT_CommandList *cl, GT_ShaderDesc cs, void *sig, u32 num_threads_x, u32 num_threads_y, u32 num_threads_z) -{ - LAX cl; - LAX cs; - LAX sig; - LAX num_threads_x; - LAX num_threads_y; - LAX num_threads_z; -} - -//////////////////////////////// -//~ @hookdef Copy hooks - -void GT_PushResource(GT_CommandList *cl, GT_Resource *dst, GT_Resource *src) -{ - LAX cl; - LAX dst; - LAX src; -} - -void GT_PushString(GT_CommandList *cl, GT_Resource *dst, String src) -{ - LAX cl; - LAX dst; - LAX src; -} - -//////////////////////////////// -//~ @hookdef Memory info hooks - -GT_MemoryInfo GT_QueryMemoryInfo(void) -{ - return (GT_MemoryInfo) ZI; -} - -//////////////////////////////// -//~ @hookdef Swapchain hooks - -GT_Swapchain *GT_AcquireSwapchain(P_Window *window, Vec2I32 size) -{ - LAX window; - LAX size; - return 0; -} - -void GT_ReleaseSwapchain(GT_Swapchain *swapchain) -{ - LAX swapchain; -} - -void GT_WaitOnSwapchain(GT_Swapchain *swapchain) -{ - LAX swapchain; -} - -void GT_PresentSwapchain(GT_Swapchain *swapchain, Vec2I32 backbuffer_resolution, GT_Resource *texture, Xform texture_xf, i32 vsync) -{ - LAX swapchain; - LAX backbuffer_resolution; - LAX texture; - LAX texture_xf; - LAX vsync; -} diff --git a/src/gtest/dx12/gtest_dx12.h b/src/gtest/dx12/gtest_dx12.h deleted file mode 100644 index e69de29b..00000000 diff --git a/src/gtest/gtest.lay b/src/gtest/gtest.lay deleted file mode 100644 index 95391e7e..00000000 --- a/src/gtest/gtest.lay +++ /dev/null @@ -1,20 +0,0 @@ -@Layer gtest - -//////////////////////////////// -//~ Dependencies - -@Dep base -@Dep platform - -//////////////////////////////// -//~ Api - -@CpuApi gtest_core - -//- Dx12 -@CpuApiWindows dx12/gtest_dx12 - -//////////////////////////////// -//~ Init - -@Init GT_StartupCore diff --git a/src/gtest/gtest_core.h b/src/gtest/gtest_core.h deleted file mode 100644 index 0ee9513a..00000000 --- a/src/gtest/gtest_core.h +++ /dev/null @@ -1,349 +0,0 @@ -//////////////////////////////// -//~ Opaque types - -Struct(GT_Resource); -Struct(GT_CommandList); -Struct(GT_VertexShader); -Struct(GT_PixelShader); -Struct(GT_ComputeShader); -Struct(GT_Swapchain); - -//////////////////////////////// -//~ Queue types - -#define GT_MultiQueueEnabled !ProfilingIsEnabled -typedef i32 GT_QueueKind; -#if GT_MultiQueueEnabled -# define GT_QueueKind_Direct 0 -# define GT_QueueKind_Compute 1 -# define GT_QueueKind_Copy 2 -# define GT_QueueKind_BackgroundCopy 3 -# define GT_NumQueues 4 -#else -# define GT_QueueKind_Direct 0 -# define GT_QueueKind_Compute 0 -# define GT_QueueKind_Copy 0 -# define GT_QueueKind_BackgroundCopy 0 -# define GT_NumQueues 1 -#endif - -//////////////////////////////// -//~ Format types - -/* NOTE: Matches DXGI_FORMAT */ -typedef i32 GT_Format; enum -{ - GT_Format_Unknown = 0, - GT_Format_R32G32B32A32_Typeless = 1, - GT_Format_R32G32B32A32_Float = 2, - GT_Format_R32G32B32A32_Uint = 3, - GT_Format_R32G32B32A32_Sint = 4, - GT_Format_R32G32B32_Typeless = 5, - GT_Format_R32G32B32_Float = 6, - GT_Format_R32G32B32_Uint = 7, - GT_Format_R32G32B32_Sint = 8, - GT_Format_R16G16B16A16_Typeless = 9, - GT_Format_R16G16B16A16_Float = 10, - GT_Format_R16G16B16A16_Unorm = 11, - GT_Format_R16G16B16A16_Uint = 12, - GT_Format_R16G16B16A16_Snorm = 13, - GT_Format_R16G16B16A16_Sint = 14, - GT_Format_R32G32_Typeless = 15, - GT_Format_R32G32_Float = 16, - GT_Format_R32G32_Uint = 17, - GT_Format_R32G32_Sint = 18, - GT_Format_R32G8X24_Typeless = 19, - GT_Format_D32_Float_S8X24_Uint = 20, - GT_Format_R32_Float_X8X24_Typeless = 21, - GT_Format_X32_Typeless_G8X24_Uint = 22, - GT_Format_R10G10B10A2_Typeless = 23, - GT_Format_R10G10B10A2_Unorm = 24, - GT_Format_R10G10B10A2_Uint = 25, - GT_Format_R11G11B10_Float = 26, - GT_Format_R8G8B8A8_Typeless = 27, - GT_Format_R8G8B8A8_Unorm = 28, - GT_Format_R8G8B8A8_Unorm_Srgb = 29, - GT_Format_R8G8B8A8_Uint = 30, - GT_Format_R8G8B8A8_Snorm = 31, - GT_Format_R8G8B8A8_Sint = 32, - GT_Format_R16G16_Typeless = 33, - GT_Format_R16G16_Float = 34, - GT_Format_R16G16_Unorm = 35, - GT_Format_R16G16_Uint = 36, - GT_Format_R16G16_Snorm = 37, - GT_Format_R16G16_Sint = 38, - GT_Format_R32_Typeless = 39, - GT_Format_D32_Float = 40, - GT_Format_R32_Float = 41, - GT_Format_R32_Uint = 42, - GT_Format_R32_Sint = 43, - GT_Format_R24G8_Typeless = 44, - GT_Format_D24_Unorm_S8_Uint = 45, - GT_Format_R24_Unorm_X8_Typeless = 46, - GT_Format_X24_Typeless_G8_Uint = 47, - GT_Format_R8G8_Typeless = 48, - GT_Format_R8G8_Unorm = 49, - GT_Format_R8G8_Uint = 50, - GT_Format_R8G8_Snorm = 51, - GT_Format_R8G8_Sint = 52, - GT_Format_R16_Typeless = 53, - GT_Format_R16_Float = 54, - GT_Format_D16_Unorm = 55, - GT_Format_R16_Unorm = 56, - GT_Format_R16_Uint = 57, - GT_Format_R16_Snorm = 58, - GT_Format_R16_Sint = 59, - GT_Format_R8_Typeless = 60, - GT_Format_R8_Unorm = 61, - GT_Format_R8_Uint = 62, - GT_Format_R8_Snorm = 63, - GT_Format_R8_Sint = 64, - GT_Format_A8_Unorm = 65, - GT_Format_R1_Unorm = 66, - GT_Format_R9G9B9E5_SharedXP = 67, - GT_Format_R8G8_B8G8_Unorm = 68, - GT_Format_G8R8_G8B8_Unorm = 69, - GT_Format_BC1_Typeless = 70, - GT_Format_BC1_Unorm = 71, - GT_Format_BC1_Unorm_Srgb = 72, - GT_Format_BC2_Typeless = 73, - GT_Format_BC2_Unorm = 74, - GT_Format_BC2_Unorm_Srgb = 75, - GT_Format_BC3_Typeless = 76, - GT_Format_BC3_Unorm = 77, - GT_Format_BC3_Unorm_Srgb = 78, - GT_Format_BC4_Typeless = 79, - GT_Format_BC4_Unorm = 80, - GT_Format_BC4_Snorm = 81, - GT_Format_BC5_Typeless = 82, - GT_Format_BC5_Unorm = 83, - GT_Format_BC5_Snorm = 84, - GT_Format_B5G6R5_Unorm = 85, - GT_Format_B5G5R5A1_Unorm = 86, - GT_Format_B8G8R8A8_Unorm = 87, - GT_Format_B8G8R8X8_Unorm = 88, - GT_Format_R10G10B10_XR_BIAS_A2_Unorm = 89, - GT_Format_B8G8R8A8_Typeless = 90, - GT_Format_B8G8R8A8_Unorm_Srgb = 91, - GT_Format_B8G8R8X8_Typeless = 92, - GT_Format_B8G8R8X8_Unorm_Srgb = 93, - GT_Format_BC6H_Typeless = 94, - GT_Format_BC6H_UF16 = 95, - GT_Format_BC6H_SF16 = 96, - GT_Format_BC7_Typeless = 97, - GT_Format_BC7_Unorm = 98, - GT_Format_BC7_Unorm_Srgb = 99, - GT_Format_AYUV = 100, - GT_Format_Y410 = 101, - GT_Format_Y416 = 102, - GT_Format_NV12 = 103, - GT_Format_P010 = 104, - GT_Format_P016 = 105, - GT_Format_420_Opaque = 106, - GT_Format_YUY2 = 107, - GT_Format_Y210 = 108, - GT_Format_Y216 = 109, - GT_Format_NV11 = 110, - GT_Format_AI44 = 111, - GT_Format_IA44 = 112, - GT_Format_P8 = 113, - GT_Format_A8P8 = 114, - GT_Format_B4G4R4A4_Unorm = 115, - GT_Format_P208 = 130, - GT_Format_V208 = 131, - GT_Format_V408 = 132, - GT_Format_SAMPLER_FEEDBACK_MIN_MIP_Opaque = 189, - GT_Format_SAMPLER_FEEDBACK_MIP_REGION_USED_Opaque = 190, - GT_Format_A4B4G4R4_Unorm = 191, - GT_Format_Count = 192 -}; - -//////////////////////////////// -//~ Resource types - -typedef i32 GT_ResourceKind; enum -{ - GT_ResourceKind_Unknown, - GT_ResourceKind_Buffer, - GT_ResourceKind_Texture1D, - GT_ResourceKind_Texture2D, - GT_ResourceKind_Texture3D, - GT_ResourceKind_Sampler -}; - -typedef i32 GT_ResourceFlag; enum -{ - GT_ResourceFlag_None = 0, - GT_ResourceFlag_AllowSrv = (1 << 0), - GT_ResourceFlag_AllowUav = (1 << 1), - GT_ResourceFlag_AllowRtv = (1 << 2) -}; - -typedef i32 GT_HeapKind; enum -{ - GT_HeapKind_Default, - GT_HeapKind_Upload, - GT_HeapKind_Download -}; - -typedef i32 GT_ReleaseFlag; enum -{ - GT_ReleaseFlag_None = 0, - GT_ReleaseFlag_Reuse = (1 << 0) -}; - -Struct(GT_ResourceDesc) -{ - GT_ResourceKind kind; - GT_ResourceFlag flags; - union - { - struct - { - GT_Format format; - Vec3I32 size; - i32 mip_levels; - } texture; - struct - { - GT_HeapKind heap_kind; - u32 size; - u32 element_count; - u32 element_size; - } buffer; - }; -}; - -//////////////////////////////// -//~ Shader types - -Struct(GT_ShaderDesc) -{ - char *shader_id; -}; - -#define GT_ShaderDecl(name) static GT_ShaderDesc name = { .shader_id = #name } - -//////////////////////////////// -//~ Rasterizer types - -typedef i32 GT_RasterizeMode; enum -{ - GT_RasterizeMode_None, - GT_RasterizeMode_TriangleList -}; - -Struct(GT_Viewport) -{ - i32 _; -}; - -Struct(GT_Scissor) -{ - i32 _; -}; - -//////////////////////////////// -//~ Fence types - -Struct(GT_Fence) -{ - u64 targets[GT_NumQueues]; - u32 num_targets; -}; - -//////////////////////////////// -//~ Memory info types - -Struct(GT_MemoryInfo) -{ - i32 _; -}; - -//////////////////////////////// -//~ Startup - -void GT_StartupCore(void); - -//////////////////////////////// -//~ Rasterizer helpers - -GT_Viewport GT_ViewportFromRect(Rect rect); -GT_Scissor GT_ScissorRectFromRect(Rect rect); - -//////////////////////////////// -//~ Fence operations - -GT_Fence GT_GetGlobalFence(void); - -//////////////////////////////// -//~ Resource operations - -GT_Resource *GT_AcquireResource(GT_ResourceDesc desc); -void GT_ReleaseResource(GT_Resource *resource, GT_Fence fence, GT_ReleaseFlag flags); - -u32 GT_GetResourceId(GT_Resource *resource); -Vec2I32 GT_GetTextureSize(GT_Resource *resource); - -//////////////////////////////// -//~ Command list operations - -GT_CommandList *GT_BeginCommandList(void); -GT_Fence GT_EndCommandList(GT_CommandList *cl); - -void GT_ProfileDF(GT_CommandList *cl, String zone_name); - -//////////////////////////////// -//~ Resource transition operations - -void GT_TransitionToSrv(GT_CommandList *cl, GT_Resource *resource); -void GT_TransitionToUav(GT_CommandList *cl, GT_Resource *resource); -void GT_TransitionToRtv(GT_CommandList *cl, GT_Resource *resource); -void GT_Flush(GT_CommandList *cl, GT_Resource *resource); - -//////////////////////////////// -//~ Dispatch operations - -void GT_DispatchClear(GT_CommandList *cl, GT_Resource *resource); - -void GT_DispatchRasterize(GT_CommandList *cl, - GT_ShaderDesc vs, - GT_ShaderDesc ps, - void *sig, - u32 rts_count, - GT_Resource **rts, - u32 viewports_count, - GT_Viewport *viewports, - u32 scissors_count, - GT_Scissor *scissors, - u32 instances_count, - GT_Resource *index_buffer, - GT_RasterizeMode mode); - -void GT_DispatchCompute(GT_CommandList *cl, GT_ShaderDesc cs, void *sig, u32 num_threads_x, u32 num_threads_y, u32 num_threads_z); - -//////////////////////////////// -//~ Resource copy operations - -void GT_PushResource(GT_CommandList *cl, GT_Resource *dst, GT_Resource *src); -void GT_PushString(GT_CommandList *cl, GT_Resource *dst, String src); - -//////////////////////////////// -//~ Memory info operations - -GT_MemoryInfo GT_QueryMemoryInfo(void); - -//////////////////////////////// -//~ Swapchain operations - -GT_Swapchain *GT_AcquireSwapchain(P_Window *window, Vec2I32 size); -void GT_ReleaseSwapchain(GT_Swapchain *swapchain); - -/* Waits until a new backbuffer is ready to be written to. -* This should be called before rendering for minimum latency. */ -void GT_WaitOnSwapchain(GT_Swapchain *swapchain); - -/* 1. Clears the backbuffer and ensures it's at size `backbuffer_resolution` - * 2. Blits `texture` to the backbuffer using `texture_xf` - * 3. Presents the backbuffer */ -void GT_PresentSwapchain(GT_Swapchain *swapchain, Vec2I32 backbuffer_resolution, GT_Resource *texture, Xform texture_xf, i32 vsync); diff --git a/src/inc/inc.lay b/src/inc/inc.lay index 92cd16f2..80186c02 100644 --- a/src/inc/inc.lay +++ b/src/inc/inc.lay @@ -8,4 +8,4 @@ //////////////////////////////// //~ Api -@CpuApi inc_core +@ApiC inc_core diff --git a/src/json/json.lay b/src/json/json.lay index fd59c9f4..62e52c5a 100644 --- a/src/json/json.lay +++ b/src/json/json.lay @@ -8,4 +8,4 @@ //////////////////////////////// //~ Api -@CpuApi json_core +@ApiC json_core diff --git a/src/kernel/kernel.lay b/src/kernel/kernel.lay index cb71c4ca..1d905368 100644 --- a/src/kernel/kernel.lay +++ b/src/kernel/kernel.lay @@ -8,5 +8,5 @@ //////////////////////////////// //~ Api -@CpuApi kernel_core -@GpuApi kernel_core +@ApiC kernel_core +@ApiGpu kernel_core diff --git a/src/kernel/kernel_core.h b/src/kernel/kernel_core.h index c7b21e71..a0728992 100644 --- a/src/kernel/kernel_core.h +++ b/src/kernel/kernel_core.h @@ -1,5 +1,5 @@ /* Determine if file was included from C or from HLSL */ -#if !LanguageIsGpu +#if LanguageIsC # define K_IS_CPU 1 #else # define K_IS_CPU 0 diff --git a/src/meta/meta.c b/src/meta/meta.c index 9fea10a7..cef29159 100644 --- a/src/meta/meta.c +++ b/src/meta/meta.c @@ -52,21 +52,411 @@ i32 main(i32 argc, u8 **argv) Arena *arena = AcquireArena(Gibi(64)); //- Unpack args - StringList args = ZI; StringList exe_layer_names = ZI; + StringList args = ZI; + i32 hyphens = 0; for (i32 i = 1; i < argc; ++i) { String arg = StringFromCstrNoLimit(argv[i]); - if (EndsWith(arg, Lit(".exe"))) + if (EqString(arg, Lit("-")) { - String layer_name = TrimRight(arg, Lit(".exe")); - PushStringToList(arena, layer_name); + ++hyphens; } else { - PushStringToList(arena, &args, arg); + if (hyphens == 0) + { + PushStringToList(perm, &exe_layer_names, arg); + } + else + { + PushStringToList(perm, &args, arg); + } } } + StringList lay_dirs = ZI; + PushStringToList(perm, &lay_dirs, Lit("src")); + LayResult lay_result = ParseLay(lay_dirs, exe_layer_names); + + + + + + // Things to do: + // - For each leaf layer: + // - Walk deps to determine all layers that must be built + + for ( + + for (StringListNode *n = exe_layer_names; n; n = n->next) + { + String name = n->s; + Lay *lay = LayFromName(name); + + for (LayItem *dep_objs + + Run("cl.exe obj_files out_path"); + } + + + + + + + + + + for (StringListNode *n = exe_layer_names.first; n; n = n->next) + { + String name = n->s; + Lay *lay = LayFromName(name); + + Dict *visited_dict = InitDict(arena, 64); + + u64 level = 1; + for (LayEntry *dep = lay->deps.first; dep; dep = dep->next) + { + String dep_name = dep->name; + u64 dep_hash = dep->name_hash; + SetDictValue(visited_dict, dep_hash, level); + + // Lay *dep_lay = LayFromName(dep_name); + } + } + + + + + + + + + + + for (LayNode *leaf_lay_node = leaf_lays.first; leaf_lay_node; leaf_lay_node = leaf_lay_node->next) + { + Lay *lay = leaf_lay_node->l; + String name = lay->name; + + for (LayNode *dep_node = lay->deps.first; + } + + for (StringListNode *n = obj_files.first; n; n = n->next) + { + String file = n->s; + String cmd = StringF("cl.exe /c /Zi /DEBUG %F", file); + } + + for (StringListNode *n = gpu_code_files.first; n; n = n->next) + { + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#if 0 + StringList src_files; + FilesFromDir(arena, &src_files, Lit("src"), FileIterFlag_Recurse); + + //- Parse layer files in source directory + Dict *lay_info_dict = InitDict(arena, 1024); + for (StringListNode *n = src_files.first; n; n = n->next) + { + String file = n->s; + String extension = GetFileExtension(name); + if (MatchString(extension, Lit("lay")) + { + String file_data = StringFromFile(arena, file); + LayInfo *lay_info = PushStruct(arena, LayInfo); + *lay_info = LayInfoFromString(arena, file_data); + u64 hash = HashFnv64(Fnv64Basis, lay_info->name); + SetDictValue(lay_info_dict, hash, lay_info); + } + } + + for (DictEntry *e = lay_info_dict->first; e; e = e->next) + { + LayInfo *lay_info = (LayInfo *)e->value; + } + + + + + + + for (MetaNode *layer_node = layers.first; layer_node; layer_node = layer_node->next) + { + b32 has_cpu_code = 0; + b32 has_gpu_code = 0; + + Meta *layer = layer_node->m; + StringList cpu_api_header_files = ZI; + StringList gpu_api_header_files = ZI; + StringList c_api_code_files = ZI; + StringList cpp_api_code_files = ZI; + StringList gpu_api_code_files = ZI; + for (MetaNode *api_node = layer->apis.first; api_node; api_node = api_node->next) + { + Meta *api = api_node->m; + String api_name = api->name; + String h_file = StringF(arena, "%F.h", FmtStr(api_name)); + String c_file = StringF(arena, "%F.c", FmtStr(api_name)); + String cpp_file = StringF(arena, "%F.cpp", FmtStr(api_name)); + String gpu_file = StringF(arena, "%F.gpu", FmtStr(api_name)); + if (FileExists(h_file)) + { + if (api->api_kind == MetaApiKind_Cpu) + { + PushStringToList(arena, &cpu_api_header_files, h_file); + } + else if (api->api_kind == MetaApiKind_Gpu) + { + PushStringToList(arena, &gpu_api_header_files, h_file); + } + } + if (FileExists(c_file)) + { + PushStringToList(arena, &c_api_code_files, c_file); + has_cpu_code = 1; + } + if (FileExists(cpp_file)) + { + PushStringToList(arena, &cpp_api_code_files, cpp_file); + has_cpu_code = 1; + } + if (FileExists(gpu_file)) + { + PushStringToList(arena, &gpu_api_code_files, gpu_file); + has_gpu_code = 1; + } + } + + StringList cpu_dep_header_files = ZI; + StringList gpu_dep_header_files = ZI; + if (has_cpu_code || has_gpu_code) + { + for (MetaNode *dep_node = layer->deps.first; dep_node; dep_node = dep_node->next) + { + MetaNode *dep = dep_node->m; + String dep_name = dep->name; + } + } + } +#endif + + + + + + + + + + + + + + + + + + + + + + + +#if 0 + //- Build tree + String graph_file = ZI; + if (args.first) + { + graph_file = args.first->s; + } + MetaTree *tree = MetaTreeFromFile(graph_file); + + Rm("build/layers"); + Mkdir("build/layers"); + + StringList init_funcs = ZI; + for (MetaNode *layer = tree->first_layer; layer; layer = layer->next) + { + StringList cpu_header_files = ZI; + StringList gpu_header_files = ZI; + StringList c_files = ZI; + StringList cpp_files = ZI; + StringList gpu_files = ZI; + for (MetaNode *api = layer->first_api; api; api = api->next) + { + String api_name = api->name; + String h_file = StringF(arena, "%F.h", FmtStr(api_name)); + String c_file = StringF(arena, "%F.c", FmtStr(api_name)); + String cpp_file = StringF(arena, "%F.cpp", FmtStr(api_name)); + String gpu_file = StringF(arena, "%F.gpu", FmtStr(api_name)); + if (FileExists(h_file)) + { + if (api->api_kind == MetaApiKind_Cpu) + { + PushStringToList(arena, &cpu_header_files, h_file); + } + else if (api->api_kind == MetaApiKind_Gpu) + { + PushStringToList(arena, &gpu_header_files, h_file); + } + } + if (FileExists(c_file)) PushStringToList(arena, &c_files, c_file); + if (FileExists(cpp_file)) PushStringToList(arena, &cpp_files, cpp_file); + if (FileExists(gpu_file)) PushStringToList(arena, &gpu_files, gpu_file); + } + + StringList cpu_dep_files = ZI; + StringList gpu_dep_files = ZI; + for (MetaNode *dep = layer->first_dep; dep; dep = dep->next) + { + String dep_name = dep->name; + if (dep->has_cpu_api) + { + String cpu_dep_file = StringF(arena, "%F__cpu_api.h", FmtStr(dep_name)); + PushStringToList(arena, &cpu_dep_files, cpu_dep_file); + } + if (dep->has_gpu_api) + { + String gpu_dep_file = StringF(arena, "%F__gpu_api.h", FmtStr(dep_name)); + PushStringToList(arena, &gpu_dep_files, gpu_dep_file); + } + } + + StringList cpu_header_lines = ZI; + StringList gpu_header_lines = ZI; + StringList c_code_lines = ZI; + StringList cpp_code_lines = ZI; + StringList gpu_code_lines = ZI; + + //- Cpu header file + { + PushStringNodeF(arena, &cpu_header_lines, "// Auto generated Cpu layer header file"); + + PushStringNodeF(arena, &cpu_header_lines, "////////////////////////////////\n//~ Api header includes"); + for (StringListNode *n = cpu_header_files.first; n; n = n->next) + { + String line = StringF(arena, "#include <%F>", FmtStr(n->s)); + PushStringToList(arena, &cpu_header_lines, line); + } + } + + //- Gpu header file + { + PushStringNodeF(arena, &gpu_header_lines, "// Auto generated Gpu layer header file"); + + PushStringNodeF(arena, &gpu_header_lines, "////////////////////////////////\n//~ Api header includes"); + for (StringListNode *n = gpu_header_files.first; n; n = n->next) + { + String line = StringF(arena, "#include <%F>", FmtStr(n->s)); + PushStringToList(arena, &gpu_header_lines, line); + } + } + + //- C code file + { + PushStringNodeF(arena, &c_code_lines, "// Auto generated C layer code file"); + + PushStringNodeF(arena, &c_code_lines, "////////////////////////////////\n//~ Layer dependency includes"); + for (StringListNode *n = cpu_dep_files.first; n; n = n->next) + { + String line = StringF(arena, "#include <%F>", FmtStr(n->s)); + PushStringToList(arena, &c_code_lines, line); + } + + PushStringNodeF(arena, &c_code_lines, "////////////////////////////////\n//~ Api code includes"); + for (StringListNode *n = c_files.first; n; n = n->next) + { + String line = StringF(arena, "#include <%F>", FmtStr(n->s)); + PushStringToList(arena, &c_code_lines, line); + } + } + + //- Gpu code file + { + PushStringNodeF(arena, &gpu_code_lines, "// Auto generated Gpu layer code file"); + + PushStringNodeF(arena, &c_code_lines, "////////////////////////////////\n//~ Layer dependency includes"); + for (StringListNode *n = gpu_dep_files.first; n; n = n->next) + { + String line = StringF(arena, "#include <%F>", FmtStr(n->s)); + PushStringToList(arena, &gpu_code_lines, line); + } + + PushStringNodeF(arena, &gpu_code_lines, "////////////////////////////////\n//~ Api code includes"); + for (StringListNode *n = gpu_files.first; n; n = n->next) + { + String line = StringF(arena, "#include <%F>", FmtStr(n->s)); + PushStringToList(arena, &gpu_code_lines, line); + } + } + + + + + + + + // { + // String init_name = init->name; + // PushStringToList(arena, init_funcs, init_name); + // } + // full_path = n->full_path; + // String line = StringF(arena, "#include <%F>", full_path); + // PushStringToList(arena, &gen_lines, line); + } +#endif + + + + + + + return 0; } diff --git a/src/meta/meta_arena.h b/src/meta/meta_arena.h index c83fa066..d980952d 100644 --- a/src/meta/meta_arena.h +++ b/src/meta/meta_arena.h @@ -14,7 +14,8 @@ Struct(Arena) #endif }; -Struct(TempArena) { +Struct(TempArena) +{ Arena *arena; u64 start_pos; @@ -118,16 +119,22 @@ void SetArenaReadWrite(Arena *arena); Inline void *AlignArena(Arena *arena, u64 align) { Assert(!arena->readonly); - if (align > 0) { + if (align > 0) + { u64 aligned_start_pos = (arena->pos + (align - 1)); aligned_start_pos -= aligned_start_pos % align; u64 align_bytes = aligned_start_pos - (u64)arena->pos; - if (align_bytes > 0) { + if (align_bytes > 0) + { return (void *)PushStructsNoZero(arena, u8, align_bytes); - } else { + } + else + { return (void *)(ArenaBase(arena) + arena->pos); } - } else { + } + else + { /* 0 alignment */ Assert(0); return (void *)(ArenaBase(arena) + arena->pos); @@ -163,9 +170,11 @@ Inline ArenaCtx *ArenaCtxFromThreadId(i16 thread_id) { SharedArenaCtx *shared = &shared_arena_ctx; ArenaCtx *ctx = &shared->arena_contexts[thread_id]; - if (!ctx->scratch_arenas[0]) { + if (!ctx->scratch_arenas[0]) + { __profn("Initialize thread arena ctx"); - for (i32 i = 0; i < (i32)countof(ctx->scratch_arenas); ++i) { + for (i32 i = 0; i < (i32)countof(ctx->scratch_arenas); ++i) + { ctx->scratch_arenas[i] = AcquireArena(Gibi(64)); } ctx->perm_arena = AcquireArena(Gibi(64)); @@ -196,7 +205,8 @@ Inline TempArena _BeginScratch(Arena *potential_conflict) ArenaCtx *ctx = ArenaCtxFromThreadId(ThreadId()); Arena *scratch_arena = ctx->scratch_arenas[0]; - if (potential_conflict && scratch_arena == potential_conflict) { + if (potential_conflict && scratch_arena == potential_conflict) + { scratch_arena = ctx->scratch_arenas[1]; } TempArena temp = BeginTempArena(scratch_arena); diff --git a/src/meta/meta_core.h b/src/meta/meta_core.h index 8015134c..c72c7994 100644 --- a/src/meta/meta_core.h +++ b/src/meta/meta_core.h @@ -59,16 +59,10 @@ #endif //- Language -#if defined(__cplusplus) -# define LanguageIsCpp 1 -# define LanguageIsC 0 -# define LanguageIsGpu 0 -#elif defined(__HLSL_VERSION) -# define LanguageIsCpp 0 +#if defined(__HLSL_VERSION) # define LanguageIsC 0 # define LanguageIsGpu 1 #else -# define LanguageIsCpp 0 # define LanguageIsC 1 # define LanguageIsGpu 0 #endif @@ -172,13 +166,6 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t); //////////////////////////////// //~ Common utility macros -//- Initlist compatibility -#if CompilerIsMsvc && LanguageIsCpp -# define CppCompatInitListType(type) -#else -# define CppCompatInitListType(type) (type) -#endif - //- ZeroStruct initialization macro #if LanguageIsC # define ZI { 0 } @@ -247,16 +234,10 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t); #define LAX (void) //- Fallthrough -#if CompilerIsMsvc -# if LanguageIsCpp -# define FALLTHROUGH [[fallthrough]] -# else -# define FALLTHROUGH -# endif -#elif CompilerIsClang -# define FALLTHROUGH __attribute((fallthrough)) +#if CompilerIsClang +# define FALLTHROUGH #else -# define FALLTHROUGH +# define FALLTHROUGH __attribute((fallthrough)) #endif //- Preprocessor concatenation @@ -280,18 +261,6 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t); //////////////////////////////// //~ Type helper macros -//- typeof -#if CompilerIsMsvc -/* Typeof not supported in MSVC */ -# define TypeofIsDefined 0 -# define typeof(type) Assert(0) -#else -# define TypeofIsDefined 1 -# if LanguageIsCpp || (__STDC_VERSION__ < 202311L) -# define typeof(type) __typeof__(type) -# endif -#endif - //- alignof #if (CompilerIsMsvc && LanguageIsC) || (LanguageIsC && (__STDC_VERSION__ < 202311L)) # define alignof(type) __alignof(type) @@ -382,7 +351,7 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t); //////////////////////////////// //~ Intrinsic headers -#if !LanguageIsGpu +#if LanguageIsC /* Intrinsic header info: * window = P_AcquireWindow(); - g->swapchain = GT_AcquireSwapchain(g->window, VEC2I32(100, 100)); + g->swapchain = GPU_AcquireSwapchain(g->window, VEC2I32(100, 100)); P_ShowWindow(g->window); /* Start jobs */ @@ -389,44 +389,44 @@ void DrawDebugConsole(i32 level, b32 minimized) //- Gbuffer -GT_Resource *AcquireGbuffer(GT_Format format, Vec2I32 size) +GPU_Resource *AcquireGbuffer(GPU_Format format, Vec2I32 size) { __prof; - GT_ResourceDesc desc = ZI; - desc.kind = GT_ResourceKind_Texture2D; - desc.flags = GT_ResourceFlag_AllowSrv | GT_ResourceFlag_AllowUav | GT_ResourceFlag_AllowRtv; + GPU_ResourceDesc desc = ZI; + desc.kind = GPU_ResourceKind_Texture2D; + desc.flags = GPU_ResourceFlag_AllowSrv | GPU_ResourceFlag_AllowUav | GPU_ResourceFlag_AllowRtv; desc.texture.format = format; desc.texture.size = VEC3I32(size.x, size.y, 1); desc.texture.mip_levels = 1; - return GT_AcquireResource(desc); + return GPU_AcquireResource(desc); } //- Transfer buffer -GT_Resource *AcquireTransferBuffer(u32 element_count, u32 element_size, void *src) +GPU_Resource *AcquireTransferBuffer(u32 element_count, u32 element_size, void *src) { __prof; u64 size = element_size * element_count; - GT_ResourceDesc desc = ZI; - desc.kind = GT_ResourceKind_Buffer; - desc.flags = GT_ResourceFlag_None; - desc.buffer.heap_kind = GT_HeapKind_Upload; + GPU_ResourceDesc desc = ZI; + desc.kind = GPU_ResourceKind_Buffer; + desc.flags = GPU_ResourceFlag_None; + desc.buffer.heap_kind = GPU_HeapKind_Upload; desc.buffer.size = size; desc.buffer.element_count = element_count; desc.buffer.element_size = element_size; - GT_Resource *r = GT_AcquireResource(desc); + GPU_Resource *r = GPU_AcquireResource(desc); { __profn("Copy to transfer buffer"); - GT_PushString(0, r, STRING(size, src)); + GPU_PushString(0, r, STRING(size, src)); } return r; } -GT_Resource *AcquireTransferBufferFromArena(u32 element_count, Arena *arena) +GPU_Resource *AcquireTransferBufferFromArena(u32 element_count, Arena *arena) { __prof; u64 element_size = element_count > 0 ? arena->pos / element_count : 0; - GT_Resource *r = AcquireTransferBuffer(element_count, element_size, (void *)ArenaBase(arena)); + GPU_Resource *r = AcquireTransferBuffer(element_count, element_size, (void *)ArenaBase(arena)); return r; } @@ -1256,9 +1256,9 @@ void UpdateUser(P_Window *window) { Vec2I32 local_tile_index = VEC2I32(tile_x, tile_y); TileKind tile = ent->tile_chunk_tiles[local_tile_index.x + (local_tile_index.y * SIM_TILES_PER_CHUNK_SQRT)]; - //if (tile > -1) { /* FIXME: Enable this */ #if 0 + //if (tile > -1) if (tile == TileKind_Wall) { Vec2I32 world_tile_index = WorldTileIndexFromLocalTileIndex(chunk_index, local_tile_index); @@ -1793,7 +1793,7 @@ void UpdateUser(P_Window *window) { /* Queue player move cmd */ f32 move_speed = 1.0f; - //if (g->bind_states[BindKind_Walk].is_held) { + //if (g->bind_states[BindKind_Walk].is_held) if (g->bind_states[BindKind_FullscreenMod].is_held) { //const f32 walk_ratio = 0.25f; @@ -2008,7 +2008,7 @@ void UpdateUser(P_Window *window) //- Query vram - GT_MemoryInfo vram = GT_QueryMemoryInfo(); + GPU_MemoryInfo vram = GPU_QueryMemoryInfo(); //- Draw global debug info @@ -2149,51 +2149,51 @@ void UpdateUser(P_Window *window) Rect render_viewport = RectFromVec2(VEC2(0, 0), VEC2(g->render_size.x, g->render_size.y)); /* Acquire gbuffers */ - if (g->shade_target && !EqVec2I32(g->render_size, GT_GetTextureSize(g->shade_target))) + if (g->shade_target && !EqVec2I32(g->render_size, GPU_GetTextureSize(g->shade_target))) { __profn("Release render resources"); - GT_ReleaseResource(g->albedo, g->render_fence, GT_ReleaseFlag_None); - GT_ReleaseResource(g->emittance, g->render_fence, GT_ReleaseFlag_None); - GT_ReleaseResource(g->emittance_flood_read, g->render_fence, GT_ReleaseFlag_None); - GT_ReleaseResource(g->emittance_flood_target, g->render_fence, GT_ReleaseFlag_None); - GT_ReleaseResource(g->shade_read, g->render_fence, GT_ReleaseFlag_None); - GT_ReleaseResource(g->shade_target, g->render_fence, GT_ReleaseFlag_None); + GPU_ReleaseResource(g->albedo, g->render_fence, GPU_ReleaseFlag_None); + GPU_ReleaseResource(g->emittance, g->render_fence, GPU_ReleaseFlag_None); + GPU_ReleaseResource(g->emittance_flood_read, g->render_fence, GPU_ReleaseFlag_None); + GPU_ReleaseResource(g->emittance_flood_target, g->render_fence, GPU_ReleaseFlag_None); + GPU_ReleaseResource(g->shade_read, g->render_fence, GPU_ReleaseFlag_None); + GPU_ReleaseResource(g->shade_target, g->render_fence, GPU_ReleaseFlag_None); g->shade_target = 0; } if (!g->shade_target) { __profn("Acquire sig resources"); - g->albedo = AcquireGbuffer(GT_Format_R8G8B8A8_Unorm, g->render_size); - g->emittance = AcquireGbuffer(GT_Format_R16G16B16A16_Float, g->render_size); - g->emittance_flood_read = AcquireGbuffer(GT_Format_R16G16_Uint, g->render_size); - g->emittance_flood_target = AcquireGbuffer(GT_Format_R16G16_Uint, g->render_size); - g->shade_read = AcquireGbuffer(GT_Format_R16G16B16A16_Float, g->render_size); - g->shade_target = AcquireGbuffer(GT_Format_R16G16B16A16_Float, g->render_size); + g->albedo = AcquireGbuffer(GPU_Format_R8G8B8A8_Unorm, g->render_size); + g->emittance = AcquireGbuffer(GPU_Format_R16G16B16A16_Float, g->render_size); + g->emittance_flood_read = AcquireGbuffer(GPU_Format_R16G16_Uint, g->render_size); + g->emittance_flood_target = AcquireGbuffer(GPU_Format_R16G16_Uint, g->render_size); + g->shade_read = AcquireGbuffer(GPU_Format_R16G16B16A16_Float, g->render_size); + g->shade_target = AcquireGbuffer(GPU_Format_R16G16B16A16_Float, g->render_size); } /* Acquire ui buffers */ - if (g->ui_target && !EqVec2I32(g->ui_size, GT_GetTextureSize(g->ui_target))) + if (g->ui_target && !EqVec2I32(g->ui_size, GPU_GetTextureSize(g->ui_target))) { - GT_ReleaseResource(g->ui_target, g->render_fence, GT_ReleaseFlag_None); + GPU_ReleaseResource(g->ui_target, g->render_fence, GPU_ReleaseFlag_None); g->ui_target = 0; } if (!g->ui_target) { - g->ui_target = AcquireGbuffer(GT_Format_R8G8B8A8_Unorm, g->ui_size); + g->ui_target = AcquireGbuffer(GPU_Format_R8G8B8A8_Unorm, g->ui_size); } /* Acquire transfer buffers */ /* TODO: Make these static */ LocalPersist u16 quad_indices[6] = { 0, 1, 2, 0, 2, 3 }; - GT_Resource *quad_index_buffer = AcquireTransferBuffer(countof(quad_indices), sizeof(*quad_indices), quad_indices); - GT_Resource *material_instance_buffer = AcquireTransferBufferFromArena(g->material_instances_count, g->material_instances_arena); - GT_Resource *ui_rect_instance_buffer = AcquireTransferBufferFromArena(g->ui_rect_instances_count, g->ui_rect_instances_arena); - GT_Resource *ui_shape_verts_buffer = AcquireTransferBufferFromArena(g->ui_shape_verts_count, g->ui_shape_verts_arena); - GT_Resource *ui_shape_indices_buffer = AcquireTransferBufferFromArena(g->ui_shape_indices_count, g->ui_shape_indices_arena); - GT_Resource *grids_buffer = AcquireTransferBufferFromArena(g->grids_count, g->grids_arena); + GPU_Resource *quad_index_buffer = AcquireTransferBuffer(countof(quad_indices), sizeof(*quad_indices), quad_indices); + GPU_Resource *material_instance_buffer = AcquireTransferBufferFromArena(g->material_instances_count, g->material_instances_arena); + GPU_Resource *ui_rect_instance_buffer = AcquireTransferBufferFromArena(g->ui_rect_instances_count, g->ui_rect_instances_arena); + GPU_Resource *ui_shape_verts_buffer = AcquireTransferBufferFromArena(g->ui_shape_verts_count, g->ui_shape_verts_arena); + GPU_Resource *ui_shape_indices_buffer = AcquireTransferBufferFromArena(g->ui_shape_indices_count, g->ui_shape_indices_arena); + GPU_Resource *grids_buffer = AcquireTransferBufferFromArena(g->grids_count, g->grids_arena); - GT_CommandList *cl = GT_BeginCommandList(); - GT_ProfileDF(cl, Lit("Run render")); + GPU_CommandList *cl = GPU_BeginCommandList(); + GPU_ProfileDF(cl, Lit("Run render")); { __profn("Run render"); Mat4x4 world_to_render_vp_matrix = ProjectMat4x4View(g->world_to_render_xf, render_viewport.width, render_viewport.height); @@ -2207,32 +2207,32 @@ void UpdateUser(P_Window *window) } //- Prep material pass - GT_ProfileDF(cl, Lit("Clear gbuffers")); + GPU_ProfileDF(cl, Lit("Clear gbuffers")); { __profn("Clear gbuffers"); - GT_TransitionToRtv(cl, g->albedo); - GT_TransitionToRtv(cl, g->emittance); - GT_DispatchClear(cl, g->albedo); - GT_DispatchClear(cl, g->emittance); + GPU_TransitionToRtv(cl, g->albedo); + GPU_TransitionToRtv(cl, g->emittance); + GPU_DispatchClear(cl, g->albedo); + GPU_DispatchClear(cl, g->emittance); } //- Material pass - GT_ProfileDF(cl, Lit("Material pass")); + GPU_ProfileDF(cl, Lit("Material pass")); { __profn("Material pass"); - GT_Resource *rts[] = { + GPU_Resource *rts[] = { g->albedo, g->emittance }; - GT_Viewport viewport = GT_ViewportFromRect(render_viewport); - GT_Scissor scissor = GT_ScissorRectFromRect(render_viewport); + GPU_Viewport viewport = GPU_ViewportFromRect(render_viewport); + GPU_Scissor scissor = GPU_ScissorFromRect(render_viewport); MaterialSig sig = ZI; sig.projection = world_to_render_vp_matrix; - sig.instances_urid = GT_GetResourceId(material_instance_buffer); - sig.grids_urid = GT_GetResourceId(grids_buffer); - GT_DispatchRasterize(cl, + sig.instances_urid = GPU_GetResourceId(material_instance_buffer); + sig.grids_urid = GPU_GetResourceId(grids_buffer); + GPU_DispatchRasterize(cl, MaterialVS, MaterialPS, &sig, countof(rts), rts, @@ -2240,19 +2240,19 @@ void UpdateUser(P_Window *window) 1, &scissor, g->material_instances_count, quad_index_buffer, - GT_RasterizeMode_TriangleList); + GPU_RasterizeMode_TriangleList); } //- Prep flood pass { - GT_TransitionToSrv(cl, g->emittance); - GT_TransitionToUav(cl, g->emittance_flood_read); - GT_TransitionToUav(cl, g->emittance_flood_target); + GPU_TransitionToSrv(cl, g->emittance); + GPU_TransitionToUav(cl, g->emittance_flood_read); + GPU_TransitionToUav(cl, g->emittance_flood_target); } //- Flood pass if (!effects_disabled) - GT_ProfileDF(cl, Lit("Flood pass")); + GPU_ProfileDF(cl, Lit("Flood pass")); { __profn("Flood pass"); @@ -2262,23 +2262,23 @@ void UpdateUser(P_Window *window) u64 max_steps = GetGstat(GSTAT_DEBUG_STEPS); u64 step = 0; while (step_length != 0 && step < max_steps) - GT_ProfileDF(cl, Lit("Flood step")); + GPU_ProfileDF(cl, Lit("Flood step")); { __profn("Flood step"); - GT_Flush(cl, g->emittance_flood_read); + GPU_Flush(cl, g->emittance_flood_read); FloodSig sig = ZI; sig.step_len = step_length; - sig.emittance_tex_urid = GT_GetResourceId(g->emittance); - sig.read_flood_tex_urid = GT_GetResourceId(g->emittance_flood_read); - sig.target_flood_tex_urid = GT_GetResourceId(g->emittance_flood_target); + sig.emittance_tex_urid = GPU_GetResourceId(g->emittance); + sig.read_flood_tex_urid = GPU_GetResourceId(g->emittance_flood_read); + sig.target_flood_tex_urid = GPU_GetResourceId(g->emittance_flood_target); sig.tex_width = g->render_size.x; sig.tex_height = g->render_size.y; - GT_DispatchCompute(cl, FloodCS, &sig, (g->render_size.x + 7) / 8, (g->render_size.y + 7) / 8, 1); + GPU_DispatchCompute(cl, FloodCS, &sig, (g->render_size.x + 7) / 8, (g->render_size.y + 7) / 8, 1); /* Swap buffers */ - GT_Resource *swp = g->emittance_flood_read; + GPU_Resource *swp = g->emittance_flood_read; g->emittance_flood_read = g->emittance_flood_target; g->emittance_flood_target = swp; @@ -2296,19 +2296,19 @@ void UpdateUser(P_Window *window) } //- Prep shade pass - GT_ProfileDF(cl, Lit("Clear shade target")); + GPU_ProfileDF(cl, Lit("Clear shade target")); { __profn("Clear shade target"); - GT_TransitionToSrv(cl, g->albedo); - GT_TransitionToSrv(cl, g->emittance); - GT_TransitionToUav(cl, g->shade_target); - GT_Flush(cl, g->emittance_flood_read); - GT_Flush(cl, g->shade_read); - GT_DispatchClear(cl, g->shade_target); + GPU_TransitionToSrv(cl, g->albedo); + GPU_TransitionToSrv(cl, g->emittance); + GPU_TransitionToUav(cl, g->shade_target); + GPU_Flush(cl, g->emittance_flood_read); + GPU_Flush(cl, g->shade_read); + GPU_DispatchClear(cl, g->shade_target); } //- Shade pass - GT_ProfileDF(cl, Lit("Shade pass")); + GPU_ProfileDF(cl, Lit("Shade pass")); { __profn("Shade pass"); @@ -2327,43 +2327,43 @@ void UpdateUser(P_Window *window) (u32)(RandU64FromState(&g->frame_rand) & 0xFFFFFFFF)); sig.frame_index = g->frame_index; sig.camera_offset = g->world_to_render_xf.og; - sig.albedo_tex_urid = GT_GetResourceId(g->albedo); - sig.emittance_tex_urid = GT_GetResourceId(g->emittance); - sig.emittance_flood_tex_urid = GT_GetResourceId(g->emittance_flood_read); - sig.read_tex_urid = GT_GetResourceId(g->shade_read); - sig.target_tex_urid = GT_GetResourceId(g->shade_target); - GT_DispatchCompute(cl, ShadeCS, &sig, (g->render_size.x + 7) / 8, (g->render_size.y + 7) / 8, 1); + sig.albedo_tex_urid = GPU_GetResourceId(g->albedo); + sig.emittance_tex_urid = GPU_GetResourceId(g->emittance); + sig.emittance_flood_tex_urid = GPU_GetResourceId(g->emittance_flood_read); + sig.read_tex_urid = GPU_GetResourceId(g->shade_read); + sig.target_tex_urid = GPU_GetResourceId(g->shade_target); + GPU_DispatchCompute(cl, ShadeCS, &sig, (g->render_size.x + 7) / 8, (g->render_size.y + 7) / 8, 1); /* Swap */ - GT_Resource *swp = g->shade_read; + GPU_Resource *swp = g->shade_read; g->shade_read = g->shade_target; g->shade_target = swp; } //- Prep ui pass - GT_ProfileDF(cl, Lit("Clear ui target")); + GPU_ProfileDF(cl, Lit("Clear ui target")); { __profn("Clear ui target"); - GT_TransitionToRtv(cl, g->ui_target); - GT_Flush(cl, g->shade_read); - GT_DispatchClear(cl, g->ui_target); + GPU_TransitionToRtv(cl, g->ui_target); + GPU_Flush(cl, g->shade_read); + GPU_DispatchClear(cl, g->ui_target); } //- Ui blit pass - GT_ProfileDF(cl, Lit("UI blit pass")); + GPU_ProfileDF(cl, Lit("UI blit pass")); { __profn("UI blit pass"); - GT_Viewport viewport = GT_ViewportFromRect(ui_viewport); - GT_Scissor scissor = GT_ScissorRectFromRect(ui_viewport); + GPU_Viewport viewport = GPU_ViewportFromRect(ui_viewport); + GPU_Scissor scissor = GPU_ScissorFromRect(ui_viewport); UiBlitSig sig = ZI; sig.projection = blit_vp_matrix; sig.flags = UiBlitFlag_ToneMap | UiBlitFlag_GammaCorrect; sig.exposure = 2.0; sig.gamma = (f32)2.2; - sig.tex_urid = GT_GetResourceId(g->shade_read); - GT_DispatchRasterize(cl, + sig.tex_urid = GPU_GetResourceId(g->shade_read); + GPU_DispatchRasterize(cl, UiBlitVS, UiBlitPS, &sig, 1, &g->ui_target, @@ -2371,21 +2371,21 @@ void UpdateUser(P_Window *window) 1, &scissor, 1, quad_index_buffer, - GT_RasterizeMode_TriangleList); + GPU_RasterizeMode_TriangleList); } //- Ui rect pass - GT_ProfileDF(cl, Lit("UI rect pass")); + GPU_ProfileDF(cl, Lit("UI rect pass")); { __profn("UI rect pass"); - GT_Viewport viewport = GT_ViewportFromRect(ui_viewport); - GT_Scissor scissor = GT_ScissorRectFromRect(ui_viewport); + GPU_Viewport viewport = GPU_ViewportFromRect(ui_viewport); + GPU_Scissor scissor = GPU_ScissorFromRect(ui_viewport); UiRectSig sig = ZI; sig.projection = ui_vp_matrix; - sig.instances_urid = GT_GetResourceId(ui_rect_instance_buffer); - GT_DispatchRasterize(cl, + sig.instances_urid = GPU_GetResourceId(ui_rect_instance_buffer); + GPU_DispatchRasterize(cl, UiRectVS, UiRectPS, &sig, 1, &g->ui_target, @@ -2393,21 +2393,21 @@ void UpdateUser(P_Window *window) 1, &scissor, g->ui_rect_instances_count, quad_index_buffer, - GT_RasterizeMode_TriangleList); + GPU_RasterizeMode_TriangleList); } //- Ui shape pass - GT_ProfileDF(cl, Lit("UI shape pass")); + GPU_ProfileDF(cl, Lit("UI shape pass")); { __profn("UI shape pass"); - GT_Viewport viewport = GT_ViewportFromRect(ui_viewport); - GT_Scissor scissor = GT_ScissorRectFromRect(ui_viewport); + GPU_Viewport viewport = GPU_ViewportFromRect(ui_viewport); + GPU_Scissor scissor = GPU_ScissorFromRect(ui_viewport); UiShapeSig sig = ZI; sig.projection = ui_vp_matrix; - sig.verts_urid = GT_GetResourceId(ui_shape_verts_buffer); - GT_DispatchRasterize(cl, + sig.verts_urid = GPU_GetResourceId(ui_shape_verts_buffer); + GPU_DispatchRasterize(cl, UiShapeVS, UiShapePS, &sig, 1, &g->ui_target, @@ -2415,19 +2415,19 @@ void UpdateUser(P_Window *window) 1, &scissor, 1, ui_shape_indices_buffer, - GT_RasterizeMode_TriangleList); + GPU_RasterizeMode_TriangleList); } } - g->render_fence = GT_EndCommandList(cl); + g->render_fence = GPU_EndCommandList(cl); /* Release transfer buffers */ { - GT_ReleaseResource(quad_index_buffer, g->render_fence, GT_ReleaseFlag_Reuse); - GT_ReleaseResource(material_instance_buffer, g->render_fence, GT_ReleaseFlag_Reuse); - GT_ReleaseResource(ui_rect_instance_buffer, g->render_fence, GT_ReleaseFlag_Reuse); - GT_ReleaseResource(ui_shape_verts_buffer, g->render_fence, GT_ReleaseFlag_Reuse); - GT_ReleaseResource(ui_shape_indices_buffer, g->render_fence, GT_ReleaseFlag_Reuse); - GT_ReleaseResource(grids_buffer, g->render_fence, GT_ReleaseFlag_Reuse); + GPU_ReleaseResource(quad_index_buffer, g->render_fence, GPU_ReleaseFlag_Reuse); + GPU_ReleaseResource(material_instance_buffer, g->render_fence, GPU_ReleaseFlag_Reuse); + GPU_ReleaseResource(ui_rect_instance_buffer, g->render_fence, GPU_ReleaseFlag_Reuse); + GPU_ReleaseResource(ui_shape_verts_buffer, g->render_fence, GPU_ReleaseFlag_Reuse); + GPU_ReleaseResource(ui_shape_indices_buffer, g->render_fence, GPU_ReleaseFlag_Reuse); + GPU_ReleaseResource(grids_buffer, g->render_fence, GPU_ReleaseFlag_Reuse); ResetArena(g->material_instances_arena); ResetArena(g->ui_rect_instances_arena); ResetArena(g->ui_shape_verts_arena); @@ -2462,7 +2462,7 @@ JobDef(UpdateUserJob, UNUSED sig, UNUSED id) __profn("User sleep"); { __profn("Swapchain wait"); - GT_WaitOnSwapchain(g->swapchain); + GPU_WaitOnSwapchain(g->swapchain); } { __profn("Frame limiter wait"); diff --git a/src/pp/pp_core.h b/src/pp/pp_core.h index 8c25a681..7e413c94 100644 --- a/src/pp/pp_core.h +++ b/src/pp/pp_core.h @@ -155,7 +155,7 @@ Struct(SharedUserState) Atomic32 shutdown; Counter shutdown_job_counters; P_Window *window; - GT_Swapchain *swapchain; + GPU_Swapchain *swapchain; Arena *arena; String connect_address_str; @@ -171,13 +171,13 @@ Struct(SharedUserState) SecondsStat net_bytes_sent; //- Gpu resources - GT_Resource *albedo; - GT_Resource *emittance; - GT_Resource *emittance_flood_read; - GT_Resource *emittance_flood_target; - GT_Resource *shade_read; - GT_Resource *shade_target; - GT_Resource *ui_target; + GPU_Resource *albedo; + GPU_Resource *emittance; + GPU_Resource *emittance_flood_read; + GPU_Resource *emittance_flood_target; + GPU_Resource *shade_read; + GPU_Resource *shade_target; + GPU_Resource *ui_target; RandState frame_rand; u64 frame_index; @@ -193,7 +193,7 @@ Struct(SharedUserState) u32 ui_shape_indices_count; u32 grids_count; - GT_Fence render_fence; + GPU_Fence render_fence; //- Bind state BindState bind_states[BindKind_Count]; @@ -296,9 +296,9 @@ void DrawDebugConsole(i32 level, b32 minimized); //////////////////////////////// //~ Gpu buffer helpers -GT_Resource *AcquireGbuffer(GT_Format format, Vec2I32 size); -GT_Resource *AcquireTransferBuffer(u32 element_count, u32 element_size, void *src); -GT_Resource *AcquireTransferBufferFromArena(u32 element_count, Arena *arena); +GPU_Resource *AcquireGbuffer(GPU_Format format, Vec2I32 size); +GPU_Resource *AcquireTransferBuffer(u32 element_count, u32 element_size, void *src); +GPU_Resource *AcquireTransferBufferFromArena(u32 element_count, Arena *arena); //////////////////////////////// //~ Entity sorting diff --git a/src/pp/pp_draw.gpu b/src/pp/pp_draw.gpu index 988425c0..1c14339a 100644 --- a/src/pp/pp_draw.gpu +++ b/src/pp/pp_draw.gpu @@ -308,7 +308,7 @@ Vec3 tone_map(Vec3 v) //- Vertex shader -UiBlitPS_Input GT_VertexShaderDef(UiBlitVS)(Semantic(u32, SV_VertexID)) +UiBlitPS_Input GPUVertexShaderDef(UiBlitVS)(Semantic(u32, SV_VertexID)) { static const Vec2 unit_quad_verts[4] = { Vec2(-0.5f, -0.5f), @@ -327,7 +327,7 @@ UiBlitPS_Input GT_VertexShaderDef(UiBlitVS)(Semantic(u32, SV_VertexID)) //- Pixel shader -UiBlitPS_Output GT_PixelShaderDef(UiBlitPS)(UiBlitPS_Input input) +UiBlitPS_Output GPUPixelShaderDef(UiBlitPS)(UiBlitPS_Input input) { UiBlitPS_Output output; Texture2D tex = GpuResourceFromUrid(sig.tex_urid); @@ -369,7 +369,7 @@ Struct(UiRectPS_Output) //- Vertex shader -UiRectPS_Input GT_VertexShaderDef(UiRectVS)(Semantic(u32, SV_InstanceID), Semantic(u32, SV_VertexID)) +UiRectPS_Input GPUVertexShaderDef(UiRectVS)(Semantic(u32, SV_InstanceID), Semantic(u32, SV_VertexID)) { static const Vec2 unit_quad_verts[4] = { Vec2(-0.5f, -0.5f), @@ -393,7 +393,7 @@ UiRectPS_Input GT_VertexShaderDef(UiRectVS)(Semantic(u32, SV_InstanceID), Semant //- Pixel shader -UiRectPS_Output GT_PixelShaderDef(UiRectPS)(PSInput input) +UiRectPS_Output GPUPixelShaderDef(UiRectPS)(PSInput input) { UiRectPS_Output output; Vec4 color = input.tint_srgb; @@ -425,7 +425,7 @@ Struct(UiShapePS_Output) //- Vertex shader -UiShapePS_Input GT_VertexShaderDef(UiShapeVS)(Semantic(u32, SV_VertexID)) +UiShapePS_Input GPUVertexShaderDef(UiShapeVS)(Semantic(u32, SV_VertexID)) { StructuredBuffer verts = GpuResourceFromUrid(sig.verts_urid); UiShapeVert vert = verts[SV_VertexID]; @@ -437,7 +437,7 @@ UiShapePS_Input GT_VertexShaderDef(UiShapeVS)(Semantic(u32, SV_VertexID)) //- Pixel shader -UiShapePS_Output GT_PixelShaderDef(UiShapePS)(PSInput input) +UiShapePS_Output GPUPixelShaderDef(UiShapePS)(PSInput input) { UiShapePS_Output output; output.SV_Target = input.color_srgb; diff --git a/src/pp/pp_draw.h b/src/pp/pp_draw.h index d7671229..a11cc60e 100644 --- a/src/pp/pp_draw.h +++ b/src/pp/pp_draw.h @@ -158,23 +158,23 @@ Struct(UiShapeVert) //~ Shaders //- Material -GT_ShaderDecl(MaterialVS); -GT_ShaderDecl(MaterialPS); +GPU_ShaderDecl(MaterialVS); +GPU_ShaderDecl(MaterialPS); //- Flood -GT_ShaderDecl(FloodCS); +GPU_ShaderDecl(FloodCS); //- Shade -GT_ShaderDecl(ShadeCS); +GPU_ShaderDecl(ShadeCS); //- Ui blit -GT_ShaderDecl(UiBlitVS); -GT_ShaderDecl(UiBlitPS); +GPU_ShaderDecl(UiBlitVS); +GPU_ShaderDecl(UiBlitPS); //- Ui rect -GT_ShaderDecl(UiRectVS); -GT_ShaderDecl(UiRectPS); +GPU_ShaderDecl(UiRectVS); +GPU_ShaderDecl(UiRectPS); //- Ui shape -GT_ShaderDecl(UiShapeVS); -GT_ShaderDecl(UiShapePS); +GPU_ShaderDecl(UiShapeVS); +GPU_ShaderDecl(UiShapePS); diff --git a/src/prof/prof.lay b/src/prof/prof.lay deleted file mode 100644 index 22a5d8cc..00000000 --- a/src/prof/prof.lay +++ /dev/null @@ -1,6 +0,0 @@ -@Lay prof - -//////////////////////////////// -//~ Api - -@CpuApi prof_tracy diff --git a/src/rendertest/rendertest.lay b/src/rendertest/rendertest.lay index de855edc..7e0ce1a3 100644 --- a/src/rendertest/rendertest.lay +++ b/src/rendertest/rendertest.lay @@ -12,7 +12,7 @@ //////////////////////////////// //~ Api -@CpuApi rendertest_core +@ApiC rendertest_core //////////////////////////////// //~ Init diff --git a/src/resource/resource.lay b/src/resource/resource.lay index 824ccbca..bea551ba 100644 --- a/src/resource/resource.lay +++ b/src/resource/resource.lay @@ -11,7 +11,7 @@ //////////////////////////////// //~ Api -@CpuApi resource_core +@ApiC resource_core //////////////////////////////// //~ Init diff --git a/src/settings/settings.lay b/src/settings/settings.lay index af082770..8e77fbad 100644 --- a/src/settings/settings.lay +++ b/src/settings/settings.lay @@ -10,4 +10,4 @@ //////////////////////////////// //~ Api -@CpuApi settings_core +@ApiC settings_core diff --git a/src/sound/sound.lay b/src/sound/sound.lay index b09ca398..2b639c18 100644 --- a/src/sound/sound.lay +++ b/src/sound/sound.lay @@ -12,4 +12,4 @@ //////////////////////////////// //~ Api -@CpuApi sound_core +@ApiC sound_core diff --git a/src/sprite/sprite.lay b/src/sprite/sprite.lay index 87f6d91e..aa08c005 100644 --- a/src/sprite/sprite.lay +++ b/src/sprite/sprite.lay @@ -5,7 +5,7 @@ @Dep base @Dep platform -@Dep gtest +@Dep gpu @Dep ase @Dep resource @Dep watch @@ -13,7 +13,7 @@ //////////////////////////////// //~ Api -@CpuApi sprite_core +@ApiC sprite_core //////////////////////////////// //~ Init diff --git a/src/sprite/sprite_core.c b/src/sprite/sprite_core.c index b637a377..1fc2bae5 100644 --- a/src/sprite/sprite_core.c +++ b/src/sprite/sprite_core.c @@ -17,13 +17,13 @@ void S_StartupCore(void) g->nil_texture->loaded = 1; { TempArena scratch = BeginScratchNoConflict(); - GT_ResourceDesc desc = ZI; - desc.kind = GT_ResourceKind_Texture2D; - desc.texture.format = GT_Format_R8G8B8A8_Unorm; + GPU_ResourceDesc desc = ZI; + desc.kind = GPU_ResourceKind_Texture2D; + desc.texture.format = GPU_Format_R8G8B8A8_Unorm; desc.texture.size = VEC3I32(64, 64, 1); - g->nil_texture->gpu_resource = GT_AcquireResource(desc); + g->nil_texture->gpu_resource = GPU_AcquireResource(desc); u32 *pixels = S_GeneratePurpleBlackImage(scratch.arena, desc.texture.size.x, desc.texture.size.y); - GT_PushString(0, g->nil_texture->gpu_resource, STRING(desc.texture.size.x * desc.texture.size.y * 4, (u8 *)pixels)); + GPU_PushString(0, g->nil_texture->gpu_resource, STRING(desc.texture.size.x * desc.texture.size.y * 4, (u8 *)pixels)); EndScratch(scratch); } @@ -494,19 +494,19 @@ void S_LoadCacheEntryTexture(S_CacheEntryRef ref, S_Tag tag) if (decoded.success) { /* Initialize */ - GT_ResourceDesc gpu_desc = ZI; - gpu_desc.kind = GT_ResourceKind_Texture2D; + GPU_ResourceDesc gpu_desc = ZI; + gpu_desc.kind = GPU_ResourceKind_Texture2D; gpu_desc.texture.size = VEC3I32(decoded.width, decoded.height, 1); - gpu_desc.texture.format = GT_Format_R8G8B8A8_Unorm_Srgb; + gpu_desc.texture.format = GPU_Format_R8G8B8A8_Unorm_Srgb; e->texture = PushStruct(e->arena, S_Texture); e->texture->width = decoded.width; e->texture->height = decoded.height; e->texture->valid = 1; e->texture->loaded = 1; - e->texture->gpu_resource = GT_AcquireResource(gpu_desc); + e->texture->gpu_resource = GPU_AcquireResource(gpu_desc); { u64 size = decoded.width * decoded.height * 4; - GT_PushString(0, e->texture->gpu_resource, STRING(size, (u8 *)decoded.pixels)); + GPU_PushString(0, e->texture->gpu_resource, STRING(size, (u8 *)decoded.pixels)); } /* TODO: Query gpu for more accurate texture size in VRAM */ memory_size += (decoded.width * decoded.height) * sizeof(*decoded.pixels); @@ -1294,13 +1294,13 @@ JobDef(S_EvictorJob, UNUSED sig, UNUSED job_id) /* Release evicted node memory */ { __profn("Evictor memory release"); - GT_Fence gpu_fence = GT_GetGlobalFence(); + GPU_Fence gpu_fence = GPU_GetGlobalFence(); for (S_EvictorNode *en = first_evicted; en; en = en->next_evicted) { S_CacheEntry *n = en->cache_entry; if (n->kind == S_CacheEntryKind_Texture && n->texture->valid) { - GT_ReleaseResource(n->texture->gpu_resource, gpu_fence, GT_ReleaseFlag_None); + GPU_ReleaseResource(n->texture->gpu_resource, gpu_fence, GPU_ReleaseFlag_None); } ReleaseArena(n->arena); } diff --git a/src/sprite/sprite_core.h b/src/sprite/sprite_core.h index 980fc767..04badcd1 100644 --- a/src/sprite/sprite_core.h +++ b/src/sprite/sprite_core.h @@ -14,7 +14,7 @@ Struct(S_Texture) { b32 loaded; b32 valid; - GT_Resource *gpu_resource; + GPU_Resource *gpu_resource; u32 width; u32 height; }; diff --git a/src/tar/tar.lay b/src/tar/tar.lay index 5635b713..5870fc57 100644 --- a/src/tar/tar.lay +++ b/src/tar/tar.lay @@ -10,4 +10,4 @@ //////////////////////////////// //~ Api -@CpuApi tar_core +@ApiC tar_core diff --git a/src/ttf/dwrite/ttf_dwrite.cpp b/src/ttf/dwrite/ttf_dwrite.c similarity index 100% rename from src/ttf/dwrite/ttf_dwrite.cpp rename to src/ttf/dwrite/ttf_dwrite.c diff --git a/src/ttf/ttf.lay b/src/ttf/ttf.lay index c6fd4e76..d79d49dd 100644 --- a/src/ttf/ttf.lay +++ b/src/ttf/ttf.lay @@ -2,7 +2,7 @@ //~ Dependencies AddDep("../base/base.h"); -AddDep("../gtest/gtest.h"); +AddDep("../gpu/gpu.h"); AddDep("../sprite/sprite.h"); AddDep("../font/font.h"); AddDep("../collider/collider.h"); diff --git a/src/watch/watch.lay b/src/watch/watch.lay index 18a7fab4..b3ca3626 100644 --- a/src/watch/watch.lay +++ b/src/watch/watch.lay @@ -9,7 +9,7 @@ //////////////////////////////// //~ Api -@CpuApi watch_core +@ApiC watch_core //////////////////////////////// //~ Init