From f6c946cc648a8dfdd1d8f2d1a4cbb1299a73054e Mon Sep 17 00:00:00 2001 From: jacob Date: Sat, 22 Nov 2025 15:30:40 -0600 Subject: [PATCH] gpu layer refactor progress --- src/base/base.h | 44 +- src/gpu/gpu_common.c | 70 +- src/gpu/gpu_common.h | 12 +- src/gpu/gpu_core.h | 84 +- src/gpu/gpu_dx12/gpu_dx12.c | 1048 ++++++++++++------------ src/gpu/gpu_dx12/gpu_dx12.h | 154 ++-- src/gpu/gpu_dx12/gpu_dx12.lay | 3 - src/proto/proto.c | 40 + src/proto/proto.lay | 1 + src/window/window.h | 12 +- src/window/window_win32/window_win32.c | 19 +- 11 files changed, 756 insertions(+), 731 deletions(-) diff --git a/src/base/base.h b/src/base/base.h index a53aa2a3..6b8f3a2e 100644 --- a/src/base/base.h +++ b/src/base/base.h @@ -736,17 +736,17 @@ Struct(U128) //- Pointers - Struct(GpuBufferPtr) { u32 v; }; - Struct(GpuRWBufferPtr) { u32 v; }; - Struct(GpuIndexBufferPtr) { u32 v; }; - Struct(GpuTexture1DPtr) { u32 v; }; - Struct(GpuRWTexture1DPtr) { u32 v; }; - Struct(GpuTexture2DPtr) { u32 v; }; - Struct(GpuRWTexture2DPtr) { u32 v; }; - Struct(GpuTexture3DPtr) { u32 v; }; - Struct(GpuRWTexture3DPtr) { u32 v; }; - Struct(GpuRasterTargetPtr) { u32 v; }; - Struct(GpuSamplerPtr) { u32 v; }; + Struct(BufferGpuPtr) { u32 v; }; + Struct(RWBufferGpuPtr) { u32 v; }; + Struct(IndexBufferGpuPtr) { u32 v; }; + Struct(Texture1DGpuPtr) { u32 v; }; + Struct(RWTexture1DGpuPtr) { u32 v; }; + Struct(Texture2DGpuPtr) { u32 v; }; + Struct(RWTexture2DGpuPtr) { u32 v; }; + Struct(Texture3DGpuPtr) { u32 v; }; + Struct(RWTexture3DGpuPtr) { u32 v; }; + Struct(RasterTargetGpuPtr) { u32 v; }; + Struct(SamplerGpuPtr) { u32 v; }; #define IsGpuPtrNil(p) ((p).v == 0) #elif IsLanguageGpu @@ -764,17 +764,17 @@ Struct(U128) //- Pointers - typedef GpuBufferPtr u32; - typedef GpuRWBufferPtr u32; - typedef GpuIndexBufferPtr u32; - typedef GpuTexture1DPtr u32; - typedef GpuRWTexture1DPtr u32; - typedef GpuTexture2DPtr u32; - typedef GpuRWTexture2DPtr u32; - typedef GpuTexture3DPtr u32; - typedef GpuRWTexture3DPtr u32; - typedef GpuRasterTargetPtr u32; - typedef GpuSamplerPtr u32; + typedef BufferGpuPtr u32; + typedef RWBufferGpuPtr u32; + typedef IndexBufferGpuPtr u32; + typedef Texture1DGpuPtr u32; + typedef RWTexture1DGpuPtr u32; + typedef Texture2DGpuPtr u32; + typedef RWTexture2DGpuPtr u32; + typedef Texture3DGpuPtr u32; + typedef RWTexture3DGpuPtr u32; + typedef RasterTargetGpuPtr u32; + typedef SamplerGpuPtr u32; #define IsGpuPtrNil(p) ((p) == 0) diff --git a/src/gpu/gpu_common.c b/src/gpu/gpu_common.c index 6fb76cb2..5e72cb9f 100644 --- a/src/gpu/gpu_common.c +++ b/src/gpu/gpu_common.c @@ -7,43 +7,43 @@ void GPU_StartupCommon(void) { GPU_SharedUtilState *g = &GPU_shared_util_state; - GPU_ArenaHandle gpu_perm = GPU_PermArena(); + // GPU_ArenaHandle gpu_perm = GPU_PermArena(); - /* Init point sampler */ - GPU_ResourceHandle pt_sampler = GPU_PushSampler(gpu_perm, (GPU_SamplerDesc) { .filter = GPU_Filter_MinMagMipPoint }); - g->pt_sampler = GPU_PushSamplerPtr(gpu_perm, pt_sampler); + // /* Init point sampler */ + // GPU_ResourceHandle pt_sampler = GPU_PushSampler(gpu_perm, (GPU_SamplerDesc) { .filter = GPU_Filter_MinMagMipPoint }); + // g->pt_sampler = GPU_PushSamplerPtr(gpu_perm, pt_sampler); - GPU_CommandListHandle cl = GPU_OpenCommandList(GPU_QueueKind_Direct); - { - /* Init noise texture */ - String noise_data = DataFromResource(ResourceKeyFromStore(&GPU_Resources, Lit("noise_128x128x64_16.dat"))); - Vec3I32 noise_dims = VEC3I32(128, 128, 64); - GPU_ResourceHandle noise_tex = ZI; - { - if (noise_data.len != noise_dims.x * noise_dims.y * noise_dims.z * 2) - { - Panic(Lit("Unexpected noise texture size")); - } - noise_tex = GPU_PushTexture3D(gpu_perm, noise_dims, GPU_Format_R16_Uint, GPU_AccessKind_CopyWrite); - GPU_CopyResourceFromCpu(cl, noise_tex, noise_data); - } + // GPU_CommandListHandle cl = GPU_PrepareCommandList(); + // { + // /* Init noise texture */ + // String noise_data = DataFromResource(ResourceKeyFromStore(&GPU_Resources, Lit("noise_128x128x64_16.dat"))); + // Vec3I32 noise_dims = VEC3I32(128, 128, 64); + // GPU_ResourceHandle noise_tex = ZI; + // { + // if (noise_data.len != noise_dims.x * noise_dims.y * noise_dims.z * 2) + // { + // Panic(Lit("Unexpected noise texture size")); + // } + // noise_tex = GPU_PushTexture3D(gpu_perm, noise_dims, GPU_Format_R16_Uint, GPU_AccessKind_CopyWrite); + // GPU_CopyResourceFromCpu(cl, noise_tex, noise_data); + // } - /* Init quad index buffer */ - GPU_ResourceHandle quad_indices = ZI; - { - u16 quad_data[6] = { 0, 1, 2, 0, 2, 3 }; - quad_indices = GPU_PushBuffer(gpu_perm, u16, GPU_AccessKind_CopyWrite); - GPU_CopyResourceFromCpu(cl, quad_indices, StringFromArray(quad_data)); - } + // /* Init quad index buffer */ + // GPU_ResourceHandle quad_indices = ZI; + // { + // u16 quad_data[6] = { 0, 1, 2, 0, 2, 3 }; + // quad_indices = GPU_PushBuffer(gpu_perm, u16, GPU_AccessKind_CopyWrite); + // GPU_CopyResourceFromCpu(cl, quad_indices, StringFromArray(quad_data)); + // } - g->noise_tex = GPU_PushTexture3DPtr(gpu_perm, noise_tex); - g->quad_indices = GPU_PushIndexBufferPtr(gpu_perm, quad_indices, u16); + // g->noise_tex = GPU_PushTexture3DPtr(gpu_perm, noise_tex); + // g->quad_indices = GPU_PushIndexBufferPtr(gpu_perm, quad_indices, u16); - /* FIXME: Block other queues until common startup finishes here */ - GPU_SetAccess(cl, noise_tex, GPU_AccessKind_AnyRead); - GPU_SetAccess(cl, quad_indices, GPU_AccessKind_AnyRead); - } - GPU_CloseCommandList(cl); + // /* FIXME: Block other queues until common startup finishes here */ + // GPU_SyncAccess(cl, noise_tex, GPU_AccessKind_AnyRead); + // GPU_SyncAccess(cl, quad_indices, GPU_AccessKind_AnyRead); + // } + // GPU_CommitCommandList(cl, GPU_QueueKind_Direct); } //////////////////////////////////////////////////////////// @@ -72,17 +72,17 @@ void GPU_CopyResourceFromCpu(GPU_CommandListHandle cl, GPU_ResourceHandle dst, S //////////////////////////////////////////////////////////// //~ Common resource helpers -GpuSamplerPtr GPU_GetCommonPointSampler(void) +SamplerGpuPtr GPU_GetCommonPointSampler(void) { return GPU_shared_util_state.pt_sampler; } -GpuIndexBufferPtr GPU_GetCommonQuadIndices(void) +IndexBufferGpuPtr GPU_GetCommonQuadIndices(void) { return GPU_shared_util_state.quad_indices; } -GpuTexture3DPtr GPU_GetCommonNoise(void) +Texture3DGpuPtr GPU_GetCommonNoise(void) { return GPU_shared_util_state.noise_tex; } diff --git a/src/gpu/gpu_common.h b/src/gpu/gpu_common.h index 3dd69503..15e37dd7 100644 --- a/src/gpu/gpu_common.h +++ b/src/gpu/gpu_common.h @@ -4,9 +4,9 @@ Struct(GPU_SharedUtilState) { /* Common shared resources */ - GpuSamplerPtr pt_sampler; - GpuIndexBufferPtr quad_indices; - GpuTexture3DPtr noise_tex; + SamplerGpuPtr pt_sampler; + IndexBufferGpuPtr quad_indices; + Texture3DGpuPtr noise_tex; GPU_ArenaHandle perm_arenas[MaxFibers]; } extern GPU_shared_util_state; @@ -29,6 +29,6 @@ void GPU_CopyResourceFromCpu(GPU_CommandListHandle cl, GPU_ResourceHandle dst, S //////////////////////////////////////////////////////////// //~ Common resource helpers -GpuSamplerPtr GPU_GetCommonPointSampler(void); -GpuIndexBufferPtr GPU_GetCommonQuadIndices(void); -GpuTexture3DPtr GPU_GetCommonNoise(void); +SamplerGpuPtr GPU_GetCommonPointSampler(void); +IndexBufferGpuPtr GPU_GetCommonQuadIndices(void); +Texture3DGpuPtr GPU_GetCommonNoise(void); diff --git a/src/gpu/gpu_core.h b/src/gpu/gpu_core.h index a3a05732..da901ec1 100644 --- a/src/gpu/gpu_core.h +++ b/src/gpu/gpu_core.h @@ -187,10 +187,9 @@ Enum(GPU_AccessKind) GPU_AccessKind_PixelRead, GPU_AccessKind_PixelReadWrite, - GPU_AccessKind_DepthStencilRead, - GPU_AccessKind_DepthStencilReadWrite, + GPU_AccessKind_RasterTarget, - GPU_AccessKind_RasterTargetWrite, + GPU_AccessKind_Present, }; //////////////////////////////////////////////////////////// @@ -425,17 +424,17 @@ GPU_ResourceHandle GPU_PushSampler(GPU_ArenaHandle arena, GPU_SamplerDesc desc); //- Pointer creation -GpuBufferPtr GPU_PushBufferPtrEx (GPU_ArenaHandle arena, GPU_ResourceHandle resource, u32 element_size, RngU32 element_range); -GpuRWBufferPtr GPU_PushRWBufferPtrEx (GPU_ArenaHandle arena, GPU_ResourceHandle resource, u32 element_size, RngU32 element_range); -GpuIndexBufferPtr GPU_PushIndexBufferPtrEx (GPU_ArenaHandle arena, GPU_ResourceHandle resource, u32 element_size, RngU32 element_range); -GpuTexture1DPtr GPU_PushTexture1DPtr (GPU_ArenaHandle arena, GPU_ResourceHandle resource); -GpuRWTexture1DPtr GPU_PushRWTexture1DPtr (GPU_ArenaHandle arena, GPU_ResourceHandle resource); -GpuTexture2DPtr GPU_PushTexture2DPtr (GPU_ArenaHandle arena, GPU_ResourceHandle resource); -GpuRWTexture2DPtr GPU_PushRWTexture2DPtr (GPU_ArenaHandle arena, GPU_ResourceHandle resource); -GpuTexture3DPtr GPU_PushTexture3DPtr (GPU_ArenaHandle arena, GPU_ResourceHandle resource); -GpuRWTexture3DPtr GPU_PushRWTexture3DPtr (GPU_ArenaHandle arena, GPU_ResourceHandle resource); -GpuRasterTargetPtr GPU_PushRasterTargetPtr (GPU_ArenaHandle arena, GPU_ResourceHandle resource); -GpuSamplerPtr GPU_PushSamplerPtr (GPU_ArenaHandle arena, GPU_ResourceHandle resource); +BufferGpuPtr GPU_PushBufferPtrEx (GPU_ArenaHandle arena, GPU_ResourceHandle resource, u32 element_size, RngU32 element_range); +RWBufferGpuPtr GPU_PushRWBufferPtrEx (GPU_ArenaHandle arena, GPU_ResourceHandle resource, u32 element_size, RngU32 element_range); +IndexBufferGpuPtr GPU_PushIndexBufferPtrEx (GPU_ArenaHandle arena, GPU_ResourceHandle resource, u32 element_size, RngU32 element_range); +Texture1DGpuPtr GPU_PushTexture1DPtr (GPU_ArenaHandle arena, GPU_ResourceHandle resource); +RWTexture1DGpuPtr GPU_PushRWTexture1DPtr (GPU_ArenaHandle arena, GPU_ResourceHandle resource); +Texture2DGpuPtr GPU_PushTexture2DPtr (GPU_ArenaHandle arena, GPU_ResourceHandle resource); +RWTexture2DGpuPtr GPU_PushRWTexture2DPtr (GPU_ArenaHandle arena, GPU_ResourceHandle resource); +Texture3DGpuPtr GPU_PushTexture3DPtr (GPU_ArenaHandle arena, GPU_ResourceHandle resource); +RWTexture3DGpuPtr GPU_PushRWTexture3DPtr (GPU_ArenaHandle arena, GPU_ResourceHandle resource); +RasterTargetGpuPtr GPU_PushRasterTargetPtr (GPU_ArenaHandle arena, GPU_ResourceHandle resource); +SamplerGpuPtr GPU_PushSamplerPtr (GPU_ArenaHandle arena, GPU_ResourceHandle resource); #define GPU_PushBufferPtr(arena, resource, type) GPU_PushBufferPtrEx((arena), (resource), sizeof(type), RNGU32(0, GPU_CountBuffer((resource), type))) #define GPU_PushRWBufferPtr(arena, resource, type) GPU_PushRWBufferPtrEx((arena), (resource), sizeof(type), RNGU32(0, GPU_CountBuffer((resource), type))) @@ -454,8 +453,8 @@ u64 GPU_Count3D(GPU_ResourceHandle texture3d); //~ @hookdecl Command //- Command list -GPU_CommandListHandle GPU_OpenCommandList(GPU_QueueKind queue); -void GPU_CloseCommandList(GPU_CommandListHandle cl); +GPU_CommandListHandle GPU_PrepareCommandList(void); +void GPU_CommitCommandList(GPU_CommandListHandle cl, GPU_QueueKind queue); //- Arena void GPU_ResetArena(GPU_CommandListHandle cl, GPU_ArenaHandle arena); @@ -465,22 +464,20 @@ void GPU_CopyBuffer(GPU_CommandListHandle cl, GPU_ResourceHandle dst, u64 dst_of void GPU_CopyTexture(GPU_CommandListHandle cl, GPU_ResourceHandle dst, Vec3I32 dst_offset, GPU_ResourceHandle src, Vec3I32 src_offset, Vec3I32 dims); //- Constants -void GPU_SetConstU32 (GPU_CommandListHandle cl, i32 slot, u32 v); -void GPU_SetConstF32 (GPU_CommandListHandle cl, i32 slot, f32 v); -void GPU_SetConstBufferPtr (GPU_CommandListHandle cl, i32 slot, GpuBufferPtr v); -void GPU_SetConstRWBufferPtr (GPU_CommandListHandle cl, i32 slot, GpuRWBufferPtr v); -void GPU_SetConstIndexBufferPtr (GPU_CommandListHandle cl, i32 slot, GpuIndexBufferPtr v); -void GPU_SetConstTexture1DPtr (GPU_CommandListHandle cl, i32 slot, GpuTexture1DPtr v); -void GPU_SetConstRWTexture1DPtr (GPU_CommandListHandle cl, i32 slot, GpuRWTexture1DPtr v); -void GPU_SetConstTexture2DPtr (GPU_CommandListHandle cl, i32 slot, GpuTexture2DPtr v); -void GPU_SetConstRWTexture2DPtr (GPU_CommandListHandle cl, i32 slot, GpuRWTexture2DPtr v); -void GPU_SetConstTexture3DPtr (GPU_CommandListHandle cl, i32 slot, GpuTexture3DPtr v); -void GPU_SetConstRWTexture3DPtr (GPU_CommandListHandle cl, i32 slot, GpuRWTexture3DPtr v); -void GPU_SetConstRasterTargetPtr (GPU_CommandListHandle cl, i32 slot, GpuRasterTargetPtr v); -void GPU_SetConstSamplerPtr (GPU_CommandListHandle cl, i32 slot, GpuSamplerPtr v); +void GPU_SetConstU32 (GPU_CommandListHandle cl, i32 slot, u32 v); +void GPU_SetConstF32 (GPU_CommandListHandle cl, i32 slot, f32 v); +void GPU_SetConstBuffer (GPU_CommandListHandle cl, i32 slot, BufferGpuPtr v); +void GPU_SetConstRWBuffer (GPU_CommandListHandle cl, i32 slot, RWBufferGpuPtr v); +void GPU_SetConstTexture1D (GPU_CommandListHandle cl, i32 slot, Texture1DGpuPtr v); +void GPU_SetConstRWTexture1D (GPU_CommandListHandle cl, i32 slot, RWTexture1DGpuPtr v); +void GPU_SetConstTexture2D (GPU_CommandListHandle cl, i32 slot, Texture2DGpuPtr v); +void GPU_SetConstRWTexture2D (GPU_CommandListHandle cl, i32 slot, RWTexture2DGpuPtr v); +void GPU_SetConstTexture3D (GPU_CommandListHandle cl, i32 slot, Texture3DGpuPtr v); +void GPU_SetConstRWTexture3D (GPU_CommandListHandle cl, i32 slot, RWTexture3DGpuPtr v); +void GPU_SetConstSampler (GPU_CommandListHandle cl, i32 slot, SamplerGpuPtr v); //- Access -void GPU_SetAccess(GPU_CommandListHandle cl, GPU_ResourceHandle resource, GPU_AccessKind kind); +void GPU_SyncAccess(GPU_CommandListHandle cl, GPU_ResourceHandle resource, GPU_AccessKind kind); //- Compute void GPU_Compute(GPU_CommandListHandle cl, ComputeShader cs, Vec3I32 groups); @@ -488,17 +485,22 @@ void GPU_Compute(GPU_CommandListHandle cl, ComputeShader cs, Vec3I32 groups); //- Rasterize void GPU_Rasterize(GPU_CommandListHandle cl, VertexShader vs, PixelShader ps, - u32 instances_count, GpuIndexBufferPtr idx_buff, - u32 raster_targets_count, GpuRasterTargetPtr *raster_targets, + u32 instances_count, IndexBufferGpuPtr idx_buff, + u32 raster_targets_count, RasterTargetGpuPtr *raster_targets, Rng3 viewport, Rng2 scissor, GPU_RasterMode mode); //- Clear -void GPU_ClearRasterTarget(GPU_CommandListHandle cl, GpuRasterTargetPtr ptr); +void GPU_ClearRasterTarget(GPU_CommandListHandle cl, RasterTargetGpuPtr ptr, Vec4 color); //- Profile void GPU_ProfN(GPU_CommandListHandle cl, String name); +//////////////////////////////////////////////////////////// +//~ @hookdecl Synchronization + +void GPU_CpuWaitOnQueue(GPU_QueueKind queue_kind); + //////////////////////////////////////////////////////////// //~ @hookdecl Statistics @@ -507,19 +509,11 @@ GPU_Stats GPU_QueryStats(void); //////////////////////////////////////////////////////////// //~ @hookdecl Swapchain -GPU_SwapchainHandle GPU_AcquireSwapchain(WND_Handle window, GPU_Format format, Vec2I32 size); +GPU_SwapchainHandle GPU_AcquireSwapchain(WND_Handle window); void GPU_ReleaseSwapchain(GPU_SwapchainHandle swapchain); -/* Waits until a new backbuffer is ready to be written to. +/* Waits until a new backbuffer is ready from the swapchain. * This should be called before rendering for minimum latency. */ -void GPU_YieldOnSwapchain(GPU_SwapchainHandle swapchain); +GPU_ResourceHandle GPU_PrepareBackbuffer(GPU_SwapchainHandle swapchain_handle, GPU_Format format, Vec2I32 size); -/* 1. Recreates backbuffer at desired size if necessary - * 2. Clears the backbuffer using clear color - * 3. Blits the source texture into the backbuffer - * 4. Presents the backbuffer - */ -void GPU_PresentSwapchain(GPU_SwapchainHandle swapchain, Vec4 dst_clear_color, - Vec2U32 dst_size, Vec2U32 dst_offset, - GpuTexture2DPtr src, Vec2U32 src_offset, - i32 vsync); +void GPU_CommitBackbuffer(GPU_ResourceHandle backbuffer, i32 vsync); diff --git a/src/gpu/gpu_dx12/gpu_dx12.c b/src/gpu/gpu_dx12/gpu_dx12.c index bf124f0c..8185c357 100644 --- a/src/gpu/gpu_dx12/gpu_dx12.c +++ b/src/gpu/gpu_dx12/gpu_dx12.c @@ -155,7 +155,7 @@ void GPU_D12_Startup(void) //- Initialize command queues { - GPU_D12_CommandQueueDesc descs [] = { + GPU_D12_CommandQueueDesc descs[] = { { .type = D3D12_COMMAND_LIST_TYPE_DIRECT, .priority = D3D12_COMMAND_QUEUE_PRIORITY_HIGH }, { .type = D3D12_COMMAND_LIST_TYPE_COMPUTE, .priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL }, { .type = D3D12_COMMAND_LIST_TYPE_COPY, .priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL }, @@ -169,7 +169,7 @@ void GPU_D12_Startup(void) HRESULT hr = ID3D12Device_CreateCommandQueue(g->device, &d3d_desc, &IID_ID3D12CommandQueue, (void **)&queue->d3d_queue); if (SUCCEEDED(hr)) { - hr = ID3D12Device_CreateFence(g->device, 0, 0, &IID_ID3D12Fence, (void **)&queue->submit_fence); + hr = ID3D12Device_CreateFence(g->device, 0, 0, &IID_ID3D12Fence, (void **)&queue->commit_fence); } if (FAILED(hr)) { @@ -182,20 +182,30 @@ void GPU_D12_Startup(void) //- Initialize descriptor heaps { - Struct(Dx12HeapDesc) { GPU_D12_DescriptorHeap *dst; D3D12_DESCRIPTOR_HEAP_TYPE type; D3D12_DESCRIPTOR_HEAP_FLAGS flags; u64 max; }; + Struct(Dx12HeapDesc) { D3D12_DESCRIPTOR_HEAP_TYPE type; D3D12_DESCRIPTOR_HEAP_FLAGS flags; u64 max; }; Dx12HeapDesc descs[] = { - { .dst = &g->cbv_srv_uav_heap, .flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, .max = GPU_D12_MaxCbvSrvUavDescriptors, }, - { .dst = &g->sampler_heap, .flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, .max = GPU_D12_MaxSamplerDescriptors, }, - { .dst = &g->rtv_heap, .flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE, .max = GPU_D12_MaxRtvDescriptors, }, + { + .type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, + + .flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, + .max = GPU_D12_MaxCbvSrvUavDescriptors, + }, + { + .type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV, + .flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE, + .max = GPU_D12_MaxRtvDescriptors, + }, + { + .type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, + .flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, + .max = GPU_D12_MaxSamplerDescriptors, + }, }; for (u32 i = 0; i < countof(descs); ++i) { Dx12HeapDesc desc = descs[i]; - - - Arena *arena = AcquireArena(Gibi(64)); - GPU_D12_DescriptorHeap *heap = PushStruct(arena, GPU_D12_DescriptorHeap); - heap->arena = arena; + GPU_D12_DescriptorHeap *heap = &g->descriptor_heaps[i]; + heap->descriptors_arena = AcquireArena(Gibi(1)); heap->type = desc.type; heap->max_count = desc.max; @@ -208,10 +218,9 @@ void GPU_D12_Startup(void) HRESULT hr = ID3D12Device_CreateDescriptorHeap(g->device, &d3d_desc, &IID_ID3D12DescriptorHeap, (void **)&heap->d3d_heap); if (FAILED(hr)) { - Panic(Lit("Failed to create CPU descriptor heap")); + Panic(Lit("Failed to create descriptor heap")); } ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap->d3d_heap, &heap->start_handle); - } } @@ -266,8 +275,8 @@ void GPU_D12_Startup(void) ////////////////////////////// //- Initialize queue sync worker - JobPoolId sync_pool = InitJobPool(1, Lit("Dx12 queue sync"), JobPoolPriority_Critical); - RunJob(GPU_D12_StartQueueSync, .pool = sync_pool); + // JobPoolId sync_pool = InitJobPool(1, Lit("Dx12 queue sync"), JobPoolPriority_Critical); + // RunJob(GPU_D12_StartQueueSync, .pool = sync_pool); EndScratch(scratch); } @@ -301,7 +310,7 @@ GPU_D12_Swapchain *GPU_D12_SwapchainFromHandle(GPU_SwapchainHandle handle) } //////////////////////////////////////////////////////////// -//~ Pipeline operations +//~ Pipeline JobImpl(GPU_D12_LoadPipeline, sig, _) { @@ -407,7 +416,7 @@ JobImpl(GPU_D12_LoadPipeline, sig, _) pipeline->pso = pso; pipeline->error = error_str; - pipeline->ok = 1; + pipeline->ok = ok; } GPU_D12_Pipeline *GPU_D12_PipelineFromDesc(GPU_D12_PipelineDesc desc) @@ -459,7 +468,7 @@ GPU_D12_Pipeline *GPU_D12_PipelineFromDesc(GPU_D12_PipelineDesc desc) } //////////////////////////////////////////////////////////// -//~ Queue operations +//~ Queue GPU_D12_Queue *GPU_D12_QueueFromKind(GPU_QueueKind kind) { @@ -468,71 +477,71 @@ GPU_D12_Queue *GPU_D12_QueueFromKind(GPU_QueueKind kind) } //////////////////////////////////////////////////////////// -//~ Descriptor operations +//~ Descriptor -GPU_D12_Descriptor *GPU_D12_AcquireDescriptor(GPU_D12_DescriptorHeap *heap) -{ - GPU_D12_Descriptor *d = 0; - u32 index = 0; - D3D12_CPU_DESCRIPTOR_HANDLE handle = ZI; - { - Lock lock = LockE(&heap->mutex); - if (heap->first_free) - { - d = heap->first_free; - heap->first_free = d->next_free; - handle = d->handle; - index = d->index; - } - else - { - if (heap->allocated_count >= heap->max_count) - { - Panic(Lit("Max descriptors reached in heap")); - } - d = PushStructNoZero(heap->arena, GPU_D12_Descriptor); - index = heap->allocated_count++; - handle.ptr = heap->start_handle.ptr + (index * heap->descriptor_size); - Atomic64FetchAdd(&GPU_D12_shared_state.driver_descriptors_allocated, 1); - } - Unlock(&lock); - } - ZeroStruct(d); - d->valid = 1; - d->heap = heap; - d->handle = handle; - d->index = index; - return d; -} +// GPU_D12_Descriptor *GPU_D12_AcquireDescriptor(GPU_D12_DescriptorHeap *heap) +// { +// GPU_D12_Descriptor *d = 0; +// u32 index = 0; +// D3D12_CPU_DESCRIPTOR_HANDLE handle = ZI; +// { +// Lock lock = LockE(&heap->mutex); +// if (heap->first_free) +// { +// d = heap->first_free; +// heap->first_free = d->next_free; +// handle = d->handle; +// index = d->index; +// } +// else +// { +// if (heap->allocated_count >= heap->max_count) +// { +// Panic(Lit("Max descriptors reached in heap")); +// } +// d = PushStructNoZero(heap->arena, GPU_D12_Descriptor); +// index = heap->allocated_count++; +// handle.ptr = heap->start_handle.ptr + (index * heap->descriptor_size); +// Atomic64FetchAdd(&GPU_D12_shared_state.driver_descriptors_allocated, 1); +// } +// Unlock(&lock); +// } +// ZeroStruct(d); +// d->valid = 1; +// d->heap = heap; +// d->handle = handle; +// d->index = index; +// return d; +// } -void GPU_D12_ReleaseDescriptor(GPU_D12_Descriptor *descriptor) -{ - GPU_D12_DescriptorHeap *heap = descriptor->heap; - Lock lock = LockE(&heap->mutex); - { - descriptor->next_free = heap->first_free; - heap->first_free = descriptor; - } - Unlock(&lock); -} +// void GPU_D12_ReleaseDescriptor(GPU_D12_Descriptor *descriptor) +// { +// GPU_D12_DescriptorHeap *heap = descriptor->heap; +// Lock lock = LockE(&heap->mutex); +// { +// descriptor->next_free = heap->first_free; +// heap->first_free = descriptor; +// } +// Unlock(&lock); +// } -GPU_D12_Descriptor *GPU_D12_RtvDescriptorFromPtr(GpuRasterTargetPtr ptr) -{ - /* TODO */ - return 0; -} +// GPU_D12_Descriptor *GPU_D12_DescriptorFromRtPtr(RasterTargetGpuPtr ptr) +// { +// /* TODO */ +// return 0; +// } -D3D12_INDEX_BUFFER_VIEW GPU_D12_IbvFromPtr(GpuIndexBufferPtr ptr) -{ - /* TODO */ - D3D12_INDEX_BUFFER_VIEW result = ZI; - return result; -} +// D3D12_INDEX_BUFFER_VIEW GPU_D12_IbvFromIbPtr(IndexBufferGpuPtr ptr) +// { +// /* TODO */ +// D3D12_INDEX_BUFFER_VIEW result = ZI; +// return result; +// } //////////////////////////////////////////////////////////// //~ Raw command list -GPU_D12_RawCommandList *GPU_D12_BeginRawCommandList(GPU_QueueKind queue_kind) +GPU_D12_RawCommandList *GPU_D12_PrepareRawCommandList(GPU_QueueKind queue_kind) { GPU_D12_SharedState *g = &GPU_D12_shared_state; GPU_D12_Queue *queue = GPU_D12_QueueFromKind(queue_kind); @@ -540,13 +549,13 @@ GPU_D12_RawCommandList *GPU_D12_BeginRawCommandList(GPU_QueueKind queue_kind) /* Pull first completed command list from queue if ready */ GPU_D12_RawCommandList *cl = ZI; { - Lock lock = LockE(&queue->submit_mutex); + Lock lock = LockE(&queue->commit_mutex); { - u64 completed = ID3D12Fence_GetCompletedValue(queue->submit_fence); - cl = queue->first_submitted_cl; - if (cl && cl->submit_fence_target <= completed) + u64 completed = ID3D12Fence_GetCompletedValue(queue->commit_fence); + cl = queue->first_committed_cl; + if (cl && cl->commit_fence_target <= completed) { - SllQueuePop(queue->first_submitted_cl, queue->last_submitted_cl); + SllQueuePop(queue->first_committed_cl, queue->last_committed_cl); } else { @@ -604,7 +613,7 @@ GPU_D12_RawCommandList *GPU_D12_BeginRawCommandList(GPU_QueueKind queue_kind) return cl; } -u64 GPU_D12_EndRawCommandList(GPU_D12_RawCommandList *cl) +void GPU_D12_CommitRawCommandList(GPU_D12_RawCommandList *cl) { GPU_D12_Queue *queue = cl->queue; @@ -619,56 +628,55 @@ u64 GPU_D12_EndRawCommandList(GPU_D12_RawCommandList *cl) } } - /* Submit */ - u64 target = 0; + /* Commit */ { - __profn("Execute"); - Lock lock = LockE(&queue->submit_mutex); + __profn("Commit"); + Lock lock = LockE(&queue->commit_mutex); { - target = ++queue->submit_fence_target; - cl->submit_fence_target = target; + u64 target = ++queue->commit_fence_target; + cl->commit_fence_target = target; + /* Execute */ ID3D12CommandQueue_ExecuteCommandLists(queue->d3d_queue, 1, (ID3D12CommandList **)&cl->cl); - ID3D12CommandQueue_Signal(queue->d3d_queue, queue->submit_fence, target); + ID3D12CommandQueue_Signal(queue->d3d_queue, queue->commit_fence, target); + /* Append */ - SllQueuePush(queue->first_submitted_cl, queue->last_submitted_cl, cl); + SllQueuePush(queue->first_committed_cl, queue->last_committed_cl, cl); } Unlock(&lock); } - - return target; } //////////////////////////////////////////////////////////// //~ Queue sync job -JobImpl(GPU_D12_StartQueueSync, _, __) -{ - GPU_D12_SharedState *g = &GPU_D12_shared_state; - HANDLE queue_fences_events[GPU_NumQueues] = ZI; - i64 queue_fences_seen[GPU_NumQueues] = ZI; - for (i32 i = 0; i < countof(queue_fences_events); ++i) - { - queue_fences_events[i] = CreateEvent(0, 0, 1, 0); - queue_fences_seen[i] = -1; - } - for (;;) - { - WaitForMultipleObjects(countof(queue_fences_events), queue_fences_events, 0, INFINITE); - for (GPU_QueueKind queue_kind = 0; queue_kind < GPU_NumQueues; ++queue_kind) - { - GPU_D12_Queue *queue = GPU_D12_QueueFromKind(queue_kind); - i64 last_seen = queue_fences_seen[queue_kind]; - i64 completed = ID3D12Fence_GetCompletedValue(queue->submit_fence); - if (completed > last_seen) - { - SetFence(&queue->sync_fence, completed); - queue_fences_seen[queue_kind] = completed; - ID3D12Fence_SetEventOnCompletion(queue->submit_fence, completed + 1, queue_fences_events[queue_kind]); - } - } - } -} +// JobImpl(GPU_D12_StartQueueSync, _, __) +// { +// GPU_D12_SharedState *g = &GPU_D12_shared_state; +// HANDLE queue_fences_events[GPU_NumQueues] = ZI; +// i64 queue_fences_seen[GPU_NumQueues] = ZI; +// for (i32 i = 0; i < countof(queue_fences_events); ++i) +// { +// queue_fences_events[i] = CreateEvent(0, 0, 1, 0); +// queue_fences_seen[i] = -1; +// } +// for (;;) +// { +// WaitForMultipleObjects(countof(queue_fences_events), queue_fences_events, 0, INFINITE); +// for (GPU_QueueKind queue_kind = 0; queue_kind < GPU_NumQueues; ++queue_kind) +// { +// GPU_D12_Queue *queue = GPU_D12_QueueFromKind(queue_kind); +// i64 last_seen = queue_fences_seen[queue_kind]; +// i64 completed = ID3D12Fence_GetCompletedValue(queue->commit_fence); +// if (completed > last_seen) +// { +// SetFence(&queue->sync_fence, completed); +// queue_fences_seen[queue_kind] = completed; +// ID3D12Fence_SetEventOnCompletion(queue->commit_fence, completed + 1, queue_fences_events[queue_kind]); +// } +// } +// } +// } //////////////////////////////////////////////////////////// //~ @hookimpl Startup hook @@ -691,7 +699,7 @@ void GPU_QueueWait(GPU_QueueKind a, GPU_QueueKind b, i64 b_target_fence_value) { GPU_D12_Queue *queue_a = GPU_D12_QueueFromKind(a); GPU_D12_Queue *queue_b = GPU_D12_QueueFromKind(b); - ID3D12Fence *b_fence = queue_b->submit_fence; + ID3D12Fence *b_fence = queue_b->commit_fence; ID3D12CommandQueue_Wait(queue_a->d3d_queue, b_fence, b_target_fence_value); } @@ -1079,8 +1087,12 @@ u64 GPU_GetBufferCount(GPU_Resource *gpu_resource) GPU_ArenaHandle GPU_AcquireArena(void) { - /* TODO */ - return (GPU_ArenaHandle) { 0 }; + GPU_D12_Arena *gpu_arena = 0; + { + Arena *perm = PermArena(); + gpu_arena = PushStruct(perm, GPU_D12_Arena); + } + return (GPU_ArenaHandle) { .v = (u64)gpu_arena }; } void GPU_ReleaseArena(GPU_ArenaHandle arena) @@ -1088,6 +1100,92 @@ void GPU_ReleaseArena(GPU_ArenaHandle arena) /* TODO */ } +//////////////////////////////////////////////////////////// +//~ Resource helpers + +GPU_D12_Descriptor *GPU_D12_PushDescriptor(GPU_D12_Arena *gpu_arena, GPU_D12_Resource *resource, GPU_D12_DescriptorHeapKind heap_kind) +{ + GPU_D12_SharedState *g = &GPU_D12_shared_state; + GPU_D12_DescriptorHeap *heap = &g->descriptor_heaps[heap_kind]; + + GPU_D12_Descriptor *descriptor = 0; + + /* Grab completed descriptor from arena */ + if (!descriptor) + { + GPU_D12_DescriptorList *descriptors_by_queue = gpu_arena->committed_descriptors_by_heap_and_queue[heap_kind]; + for (GPU_QueueKind queue_kind = 0; !descriptor && queue_kind < GPU_NumQueues; ++queue_kind) + { + GPU_D12_DescriptorList *descriptors = &descriptors_by_queue[queue_kind]; + descriptor = descriptors->first; + if (descriptor) + { + GPU_D12_Queue *queue = GPU_D12_QueueFromKind(queue_kind); + u64 queue_commit_completion = ID3D12Fence_GetCompletedValue(queue->commit_fence); + if (queue_commit_completion >= descriptor->queue_commit_target) + { + /* Descriptor no longer in use by gpu, reuse it */ + SllQueuePop(descriptors->first, descriptors->last); + } + else + { + /* Descriptor may still be in use by gpu */ + descriptor = 0; + } + } + } + } + + /* Allocate new descriptor from heap */ + u32 index = 0; + if (!descriptor) + { + Lock lock = LockE(&heap->mutex); + { + if (heap->first_free) + { + descriptor = heap->first_free; + SllStackPop(heap->first_free); + index = descriptor->index; + } + else + { + descriptor = PushStructNoZero(heap->descriptors_arena, GPU_D12_Descriptor); + index = heap->allocated_count++; + if (index >= heap->max_count) + { + Panic(Lit("Max descriptors reached in heap")); + } + } + } + Unlock(&lock); + } + + /* Initialize descriptor handle */ + ZeroStruct(descriptor); + descriptor->heap = heap; + descriptor->resource = resource; + descriptor->index = index; + descriptor->handle.ptr = heap->start_handle.ptr + (index * heap->descriptor_size); + + return descriptor; +} + +GPU_D12_Descriptor *GPU_D12_DescriptorFromIndex(GPU_D12_DescriptorHeapKind heap_kind, u32 index) +{ + GPU_D12_SharedState *g = &GPU_D12_shared_state; + GPU_D12_DescriptorHeap *heap = &g->descriptor_heaps[heap_kind]; + GPU_D12_Descriptor *descriptors = ArenaFirst(heap->descriptors_arena, GPU_D12_Descriptor); + return &descriptors[index]; +} + +D3D12_INDEX_BUFFER_VIEW GPU_D12_IbvFromIbPtr(IndexBufferGpuPtr ptr) +{ + /* TODO */ + D3D12_INDEX_BUFFER_VIEW result = ZI; + return result; +} + //////////////////////////////////////////////////////////// //~ @hookimpl Resource @@ -1113,70 +1211,79 @@ GPU_ResourceHandle GPU_PushSampler(GPU_ArenaHandle arena, GPU_SamplerDesc desc) //- Pointer creation -GpuBufferPtr GPU_PushBufferPtrEx(GPU_ArenaHandle arena, GPU_ResourceHandle resource, u32 element_size, RngU32 element_range) +BufferGpuPtr GPU_PushBufferPtrEx(GPU_ArenaHandle arena_handle, GPU_ResourceHandle resource_handle, u32 element_size, RngU32 element_range) { /* TODO */ - return (GpuBufferPtr) { 0 }; + return (BufferGpuPtr) { 0 }; } -GpuRWBufferPtr GPU_PushRWBufferPtrEx(GPU_ArenaHandle arena, GPU_ResourceHandle resource, u32 element_size, RngU32 element_range) +RWBufferGpuPtr GPU_PushRWBufferPtrEx(GPU_ArenaHandle arena_handle, GPU_ResourceHandle resource_handle, u32 element_size, RngU32 element_range) { /* TODO */ - return (GpuRWBufferPtr) { 0 }; + return (RWBufferGpuPtr) { 0 }; } -GpuIndexBufferPtr GPU_PushIndexBufferPtrEx(GPU_ArenaHandle arena, GPU_ResourceHandle resource, u32 element_size, RngU32 element_range) +IndexBufferGpuPtr GPU_PushIndexBufferPtrEx(GPU_ArenaHandle arena_handle, GPU_ResourceHandle resource_handle, u32 element_size, RngU32 element_range) { /* TODO */ - return (GpuIndexBufferPtr) { 0 }; + return (IndexBufferGpuPtr) { 0 }; } -GpuTexture1DPtr GPU_PushTexture1DPtr(GPU_ArenaHandle arena, GPU_ResourceHandle resource) +Texture1DGpuPtr GPU_PushTexture1DPtr(GPU_ArenaHandle arena_handle, GPU_ResourceHandle resource_handle) { /* TODO */ - return (GpuTexture1DPtr) { 0 }; + return (Texture1DGpuPtr) { 0 }; } -GpuRWTexture1DPtr GPU_PushRWTexture1DPtr(GPU_ArenaHandle arena, GPU_ResourceHandle resource) +RWTexture1DGpuPtr GPU_PushRWTexture1DPtr(GPU_ArenaHandle arena_handle, GPU_ResourceHandle resource_handle) { /* TODO */ - return (GpuRWTexture1DPtr) { 0 }; + return (RWTexture1DGpuPtr) { 0 }; } -GpuTexture2DPtr GPU_PushTexture2DPtr(GPU_ArenaHandle arena, GPU_ResourceHandle resource) +Texture2DGpuPtr GPU_PushTexture2DPtr(GPU_ArenaHandle arena_handle, GPU_ResourceHandle resource_handle) { /* TODO */ - return (GpuTexture2DPtr) { 0 }; + return (Texture2DGpuPtr) { 0 }; } -GpuRWTexture2DPtr GPU_PushRWTexture2DPtr(GPU_ArenaHandle arena, GPU_ResourceHandle resource) +RWTexture2DGpuPtr GPU_PushRWTexture2DPtr(GPU_ArenaHandle arena_handle, GPU_ResourceHandle resource_handle) { /* TODO */ - return (GpuRWTexture2DPtr) { 0 }; + return (RWTexture2DGpuPtr) { 0 }; } -GpuTexture3DPtr GPU_PushTexture3DPtr(GPU_ArenaHandle arena, GPU_ResourceHandle resource) +Texture3DGpuPtr GPU_PushTexture3DPtr(GPU_ArenaHandle arena_handle, GPU_ResourceHandle resource_handle) { /* TODO */ - return (GpuTexture3DPtr) { 0 }; + return (Texture3DGpuPtr) { 0 }; } -GpuRWTexture3DPtr GPU_PushRWTexture3DPtr(GPU_ArenaHandle arena, GPU_ResourceHandle resource) +RWTexture3DGpuPtr GPU_PushRWTexture3DPtr(GPU_ArenaHandle arena_handle, GPU_ResourceHandle resource_handle) { /* TODO */ - return (GpuRWTexture3DPtr) { 0 }; + return (RWTexture3DGpuPtr) { 0 }; } -GpuRasterTargetPtr GPU_PushRasterTargetPtr(GPU_ArenaHandle arena, GPU_ResourceHandle resource) +RasterTargetGpuPtr GPU_PushRasterTargetPtr(GPU_ArenaHandle arena_handle, GPU_ResourceHandle resource_handle) { + /* Allocate descriptor */ + GPU_D12_SharedState *g = &GPU_D12_shared_state; + GPU_D12_Arena *arena = GPU_D12_ArenaFromHandle(arena_handle); + GPU_D12_Resource *resource = GPU_D12_ResourceFromHandle(resource_handle); + GPU_D12_Descriptor *rtv_descriptor = GPU_D12_PushDescriptor(arena, resource, GPU_D12_DescriptorHeapKind_Rtv); + + /* Initialize descriptor */ + ID3D12Device_CreateRenderTargetView(g->device, resource->d3d_resource, 0, rtv_descriptor->handle); + /* TODO */ - return (GpuRasterTargetPtr) { 0 }; + return (RasterTargetGpuPtr) { .v = rtv_descriptor->index }; } -GpuSamplerPtr GPU_PushSamplerPtr(GPU_ArenaHandle arena, GPU_ResourceHandle resource) +SamplerGpuPtr GPU_PushSamplerPtr(GPU_ArenaHandle arena_handle, GPU_ResourceHandle resource_handle) { /* TODO */ - return (GpuSamplerPtr) { 0 }; + return (SamplerGpuPtr) { 0 }; } //- Count @@ -1251,6 +1358,7 @@ GPU_D12_Cmd *GPU_D12_PushCmd(GPU_D12_CmdList *cl) /* Push cmd to chunk */ GPU_D12_Cmd *cmd = &chunk->cmds[chunk->cmds_count++]; + ++cl->cmds_count; return cmd; } @@ -1259,7 +1367,7 @@ GPU_D12_Cmd *GPU_D12_PushCmd(GPU_D12_CmdList *cl) //- Command list -GPU_CommandListHandle GPU_OpenCommandList(GPU_QueueKind queue_kind) +GPU_CommandListHandle GPU_PrepareCommandList(void) { GPU_D12_SharedState *g = &GPU_D12_shared_state; GPU_D12_CmdList *cl = 0; @@ -1281,16 +1389,15 @@ GPU_CommandListHandle GPU_OpenCommandList(GPU_QueueKind queue_kind) return (GPU_CommandListHandle) { .v = (u64)cl }; } -void GPU_CloseCommandList(GPU_CommandListHandle cl_handle) +void GPU_CommitCommandList(GPU_CommandListHandle cl_handle, GPU_QueueKind queue_kind) { GPU_D12_SharedState *g = &GPU_D12_shared_state; GPU_D12_CmdList *cl = GPU_D12_CmdListFromHandle(cl_handle); - GPU_QueueKind queue_kind = cl->queue_kind; GPU_D12_Queue *queue = GPU_D12_QueueFromKind(queue_kind); TempArena scratch = BeginScratchNoConflict(); /* Begin dx12 command list */ - GPU_D12_RawCommandList *dx12_cl = GPU_D12_BeginRawCommandList(queue_kind); + GPU_D12_RawCommandList *dx12_cl = GPU_D12_PrepareRawCommandList(queue_kind); ID3D12GraphicsCommandList *rcl = dx12_cl->cl; /* Pipeline state */ @@ -1343,7 +1450,10 @@ void GPU_CloseCommandList(GPU_CommandListHandle cl_handle) GPU_D12_Cmd *cmd = &cmds[cmd_idx]; switch (cmd->kind) { - default: break; + default: + { + cmd_idx += 1; + } break; //- Resource barrier // case GPU_D12_CmdKind_TransitionToSrv: @@ -1451,7 +1561,7 @@ void GPU_CloseCommandList(GPU_CommandListHandle cl_handle) // cmd = cmd->next; // } - // /* Submit batched barriers */ + // /* Commit batched barriers */ // /* FIXME: Transitions from UAV -> UAV should insert UAV barrier */ // u32 barriers_count = 0; // D3D12_RESOURCE_BARRIER *rbs = PushStructs(scratch.arena, D3D12_RESOURCE_BARRIER, max_barriers_count); @@ -1543,6 +1653,14 @@ void GPU_CloseCommandList(GPU_CommandListHandle cl_handle) // cmd_idx += 1; // } break; + //- Access + + case GPU_D12_CmdKind_Access: + { + /* TODO */ + cmd_idx += 1; + } break; + //- Dispatch compute shader case GPU_D12_CmdKind_Compute: { @@ -1558,7 +1676,10 @@ void GPU_CloseCommandList(GPU_CommandListHandle cl_handle) /* Set descriptor heaps */ if (!descriptor_heaps_set) { - ID3D12DescriptorHeap *heaps[] = { g->cbv_srv_uav_heap.d3d_heap, g->sampler_heap.d3d_heap }; + ID3D12DescriptorHeap *heaps[] = { + g->descriptor_heaps[GPU_D12_DescriptorHeapKind_CbvSrvUav].d3d_heap, + g->descriptor_heaps[GPU_D12_DescriptorHeapKind_Sampler].d3d_heap, + }; ID3D12GraphicsCommandList_SetDescriptorHeaps(rcl, countof(heaps), heaps); descriptor_heaps_set = 1; } @@ -1643,7 +1764,10 @@ void GPU_CloseCommandList(GPU_CommandListHandle cl_handle) /* Set descriptor heaps */ if (!descriptor_heaps_set) { - ID3D12DescriptorHeap *heaps[] = { g->cbv_srv_uav_heap.d3d_heap, g->sampler_heap.d3d_heap }; + ID3D12DescriptorHeap *heaps[] = { + g->descriptor_heaps[GPU_D12_DescriptorHeapKind_CbvSrvUav].d3d_heap, + g->descriptor_heaps[GPU_D12_DescriptorHeapKind_Sampler].d3d_heap, + }; ID3D12GraphicsCommandList_SetDescriptorHeaps(rcl, countof(heaps), heaps); descriptor_heaps_set = 1; } @@ -1771,7 +1895,7 @@ void GPU_CloseCommandList(GPU_CommandListHandle cl_handle) { GPU_D12_Descriptor *descriptor = cmd->clear_rtv.rtv_descriptor; GPU_D12_Resource *resource = descriptor->resource; - Assert(resource->layout == D3D12_BARRIER_LAYOUT_RENDER_TARGET); + Assert(resource->texture_layout == D3D12_BARRIER_LAYOUT_RENDER_TARGET); f32 clear_color[4] = ZI; clear_color[0] = resource->texture_desc.clear_color.x; clear_color[1] = resource->texture_desc.clear_color.y; @@ -1785,7 +1909,7 @@ void GPU_CloseCommandList(GPU_CommandListHandle cl_handle) } /* End dx12 command list */ - u64 fence_target = GPU_D12_EndRawCommandList(dx12_cl); + GPU_D12_CommitRawCommandList(dx12_cl); /* Free command list */ { @@ -1802,95 +1926,89 @@ void GPU_CloseCommandList(GPU_CommandListHandle cl_handle) //- Arena -void GPU_ResetArena(GPU_CommandListHandle cl, GPU_ArenaHandle arena) +void GPU_ResetArena(GPU_CommandListHandle cl_handle, GPU_ArenaHandle arena) { /* TODO */ } //- Copy -void GPU_CopyBuffer(GPU_CommandListHandle cl, GPU_ResourceHandle dst, u64 dst_offset, GPU_ResourceHandle src, u64 src_offset, u64 size) +void GPU_CopyBuffer(GPU_CommandListHandle cl_handle, GPU_ResourceHandle dst, u64 dst_offset, GPU_ResourceHandle src, u64 src_offset, u64 size) { /* TODO */ } -void GPU_CopyTexture(GPU_CommandListHandle cl, GPU_ResourceHandle dst, Vec3I32 dst_offset, GPU_ResourceHandle src, Vec3I32 src_offset, Vec3I32 dims) +void GPU_CopyTexture(GPU_CommandListHandle cl_handle, GPU_ResourceHandle dst, Vec3I32 dst_offset, GPU_ResourceHandle src, Vec3I32 src_offset, Vec3I32 dims) { /* TODO */ } //- Constants -void GPU_SetConstU32(GPU_CommandListHandle cl, i32 slot, u32 v) +void GPU_SetConstU32(GPU_CommandListHandle cl_handle, i32 slot, u32 v) { /* TODO */ } -void GPU_SetConstF32(GPU_CommandListHandle cl, i32 slot, f32 v) +void GPU_SetConstF32(GPU_CommandListHandle cl_handle, i32 slot, f32 v) { /* TODO */ } -void GPU_SetConstBufferPtr(GPU_CommandListHandle cl, i32 slot, GpuBufferPtr v) +void GPU_SetConstBuffer(GPU_CommandListHandle cl_handle, i32 slot, BufferGpuPtr v) { /* TODO */ } -void GPU_SetConstRWBufferPtr(GPU_CommandListHandle cl, i32 slot, GpuRWBufferPtr v) +void GPU_SetConstRWBuffer(GPU_CommandListHandle cl_handle, i32 slot, RWBufferGpuPtr v) { /* TODO */ } -void GPU_SetConstIndexBufferPtr(GPU_CommandListHandle cl, i32 slot, GpuIndexBufferPtr v) +void GPU_SetConstTexture1D(GPU_CommandListHandle cl_handle, i32 slot, Texture1DGpuPtr v) { /* TODO */ } -void GPU_SetConstTexture1DPtr(GPU_CommandListHandle cl, i32 slot, GpuTexture1DPtr v) +void GPU_SetConstRWTexture1D(GPU_CommandListHandle cl_handle, i32 slot, RWTexture1DGpuPtr v) { /* TODO */ } -void GPU_SetConstRWTexture1DPtr(GPU_CommandListHandle cl, i32 slot, GpuRWTexture1DPtr v) +void GPU_SetConstTexture2D(GPU_CommandListHandle cl_handle, i32 slot, Texture2DGpuPtr v) { /* TODO */ } -void GPU_SetConstTexture2DPtr(GPU_CommandListHandle cl, i32 slot, GpuTexture2DPtr v) +void GPU_SetConstRWTexture2D(GPU_CommandListHandle cl_handle, i32 slot, RWTexture2DGpuPtr v) { /* TODO */ } -void GPU_SetConstRWTexture2DPtr(GPU_CommandListHandle cl, i32 slot, GpuRWTexture2DPtr v) +void GPU_SetConstTexture3D(GPU_CommandListHandle cl_handle, i32 slot, Texture3DGpuPtr v) { /* TODO */ } -void GPU_SetConstTexture3DPtr(GPU_CommandListHandle cl, i32 slot, GpuTexture3DPtr v) +void GPU_SetConstRWTexture3D(GPU_CommandListHandle cl_handle, i32 slot, RWTexture3DGpuPtr v) { /* TODO */ } -void GPU_SetConstRWTexture3DPtr(GPU_CommandListHandle cl, i32 slot, GpuRWTexture3DPtr v) -{ - /* TODO */ -} - -void GPU_SetConstRasterTargetPtr(GPU_CommandListHandle cl, i32 slot, GpuRasterTargetPtr v) -{ - /* TODO */ -} - -void GPU_SetConstSamplerPtr(GPU_CommandListHandle cl, i32 slot, GpuSamplerPtr v) +void GPU_SetConstSampler(GPU_CommandListHandle cl_handle, i32 slot, SamplerGpuPtr v) { /* TODO */ } //- Access -void GPU_SetAccess(GPU_CommandListHandle cl, GPU_ResourceHandle handle, GPU_AccessKind kind) +void GPU_SyncAccess(GPU_CommandListHandle cl_handle, GPU_ResourceHandle handle, GPU_AccessKind kind) { - /* TODO */ + GPU_D12_CmdList *cl = GPU_D12_CmdListFromHandle(cl_handle); + GPU_D12_Cmd *cmd = GPU_D12_PushCmd(cl); + cmd->kind = GPU_D12_CmdKind_Access; + cmd->access.kind = kind; + cmd->access.resource = GPU_D12_ResourceFromHandle(handle); } //- Compute @@ -1908,8 +2026,8 @@ void GPU_Compute(GPU_CommandListHandle cl_handle, ComputeShader cs, Vec3I32 grou void GPU_Rasterize(GPU_CommandListHandle cl_handle, VertexShader vs, PixelShader ps, - u32 instances_count, GpuIndexBufferPtr idx_buff, - u32 raster_targets_count, GpuRasterTargetPtr *raster_targets, + u32 instances_count, IndexBufferGpuPtr idx_buff, + u32 raster_targets_count, RasterTargetGpuPtr *raster_targets, Rng3 viewport, Rng2 scissor, GPU_RasterMode mode) { @@ -1919,10 +2037,10 @@ void GPU_Rasterize(GPU_CommandListHandle cl_handle, cmd->rasterize.vs = vs; cmd->rasterize.ps = ps; cmd->rasterize.instances_count = instances_count; - cmd->rasterize.ibv = GPU_D12_IbvFromPtr(idx_buff); + cmd->rasterize.ibv = GPU_D12_IbvFromIbPtr(idx_buff); for (u32 i = 0; i < MinU32(raster_targets_count, GPU_MaxRasterTargets); ++i) { - cmd->rasterize.rtv_descriptors[i] = GPU_D12_RtvDescriptorFromPtr(raster_targets[i]); + cmd->rasterize.rtv_descriptors[i] = GPU_D12_DescriptorFromIndex(GPU_D12_DescriptorHeapKind_Rtv, raster_targets[i].v); } cmd->rasterize.viewport = viewport; cmd->rasterize.scissor = scissor; @@ -1931,12 +2049,13 @@ void GPU_Rasterize(GPU_CommandListHandle cl_handle, //- Clear -void GPU_ClearRasterTarget(GPU_CommandListHandle cl_handle, GpuRasterTargetPtr ptr) +void GPU_ClearRasterTarget(GPU_CommandListHandle cl_handle, RasterTargetGpuPtr ptr, Vec4 color) { GPU_D12_CmdList *cl = GPU_D12_CmdListFromHandle(cl_handle); GPU_D12_Cmd *cmd = GPU_D12_PushCmd(cl); cmd->kind = GPU_D12_CmdKind_ClearRtv; - cmd->clear_rtv.rtv_descriptor = GPU_D12_RtvDescriptorFromPtr(ptr); + cmd->clear_rtv.rtv_descriptor = GPU_D12_DescriptorFromIndex(GPU_D12_DescriptorHeapKind_Rtv, ptr.v); + cmd->clear_rtv.color = color; } //- Profile @@ -2005,6 +2124,28 @@ void GPU_ProfN(GPU_CommandListHandle cl, String name) // } // } +//////////////////////////////////////////////////////////// +//~ @hookimpl Synchronization + +void GPU_CpuWaitOnQueue(GPU_QueueKind queue_kind) +{ + GPU_D12_Queue *queue = GPU_D12_QueueFromKind(queue_kind); + u64 commit_fence_target = 0; + { + Lock lock = LockS(&queue->commit_mutex); + commit_fence_target = queue->commit_fence_target; + Unlock(&lock); + } + if (commit_fence_target > 0) + { + /* TODO: Cache event handle */ + HANDLE event = CreateEvent(0, 0, 0, 0); + ID3D12Fence_SetEventOnCompletion(queue->commit_fence, commit_fence_target, event); + WaitForSingleObject(event, INFINITE); + CloseHandle(event); + } +} + //////////////////////////////////////////////////////////// //~ @hookimpl Statistics @@ -2037,302 +2178,17 @@ GPU_Stats GPU_QuerySharedMemoryStats(void) } //////////////////////////////////////////////////////////// -//~ Swapchain helpers +//~ @hookimpl Swapchain -void GPU_D12_InitSwapchainResources(GPU_D12_Swapchain *swapchain) +GPU_SwapchainHandle GPU_AcquireSwapchain(WND_Handle window) { - // 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->d3d_resource = resource; - // sb->state = D3D12_RESOURCE_STATE_COMMON; - // } -} - -GPU_D12_SwapchainBuffer *GPU_D12_UpdateSwapchain(GPU_D12_Swapchain *swapchain, Vec2I32 resolution) -{ -#if 0 - __prof; - GPU_D12_SharedState *g = &GPU_D12_shared_state; - resolution.x = MaxI32(resolution.x, 1); - resolution.y = MaxI32(resolution.y, 1); - b32 should_rebuild = !MatchVec2I32(swapchain->resolution, resolution); - if (should_rebuild) - { - HRESULT hr = 0; - GPU_D12_Queue *queue = GPU_D12_QueueFromKind(GPU_QueueKind_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(&queue->submit_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(queue->submit_fence, queue->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]; - ID3D12Resource_Release(sb->d3d_resource); - } - - /* Resize buffers */ - hr = IDXGISwapChain_ResizeBuffers(swapchain->swapchain, 0, resolution.x, resolution.y, DXGI_FORMAT_UNKNOWN, GPU_D12_SwapchainFlags); - 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]; -#else - return 0; -#endif -} - -void GPU_D12_BlitToSwapchain(GPU_D12_SwapchainBuffer *dst, GPU_D12_Resource *texture, Vec2I32 dst_p0, Vec2I32 dst_p1, Vec2I32 src_p0, Vec2I32 src_p1, Vec4 clear_color) -{ - // GPU_D12_SharedState *g = &GPU_D12_shared_state; - - // GPU_D12_Swapchain *swapchain = dst->swapchain; - // GPU_D12_RawCommandList *dx12_cl = GPU_D12_BeginRawCommandList(GPU_QueueKind_Direct); - // ID3D12GraphicsCommandList *rcl = dx12_cl->cl; - // D3D12_RESOURCE_STATES old_texture_state = texture->state; - - // { - // u32 barriers_count = 0; - // D3D12_RESOURCE_BARRIER rbs[2] = ZI; - // /* Transition backbuffer to RENDER_TARGET */ - // { - // D3D12_RESOURCE_BARRIER *rb = &rbs[barriers_count++]; - // rb->Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - // rb->Transition.pResource = dst->d3d_resource; - // rb->Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - // rb->Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT; - // rb->Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; - // } - // ID3D12GraphicsCommandList_ResourceBarrier(rcl, barriers_count, rbs); - // } - - // /* Clear */ - // { - // f32 clear_color_arr[4] = { clear_color.x, clear_color.y, clear_color.z, clear_color.w }; - // ID3D12GraphicsCommandList_ClearRenderTargetView(rcl, dst->rtv_descriptor->handle, clear_color_arr, 0, 0); - // } - - // { - // u32 barriers_count = 0; - // D3D12_RESOURCE_BARRIER rbs[2] = ZI; - // /* Transition backbuffer to COPY_DEST */ - // { - // D3D12_RESOURCE_BARRIER *rb = &rbs[barriers_count++]; - // rb->Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - // rb->Transition.pResource = dst->d3d_resource; - // rb->Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - // rb->Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; - // rb->Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST; - // } - // /* Transition texture to COPY_SRC */ - // if (texture->state != D3D12_RESOURCE_STATE_COPY_SOURCE) - // { - // D3D12_RESOURCE_BARRIER *rb = &rbs[barriers_count++]; - // rb->Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - // rb->Transition.pResource = texture->d3d_resource; - // rb->Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - // rb->Transition.StateBefore = texture->state; - // rb->Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE; - // texture->state = rb->Transition.StateAfter; - // } - // ID3D12GraphicsCommandList_ResourceBarrier(rcl, barriers_count, rbs); - // } - - // /* Copy */ - // { - // D3D12_TEXTURE_COPY_LOCATION dst_loc = ZI; - // dst_loc.pResource = dst->d3d_resource; - // dst_loc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - // dst_loc.SubresourceIndex = 0; - - // D3D12_TEXTURE_COPY_LOCATION src_loc = ZI; - // src_loc.pResource = texture->d3d_resource; - // src_loc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - // src_loc.SubresourceIndex = 0; - - // Vec2I32 dst_size = swapchain->resolution; - - // i32 dst_top = dst_p0.y; - // i32 dst_left = dst_p0.x; - - // i32 src_left = src_p0.x; - // i32 src_top = src_p0.y; - // i32 src_right = src_p1.x; - // i32 src_bottom = src_p1.y; - - // /* Clamp copy src & dst */ - // if (dst_left < 0) - // { - // src_left -= dst_left; - // dst_left = 0; - // } - // if (dst_top < 0) - // { - // src_top -= dst_top; - // dst_top = 0; - // } - // if (dst_left + (src_left + src_right) > dst_size.x) - // { - // src_right -= (dst_left + (src_left + src_right)) - dst_size.x; - // } - // if (dst_top + (src_top + src_bottom) > dst_size.y) - // { - // src_bottom -= (dst_top + (src_top + src_bottom)) - dst_size.y; - // } - - // if (src_left < src_right && src_bottom > src_top) - // { - // D3D12_BOX src_box = ZI; - // src_box.left = src_left; - // src_box.top = src_top; - // src_box.right = src_right; - // src_box.bottom = src_bottom; - // src_box.back = 1; - // ID3D12GraphicsCommandList_CopyTextureRegion(rcl, &dst_loc, dst_left, dst_top, 0, &src_loc, &src_box); - // } - // } - - // { - // u32 barriers_count = 0; - // D3D12_RESOURCE_BARRIER rbs[2] = ZI; - // /* Transition backbuffer to PRESENT */ - // { - // D3D12_RESOURCE_BARRIER *rb = &rbs[barriers_count++]; - // rb->Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - // rb->Transition.pResource = dst->d3d_resource; - // rb->Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - // rb->Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; - // rb->Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT; - // } - // /* Transition texture to original state */ - // if (texture->state != old_texture_state) - // { - // D3D12_RESOURCE_BARRIER *rb = &rbs[barriers_count++]; - // rb->Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; - // rb->Transition.pResource = texture->d3d_resource; - // rb->Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - // rb->Transition.StateBefore = texture->state; - // rb->Transition.StateAfter = old_texture_state; - // texture->state = rb->Transition.StateAfter; - // } - // ID3D12GraphicsCommandList_ResourceBarrier(rcl, barriers_count, rbs); - // } -} - -//////////////////////////////////////////////////////////// -//~ @hookimpl Swapchain operations - -GPU_SwapchainHandle GPU_AcquireSwapchain(WND_Handle window, GPU_Format format, Vec2I32 size) -{ -#if 0 - GPU_D12_SharedState *g = &GPU_D12_shared_state; - HRESULT hr = 0; - HWND hwnd = WND_W32_WindowFromHandle(window)->hwnd; - GPU_D12_Queue *queue = GPU_D12_QueueFromKind(GPU_QueueKind_Direct); - GPU_D12_Swapchain *swapchain = 0; - { - Lock lock = LockE(&g->free_swapchains_mutex); - { - swapchain = g->first_free_swapchain; - if (swapchain) - { - g->first_free_swapchain = swapchain->next; - } - } - Unlock(&lock); - } - if (!swapchain) { Arena *perm = PermArena(); - PushAlign(perm, CachelineSize); - swapchain = PushStructNoZero(perm, GPU_D12_Swapchain); - PushAlign(perm, CachelineSize); + swapchain = PushStruct(perm, GPU_D12_Swapchain); } - ZeroStruct(swapchain); - swapchain->format = format; - - /* Create swapchain1 */ - IDXGISwapChain1 *swapchain1 = 0; - { - DXGI_SWAP_CHAIN_DESC1 desc = ZI; - desc.Format = GPU_D12_DxgiFormatFromGpuFormat(format); - desc.Width = MaxI32(size.x, 1); - desc.Height = MaxI32(size.y, 1); - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.BufferUsage = DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT; - desc.BufferCount = GPU_D12_SwapchainBufferCount; - desc.Scaling = DXGI_SCALING_NONE; - desc.Flags = GPU_D12_SwapchainFlags; - desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; - desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - hr = IDXGIFactory2_CreateSwapChainForHwnd(g->factory, (IUnknown *)queue->d3d_queue, 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 GPU_D12_FrameLatency > 0 - IDXGISwapChain3_SetMaximumFrameLatency(swapchain->swapchain, GPU_D12_FrameLatency); - 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->window_hwnd = hwnd; - - GPU_D12_InitSwapchainResources(swapchain); - + swapchain->window_hwnd = (HWND)WND_OsHandleFromWindow(window); return (GPU_SwapchainHandle) { .v = (u64)swapchain }; -#else - return (GPU_SwapchainHandle) { 0 }; -#endif } void GPU_ReleaseSwapchain(GPU_SwapchainHandle swapchain_handle) @@ -2340,63 +2196,205 @@ void GPU_ReleaseSwapchain(GPU_SwapchainHandle swapchain_handle) /* TODO */ } -void GPU_YieldOnSwapchain(GPU_SwapchainHandle swapchain_handle) +GPU_ResourceHandle GPU_PrepareBackbuffer(GPU_SwapchainHandle swapchain_handle, GPU_Format format, Vec2I32 size) { - /* TODO: Actually yield, don't block */ - // GPU_D12_Swapchain *swapchain = GPU_D12_SwapchainFromHandle(swapchain_handle); - // if (swapchain->waitable) - // { - // WaitForSingleObjectEx(swapchain->waitable, 1000, 1); - // } + GPU_D12_SharedState *g = &GPU_D12_shared_state; + GPU_D12_Swapchain *swapchain = GPU_D12_SwapchainFromHandle(swapchain_handle); + size = VEC2I32(MaxI32(size.x, 1), MaxI32(size.y, 1)); + GPU_D12_Queue *direct_queue = GPU_D12_QueueFromKind(GPU_QueueKind_Direct); + + + /* Initialize swapchain */ + if (!swapchain->d3d_swapchain) + { + HRESULT hr = 0; + + /* Create d3d swapchain */ + { + IDXGISwapChain3 *swapchain3 = 0; + { + /* Create swapchain1 */ + IDXGISwapChain1 *swapchain1 = 0; + if (SUCCEEDED(hr)) + { + DXGI_SWAP_CHAIN_DESC1 desc = ZI; + desc.Format = GPU_D12_DxgiFormatFromGpuFormat(format); + desc.Width = size.x; + desc.Height = size.y; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + desc.BufferCount = GPU_D12_SwapchainBufferCount; + desc.Scaling = DXGI_SCALING_NONE; + desc.Flags = GPU_D12_SwapchainFlags; + desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; + desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + hr = IDXGIFactory2_CreateSwapChainForHwnd(g->factory, (IUnknown *)direct_queue->d3d_queue, swapchain->window_hwnd, &desc, 0, 0, &swapchain1); + } + + /* Upgrade to swapchain3 */ + if (SUCCEEDED(hr)) + { + hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void **)&swapchain3); + IDXGISwapChain1_Release(swapchain1); + } + + + } + swapchain->d3d_swapchain = swapchain3; + swapchain->backbuffers_format = format; + swapchain->backbuffers_resolution = size; + } + + /* Create waitable object */ + { + HANDLE waitable = 0; + if (SUCCEEDED(hr) && GPU_D12_FrameLatency > 0) + { + hr = IDXGISwapChain3_SetMaximumFrameLatency(swapchain->d3d_swapchain, GPU_D12_FrameLatency); + waitable = IDXGISwapChain2_GetFrameLatencyWaitableObject(swapchain->d3d_swapchain); + } + swapchain->waitable = waitable; + } + + /* Create present fence */ + { + HANDLE present_event = 0; + ID3D12Fence *present_fence = 0; + if (SUCCEEDED(hr)) + { + present_event = CreateEvent(0, 0, 0, 0); + hr = ID3D12Device_CreateFence(g->device, 0, 0, &IID_ID3D12Fence, (void **)&present_fence); + } + swapchain->present_fence = present_fence; + swapchain->present_event = present_event; + } + + /* Disable Alt+Enter */ + IDXGIFactory_MakeWindowAssociation(g->factory, swapchain->window_hwnd, DXGI_MWA_NO_ALT_ENTER); + + if (FAILED(hr)) + { + Panic(Lit("Failed to create swapchain")); + } + } + + /* Resize backbuffers */ + if (!MatchVec2I32(swapchain->backbuffers_resolution, size) || swapchain->backbuffers_format != format) + { + HRESULT hr = 0; + + /* Wait for any previous backbuffer commands to finish */ + { + ID3D12Fence_SetEventOnCompletion(swapchain->present_fence, swapchain->present_fence_target, swapchain->present_event); + WaitForSingleObject(swapchain->present_event, INFINITE); + } + + /* Release backbuffers */ + for (u32 i = 0; i < countof(swapchain->backbuffers); ++i) + { + GPU_D12_Resource *backbuffer = &swapchain->backbuffers[i]; + if (backbuffer->d3d_resource) + { + ID3D12Resource_Release(backbuffer->d3d_resource); + backbuffer->d3d_resource = 0; + } + } + + /* Resize buffers */ + hr = IDXGISwapChain_ResizeBuffers(swapchain->d3d_swapchain, 0, size.x, size.y, DXGI_FORMAT_UNKNOWN, GPU_D12_SwapchainFlags); + if (FAILED(hr)) + { + /* TODO: Don't panic */ + Panic(Lit("Failed to resize swapchain")); + } + } + + /* Initialize backbuffers */ + { + for (u32 i = 0; i < countof(swapchain->backbuffers); ++i) + { + GPU_D12_Resource *backbuffer = &swapchain->backbuffers[i]; + if (!backbuffer->d3d_resource) + { + ID3D12Resource *d3d_resource = 0; + HRESULT hr = IDXGISwapChain3_GetBuffer(swapchain->d3d_swapchain, i, &IID_ID3D12Resource, (void **)&d3d_resource); + if (FAILED(hr)) + { + /* TODO: Don't panic */ + Panic(Lit("Failed to get swapchain buffer")); + } + ZeroStruct(backbuffer); + backbuffer->d3d_resource = d3d_resource; + backbuffer->is_texture = 1; + backbuffer->texture_layout = D3D12_BARRIER_LAYOUT_PRESENT; + backbuffer->swapchain = swapchain; + { + backbuffer->texture_desc.kind = GPU_TextureKind_2D; + backbuffer->texture_desc.format = format; + backbuffer->texture_desc.dims = VEC3I32(size.x, size.y, 1); + backbuffer->texture_desc.flags = GPU_TextureFlag_AllowRasterTarget; + backbuffer->texture_desc.initial_access = GPU_AccessKind_Present; + backbuffer->texture_desc.mip_levels = 1; + } + } + } + swapchain->backbuffers_format = format; + swapchain->backbuffers_resolution = size; + } + + /* Wait for available backbuffer */ + if (swapchain->waitable) + { + DWORD wait_result = WaitForSingleObject(swapchain->waitable, 500); + if (wait_result == WAIT_TIMEOUT) + { + ID3D12Fence_SetEventOnCompletion(swapchain->present_fence, swapchain->present_fence_target, swapchain->present_event); + WaitForSingleObject(swapchain->present_event, INFINITE); + } + } + + /* Grab current backbuffer */ + GPU_D12_Resource *cur_backbuffer = 0; + { + u32 backbuffer_idx = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain->d3d_swapchain); + cur_backbuffer = &swapchain->backbuffers[backbuffer_idx]; + } + + return (GPU_ResourceHandle) { .v = (u64)cur_backbuffer }; } -void GPU_PresentSwapchain(GPU_SwapchainHandle swapchain, Vec4 dst_clear_color, - Vec2U32 dst_size, Vec2U32 dst_offset, - GpuTexture2DPtr src_handle, Vec2U32 src_offset, - i32 vsync) +void GPU_CommitBackbuffer(GPU_ResourceHandle backbuffer_handle, i32 vsync) { - // GPU_D12_Swapchain *swapchain = GPU_D12_SwapchainFromHandle(swapchain_handle); - // GPU_D12_Resource *src = ; - // GPU_D12_SwapchainBuffer *swapchain_buffer = GPU_D12_UpdateSwapchain(swapchain, backbuffer_size); + GPU_D12_Resource *backbuffer = GPU_D12_ResourceFromHandle(backbuffer_handle); + GPU_D12_Swapchain *swapchain = backbuffer->swapchain; + GPU_D12_Queue *direct_queue = GPU_D12_QueueFromKind(GPU_QueueKind_Direct); - // D3D12_RESOURCE_DESC src_desc = ZI; - // D3D12_RESOURCE_DESC dst_desc = ZI; - // ID3D12Resource_GetDesc(src->d3d_resource, &src_desc); - // ID3D12Resource_GetDesc(swapchain_buffer->d3d_resource, &dst_desc); + u32 present_flags = 0; + if (GPU_D12_TearingIsAllowed && vsync == 0) + { + present_flags |= DXGI_PRESENT_ALLOW_TEARING; + } - // b32 is_blitable = src_desc.Dimension == dst_desc.Dimension - // && src_desc.SampleDesc.Count == dst_desc.SampleDesc.Count - // && src_desc.SampleDesc.Quality == dst_desc.SampleDesc.Quality; - // Assert(is_blitable == 1); /* Texture resource must be similar enough to backbuffer resource to blit */ + /* Present */ + { + __profn("Present"); + HRESULT hr = IDXGISwapChain3_Present(swapchain->d3d_swapchain, vsync, present_flags); + if (!SUCCEEDED(hr)) + { + Assert(0); + } + } - // i64 fence_target = 0; - // if (is_blitable) - // { - // /* Blit */ - // fence_target = GPU_D12_BlitToSwapchain(swapchain_buffer, src, dst_p0, dst_p1, src_p0, src_p1, clear_color); + if (vsync != 0 && !(present_flags & DXGI_PRESENT_ALLOW_TEARING)) + { + /* FIXME: Don't flush in fullscreen mode? */ + // DwmFlush(); + } - // u32 present_flags = 0; - // if (GPU_D12_TearingIsAllowed && vsync == 0) - // { - // present_flags |= DXGI_PRESENT_ALLOW_TEARING; - // } - - // if (vsync != 0) - // { - // /* FIXME: Don't flush in fullscreen mode? */ - // // DwmFlush(); - // } - - // /* Present */ - // { - // __profn("Present"); - // HRESULT hr = IDXGISwapChain3_Present(swapchain->swapchain, vsync, present_flags); - // if (!SUCCEEDED(hr)) - // { - // Assert(0); - // } - // } - // } - - // return fence_target; + /* Increment swapchain fence */ + { + u64 target = ++swapchain->present_fence_target; + ID3D12CommandQueue_Signal(direct_queue->d3d_queue, swapchain->present_fence, target); + } } diff --git a/src/gpu/gpu_dx12/gpu_dx12.h b/src/gpu/gpu_dx12/gpu_dx12.h index d2f4ad2c..bff52de5 100644 --- a/src/gpu/gpu_dx12/gpu_dx12.h +++ b/src/gpu/gpu_dx12/gpu_dx12.h @@ -24,14 +24,6 @@ #define GPU_D12_MaxSamplerDescriptors (1024 * 1) #define GPU_D12_MaxRtvDescriptors (1024 * 64) -//////////////////////////////////////////////////////////// -//~ Arena types - -Struct(GPU_D12_Arena) -{ - i32 _; -}; - //////////////////////////////////////////////////////////// //~ Pipeline types @@ -67,23 +59,18 @@ Struct(GPU_D12_PipelineBin) //////////////////////////////////////////////////////////// //~ Descriptor types -Struct(GPU_D12_Descriptor) +Enum(GPU_D12_DescriptorHeapKind) { - GPU_D12_Descriptor *next_free; + GPU_D12_DescriptorHeapKind_CbvSrvUav, + GPU_D12_DescriptorHeapKind_Rtv, + GPU_D12_DescriptorHeapKind_Sampler, - struct GPU_D12_DescriptorHeap *heap; - struct GPU_D12_Resource *resource; - - b32 valid; - u32 index; - D3D12_CPU_DESCRIPTOR_HANDLE handle; -} extern Readonly GPU_D12_NilDescriptor = { - .index = U32Max + GPU_D12_DescriptorHeapKind_Count }; Struct(GPU_D12_DescriptorHeap) { - Arena *arena; + Arena *descriptors_arena; D3D12_DESCRIPTOR_HEAP_TYPE type; u32 descriptor_size; @@ -91,49 +78,60 @@ Struct(GPU_D12_DescriptorHeap) D3D12_CPU_DESCRIPTOR_HANDLE start_handle; Mutex mutex; - GPU_D12_Descriptor *first_free; + struct GPU_D12_Descriptor *first_free; u32 allocated_count; u32 max_count; }; +Struct(GPU_D12_Descriptor) +{ + GPU_D12_Descriptor *next; + u64 queue_commit_target; + + GPU_D12_DescriptorHeap *heap; + D3D12_CPU_DESCRIPTOR_HANDLE handle; + u32 index; + + struct GPU_D12_Resource *resource; +}; + +Struct(GPU_D12_DescriptorList) +{ + GPU_D12_Descriptor *first; + GPU_D12_Descriptor *last; +}; + +//////////////////////////////////////////////////////////// +//~ Arena types + +Struct(GPU_D12_Arena) +{ + GPU_D12_DescriptorList committed_descriptors_by_heap_and_queue[GPU_D12_DescriptorHeapKind_Count][GPU_NumQueues]; +}; + //////////////////////////////////////////////////////////// //~ Resource types Struct(GPU_D12_Resource) { GPU_D12_Resource *next_free; - ID3D12Resource *d3d_resource; - D3D12_BARRIER_LAYOUT layout; - /* Buffer info */ GPU_BufferDesc buffer_desc; D3D12_GPU_VIRTUAL_ADDRESS buffer_gpu_address; /* Texture info */ b32 is_texture; + D3D12_BARRIER_LAYOUT texture_layout; GPU_TextureDesc texture_desc; -}; -Struct(GPU_D12_ResourceReuseList) -{ - u64 hash; - GPU_D12_ResourceReuseList *next; - GPU_D12_ResourceReuseList *prev; - GPU_D12_Resource *first; -}; - -Struct(GPU_D12_ResourceReuseListBin) -{ - Mutex mutex; - GPU_D12_ResourceReuseList *first; - GPU_D12_ResourceReuseList *last; - GPU_D12_ResourceReuseList *first_free; + /* Backbuffer info */ + struct GPU_D12_Swapchain *swapchain; }; //////////////////////////////////////////////////////////// -//~ Queue types +//~ Command queue types Struct(GPU_D12_CommandQueueDesc) { @@ -146,11 +144,11 @@ Struct(GPU_D12_Queue) ID3D12CommandQueue *d3d_queue; GPU_D12_CommandQueueDesc desc; - Mutex submit_mutex; - ID3D12Fence *submit_fence; - u64 submit_fence_target; - struct GPU_D12_RawCommandList *first_submitted_cl; - struct GPU_D12_RawCommandList *last_submitted_cl; + Mutex commit_mutex; + ID3D12Fence *commit_fence; + u64 commit_fence_target; + struct GPU_D12_RawCommandList *first_committed_cl; + struct GPU_D12_RawCommandList *last_committed_cl; Fence sync_fence; }; @@ -163,7 +161,7 @@ Struct(GPU_D12_RawCommandList) GPU_D12_Queue *queue; GPU_D12_RawCommandList *next; - u64 submit_fence_target; + u64 commit_fence_target; ID3D12CommandAllocator *ca; ID3D12GraphicsCommandList *cl; @@ -179,10 +177,10 @@ Enum(GPU_D12_CmdKind) GPU_D12_CmdKind_None, /* Access */ - GPU_D12_CmdKind_SetAccess, + GPU_D12_CmdKind_Access, /* Constant */ - GPU_D12_CmdKind_SetConstant, + GPU_D12_CmdKind_Constant, /* Copy */ GPU_D12_CmdKind_Copy, @@ -204,8 +202,8 @@ Struct(GPU_D12_Cmd) { struct { + GPU_AccessKind kind; GPU_D12_Resource *resource; - GPU_AccessKind access_kind; } access; struct @@ -253,6 +251,7 @@ Struct(GPU_D12_Cmd) struct { GPU_D12_Descriptor *rtv_descriptor; + Vec4 color; } clear_rtv; }; }; @@ -273,31 +272,25 @@ Struct(GPU_D12_CmdList) GPU_D12_CmdChunk *last_cmd_chunk; u64 chunks_count; u64 cmds_count; - - GPU_QueueKind queue_kind; }; //////////////////////////////////////////////////////////// //~ Swapchain types -Struct(GPU_D12_SwapchainBuffer) -{ - struct GPU_D12_Swapchain *swapchain; - ID3D12Resource *d3d_resource; - D3D12_RESOURCE_STATES state; -}; - Struct(GPU_D12_Swapchain) { - GPU_D12_Swapchain *next; - GPU_Format format; - IDXGISwapChain3 *swapchain; + IDXGISwapChain3 *d3d_swapchain; HWND window_hwnd; HANDLE waitable; - Vec2I32 resolution; - GPU_D12_SwapchainBuffer buffers[GPU_D12_SwapchainBufferCount]; + HANDLE present_event; + ID3D12Fence *present_fence; + u64 present_fence_target; + + GPU_Format backbuffers_format; + Vec2I32 backbuffers_resolution; + GPU_D12_Resource backbuffers[GPU_D12_SwapchainBufferCount]; }; //////////////////////////////////////////////////////////// @@ -314,17 +307,15 @@ Struct(GPU_D12_SharedState) /* Queues */ GPU_D12_Queue queues[GPU_NumQueues]; + /* Descriptor heaps */ + GPU_D12_DescriptorHeap descriptor_heaps[GPU_D12_DescriptorHeapKind_Count]; + /* Rootsig */ ID3D12RootSignature *bindless_rootsig; /* Pipelines */ GPU_D12_PipelineBin pipeline_bins[1024]; - /* Descriptor heaps */ - GPU_D12_DescriptorHeap cbv_srv_uav_heap; - GPU_D12_DescriptorHeap sampler_heap; - GPU_D12_DescriptorHeap rtv_heap; - /* Command lists */ Mutex free_cmd_lists_mutex; GPU_D12_CmdList *first_free_cmd_list; @@ -358,44 +349,35 @@ GPU_D12_Resource *GPU_D12_ResourceFromHandle(GPU_ResourceHandle handle); GPU_D12_Swapchain *GPU_D12_SwapchainFromHandle(GPU_SwapchainHandle handle); //////////////////////////////////////////////////////////// -//~ Pipeline operations +//~ Pipeline JobDecl(GPU_D12_LoadPipeline, { GPU_D12_Pipeline *pipeline; }); GPU_D12_Pipeline *GPU_D12_PipelineFromDesc(GPU_D12_PipelineDesc desc); //////////////////////////////////////////////////////////// -//~ Queue operations +//~ Queue GPU_D12_Queue *GPU_D12_QueueFromKind(GPU_QueueKind kind); //////////////////////////////////////////////////////////// -//~ Descriptor operations +//~ Resource helpers -GPU_D12_Descriptor *GPU_D12_AcquireDescriptor(GPU_D12_DescriptorHeap *heap); -void GPU_D12_ReleaseDescriptor(GPU_D12_Descriptor *descriptor); - -GPU_D12_Descriptor *GPU_D12_RtvDescriptorFromPtr(GpuRasterTargetPtr ptr); -D3D12_INDEX_BUFFER_VIEW GPU_D12_IbvFromPtr(GpuIndexBufferPtr ptr); +GPU_D12_Descriptor *GPU_D12_PushDescriptor(GPU_D12_Arena *gpu_arena, GPU_D12_Resource *resource, GPU_D12_DescriptorHeapKind heap_kind); +GPU_D12_Descriptor *GPU_D12_DescriptorFromIndex(GPU_D12_DescriptorHeapKind heap_kind, u32 index); +D3D12_INDEX_BUFFER_VIEW GPU_D12_IbvFromIbPtr(IndexBufferGpuPtr ptr); //////////////////////////////////////////////////////////// -//~ Raw command list operations +//~ Raw command list -GPU_D12_RawCommandList *GPU_D12_BeginRawCommandList(GPU_QueueKind queue_kind); -u64 GPU_D12_EndRawCommandList(GPU_D12_RawCommandList *cl); +GPU_D12_RawCommandList *GPU_D12_PrepareRawCommandList(GPU_QueueKind queue_kind); +void GPU_D12_CommitRawCommandList(GPU_D12_RawCommandList *cl); //////////////////////////////////////////////////////////// //~ Command helpers GPU_D12_Cmd *GPU_D12_PushCmd(GPU_D12_CmdList *cl); -//////////////////////////////////////////////////////////// -//~ Swapchain helpers - -void GPU_D12_InitSwapchainResources(GPU_D12_Swapchain *swapchain); -GPU_D12_SwapchainBuffer *GPU_D12_UpdateSwapchain(GPU_D12_Swapchain *swapchain, Vec2I32 resolution); -void GPU_D12_BlitToSwapchain(GPU_D12_SwapchainBuffer *dst, GPU_D12_Resource *texture, Vec2I32 dst_p0, Vec2I32 dst_p1, Vec2I32 src_p0, Vec2I32 src_p1, Vec4 clear_color); - //////////////////////////////////////////////////////////// //~ Sync job -JobDecl(GPU_D12_StartQueueSync, EmptySig); +// JobDecl(GPU_D12_StartQueueSync, EmptySig); diff --git a/src/gpu/gpu_dx12/gpu_dx12.lay b/src/gpu/gpu_dx12/gpu_dx12.lay index ffd9189f..47557a18 100644 --- a/src/gpu/gpu_dx12/gpu_dx12.lay +++ b/src/gpu/gpu_dx12/gpu_dx12.lay @@ -1,8 +1,5 @@ @Layer gpu_dx12 -//- Dependencies -@Dep window_win32 - //- Api @IncludeC gpu_dx12.h diff --git a/src/proto/proto.c b/src/proto/proto.c index 14819158..17375eb8 100644 --- a/src/proto/proto.c +++ b/src/proto/proto.c @@ -1,3 +1,43 @@ void PR_Startup(void) { + GPU_ArenaHandle gpu_frame_arena = GPU_AcquireArena(); + + b32 swapchain_initialized = 0; + GPU_SwapchainHandle swapchain = ZI; + + for (;;) + { + WND_Frame window_frame = WND_BeginFrame(); + { + if (!swapchain_initialized) + { + swapchain_initialized = 1; + swapchain = GPU_AcquireSwapchain(window_frame.window); + } + + GPU_ResourceHandle backbuffer = GPU_PrepareBackbuffer(swapchain, GPU_Format_R16G16B16A16_Float, window_frame.draw_size); + { + /* Draw to backbuffer */ + GPU_CommandListHandle cl = GPU_PrepareCommandList(); + { + RasterTargetGpuPtr backbuffer_rt = GPU_PushRasterTargetPtr(gpu_frame_arena, backbuffer); + + /* Clear backbuffer */ + { + GPU_SyncAccess(cl, backbuffer, GPU_AccessKind_RasterTarget); + GPU_ClearRasterTarget(cl, backbuffer_rt, VEC4(1, 0, 0, 1)); + } + + /* Make backbuffer presentable */ + GPU_SyncAccess(cl, backbuffer, GPU_AccessKind_Present); + + /* Reset */ + GPU_ResetArena(cl, gpu_frame_arena); + } + GPU_CommitCommandList(cl, GPU_QueueKind_Direct); + } + GPU_CommitBackbuffer(backbuffer, VSYNC); + } + WND_EndFrame(window_frame); + } } diff --git a/src/proto/proto.lay b/src/proto/proto.lay index e68376b9..81ad5541 100644 --- a/src/proto/proto.lay +++ b/src/proto/proto.lay @@ -3,6 +3,7 @@ //- Dependencies @Dep gpu +@Dep window //- Impl diff --git a/src/window/window.h b/src/window/window.h index 30304650..16346b68 100644 --- a/src/window/window.h +++ b/src/window/window.h @@ -31,14 +31,13 @@ Struct(WND_Cmd) Struct(WND_Frame) { - WND_Handle window_handle; + WND_Handle window; - /* User input since last update */ ControllerEventsArray controller_events; - /* Window info */ Vec2I32 draw_size; Vec2I32 monitor_size; + String restore; b32 minimized; b32 maximized; @@ -53,7 +52,12 @@ Struct(WND_Frame) void WND_Startup(void); //////////////////////////////////////////////////////////// -//~ @hookdecl Command operations +//~ @hookdecl Helpers + +u64 WND_OsHandleFromWindow(WND_Handle window); + +//////////////////////////////////////////////////////////// +//~ @hookdecl Command #define WND_PushCmd(frame, ...) WND_PushCmd_((frame), (WND_Cmd) { __VA_ARGS__ }) void WND_PushCmd_(WND_Frame frame, WND_Cmd desc); diff --git a/src/window/window_win32/window_win32.c b/src/window/window_win32/window_win32.c index f339bc29..f8793342 100644 --- a/src/window/window_win32/window_win32.c +++ b/src/window/window_win32/window_win32.c @@ -108,7 +108,7 @@ JobImpl(WND_W32_ProcessMessagesForever, sig, id) WND_W32_Window *window = &g->window; window->w2u_events_arena = AcquireArena(Gibi(64)); - //- Init hwnd + //- Initialize hwnd HWND hwnd = 0; { /* @@ -385,11 +385,20 @@ LRESULT CALLBACK WND_W32_WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM l } //////////////////////////////////////////////////////////// -//~ @hookimpl Cmds +//~ @hookimpl Helpers + +u64 WND_OsHandleFromWindow(WND_Handle handle) +{ + WND_W32_Window *window = WND_W32_WindowFromHandle(handle); + return (u64)window->hwnd; +} + +//////////////////////////////////////////////////////////// +//~ @hookimpl Command void WND_PushCmd_(WND_Frame frame, WND_Cmd desc) { - WND_W32_Window *window = WND_W32_WindowFromHandle(frame.window_handle); + WND_W32_Window *window = WND_W32_WindowFromHandle(frame.window); WND_W32_CmdNode *n = PushStruct(window->frame_arena, WND_W32_CmdNode); n->cmd = desc; SllQueuePush(window->first_cmd, window->last_cmd, n); @@ -413,7 +422,7 @@ WND_Frame WND_BeginFrame(void) _mm_pause(); } HWND hwnd = window->hwnd; - result.window_handle.v = (u64)window; + result.window.v = (u64)window; /* Reset per-frame data */ if (!window->frame_arena) @@ -515,7 +524,7 @@ void WND_EndFrame(WND_Frame frame) { TempArena scratch = BeginScratchNoConflict(); WND_W32_SharedState *g = &WND_W32_shared_state; - WND_W32_Window *window = WND_W32_WindowFromHandle(frame.window_handle); + WND_W32_Window *window = WND_W32_WindowFromHandle(frame.window); HWND hwnd = window->hwnd; /* Process cmds */