gpu layer refactor progress

This commit is contained in:
jacob 2025-11-19 16:32:42 -06:00
parent b10866bed7
commit b4a51ff5af
14 changed files with 193 additions and 334 deletions

View File

@ -13,15 +13,13 @@ Enum(GPU_QueueKind)
{ {
#if GPU_MultiQueueEnabled #if GPU_MultiQueueEnabled
GPU_QueueKind_Direct = 0, GPU_QueueKind_Direct = 0,
GPU_QueueKind_Compute = 1, GPU_QueueKind_AsyncCompute = 1,
GPU_QueueKind_Copy = 2, GPU_QueueKind_AsyncCopy = 2,
GPU_QueueKind_BackgroundCopy = 3, GPU_NumQueues = 3
GPU_NumQueues = 4
#else #else
GPU_QueueKind_Direct = 0, GPU_QueueKind_Direct = 0,
GPU_QueueKind_Compute = 0, GPU_QueueKind_AsyncCompute = 0,
GPU_QueueKind_Copy = 0, GPU_QueueKind_AsyncCopy = 0,
GPU_QueueKind_BackgroundCopy = 0,
GPU_NumQueues = 1 GPU_NumQueues = 1
#endif #endif
}; };

View File

@ -1,94 +1,200 @@
GPU_D12_SharedState GPU_D12_shared_state = ZI; GPU_D12_SharedState GPU_D12_shared_state = ZI;
////////////////////////////////////////////////////////////
//~ Helpers
GPU_D12_FiberState *GPU_D12_FiberStateFromId(i16 fiber_id)
{
GPU_D12_SharedState *g = &GPU_D12_shared_state;
GPU_D12_FiberState **f = &g->fiber_states[fiber_id];
if (!*f)
{
Arena *perm = PermArena();
*f = PushStruct(perm, GPU_D12_FiberState);
}
return *f;
}
DXGI_FORMAT GPU_D12_DxgiFormatFromGpuFormat(GPU_Format format)
{
return (DXGI_FORMAT)format;
}
GPU_D12_Command *GPU_D12_PushCmd(GPU_D12_CommandList *cl)
{
GPU_D12_FiberState *f = GPU_D12_FiberStateFromId(FiberId());
Arena *perm = PermArena();
GPU_D12_Command *cmd = f->first_free_command;
if (cmd)
{
f->first_free_command = cmd->next;
}
else
{
cmd = PushStructNoZero(perm, GPU_D12_Command);
}
ZeroStruct(cmd);
SllQueuePush(cl->first, cl->last, cmd);
++cl->count;
return cmd;
}
u64 GPU_D12_ReuseHashFromResourceDesc(GPU_ResourceDesc desc, u64 buffer_size)
{
u64 result = RandU64FromSeeds(desc.kind, desc.flags);
switch(desc.kind)
{
default: break;
case GPU_ResourceKind_Texture1D:
case GPU_ResourceKind_Texture2D:
case GPU_ResourceKind_Texture3D:
{
result = RandU64FromSeeds(result, desc.texture.format);
result = RandU64FromSeeds(result, desc.texture.mip_levels);
result = RandU64FromSeeds(result, desc.clear_color.x);
result = RandU64FromSeeds(result, desc.clear_color.y);
result = RandU64FromSeeds(result, desc.clear_color.z);
result = RandU64FromSeeds(result, desc.clear_color.w);
result = RandU64FromSeeds(result, desc.texture.size.x);
result = RandU64FromSeeds(result, desc.texture.size.y);
result = RandU64FromSeeds(result, desc.texture.size.z);
} break;
case GPU_ResourceKind_Buffer:
{
result = RandU64FromSeeds(result, desc.buffer.heap_kind);
result = RandU64FromSeeds(result, buffer_size);
} break;
}
return result;
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Startup //~ Startup
void GPU_D12_Startup(void) void GPU_D12_Startup(void)
{ {
GPU_D12_SharedState *g = &GPU_D12_shared_state; GPU_D12_SharedState *g = &GPU_D12_shared_state;
TempArena scratch = BeginScratchNoConflict();
Arena *perm = PermArena();
/* Init device */ //////////////////////////////
GPU_D12_InitDevice(); //- Initialize device
/* Init queues */
{ {
GPU_D12_QueueDesc descs[] = { HRESULT hr = 0;
{.kind = GPU_QueueKind_Direct, .d3d_type = D3D12_COMMAND_LIST_TYPE_DIRECT, .d3d_priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, .dbg_name = Lit("Direct queue") },
{.kind = GPU_QueueKind_Compute, .d3d_type = D3D12_COMMAND_LIST_TYPE_COMPUTE, .d3d_priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, .dbg_name = Lit("Compute queue") }, //- Enable debug layer
{.kind = GPU_QueueKind_Copy, .d3d_type = D3D12_COMMAND_LIST_TYPE_COPY, .d3d_priority = D3D12_COMMAND_QUEUE_PRIORITY_HIGH, .dbg_name = Lit("Copy queue") }, u32 dxgi_factory_flags = 0;
{.kind = GPU_QueueKind_BackgroundCopy, .d3d_type = D3D12_COMMAND_LIST_TYPE_COPY, .d3d_priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, .dbg_name = Lit("Background copy queue") } #if GPU_DEBUG
}; {
u32 job_count = 0; Fence job_fence = ZI; __profn("Enable debug layer");
job_count += RunJob(GPU_D12_InitQueue, .count = GPU_NumQueues, .sig.descs = descs, .fence = &job_fence); ID3D12Debug *debug_controller0 = 0;
YieldOnFence(&job_fence, job_count); {
hr = D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug_controller0);
if (FAILED(hr))
{
Panic(Lit("Failed to create ID3D12Debug0"));
}
ID3D12Debug_EnableDebugLayer(debug_controller0);
#if GPU_DEBUG_VALIDATION
{
ID3D12Debug1 *debug_controller1 = 0;
{
hr = ID3D12Debug_QueryInterface(debug_controller0, &IID_ID3D12Debug1, (void **)&debug_controller1);
if (FAILED(hr))
{
Panic(Lit("Failed to create ID3D12Debug1"));
}
ID3D12Debug1_SetEnableGPUBasedValidation(debug_controller1, 1);
}
ID3D12Debug_Release(debug_controller1);
}
#endif
}
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))
{
Panic(Lit("Failed to initialize DXGI factory"));
}
}
//- Create device
{
__profn("Create device");
IDXGIAdapter3 *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 iGPU testing */
for (;;)
{
{
hr = IDXGIFactory6_EnumAdapterByGpuPreference(g->factory, adapter_index, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, &IID_IDXGIAdapter3, (void **)&adapter);
}
if (SUCCEEDED(hr))
{
DXGI_ADAPTER_DESC1 desc;
IDXGIAdapter3_GetDesc1(adapter, &desc);
if (first_gpu_name.len == 0)
{
first_gpu_name = StringFromWstrNoLimit(scratch.arena, desc.Description);
}
{
/* TODO: Verify feature support:
* - HighestShaderModel >= D3D_SHADER_MODEL_6_6
* - ResourceBindingTier >= D3D12_RESOURCE_BINDING_TIER_3
* - EnhancedBarriersSupported == 1
*/
hr = D3D12CreateDevice((IUnknown *)adapter, D3D_FEATURE_LEVEL_12_0, &IID_ID3D12Device, (void **)&device);
}
if (SUCCEEDED(hr) && !skip)
{
break;
}
skip = 0;
ID3D12Device_Release(device);
IDXGIAdapter3_Release(adapter);
adapter = 0;
device = 0;
++adapter_index;
}
else
{
break;
}
}
if (!device)
{
if (first_gpu_name.len > 0)
{
error = StringF(scratch.arena,
"Could not initialize device '%F' with D3D_FEATURE_LEVEL_12_0. Ensure that the device is capable and drivers are up to date.",
FmtString(first_gpu_name));
}
Panic(error);
}
g->adapter = adapter;
g->device = device;
}
//- Enable debug layer breaks
{
#if GPU_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))
{
Panic(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))
{
Panic(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
}
}
//////////////////////////////
//- Initialize queues
{
GPU_D12_Queue *direct = PushStruct(perm, GPU_D12_Queue);
GPU_D12_Queue *async_compute = PushStruct(perm, GPU_D12_Queue);
GPU_D12_Queue *async_copy = PushStruct(perm, GPU_D12_Queue);
g->queues[GPU_QueueKind_Direct] = direct;
g->queues[GPU_QueueKind_AsyncCompute] = async_compute;
g->queues[GPU_QueueKind_AsyncCopy] = async_copy;
b32 ok = 1;
{
if (ok)
{
D3D12_COMMAND_QUEUE_DESC desc = { .Type = D3D12_COMMAND_LIST_TYPE_DIRECT, .Priority = D3D12_COMMAND_QUEUE_PRIORITY_HIGH };
ok = SUCCEEDED(ID3D12Device_CreateCommandQueue(g->device, &desc, &IID_ID3D12CommandQueue, (void **)&direct->d3d_queue));
if (ok)
{
ok = SUCCEEDED(ID3D12Device_CreateFence(g->device, 0, 0, &IID_ID3D12Fence, (void **)&direct->submit_fence));
}
}
if (ok)
{
D3D12_COMMAND_QUEUE_DESC desc = { .Type = D3D12_COMMAND_LIST_TYPE_COMPUTE, .Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL };
ok = SUCCEEDED(ID3D12Device_CreateCommandQueue(g->device, &desc, &IID_ID3D12CommandQueue, (void **)&async_compute->d3d_queue));
if (ok)
{
ok = SUCCEEDED(ID3D12Device_CreateFence(g->device, 0, 0, &IID_ID3D12Fence, (void **)&async_compute->submit_fence));
}
}
if (ok)
{
D3D12_COMMAND_QUEUE_DESC desc = { .Type = D3D12_COMMAND_LIST_TYPE_COPY, .Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL };
ok = SUCCEEDED(ID3D12Device_CreateCommandQueue(g->device, &desc, &IID_ID3D12CommandQueue, (void **)&async_copy->d3d_queue));
if (ok)
{
ok = SUCCEEDED(ID3D12Device_CreateFence(g->device, 0, 0, &IID_ID3D12Fence, (void **)&async_copy->submit_fence));
}
}
}
if (!ok)
{
Panic(Lit("Failed to create GPU Command Queues"));
}
} }
/* Init descriptor heaps */ /* Init descriptor heaps */
@ -113,192 +219,12 @@ void GPU_D12_Startup(void)
/* Start queue sync job */ /* Start queue sync job */
JobPoolId sync_pool = InitJobPool(1, Lit("Dx12 queue sync"), JobPoolPriority_Critical); JobPoolId sync_pool = InitJobPool(1, Lit("Dx12 queue sync"), JobPoolPriority_Critical);
RunJob(GPU_D12_StartQueueSync, .pool = sync_pool); RunJob(GPU_D12_StartQueueSync, .pool = sync_pool);
}
////////////////////////////////////////////////////////////
//~ Initialization
//- Device initialization
void GPU_D12_InitDevice(void)
{
GPU_D12_SharedState *g = &GPU_D12_shared_state;
TempArena scratch = BeginScratchNoConflict();
HRESULT hr = 0;
/* Enable debug layer */
u32 dxgi_factory_flags = 0;
#if GPU_DEBUG
{
__profn("Enable debug layer");
ID3D12Debug *debug_controller0 = 0;
{
hr = D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug_controller0);
if (FAILED(hr))
{
Panic(Lit("Failed to create ID3D12Debug0"));
}
ID3D12Debug_EnableDebugLayer(debug_controller0);
#if GPU_DEBUG_VALIDATION
{
ID3D12Debug1 *debug_controller1 = 0;
{
hr = ID3D12Debug_QueryInterface(debug_controller0, &IID_ID3D12Debug1, (void **)&debug_controller1);
if (FAILED(hr))
{
Panic(Lit("Failed to create ID3D12Debug1"));
}
ID3D12Debug1_SetEnableGPUBasedValidation(debug_controller1, 1);
}
ID3D12Debug_Release(debug_controller1);
}
#endif
}
ID3D12Debug_Release(debug_controller0);
dxgi_factory_flags |= DXGI_CREATE_FACTORY_DEBUG;
}
#endif
#if GPU_DEBUG == 0 && GPU_DEBUG_VALIDATION != 0
# error Gpu validation is enabled but gpu debugging is not
#endif
/* Create factory */
{
__profn("Create factory");
hr = CreateDXGIFactory2(dxgi_factory_flags, &IID_IDXGIFactory6, (void **)&g->factory);
if (FAILED(hr))
{
Panic(Lit("Failed to initialize DXGI factory"));
}
}
/* Create device */
{
__profn("Create device");
IDXGIAdapter3 *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_IDXGIAdapter3, (void **)&adapter);
}
if (SUCCEEDED(hr))
{
DXGI_ADAPTER_DESC1 desc;
IDXGIAdapter3_GetDesc1(adapter, &desc);
if (first_gpu_name.len == 0)
{
first_gpu_name = StringFromWstrNoLimit(scratch.arena, desc.Description);
}
{
/* TODO: Verify feature support:
* - HighestShaderModel >= D3D_SHADER_MODEL_6_6
* - ResourceBindingTier >= D3D12_RESOURCE_BINDING_TIER_3
* - EnhancedBarriersSupported == 1
*/
hr = D3D12CreateDevice((IUnknown *)adapter, D3D_FEATURE_LEVEL_12_0, &IID_ID3D12Device, (void **)&device);
}
if (SUCCEEDED(hr) && !skip)
{
break;
}
skip = 0;
ID3D12Device_Release(device);
IDXGIAdapter3_Release(adapter);
adapter = 0;
device = 0;
++adapter_index;
}
else
{
break;
}
}
if (!device)
{
if (first_gpu_name.len > 0)
{
error = StringF(scratch.arena,
"Could not initialize device '%F' with D3D_FEATURE_LEVEL_12_0. Ensure that the device is capable and drivers are up to date.",
FmtString(first_gpu_name));
}
Panic(error);
}
g->adapter = adapter;
g->device = device;
}
#if GPU_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))
{
Panic(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))
{
Panic(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
EndScratch(scratch); EndScratch(scratch);
} }
//- Queue initialization ////////////////////////////////////////////////////////////
//~ Initialization
JobDef(GPU_D12_InitQueue, sig, id)
{
GPU_D12_SharedState *g = &GPU_D12_shared_state;
GPU_D12_QueueDesc desc = sig->descs[id];
Arena *perm = PermArena();
HRESULT hr = 0;
GPU_D12_Queue *queue = 0;
{
PushAlign(perm, CachelineSize);
queue = PushStruct(perm, GPU_D12_Queue);
PushAlign(perm, CachelineSize);
}
queue->desc = desc;
D3D12_COMMAND_QUEUE_DESC d3d_desc = ZI;
d3d_desc.Type = desc.d3d_type;
d3d_desc.Priority = desc.d3d_priority;
hr = ID3D12Device_CreateCommandQueue(g->device, &d3d_desc, &IID_ID3D12CommandQueue, (void **)&queue->d3d_queue);
if (FAILED(hr))
{
Panic(Lit("Failed to create command queue"));
}
hr = ID3D12Device_CreateFence(g->device, 0, 0, &IID_ID3D12Fence, (void **)&queue->submit_fence);
if (FAILED(hr))
{
Panic(Lit("Failed to create command queue fence"));
}
g->queues[desc.kind] = queue;
}
//- Heap initialization //- Heap initialization
@ -772,31 +698,6 @@ void GPU_QueueWait(GPU_QueueKind a, GPU_QueueKind b, i64 b_target_fence_value)
ID3D12CommandQueue_Wait(queue_a->d3d_queue, b_fence, b_target_fence_value); ID3D12CommandQueue_Wait(queue_a->d3d_queue, b_fence, b_target_fence_value);
} }
////////////////////////////////////////////////////////////
//~ @hookdef Rasterizer helper hooks
GPU_Viewport GPU_ViewportFromRect(Rng2 rect)
{
GPU_Viewport viewport = ZI;
viewport.top_left_x = rect.p0.x;
viewport.top_left_y = rect.p0.y;
viewport.width = rect.p1.x - rect.p0.x;
viewport.height = rect.p1.y - rect.p0.y;
viewport.min_depth = 0.0f;
viewport.max_depth = 1.0f;
return viewport;
}
GPU_Scissor GPU_ScissorFromRect(Rng2 rect)
{
GPU_Scissor scissor = ZI;
scissor.left = rect.p0.x;
scissor.top = rect.p0.y;
scissor.right = rect.p1.x;
scissor.bottom = rect.p1.y;
return scissor;
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ @hookdef Resource hooks //~ @hookdef Resource hooks

View File

@ -130,14 +130,6 @@ Struct(GPU_D12_ResourceReuseListBin)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Queue types //~ Queue types
Struct(GPU_D12_QueueDesc)
{
GPU_QueueKind kind;
D3D12_COMMAND_LIST_TYPE d3d_type;
D3D12_COMMAND_QUEUE_PRIORITY d3d_priority;
String dbg_name;
};
Struct(GPU_D12_Queue) Struct(GPU_D12_Queue)
{ {
GPU_D12_QueueDesc desc; GPU_D12_QueueDesc desc;
@ -287,8 +279,6 @@ Struct(GPU_D12_FiberState)
Struct(GPU_D12_SharedState) Struct(GPU_D12_SharedState)
{ {
GPU_D12_FiberState *fiber_states[MaxFibers];
Atomic64Padded resource_barrier_gen; Atomic64Padded resource_barrier_gen;
/* Stats */ /* Stats */

BIN
src/pp/pp_res/sound/test.mp3 (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

BIN
src/proto/pp_vis/pp_vis_res/sound/test.mp3 (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

BIN
src/proto/pp_vis/pp_vis_res/sprite/box.ase (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
src/proto/pp_vis/pp_vis_res/sprite/gun.ase (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

BIN
src/proto/pp_vis/pp_vis_res/sprite/tim.ase (Stored with Git LFS)

Binary file not shown.