From f241379dba99f7d35ae0b0179ac667dfe57a9f8a Mon Sep 17 00:00:00 2001 From: jacob Date: Sat, 13 Dec 2025 16:04:21 -0600 Subject: [PATCH] unify gpu resource creation codepath --- src/base/base_math.c | 17 +- src/base/base_math.h | 2 + src/gpu/gpu_common.c | 12 +- src/gpu/gpu_common.h | 4 +- src/gpu/gpu_core.h | 180 +++++----- src/gpu/gpu_dx12/gpu_dx12_core.c | 585 +++++++++++++++---------------- src/gpu/gpu_dx12/gpu_dx12_core.h | 41 ++- src/ttf/ttf_dwrite/ttf_dwrite.c | 2 +- src/ui/ui_core.c | 4 +- 9 files changed, 427 insertions(+), 420 deletions(-) diff --git a/src/base/base_math.c b/src/base/base_math.c index c7d2ee89..4c35f043 100644 --- a/src/base/base_math.c +++ b/src/base/base_math.c @@ -1199,6 +1199,14 @@ Rng2 AddRng2Vec2(Rng2 r, Vec2 v) return result; } +Rng2 MulRng2Vec2(Rng2 r, Vec2 v) +{ + Rng2 result = ZI; + result.p0 = MulVec2Vec2(r.p0, v); + result.p1 = MulVec2Vec2(r.p1, v); + return result; +} + Rng2 DivRng2Vec2(Rng2 r, Vec2 v) { Rng2 result = ZI; @@ -1235,6 +1243,14 @@ Rng2I32 AddRng2I32Vec2I32(Rng2I32 r, Vec2I32 v) return result; } +Rng2I32 MulRng2I32Vec2I32(Rng2I32 r, Vec2I32 v) +{ + Rng2I32 result = ZI; + result.p0 = MulVec2I32Vec2I32(r.p0, v); + result.p1 = MulVec2I32Vec2I32(r.p1, v); + return result; +} + Rng2I32 DivRng2I32Vec2I32(Rng2I32 r, Vec2I32 v) { Rng2I32 result = ZI; @@ -1243,7 +1259,6 @@ Rng2I32 DivRng2I32Vec2I32(Rng2I32 r, Vec2I32 v) return result; } - //////////////////////////////////////////////////////////// //~ Xform diff --git a/src/base/base_math.h b/src/base/base_math.h index 201ba97c..3cf0500c 100644 --- a/src/base/base_math.h +++ b/src/base/base_math.h @@ -394,12 +394,14 @@ u32 U32FromVec4(Vec4 v); Vec2 DimsFromRng2(Rng2 r); Rng2 UnionRng2(Rng2 a, Rng2 b); Rng2 AddRng2Vec2(Rng2 r, Vec2 v); +Rng2 MulRng2Vec2(Rng2 a, Vec2 v); Rng2 DivRng2Vec2(Rng2 a, Vec2 v); //- Rng2I32 Vec2I32 DimsFromRng2I32(Rng2I32 r); Rng2I32 UnionRng2I32(Rng2I32 a, Rng2I32 b); Rng2I32 AddRng2I32Vec2I32(Rng2I32 r, Vec2I32 v); +Rng2I32 MulRng2I32Vec2I32(Rng2I32 a, Vec2I32 v); Rng2I32 DivRng2I32Vec2I32(Rng2I32 a, Vec2I32 v); //////////////////////////////////////////////////////////// diff --git a/src/gpu/gpu_common.c b/src/gpu/gpu_common.c index 1f66e367..5e0c0c68 100644 --- a/src/gpu/gpu_common.c +++ b/src/gpu/gpu_common.c @@ -23,7 +23,7 @@ void G_BootstrapCommon(void) /* Init point sampler */ { - G_ResourceHandle pt_sampler = G_PushSampler(gpu_perm, (G_SamplerResourceDesc) { .filter = G_Filter_MinMagMipPoint }); + G_ResourceHandle pt_sampler = G_PushSampler(gpu_perm, .filter = G_Filter_MinMagMipPoint); g->basic_sampler = G_PushSamplerStateRef(gpu_perm, pt_sampler); } @@ -37,9 +37,9 @@ void G_BootstrapCommon(void) Panic(Lit("Unexpected noise texture size")); } noise_tex = G_PushTexture3D(gpu_perm, - G_Format_R16_Uint, - noise_dims, - G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present); + G_Format_R16_Uint, + noise_dims, + G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present); G_CopyCpuToTexture(cl, noise_tex, VEC3I32(0, 0, 0), noise_data.text, noise_dims, @@ -73,9 +73,9 @@ G_ArenaHandle G_PermArena(void) //- Cpu -> Gpu upload -G_ResourceHandle G_PushBufferFromString_(G_ArenaHandle gpu_arena, G_CommandListHandle cl, String src, G_BufferResourceDesc desc) +G_ResourceHandle G_PushBufferFromString_(G_ArenaHandle gpu_arena, G_CommandListHandle cl, String src, G_BufferDesc desc) { - G_ResourceHandle buffer = G_PushBufferEx(gpu_arena, desc); + G_ResourceHandle buffer = G_PushResource(gpu_arena, (G_ResourceDesc) { .kind = G_ResourceKind_Buffer, .buffer = desc }); G_CopyCpuToBuffer(cl, buffer, 0, src.text, RNGU64(0, src.len)); G_MemorySync( cl, buffer, diff --git a/src/gpu/gpu_common.h b/src/gpu/gpu_common.h index 76d3136e..2f5173b9 100644 --- a/src/gpu/gpu_common.h +++ b/src/gpu/gpu_common.h @@ -25,9 +25,9 @@ G_ArenaHandle G_PermArena(void); //- Cpu -> Gpu upload -G_ResourceHandle G_PushBufferFromString_(G_ArenaHandle gpu_arena, G_CommandListHandle cl, String src, G_BufferResourceDesc desc); +G_ResourceHandle G_PushBufferFromString_(G_ArenaHandle gpu_arena, G_CommandListHandle cl, String src, G_BufferDesc desc); #define G_PushBufferFromString(_arena, _cl, _src, ...) \ - G_PushBufferFromString_((_arena), (_cl), (_src), (G_BufferResourceDesc) { .size = (_src).len, __VA_ARGS__ }) + G_PushBufferFromString_((_arena), (_cl), (_src), (G_BufferDesc) { .size = (_src).len, __VA_ARGS__ }) //- Viewport / scissor diff --git a/src/gpu/gpu_core.h b/src/gpu/gpu_core.h index b7ce5ca0..35b723f4 100644 --- a/src/gpu/gpu_core.h +++ b/src/gpu/gpu_core.h @@ -316,52 +316,7 @@ Struct(G_MemoryBarrierDesc) }; //////////////////////////////////////////////////////////// -//~ Resource types - -Enum(G_ResourceFlag) -{ - G_ResourceFlag_None = 0, - G_ResourceFlag_AllowShaderReadWrite = (1 << 0), - G_ResourceFlag_AllowRenderTarget = (1 << 1), - G_ResourceFlag_AllowDepthStencil = (1 << 2), - G_ResourceFlag_HostMemory = (1 << 3), /* Resource will automatically be mapped into the cpu's address space */ - G_ResourceFlag_WriteCombined = (1 << 4), /* Writes into the mapped resource will be combined. Fast for linear memcpy, slow for everything else */ -}; - -//////////////////////////////////////////////////////////// -//~ Buffer types - -Struct(G_BufferResourceDesc) -{ - u64 size; - G_ResourceFlag flags; -}; - -//////////////////////////////////////////////////////////// -//~ Texture types - -#define G_MaxRenderTargets 8 - -Enum(G_TextureKind) -{ - G_TextureKind_1D, - G_TextureKind_2D, - G_TextureKind_3D, -}; - -Struct(G_TextureResourceDesc) -{ - G_TextureKind kind; - G_ResourceFlag flags; - G_Format format; - Vec3I32 dims; - G_Layout initial_layout; - i32 mip_levels; /* Will be clamped to range [1, inf) */ - Vec4 clear_color; -}; - -//////////////////////////////////////////////////////////// -//~ Sampler types +//~ Filter types /* NOTE: Matches DirectX D3D12_FILTER */ Enum(G_Filter) @@ -439,8 +394,47 @@ Enum(G_ComparisonFunc) G_ComparisonFunc_Always = 8 }; -Struct(G_SamplerResourceDesc) +//////////////////////////////////////////////////////////// +//~ Resource types + +Enum(G_ResourceKind) { + G_ResourceKind_Buffer, + G_ResourceKind_Texture1D, + G_ResourceKind_Texture2D, + G_ResourceKind_Texture3D, + G_ResourceKind_Sampler, +}; + +Enum(G_ResourceFlag) +{ + G_ResourceFlag_None = 0, + G_ResourceFlag_AllowShaderReadWrite = (1 << 0), + G_ResourceFlag_AllowRenderTarget = (1 << 1), + G_ResourceFlag_AllowDepthStencil = (1 << 2), + G_ResourceFlag_HostMemory = (1 << 3), /* Resource will be mapped into the cpu's address space */ + G_ResourceFlag_Uncached = (1 << 4), /* Cpu writes will be combined & reads will be uncached */ +}; + +Struct(G_BufferDesc) +{ + G_ResourceFlag flags; + u64 size; +}; + +Struct(G_TextureDesc) +{ + G_ResourceFlag flags; + G_Format format; + Vec3I32 dims; + G_Layout initial_layout; + i32 mip_levels; /* Will be clamped to range [1, inf) */ + Vec4 clear_color; +}; + +Struct(G_SamplerDesc) +{ + G_ResourceFlag flags; G_Filter filter; G_AddressMode x; G_AddressMode y; @@ -453,6 +447,14 @@ Struct(G_SamplerResourceDesc) f32 max_lod; }; +Struct(G_ResourceDesc) +{ + G_ResourceKind kind; + G_BufferDesc buffer; + G_TextureDesc texture; + G_SamplerDesc sampler; +}; + //////////////////////////////////////////////////////////// //~ Ref types @@ -466,6 +468,8 @@ Struct(G_RefDesc) //////////////////////////////////////////////////////////// //~ Rasterization types +#define G_MaxRenderTargets 8 + Enum(G_RasterMode) { G_RasterMode_None, @@ -519,47 +523,65 @@ void G_ReleaseArena(G_ArenaHandle arena); //- Resource creation -G_ResourceHandle G_PushBufferEx(G_ArenaHandle arena, G_BufferResourceDesc desc); -G_ResourceHandle G_PushTextureEx(G_ArenaHandle arena, G_TextureResourceDesc desc); -G_ResourceHandle G_PushSampler(G_ArenaHandle arena, G_SamplerResourceDesc desc); +G_ResourceHandle G_PushResource(G_ArenaHandle arena, G_ResourceDesc desc); -#define G_PushBuffer(arena, type, count, ...) G_PushBufferEx((arena), \ - (G_BufferResourceDesc) { \ - .size = sizeof(type) * (count), \ - __VA_ARGS__ \ - } \ +#define G_PushBuffer(arena, _type, _count, ...) G_PushResource((arena), \ + (G_ResourceDesc) { \ + .kind = G_ResourceKind_Buffer, \ + .buffer = { \ + .size = sizeof(_type) * (_count), \ + __VA_ARGS__ \ + } \ + } \ ) -#define G_PushTexture1D(arena, _format, _size, _initial_layout, ...) G_PushTextureEx((arena), \ - (G_TextureResourceDesc) { \ - .kind = G_TextureKind_1D, \ - .format = (_format), \ - .dims = VEC3I32((_size), 1, 1), \ - .initial_layout = (_initial_layout), \ - __VA_ARGS__ \ - } \ +#define G_PushTexture1D(arena, _format, _size, _initial_layout, ...) G_PushResource((arena), \ + (G_ResourceDesc) { \ + .kind = G_ResourceKind_Texture1D, \ + .texture = { \ + .format = (_format), \ + .dims = VEC3I32((_size), 1, 1), \ + .initial_layout = (_initial_layout), \ + __VA_ARGS__ \ + } \ + } \ ) -#define G_PushTexture2D(arena, _format, _size, _initial_layout, ...) G_PushTextureEx((arena), \ - (G_TextureResourceDesc) { \ - .kind = G_TextureKind_2D, \ - .format = (_format), \ - .dims = VEC3I32((_size).x, (_size).y, 1), \ - .initial_layout = (_initial_layout), \ - __VA_ARGS__ \ - } \ +#define G_PushTexture2D(arena, _format, _size, _initial_layout, ...) G_PushResource((arena), \ + (G_ResourceDesc) { \ + .kind = G_ResourceKind_Texture2D, \ + .texture = { \ + .format = (_format), \ + .dims = VEC3I32((_size).x, (_size).y, 1), \ + .initial_layout = (_initial_layout), \ + __VA_ARGS__ \ + } \ + } \ ) -#define G_PushTexture3D(arena, _format, _size, _initial_layout, ...) G_PushTextureEx((arena), \ - (G_TextureResourceDesc) { \ - .kind = G_TextureKind_3D, \ - .format = (_format), \ - .dims = (_size), \ - .initial_layout = (_initial_layout), \ - __VA_ARGS__ \ - } \ +#define G_PushTexture3D(arena, _format, _size, _initial_layout, ...) G_PushResource((arena), \ + (G_ResourceDesc) { \ + .kind = G_ResourceKind_Texture3D, \ + .texture = { \ + .format = (_format), \ + .dims = (_size), \ + .initial_layout = (_initial_layout), \ + __VA_ARGS__ \ + } \ + } \ ) +#define G_PushSampler(arena, ...) G_PushResource((arena), \ + (G_ResourceDesc) { \ + .kind = G_ResourceKind_Sampler, \ + .sampler = { \ + .filter = G_Filter_MinMagMipPoint, \ + __VA_ARGS__ \ + } \ + } \ +) + + //- Index buffer helpers #define G_IdxBuff16(_res) ((G_IndexBufferDesc) { .resource = (_res), .index_size = 2, .index_count = (G_CountBuffer((_res), i16)) }) diff --git a/src/gpu/gpu_dx12/gpu_dx12_core.c b/src/gpu/gpu_dx12/gpu_dx12_core.c index 1ff93942..f4496b6b 100644 --- a/src/gpu/gpu_dx12/gpu_dx12_core.c +++ b/src/gpu/gpu_dx12/gpu_dx12_core.c @@ -743,111 +743,6 @@ i64 G_D12_CommitRawCommandList(G_D12_RawCommandList *cl) return completion; } -//////////////////////////////////////////////////////////// -//~ Arena - -G_D12_ResourceHeap *G_D12_ResourceHeapFromArena(G_D12_Arena *gpu_arena, G_D12_ResourceHeapKind kind) -{ - G_D12_SharedState *g = &G_D12_shared_state; - G_D12_ResourceHeap *heap = &gpu_arena->resource_heaps[kind]; - - b32 is_mappable = 0; - - /* Initialize heap */ - /* FIXME: Dynamic size */ - if (heap->d3d_heap == 0) - { - HRESULT hr = 0; - - /* Create d3d heap */ - { - D3D12_HEAP_DESC d3d_desc = ZI; - d3d_desc.SizeInBytes = Mebi(512); - if (kind == G_D12_ResourceHeapKind_Cpu) - { - d3d_desc.Properties.Type = D3D12_HEAP_TYPE_CUSTOM; - d3d_desc.Properties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_BACK; - d3d_desc.Properties.MemoryPoolPreference = D3D12_MEMORY_POOL_L0; - is_mappable = 1; - } - else if (kind == G_D12_ResourceHeapKind_CpuWriteCombined) - { - d3d_desc.Properties.Type = D3D12_HEAP_TYPE_CUSTOM; - d3d_desc.Properties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE; - d3d_desc.Properties.MemoryPoolPreference = D3D12_MEMORY_POOL_L0; - is_mappable = 1; - } - else - { - d3d_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT; - } - d3d_desc.Flags |= D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; - d3d_desc.Flags |= D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES; /* TODO: Remove this and support tier 1 resource heaps */ - hr = ID3D12Device_CreateHeap(g->device, &d3d_desc, &IID_ID3D12Heap, (void **)&heap->d3d_heap); - heap->size = d3d_desc.SizeInBytes; - } - - /* Map resource */ - if (is_mappable) - { - /* Create heap-sized resource for mapping */ - if (SUCCEEDED(hr)) - { - D3D12_RESOURCE_DESC1 d3d_desc = ZI; - d3d_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - d3d_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - d3d_desc.Format = DXGI_FORMAT_UNKNOWN; - d3d_desc.Width = heap->size; - d3d_desc.Height = 1; - d3d_desc.DepthOrArraySize = 1; - d3d_desc.MipLevels = 1; - d3d_desc.SampleDesc.Count = 1; - d3d_desc.SampleDesc.Quality = 0; - d3d_desc.Flags |= D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; - - u64 alloc_size = 0; - u64 alloc_align = 0; - { - D3D12_RESOURCE_ALLOCATION_INFO alloc_info = ZI; - ID3D12Device_GetResourceAllocationInfo(g->device, &alloc_info, 0, 1, (D3D12_RESOURCE_DESC *)&d3d_desc); - alloc_size = alloc_info.SizeInBytes; - alloc_align = alloc_info.Alignment; - } - - if (alloc_size > heap->size) - { - Panic(Lit("Gpu heap overflow")); - } - - hr = ID3D12Device10_CreatePlacedResource2(g->device, - heap->d3d_heap, - 0, - &d3d_desc, - D3D12_BARRIER_LAYOUT_UNDEFINED, - 0, - 0, - 0, - &IID_ID3D12Resource, - (void **)&heap->d3d_mapped_resource); - } - if (SUCCEEDED(hr)) - { - D3D12_RANGE read_range = ZI; - hr = ID3D12Resource_Map(heap->d3d_mapped_resource, 0, &read_range, &heap->mapped); - } - } - - if (!SUCCEEDED(hr)) - { - /* TODO: Don't panic */ - Panic(Lit("Failed to create D3D12 resource heap")); - } - - } - - return heap; -} - //////////////////////////////////////////////////////////// //~ @hookimpl Arena @@ -876,7 +771,272 @@ void G_ReleaseArena(G_ArenaHandle arena) } //////////////////////////////////////////////////////////// -//~ Resource +//~ Arena + +void G_D12_ResetArena(G_D12_CmdList *cl, G_D12_Arena *gpu_arena) +{ + /* TODO */ + + /* FIXME: Move descriptors into committed lists */ + + /* FIXME: Release id3d12 resource com object references */ + for (u64 heap_idx = 0; heap_idx < countof(gpu_arena->resource_heaps); ++heap_idx) + { + G_D12_ResourceHeap *heap = &gpu_arena->resource_heaps[heap_idx]; + heap->pos = 0; + } +} + +//////////////////////////////////////////////////////////// +//~ @hookimpl Resource + +G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_ResourceDesc desc) +{ + G_D12_SharedState *g = &G_D12_shared_state; + G_D12_Arena *gpu_arena = G_D12_ArenaFromHandle(arena_handle); + G_D12_Resource *resource = 0; + HRESULT hr = 0; + + b32 is_buffer = desc.kind == G_ResourceKind_Buffer; + b32 is_texture = desc.kind == G_ResourceKind_Texture1D || + desc.kind == G_ResourceKind_Texture2D || + desc.kind == G_ResourceKind_Texture3D; + b32 is_sampler = desc.kind == G_ResourceKind_Sampler; + G_ResourceFlag flags = is_buffer ? desc.buffer.flags : + is_texture ? desc.texture.flags : + desc.sampler.flags; + + if (is_buffer || is_texture) + { + ////////////////////////////// + //- Initialize heap + + G_D12_ResourceHeap *heap = 0; + if (is_buffer || is_texture) + { + G_D12_ResourceHeapKind heap_kind = G_D12_ResourceHeapKind_Gpu; + if (flags & G_ResourceFlag_HostMemory) + { + heap_kind = G_D12_ResourceHeapKind_Cpu; + if (flags & G_ResourceFlag_Uncached) + { + heap_kind = G_D12_ResourceHeapKind_CpuWriteCombined; + } + } + heap = &gpu_arena->resource_heaps[heap_kind]; + if (heap->d3d_heap == 0) + { + b32 is_mappable = 0; + + /* Initialize heap */ + /* FIXME: Dynamic size */ + if (heap->d3d_heap == 0) + { + /* Create d3d heap */ + { + D3D12_HEAP_DESC d3d_desc = ZI; + d3d_desc.SizeInBytes = Mebi(256); + if (heap_kind == G_D12_ResourceHeapKind_Cpu) + { + d3d_desc.Properties.Type = D3D12_HEAP_TYPE_CUSTOM; + d3d_desc.Properties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_BACK; + d3d_desc.Properties.MemoryPoolPreference = D3D12_MEMORY_POOL_L0; + is_mappable = 1; + } + else if (heap_kind == G_D12_ResourceHeapKind_CpuWriteCombined) + { + d3d_desc.Properties.Type = D3D12_HEAP_TYPE_CUSTOM; + d3d_desc.Properties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE; + d3d_desc.Properties.MemoryPoolPreference = D3D12_MEMORY_POOL_L0; + is_mappable = 1; + } + else + { + d3d_desc.Properties.Type = D3D12_HEAP_TYPE_DEFAULT; + } + d3d_desc.Flags |= D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; + d3d_desc.Flags |= D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES; /* TODO: Remove this and support tier 1 resource heaps */ + hr = ID3D12Device_CreateHeap(g->device, &d3d_desc, &IID_ID3D12Heap, (void **)&heap->d3d_heap); + heap->size = d3d_desc.SizeInBytes; + } + + /* Map heap resource */ + if (is_mappable) + { + if (SUCCEEDED(hr)) + { + D3D12_RESOURCE_DESC1 d3d_desc = ZI; + d3d_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + d3d_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + d3d_desc.Format = DXGI_FORMAT_UNKNOWN; + d3d_desc.Width = heap->size; + d3d_desc.Height = 1; + d3d_desc.DepthOrArraySize = 1; + d3d_desc.MipLevels = 1; + d3d_desc.SampleDesc.Count = 1; + d3d_desc.SampleDesc.Quality = 0; + d3d_desc.Flags |= D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; + + u64 alloc_size = 0; + u64 alloc_align = 0; + { + D3D12_RESOURCE_ALLOCATION_INFO alloc_info = ZI; + ID3D12Device_GetResourceAllocationInfo(g->device, &alloc_info, 0, 1, (D3D12_RESOURCE_DESC *)&d3d_desc); + alloc_size = alloc_info.SizeInBytes; + alloc_align = alloc_info.Alignment; + } + + if (alloc_size > heap->size) + { + Panic(Lit("Gpu heap overflow")); + } + + hr = ID3D12Device10_CreatePlacedResource2(g->device, + heap->d3d_heap, + 0, + &d3d_desc, + D3D12_BARRIER_LAYOUT_UNDEFINED, + 0, + 0, + 0, + &IID_ID3D12Resource, + (void **)&heap->d3d_mapped_resource); + } + if (SUCCEEDED(hr)) + { + D3D12_RANGE read_range = ZI; + hr = ID3D12Resource_Map(heap->d3d_mapped_resource, 0, &read_range, &heap->mapped); + } + } + + if (!SUCCEEDED(hr)) + { + /* TODO: Don't panic */ + Panic(Lit("Failed to create D3D12 resource heap")); + } + } + } + } + + ////////////////////////////// + //- Create buffer / texture + + D3D12_BARRIER_LAYOUT initial_layout = D3D12_BARRIER_LAYOUT_UNDEFINED; + D3D12_CLEAR_VALUE clear_value = ZI; + D3D12_RESOURCE_DESC1 d3d_desc = ZI; + { + if (is_buffer) + { + d3d_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + d3d_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + d3d_desc.Format = DXGI_FORMAT_UNKNOWN; + d3d_desc.Width = AlignU64(MaxU64(desc.buffer.size, 1), 4); + d3d_desc.Height = 1; + d3d_desc.DepthOrArraySize = 1; + d3d_desc.MipLevels = 1; + d3d_desc.SampleDesc.Count = 1; + d3d_desc.SampleDesc.Quality = 0; + d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS * AnyBit(flags, G_ResourceFlag_AllowShaderReadWrite); + } + if (is_texture) + { + initial_layout = G_D12_BarrierLayoutFromLayout(desc.texture.initial_layout); + d3d_desc.Dimension = desc.kind == G_ResourceKind_Texture1D ? D3D12_RESOURCE_DIMENSION_TEXTURE1D : + desc.kind == G_ResourceKind_Texture2D ? D3D12_RESOURCE_DIMENSION_TEXTURE2D : + D3D12_RESOURCE_DIMENSION_TEXTURE3D; + d3d_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + d3d_desc.Format = G_D12_DxgiFormatFromGpuFormat(desc.texture.format); + d3d_desc.Width = MaxI32(desc.texture.dims.x, 1); + d3d_desc.Height = MaxI32(desc.texture.dims.y, 1); + d3d_desc.DepthOrArraySize = MaxI32(desc.texture.dims.z, 1); + d3d_desc.MipLevels = MaxI32(desc.texture.mip_levels, 1); + d3d_desc.SampleDesc.Count = 1; + d3d_desc.SampleDesc.Quality = 0; + d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS * AnyBit(flags, G_ResourceFlag_AllowShaderReadWrite); + d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET * AnyBit(flags, G_ResourceFlag_AllowRenderTarget); + d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL * AnyBit(flags, G_ResourceFlag_AllowDepthStencil); + d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS * (desc.texture.initial_layout == G_Layout_Simultaneous); + clear_value.Color[0] = desc.texture.clear_color.x, + clear_value.Color[1] = desc.texture.clear_color.y, + clear_value.Color[2] = desc.texture.clear_color.z, + clear_value.Color[3] = desc.texture.clear_color.w, + clear_value.Format = d3d_desc.Format; + } + } + + u64 alloc_size = 0; + u64 alloc_align = 0; + { + D3D12_RESOURCE_ALLOCATION_INFO alloc_info = ZI; + ID3D12Device_GetResourceAllocationInfo(g->device, &alloc_info, 0, 1, (D3D12_RESOURCE_DESC *)&d3d_desc); + alloc_size = alloc_info.SizeInBytes; + alloc_align = alloc_info.Alignment; + } + + u64 pos_in_heap = 0; + { + pos_in_heap = heap->pos; + pos_in_heap = AlignU64(pos_in_heap, alloc_align); + heap->pos = pos_in_heap + alloc_size; + if (pos_in_heap + alloc_size > heap->size) + { + Panic(Lit("Gpu arena overflow")); + } + } + + ID3D12Resource *d3d_resource = 0; + { + hr = ID3D12Device10_CreatePlacedResource2( + g->device, + heap->d3d_heap, + pos_in_heap, + &d3d_desc, + D3D12_BARRIER_LAYOUT_UNDEFINED, + (d3d_desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) ? &clear_value : 0, + 0, + 0, + &IID_ID3D12Resource, + (void **)&d3d_resource + ); + } + + resource = PushStruct(gpu_arena->arena, G_D12_Resource); + resource->heap = heap; + resource->pos_in_heap = pos_in_heap; + resource->d3d_resource = d3d_resource; + resource->uid = Atomic64FetchAdd(&g->resource_creation_gen.v, 1) + 1; + resource->flags = flags; + if (is_buffer) + { + resource->buffer_size = desc.buffer.size; + resource->buffer_size_actual = d3d_desc.Width; + resource->buffer_gpu_address = ID3D12Resource_GetGPUVirtualAddress(d3d_resource); + } + if (is_texture) + { + resource->is_texture = 1; + resource->texture_format = desc.texture.format; + resource->texture_dims = desc.texture.dims; + resource->texture_mip_levels = desc.texture.mip_levels; + resource->texture_layout = initial_layout; + } + } + + ////////////////////////////// + //- Create sampler + + if (is_sampler) + { + resource = PushStruct(gpu_arena->arena, G_D12_Resource); + resource->uid = Atomic64FetchAdd(&g->resource_creation_gen.v, 1) + 1; + resource->sampler_desc = desc.sampler; + } + + return G_D12_MakeHandle(G_ResourceHandle, resource); +} + +//////////////////////////////////////////////////////////// +//~ Descriptor G_D12_Descriptor *G_D12_DescriptorFromIndex(G_D12_DescriptorHeapKind heap_kind, u32 index) { @@ -951,194 +1111,6 @@ G_D12_Descriptor *G_D12_PushDescriptor(G_D12_Arena *gpu_arena, G_D12_DescriptorH return descriptor; } -//////////////////////////////////////////////////////////// -//~ @hookimpl Resource - -//- Resource creation - -G_ResourceHandle G_PushBufferEx(G_ArenaHandle arena_handle, G_BufferResourceDesc desc) -{ - G_D12_SharedState *g = &G_D12_shared_state; - G_D12_Arena *gpu_arena = G_D12_ArenaFromHandle(arena_handle); - - /* Fetch heap */ - G_D12_ResourceHeapKind heap_kind = G_D12_ResourceHeapKind_Gpu; - if (desc.flags & G_ResourceFlag_HostMemory) - { - heap_kind = G_D12_ResourceHeapKind_Cpu; - if (desc.flags & G_ResourceFlag_WriteCombined) - { - heap_kind = G_D12_ResourceHeapKind_CpuWriteCombined; - } - } - G_D12_ResourceHeap *heap = G_D12_ResourceHeapFromArena(gpu_arena, heap_kind); - - /* Create d3d resource */ - ID3D12Resource *d3d_resource = 0; - u64 pos_in_heap = 0; - u64 aligned_size = AlignU64(MaxU64(desc.size, 1), 4); - { - D3D12_RESOURCE_DESC1 d3d_desc = ZI; - d3d_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - d3d_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - d3d_desc.Format = DXGI_FORMAT_UNKNOWN; - d3d_desc.Width = aligned_size; - d3d_desc.Height = 1; - d3d_desc.DepthOrArraySize = 1; - d3d_desc.MipLevels = 1; - d3d_desc.SampleDesc.Count = 1; - d3d_desc.SampleDesc.Quality = 0; - d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS * AnyBit(desc.flags, G_ResourceFlag_AllowShaderReadWrite); - - u64 alloc_size = 0; - u64 alloc_align = 0; - { - D3D12_RESOURCE_ALLOCATION_INFO alloc_info = ZI; - ID3D12Device_GetResourceAllocationInfo(g->device, &alloc_info, 0, 1, (D3D12_RESOURCE_DESC *)&d3d_desc); - alloc_size = alloc_info.SizeInBytes; - alloc_align = alloc_info.Alignment; - } - - pos_in_heap = heap->pos; - pos_in_heap = AlignU64(pos_in_heap, alloc_align); - heap->pos = pos_in_heap + alloc_size; - - if (pos_in_heap + alloc_size > heap->size) - { - Panic(Lit("Gpu arena overflow")); - } - - HRESULT hr = ID3D12Device10_CreatePlacedResource2(g->device, - heap->d3d_heap, - pos_in_heap, - &d3d_desc, - D3D12_BARRIER_LAYOUT_UNDEFINED, - 0, - 0, - 0, - &IID_ID3D12Resource, - (void **)&d3d_resource); - } - - G_D12_Resource *resource = PushStruct(gpu_arena->arena, G_D12_Resource); - resource->heap = heap; - resource->pos_in_heap = pos_in_heap; - resource->d3d_resource = d3d_resource; - resource->uid = Atomic64FetchAdd(&g->resource_creation_gen.v, 1) + 1; - resource->flags = desc.flags; - - resource->buffer_size = desc.size; - resource->buffer_size_aligned = aligned_size; - resource->buffer_gpu_address = ID3D12Resource_GetGPUVirtualAddress(d3d_resource); - - return G_D12_MakeHandle(G_ResourceHandle, resource); -} - -G_ResourceHandle G_PushTextureEx(G_ArenaHandle arena_handle, G_TextureResourceDesc desc) -{ - G_D12_SharedState *g = &G_D12_shared_state; - G_D12_Arena *gpu_arena = G_D12_ArenaFromHandle(arena_handle); - D3D12_BARRIER_LAYOUT initial_layout = G_D12_BarrierLayoutFromLayout(desc.initial_layout); - - /* Fetch heap */ - G_D12_ResourceHeapKind heap_kind = G_D12_ResourceHeapKind_Gpu; - if (desc.flags & G_ResourceFlag_HostMemory) - { - heap_kind = G_D12_ResourceHeapKind_Cpu; - if (desc.flags & G_ResourceFlag_WriteCombined) - { - heap_kind = G_D12_ResourceHeapKind_CpuWriteCombined; - } - } - G_D12_ResourceHeap *heap = G_D12_ResourceHeapFromArena(gpu_arena, heap_kind); - - /* Create d3d resource */ - ID3D12Resource *d3d_resource = 0; - u64 pos_in_heap; - { - D3D12_RESOURCE_DESC1 d3d_desc = ZI; - d3d_desc.Dimension = desc.kind == G_TextureKind_1D ? D3D12_RESOURCE_DIMENSION_TEXTURE1D : - desc.kind == G_TextureKind_2D ? D3D12_RESOURCE_DIMENSION_TEXTURE2D : - D3D12_RESOURCE_DIMENSION_TEXTURE3D; - d3d_desc.Format = G_D12_DxgiFormatFromGpuFormat(desc.format); - d3d_desc.Width = MaxI32(desc.dims.x, 1); - d3d_desc.Height = MaxI32(desc.dims.y, 1); - d3d_desc.DepthOrArraySize = MaxI32(desc.dims.z, 1); - d3d_desc.MipLevels = MaxI32(desc.mip_levels, 1); - d3d_desc.SampleDesc.Count = 1; - d3d_desc.SampleDesc.Quality = 0; - d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS * AnyBit(desc.flags, G_ResourceFlag_AllowShaderReadWrite); - d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET * AnyBit(desc.flags, G_ResourceFlag_AllowRenderTarget); - d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL * AnyBit(desc.flags, G_ResourceFlag_AllowDepthStencil); - d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS * (desc.initial_layout == G_Layout_Simultaneous); - - - u64 alloc_size = 0; - u64 alloc_align = 0; - { - D3D12_RESOURCE_ALLOCATION_INFO alloc_info = ZI; - ID3D12Device_GetResourceAllocationInfo(g->device, &alloc_info, 0, 1, (D3D12_RESOURCE_DESC *)&d3d_desc); - alloc_size = alloc_info.SizeInBytes; - alloc_align = alloc_info.Alignment; - } - - pos_in_heap = heap->pos; - pos_in_heap = AlignU64(pos_in_heap, alloc_align); - heap->pos = pos_in_heap + alloc_size; - - if (pos_in_heap + alloc_size > heap->size) - { - Panic(Lit("Gpu arena overflow")); - } - - D3D12_CLEAR_VALUE clear_value = { - .Color[0] = desc.clear_color.x, - .Color[1] = desc.clear_color.y, - .Color[2] = desc.clear_color.z, - .Color[3] = desc.clear_color.w, - .Format = d3d_desc.Format - }; - - HRESULT hr = ID3D12Device10_CreatePlacedResource2(g->device, - heap->d3d_heap, - pos_in_heap, - &d3d_desc, - initial_layout, - (d3d_desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) ? &clear_value : 0, - 0, - 0, - &IID_ID3D12Resource, - (void **)&d3d_resource); - } - - G_D12_Resource *resource = PushStruct(gpu_arena->arena, G_D12_Resource); - resource->heap = heap; - resource->pos_in_heap = pos_in_heap; - resource->d3d_resource = d3d_resource; - resource->uid = Atomic64FetchAdd(&g->resource_creation_gen.v, 1) + 1; - resource->flags = desc.flags; - - resource->is_texture = 1; - resource->texture_format = desc.format; - resource->texture_dims = desc.dims; - resource->texture_mip_levels = desc.mip_levels; - resource->texture_layout = initial_layout; - - return G_D12_MakeHandle(G_ResourceHandle, resource); -} - -G_ResourceHandle G_PushSampler(G_ArenaHandle arena_handle, G_SamplerResourceDesc desc) -{ - G_D12_SharedState *g = &G_D12_shared_state; - G_D12_Arena *gpu_arena = G_D12_ArenaFromHandle(arena_handle); - - G_D12_Resource *resource = PushStruct(gpu_arena->arena, G_D12_Resource); - resource->uid = Atomic64FetchAdd(&g->resource_creation_gen.v, 1) + 1; - resource->sampler_desc = desc; - - return G_D12_MakeHandle(G_ResourceHandle, resource); -} - //////////////////////////////////////////////////////////// //~ @hookimpl Shader resource reference @@ -1185,8 +1157,8 @@ u32 G_PushRef(G_ArenaHandle arena_handle, G_ResourceHandle resource_handle, G_Re } descriptor = G_D12_PushDescriptor(gpu_arena, G_D12_DescriptorHeapKind_CbvSrvUav); - u64 buffer_size_aligned = resource->buffer_size_aligned; - u64 num_elements_in_buffer = buffer_size_aligned / ref_desc.element_size; + u64 buffer_size_actual = resource->buffer_size_actual; + u64 num_elements_in_buffer = buffer_size_actual / ref_desc.element_size; u64 num_elements_after_offset = num_elements_in_buffer > ref_desc.element_offset ? num_elements_in_buffer - ref_desc.element_offset : 0; if (num_elements_after_offset > 0) @@ -1247,7 +1219,7 @@ u32 G_PushRef(G_ArenaHandle arena_handle, G_ResourceHandle resource_handle, G_Re else if (is_sampler) { descriptor = G_D12_PushDescriptor(gpu_arena, G_D12_DescriptorHeapKind_Sampler); - G_SamplerResourceDesc sampler_desc = resource->sampler_desc; + G_SamplerDesc sampler_desc = resource->sampler_desc; D3D12_SAMPLER_DESC d3d_desc = ZI; { d3d_desc.Filter = (D3D12_FILTER)sampler_desc.filter; @@ -1523,7 +1495,7 @@ G_D12_StagingRegionNode *G_D12_PushStagingRegion(G_D12_CmdList *cl, u64 size) heap->resource.d3d_resource = d3d_resource; heap->resource.uid = Atomic64FetchAdd(&g->resource_creation_gen.v, 1) + 1; heap->resource.buffer_size = new_heap_size; - heap->resource.buffer_size_aligned = new_heap_size; + heap->resource.buffer_size_actual = new_heap_size; heap->resource.buffer_gpu_address = ID3D12Resource_GetGPUVirtualAddress(d3d_resource); /* Map */ @@ -2240,18 +2212,9 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) void G_ResetArena(G_CommandListHandle cl_handle, G_ArenaHandle arena_handle) { + G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle); G_D12_Arena *gpu_arena = G_D12_ArenaFromHandle(arena_handle); - - /* TODO */ - - /* FIXME: Move descriptors into committed lists */ - - /* FIXME: Release id3d12 resource com object references */ - for (u64 heap_idx = 0; heap_idx < countof(gpu_arena->resource_heaps); ++heap_idx) - { - G_D12_ResourceHeap *heap = &gpu_arena->resource_heaps[heap_idx]; - heap->pos = 0; - } + G_D12_ResetArena(cl, gpu_arena); } //- Cpu -> Gpu copy @@ -2935,7 +2898,7 @@ void G_D12_CollectionWorkerEntryPoint(WaveLaneCtx *lane) switch (gpu_kind) { - /* Translate unsigned args */ + /* Translate unsigned integer args */ case G_FmtArgKind_Uint: { u32 gpu_value = *(u32 *)at; @@ -2961,7 +2924,7 @@ void G_D12_CollectionWorkerEntryPoint(WaveLaneCtx *lane) at += 16; } break; - /* Translate signed args */ + /* Translate signed integer args */ case G_FmtArgKind_Sint: { i32 gpu_value = *(i32 *)at; diff --git a/src/gpu/gpu_dx12/gpu_dx12_core.h b/src/gpu/gpu_dx12/gpu_dx12_core.h index ea5198f3..7048e3cd 100644 --- a/src/gpu/gpu_dx12/gpu_dx12_core.h +++ b/src/gpu/gpu_dx12/gpu_dx12_core.h @@ -99,7 +99,7 @@ Struct(G_D12_DescriptorList) }; //////////////////////////////////////////////////////////// -//~ Resource heap types +//~ Arena types /* TODO: * To support D3D12_RESOURCE_HEAP_TIER_1 devices, create separate heaps for: @@ -124,13 +124,18 @@ Struct(G_D12_ResourceHeap) ID3D12Resource *d3d_mapped_resource; void *mapped; + u64 resources_count; + struct G_D12_Resource *first_resource; + struct G_D12_Resource *last_resource; + + u64 reset_resources_count; + struct G_D12_Resource *first_reset_resource; + struct G_D12_Resource *last_reset_resource; + u64 pos; u64 size; }; -//////////////////////////////////////////////////////////// -//~ Arena types - Struct(G_D12_Arena) { Arena *arena; @@ -144,7 +149,7 @@ Struct(G_D12_Arena) Struct(G_D12_Resource) { - G_D12_Resource *next_free; + G_D12_Resource *next; G_D12_ResourceHeap *heap; u64 pos_in_heap; @@ -155,7 +160,7 @@ Struct(G_D12_Resource) /* Buffer info */ u64 buffer_size; - u64 buffer_size_aligned; + u64 buffer_size_actual; D3D12_GPU_VIRTUAL_ADDRESS buffer_gpu_address; /* Texture info */ @@ -166,7 +171,7 @@ Struct(G_D12_Resource) D3D12_BARRIER_LAYOUT texture_layout; /* Sampler info */ - G_SamplerResourceDesc sampler_desc; + G_SamplerDesc sampler_desc; /* Backbuffer info */ struct G_D12_Swapchain *swapchain; @@ -445,23 +450,23 @@ G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc); G_D12_Queue *G_D12_QueueFromKind(G_QueueKind kind); -//////////////////////////////////////////////////////////// -//~ Arena - -G_D12_ResourceHeap *G_D12_ResourceHeapFromArena(G_D12_Arena *gpu_arena, G_D12_ResourceHeapKind kind); - -//////////////////////////////////////////////////////////// -//~ Resource - -G_D12_Descriptor *G_D12_DescriptorFromIndex(G_D12_DescriptorHeapKind heap_kind, u32 index); -G_D12_Descriptor *G_D12_PushDescriptor(G_D12_Arena *gpu_arena, G_D12_DescriptorHeapKind heap_kind); - //////////////////////////////////////////////////////////// //~ Raw command list G_D12_RawCommandList *G_D12_PrepareRawCommandList(G_QueueKind queue_kind); i64 G_D12_CommitRawCommandList(G_D12_RawCommandList *cl); +//////////////////////////////////////////////////////////// +//~ Arena + +void G_D12_ResetArena(G_D12_CmdList *cl, G_D12_Arena *gpu_arena); + +//////////////////////////////////////////////////////////// +//~ Descriptor + +G_D12_Descriptor *G_D12_DescriptorFromIndex(G_D12_DescriptorHeapKind heap_kind, u32 index); +G_D12_Descriptor *G_D12_PushDescriptor(G_D12_Arena *gpu_arena, G_D12_DescriptorHeapKind heap_kind); + //////////////////////////////////////////////////////////// //~ Command helpers diff --git a/src/ttf/ttf_dwrite/ttf_dwrite.c b/src/ttf/ttf_dwrite/ttf_dwrite.c index 31ca4221..938e812d 100644 --- a/src/ttf/ttf_dwrite/ttf_dwrite.c +++ b/src/ttf/ttf_dwrite/ttf_dwrite.c @@ -111,7 +111,7 @@ TTF_GlyphResult TTF_RasterizeGlyphFromCodepoint(Arena *arena, u32 codepoint, Res /* Best-guess a position in the middle of the render target based on metrics */ Vec2I32 rt_baseline = ZI; rt_baseline.x = (rt_dims.x / 2) - (advance / 2); - rt_baseline.y = (rt_dims.y / 2) - (font_cap / 2); + rt_baseline.y = (rt_dims.y / 2) + (font_cap / 2); /* Create render target */ IDWriteBitmapRenderTarget *render_target = 0; diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index d3d2db7c..7a245e70 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -1263,7 +1263,7 @@ void UI_EndFrame(UI_Frame *frame) for (u64 rect_idx = 0; rect_idx < raw_run.rects_count; ++rect_idx) { GC_RunRect rr = raw_run.rects[rect_idx]; - if ((rr.baseline_pos + rr.advance) <= elipses_start_pos) + if (rr.baseline_pos + rr.advance <= elipses_start_pos) { final_rects[final_rects_count] = rr; final_rects_count += 1; @@ -1275,7 +1275,7 @@ void UI_EndFrame(UI_Frame *frame) { GC_RunRect rr = elipses_run.rects[rect_idx]; rr.baseline_pos += elipses_start_pos; - if ((rr.baseline_pos + rr.advance) <= max_baseline) + if (rr.baseline_pos > 0) { final_rects[final_rects_count] = rr; final_rects_count += 1;