From e3bbeec2be6457ee17080b8cbefbb40075b3ecee Mon Sep 17 00:00:00 2001 From: jacob Date: Thu, 12 Mar 2026 05:15:51 -0500 Subject: [PATCH] bundle D3D12 descriptors with resource lifetime --- src/base/base.cgh | 2 - src/base/base_resource.c | 42 +- src/config.h | 2 +- src/gpu/gpu_common.c | 7 +- src/gpu/gpu_common.h | 4 +- src/gpu/gpu_core.h | 19 +- src/gpu/gpu_dx12/gpu_dx12_core.c | 1189 +++++------------------------- src/gpu/gpu_dx12/gpu_dx12_core.h | 69 +- src/gpu/gpu_shared.cgh | 20 +- src/proto/proto.c | 2 +- src/proto/proto_gpu.g | 4 +- 11 files changed, 249 insertions(+), 1111 deletions(-) diff --git a/src/base/base.cgh b/src/base/base.cgh index 74ae8247..80f8e899 100644 --- a/src/base/base.cgh +++ b/src/base/base.cgh @@ -774,14 +774,12 @@ Struct(ComputeShaderDesc) { ResourceKey resource; u32 x, y, z; }; String name; void **addr_ptr; }; - Struct(ApiDesc) { String path; u64 procs_count; ApiProcDesc *procs; }; - #define DeclApiProcVarX(_name, _return_type, _signature) _return_type (*_name) _signature; #define DeclApiProcDescX(_name, _return_type, _signature) { .name = CompLit(Stringize(_name)), .addr_ptr = (void **)&_name }, #define DeclApiFromXList(api_name, xlist, api_path) \ diff --git a/src/base/base_resource.c b/src/base/base_resource.c index d21ed9a2..9e43f9b1 100644 --- a/src/base/base_resource.c +++ b/src/base/base_resource.c @@ -13,28 +13,34 @@ void BootstrapResources(u64 archive_strings_count, String *archive_strings) BB_Reader bbr = BB_ReaderFromBuff(&bb); u64 magic = BB_ReadUBits(&bbr, 64); - Assert(magic == ResourceEmbeddedMagic); - - // Create & insert entries - u64 num_entries = BB_ReadUBits(&bbr, 64); - for (u64 i = 0; i < num_entries; ++i) + if (magic == ResourceEmbeddedMagic) { - u64 store_hash = BB_ReadUBits(&bbr, 64); - u64 name_start = BB_ReadUBits(&bbr, 64); - u64 name_len = BB_ReadUBits(&bbr, 64); - u64 data_start = BB_ReadUBits(&bbr, 64); - u64 data_len = BB_ReadUBits(&bbr, 64); + // Create & insert entries + u64 num_entries = BB_ReadUBits(&bbr, 64); + for (u64 i = 0; i < num_entries; ++i) + { + u64 store_hash = BB_ReadUBits(&bbr, 64); + u64 name_start = BB_ReadUBits(&bbr, 64); + u64 name_len = BB_ReadUBits(&bbr, 64); + u64 data_start = BB_ReadUBits(&bbr, 64); + u64 data_len = BB_ReadUBits(&bbr, 64); - ResourceEntry *entry = PushStruct(perm, ResourceEntry); - entry->name = STRING(name_len, archive.text + name_start); - entry->data = STRING(data_len, archive.text + data_start); - entry->hash = HashStringEx(store_hash, entry->name); + ResourceEntry *entry = PushStruct(perm, ResourceEntry); + entry->name = STRING(name_len, archive.text + name_start); + entry->data = STRING(data_len, archive.text + data_start); + entry->hash = HashStringEx(store_hash, entry->name); - ResourceEntryBin *bin = &Base.resource.bins[entry->hash % countof(Base.resource.bins)]; - SllQueuePushN(bin->first, bin->last, entry, next_in_bin); - SllQueuePushN(Base.resource.first_entry, Base.resource.last_entry, entry, next); + ResourceEntryBin *bin = &Base.resource.bins[entry->hash % countof(Base.resource.bins)]; + SllQueuePushN(bin->first, bin->last, entry, next_in_bin); + SllQueuePushN(Base.resource.first_entry, Base.resource.last_entry, entry, next); + } + Base.resource.entries_count += num_entries; + } + else + { + // Unexpected resource header magic + Assert(0); } - Base.resource.entries_count += num_entries; } } } diff --git a/src/config.h b/src/config.h index a5632274..2361b294 100644 --- a/src/config.h +++ b/src/config.h @@ -14,7 +14,7 @@ #define GPU_NAMES IsRtcEnabled #define GPU_SHADER_PRINT 1 -#define GPU_SHADER_PRINT_BUFFER_SIZE Kibi(64); +#define GPU_SHADER_PRINT_BUFFER_SIZE Kibi(64) #define GPU_SHADER_PRINT_LOG 1 // If enabled, bitbuffs will insert/verify magic numbers & length for each read & write diff --git a/src/gpu/gpu_common.c b/src/gpu/gpu_common.c index 82b15469..7436e0ea 100644 --- a/src/gpu/gpu_common.c +++ b/src/gpu/gpu_common.c @@ -13,7 +13,10 @@ void G_BootstrapCommon(void) // Init quad index buffer { u16 quad_indices[6] = { 0, 1, 2, 0, 2, 3 }; - G.quad_indices = G_PushStructsFromCpu(cl, gpu_perm, quad_indices, countof(quad_indices)); + G.quad_indices = G_IB( + countof(quad_indices), + G_PushStructsFromCpu(cl, gpu_perm, quad_indices, countof(quad_indices)) + ); } // Init blank texture @@ -224,7 +227,7 @@ G_SamplerRef G_BasicSamplerFromKind(G_BasicSamplerKind kind) return G.basic_samplers[kind]; } -G_BufferRef G_QuadIndices(void) +G_IndexBufferDesc G_QuadIndices(void) { return G.quad_indices; } diff --git a/src/gpu/gpu_common.h b/src/gpu/gpu_common.h index 0193baec..35571227 100644 --- a/src/gpu/gpu_common.h +++ b/src/gpu/gpu_common.h @@ -4,7 +4,7 @@ Struct(G_Ctx) { // Common shared resources - G_BufferRef quad_indices; + G_IndexBufferDesc quad_indices; G_TextureRef blank_tex2d; G_TextureRef basic_noise_tex3d; G_SamplerRef basic_samplers[G_BasicSamplerKind_COUNT]; @@ -48,6 +48,6 @@ Rng2 G_ScissorFromTexture(G_TextureRef texture); //- Shared resources G_SamplerRef G_BasicSamplerFromKind(G_BasicSamplerKind kind); -G_BufferRef G_QuadIndices(void); +G_IndexBufferDesc G_QuadIndices(void); G_TextureRef G_Blank2D(void); G_TextureRef G_BasicNoise3D(void); diff --git a/src/gpu/gpu_core.h b/src/gpu/gpu_core.h index b4ca57fa..ff4903aa 100644 --- a/src/gpu/gpu_core.h +++ b/src/gpu/gpu_core.h @@ -320,8 +320,8 @@ Enum(G_MemoryFlag) G_MemoryFlag_AllowTextureRW = (1 << 1), G_MemoryFlag_AllowTextureDraw = (1 << 2), G_MemoryFlag_AllowTextureDepthStencil = (1 << 3), - G_MemoryFlag_HostCached = (1 << 4), // Will be mapped to write-back Cpu memory - G_MemoryFlag_HostUncached = (1 << 5), // Will be mapped to write-combined Cpu memory + G_MemoryFlag_CpuRead = (1 << 4), + G_MemoryFlag_CpuWrite = (1 << 5), G_MemoryFlag_ForceNoReuse = (1 << 6), }; @@ -391,7 +391,7 @@ Enum(G_BlendMode) G_BlendMode_CompositePremultipliedAlpha, }; -#define G_Rt(_tex, _blend_mode, ...) ((G_RenderTargetDesc) { .texture = (_tex), .blend = (_blend_mode), __VA_ARGS__ }) +#define G_RT(_tex, _blend_mode, ...) ((G_RenderTargetDesc) { .texture = (_tex), .blend = (_blend_mode), __VA_ARGS__ }) Struct(G_RenderTargetDesc) { G_TextureRef texture; @@ -399,6 +399,13 @@ Struct(G_RenderTargetDesc) i32 mip; }; +#define G_IB(_count, _buffer) ((G_IndexBufferDesc) { .count = (_count), .buffer = (_buffer), __VA_ARGS__ }) +Struct(G_IndexBufferDesc) +{ + u64 count; + G_BufferRef buffer; +}; + //////////////////////////////////////////////////////////// //~ Statistic types @@ -519,9 +526,7 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl, G_ArenaHandle gpu_are //- Count -u64 G_CountBuffer(G_BufferRef buffer); -u64 G_CountBufferBytes(G_BufferRef buffer); -u64 G_CountBufferStride(G_BufferRef buffer); +u64 G_CountStride(G_BufferRef buffer); i32 G_Count1D(G_TextureRef texture); Vec2I32 G_Count2D(G_TextureRef texture); Vec3I32 G_Count3D(G_TextureRef texture); @@ -592,7 +597,7 @@ void G_ComputeEx(G_CommandListHandle cl, ComputeShaderDesc cs, Vec3I32 threads); void G_Draw( G_CommandListHandle cl, VertexShaderDesc vs, PixelShaderDesc ps, - u32 instances_count, G_BufferRef indices, + u32 instances_count, G_IndexBufferDesc indices, u32 render_targets_count, G_RenderTargetDesc *render_targets, Rng3 viewport, Rng2 scissor, G_DrawMode draw_mode diff --git a/src/gpu/gpu_dx12/gpu_dx12_core.c b/src/gpu/gpu_dx12/gpu_dx12_core.c index 243c85da..d436d5d5 100644 --- a/src/gpu/gpu_dx12/gpu_dx12_core.c +++ b/src/gpu/gpu_dx12/gpu_dx12_core.c @@ -460,7 +460,11 @@ void G_Bootstrap(void) Dx12HeapDesc desc = descs[heap_kind]; G_D12_DescriptorHeap *heap = &G_D12.descriptor_heaps[heap_kind]; heap->arena = AcquireArena(Gibi(64)); - heap->indices_to_descriptors_arena = AcquireArena(Gibi(64)); + + if (desc.flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE) + { + heap->gpu_visible_indices_to_descriptors_arena = AcquireArena(Gibi(4)); + } heap->kind = heap_kind; heap->type = desc.type; @@ -582,7 +586,7 @@ void G_Bootstrap(void) queue->print_readback_buffer = G_PushStructs( cl, gpu_perm, u8, queue->print_buffer_size, - .flags = G_MemoryFlag_HostCached, + .flags = G_MemoryFlag_CpuRead, .name = Lit("Debug print readback buffer") ); } @@ -1044,7 +1048,6 @@ G_D12_RawCommandList *G_D12_PrepareRawCommandList(G_QueueKind queue_kind) hr = ID3D12GraphicsCommandList_Reset(cl->d3d_cl, cl->d3d_ca, 0); } } - if (FAILED(hr)) { Panic(Lit("Failed to reset command list")); @@ -1147,166 +1150,13 @@ void G_D12_ResetArena(G_D12_CmdList *cl, G_D12_Arena *gpu_arena) ZeroStruct(&gpu_arena->resources); } - // Push descriptors to cl reset list - if (gpu_arena->descriptors.first) - { - if (cl->reset_descriptors.last) - { - cl->reset_descriptors.last->next = gpu_arena->descriptors.first; - } - else - { - cl->reset_descriptors.first = gpu_arena->descriptors.first; - } - cl->reset_descriptors.last = gpu_arena->descriptors.last; - cl->reset_descriptors.count += gpu_arena->descriptors.count; - gpu_arena->descriptors.count = 0; - gpu_arena->descriptors.first = 0; - gpu_arena->descriptors.last = 0; - } - // Full sync G_Sync(G_D12_MakeHandle(G_CommandListHandle, cl)); } - - - - - - - //////////////////////////////////////////////////////////// //~ Descriptor -// G_D12_Descriptor *G_D12_DescriptorFromIndex(G_D12_DescriptorHeapKind heap_kind, u32 index) -// { -// G_D12_DescriptorHeap *heap = &G_D12.descriptor_heaps[heap_kind]; -// G_D12_Descriptor *descriptors = ArenaFirst(heap->descriptors_arena, G_D12_Descriptor); -// return &descriptors[index]; -// } - -// G_D12_Descriptor *G_D12_PushDescriptor(G_D12_Arena *gpu_arena, G_D12_DescriptorHeapKind heap_kind) -// { -// G_D12_DescriptorHeap *heap = &G_D12.descriptor_heaps[heap_kind]; -// u64 per_batch_count = heap->per_batch_count; - -// G_D12_Descriptor *descriptor = 0; -// u32 index = 0; - -// // Grab completed descriptor from arena -// G_D12_DescriptorList *descriptors = &gpu_arena->reset_descriptors_by_heap[heap_kind]; -// descriptor = descriptors->first; -// if (descriptor) -// { -// G_D12_Queue *queue = G_D12_QueueFromKind(descriptor->completion_queue_kind); -// i64 queue_commit_completion = ID3D12Fence_GetCompletedValue(queue->commit_fence); -// if (queue_commit_completion >= descriptor->completion_queue_target) -// { -// // Descriptor no longer in use by gpu, reuse it -// DllQueueRemove(descriptors->first, descriptors->last, descriptor); -// descriptors->count -= 1; -// index = descriptor->index; -// } -// else -// { -// // Descriptor may still be in use by gpu -// descriptor = 0; -// } -// } - -// // Allocate new descriptor from heap -// if (!descriptor) -// { -// Lock lock = LockE(&heap->mutex); -// { -// if (heap->first_free) -// { -// descriptor = heap->first_free; -// DllStackRemove(heap->first_free, descriptor); -// index = descriptor->index; -// } -// else -// { -// u32 descriptors_count = ArenaCount(heap->descriptors_arena, G_D12_Descriptor); -// if (descriptors_count >= heap->max_count) -// { -// Panic(Lit("Max descriptors reached in heap")); -// } -// descriptor = PushStructNoZero(heap->descriptors_arena, G_D12_Descriptor); -// index = descriptors_count * per_batch_count; -// } -// } -// Unlock(&lock); -// } - -// // Initialize descriptor handle -// ZeroStruct(descriptor); -// descriptor->gpu_arena = gpu_arena; -// descriptor->index = index; -// descriptor->first_handle.ptr = heap->start_handle.ptr + (index * heap->stride); -// descriptor->heap = heap; - -// DllQueuePush(gpu_arena->descriptors.first, gpu_arena->descriptors.last, descriptor); -// gpu_arena->descriptors.count += 1; - -// return descriptor; -// } - - - - - - - - - - - -// void G_D12_InitRtv(G_D12_Resource *resource, D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle, i32 mip) -// { -// DXGI_FORMAT format = G_D12_DxgiFormatFromGpuFormat(resource->texture_format); -// D3D12_RESOURCE_DESC res_d3d_desc = Zi; -// { -// ID3D12Resource_GetDesc(resource->d3d_resource, &res_d3d_desc); -// } -// D3D12_RENDER_TARGET_VIEW_DESC rtv_desc = Zi; -// { -// rtv_desc.Format = res_d3d_desc.Format; -// if (res_d3d_desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D) -// { -// rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE1D; -// rtv_desc.Texture1D.MipSlice = mip; -// } -// else if (res_d3d_desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D) -// { -// rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; -// rtv_desc.Texture2D.MipSlice = mip; -// } -// else if (res_d3d_desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) -// { -// rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE3D; -// rtv_desc.Texture3D.MipSlice = mip; -// } -// } -// ID3D12Device_CreateRenderTargetView(G_D12.device, resource->d3d_resource, &rtv_desc, rtv_handle); -// } - - - - - - - - -// FIXME: Header - - - - - - - G_D12_Descriptor *G_D12_AcquireDescriptor(G_D12_DescriptorHeapKind heap_kind, u64 bundle_count) { G_D12_DescriptorHeap *heap = &G_D12.descriptor_heaps[heap_kind]; @@ -1338,12 +1188,11 @@ G_D12_Descriptor *G_D12_AcquireDescriptor(G_D12_DescriptorHeapKind heap_kind, u6 } Unlock(&lock); } - ZeroStruct(&descriptor->info); - // Fill indices - if (is_new) + // Fill descriptor indices + if (is_new && heap->gpu_visible_indices_to_descriptors_arena != 0) { - G_D12_Descriptor **indices_map_base = PushStructsNoZero(heap->indices_to_descriptors_arena, G_D12_Descriptor *, bundle_count); + G_D12_Descriptor **indices_map_base = PushStructsNoZero(heap->gpu_visible_indices_to_descriptors_arena, G_D12_Descriptor *, bundle_count); for (u64 base_offset_idx = 0; base_offset_idx < bundle_count; ++base_offset_idx) { indices_map_base[base_offset_idx] = descriptor; @@ -1355,110 +1204,54 @@ G_D12_Descriptor *G_D12_AcquireDescriptor(G_D12_DescriptorHeapKind heap_kind, u6 void G_D12_ReleaseDescriptor(G_D12_Descriptor *descriptor) { - // TODO -} + G_D12_DescriptorHeap *heap = descriptor->heap; + G_D12_DescriptorList *free_descriptors = &heap->free_descriptors_table.descriptors_by_bundle_count[descriptor->bundle_count]; + Atomic64Set(&descriptor->current_resource_ptr, 0); - - - - - - - - - -void G_D12_InitRtvDescriptor(G_D12_Descriptor *descriptor, G_D12_Resource *resource, i32 mip) -{ - DXGI_FORMAT format = G_D12_DxgiFormatFromGpuFormat(resource->texture_format); - D3D12_RESOURCE_DESC res_d3d_desc = Zi; + Lock lock = LockE(&heap->mutex); { - ID3D12Resource_GetDesc(resource->d3d_resource, &res_d3d_desc); + DllQueuePush(free_descriptors->first, free_descriptors->last, descriptor); } - D3D12_RENDER_TARGET_VIEW_DESC rtv_desc = Zi; - { - rtv_desc.Format = res_d3d_desc.Format; - if (res_d3d_desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D) - { - rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE1D; - rtv_desc.Texture1D.MipSlice = mip; - } - else if (res_d3d_desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D) - { - rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; - rtv_desc.Texture2D.MipSlice = mip; - } - else if (res_d3d_desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) - { - rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE3D; - rtv_desc.Texture3D.MipSlice = mip; - } - } - ID3D12Device_CreateRenderTargetView(G_D12.device, resource->d3d_resource, &rtv_desc, descriptor->d3d_handle); + Unlock(&lock); } - - G_D12_Descriptor *G_D12_DescriptorFromBufferRef(G_BufferRef ref) { G_D12_DescriptorHeap *heap = &G_D12.descriptor_heaps[G_D12_DescriptorHeapKind_CbvSrvUav]; - return ArenaFirst(heap->indices_to_descriptors_arena, G_D12_Descriptor *)[ref.v]; + return ArenaFirst(heap->gpu_visible_indices_to_descriptors_arena, G_D12_Descriptor *)[ref.v]; } G_D12_Descriptor *G_D12_DescriptorFromTextureRef(G_TextureRef ref) { G_D12_DescriptorHeap *heap = &G_D12.descriptor_heaps[G_D12_DescriptorHeapKind_CbvSrvUav]; - return ArenaFirst(heap->indices_to_descriptors_arena, G_D12_Descriptor *)[ref.v]; + return ArenaFirst(heap->gpu_visible_indices_to_descriptors_arena, G_D12_Descriptor *)[ref.v]; } G_D12_Descriptor *G_D12_DescriptorFromSamplerRef(G_SamplerRef ref) { G_D12_DescriptorHeap *heap = &G_D12.descriptor_heaps[G_D12_DescriptorHeapKind_Sampler]; - return ArenaFirst(heap->indices_to_descriptors_arena, G_D12_Descriptor *)[ref.v]; + return ArenaFirst(heap->gpu_visible_indices_to_descriptors_arena, G_D12_Descriptor *)[ref.v]; } G_D12_Resource *G_D12_ResourceFromBufferRef(G_BufferRef ref) { - return G_D12_DescriptorFromBufferRef(ref)->info.resource; + return (G_D12_Resource *)Atomic64Fetch(&G_D12_DescriptorFromBufferRef(ref)->current_resource_ptr); } G_D12_Resource *G_D12_ResourceFromTextureRef(G_TextureRef ref) { - return G_D12_DescriptorFromTextureRef(ref)->info.resource; + return (G_D12_Resource *)Atomic64Fetch(&G_D12_DescriptorFromTextureRef(ref)->current_resource_ptr); } G_D12_Resource *G_D12_ResourceFromSamplerRef(G_SamplerRef ref) { - return G_D12_DescriptorFromSamplerRef(ref)->info.resource; + return (G_D12_Resource *)Atomic64Fetch(&G_D12_DescriptorFromSamplerRef(ref)->current_resource_ptr); } - - - - - - - //////////////////////////////////////////////////////////// //~ @hookimpl Memory - - - - - - - - - - - -// TODO: Return nil descriptor when size is 0 - - - - - G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle gpu_arena_handle, G_MemoryDesc memory_desc) { Arena *perm = PermArena(); @@ -1503,11 +1296,11 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle { G_D12_ResourceHeapKind heap_kind = G_D12_ResourceHeapKind_Gpu; // Heap flags - if (flags & G_MemoryFlag_HostCached) + if (flags & G_MemoryFlag_CpuRead) { heap_kind = G_D12_ResourceHeapKind_CpuWriteBack; } - else if (flags & G_MemoryFlag_HostUncached) + else if (flags & G_MemoryFlag_CpuWrite) { heap_kind = G_D12_ResourceHeapKind_CpuWriteCombined; } @@ -1546,6 +1339,7 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle D3D12_CLEAR_VALUE clear_value = Zi; D3D12_RESOURCE_DESC1 d3d_desc = Zi; u64 buffer_size = 0; + u64 texture_mips_count = 0; if (is_buffer) { u64 min_buffer_size = 1024; @@ -1587,6 +1381,7 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle clear_value.Color[2] = memory_desc.texture.clear_color.z, clear_value.Color[3] = memory_desc.texture.clear_color.w, clear_value.Format = d3d_desc.Format; + texture_mips_count = d3d_desc.MipLevels; } ////////////////////////////// @@ -1638,6 +1433,7 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle ZeroStruct(release); SllQueuePush(cl->releases.first, cl->releases.last, release); release->d3d_resource = resource->d3d_resource; + release->gpu_descriptor = resource->gpu_descriptor; } ZeroStruct(resource); } @@ -1658,19 +1454,6 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle resource->flags = flags; - if (is_texture) - { - resource->is_texture = 1; - resource->texture_format = memory_desc.texture.format; - resource->texture_dims = memory_desc.texture.dims; - resource->texture_mips = d3d_desc.MipLevels; - } - - if (is_sampler) - { - resource->sampler_desc = memory_desc.sampler; - } - DllQueuePush(gpu_arena->resources.first, gpu_arena->resources.last, resource); ++gpu_arena->resources.count; @@ -1734,15 +1517,34 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle if (is_buffer) { + resource->buffer_element_offset = 0; + resource->buffer_element_stride = MaxU64(memory_desc.buffer.stride, 1); + resource->buffer_element_count = buffer_size / resource->buffer_element_stride; resource->buffer_gpu_address = ID3D12Resource_GetGPUVirtualAddress(resource->d3d_resource); } + else if (is_texture) + { + resource->is_texture = 1; + resource->texture_format = memory_desc.texture.format; + resource->texture_dims = memory_desc.texture.dims; + resource->texture_mips = RNGI32(0, d3d_desc.MipLevels - 1); + } + else if (is_sampler) + { + resource->sampler_desc = memory_desc.sampler; + } } if (should_map && !resource->mapped) { - D3D12_RANGE read_range = Zi; - HRESULT hr = ID3D12Resource_Map(resource->d3d_resource, 0, &read_range, &resource->mapped); - + D3D12_RANGE zero_read_range = Zi; + D3D12_RANGE *read_range_arg = &zero_read_range; + if (memory_desc.buffer.flags & G_MemoryFlag_CpuRead) + { + // Specify NULL read range to signal to D3D12 that any part of address range may be read by CPU + read_range_arg = 0; + } + HRESULT hr = ID3D12Resource_Map(resource->d3d_resource, 0, read_range_arg, &resource->mapped); if (!SUCCEEDED(hr)) { // TODO: Don't panic @@ -1766,98 +1568,49 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle } ////////////////////////////// - //- Push descriptor + //- Initialize descriptors - - - - - // G_D12_RefBundle *bundle = 0; - // { - // G_D12_RefBundleDesc memory_desc = Zi; - // memory_desc.resource = resource; - // if (is_buffer) - // { - // memory_desc.buffer_element_offset = 0; - // memory_desc.buffer_element_count = memory_desc.buffer.count; - // memory_desc.buffer_element_stride = memory_desc.buffer.stride; - // } - // else if (is_texture) - // { - // memory_desc.mips = RngI32(0, resource->texture_mips); - // } - - // bundle = G_D12_PushRefBundle(cl, gpu_arena, memory_desc); - // } - - - G_D12_Descriptor *descriptor = 0; + if (!resource->gpu_descriptor) { - G_QueueCompletions completions = G_CompletionValuesFromQueues(G_QueueMask_All); - G_D12_DescriptorHeapKind descriptor_heap_kind = 0; - u64 bundle_count = 0; - if (is_buffer) - { - bundle_count = 4; - descriptor_heap_kind = G_D12_DescriptorHeapKind_CbvSrvUav; - } - else if (is_texture) - { - // 0: SRV, 1: UAV - bundle_count = resource->texture_mips * 2; - descriptor_heap_kind = G_D12_DescriptorHeapKind_CbvSrvUav; - } - else - { - bundle_count = 1; - descriptor_heap_kind = G_D12_DescriptorHeapKind_Sampler; - } - G_D12_DescriptorTable *table = &gpu_arena->reset_descriptor_tables_by_heap[descriptor_heap_kind]; - G_D12_DescriptorList *reset_descriptors = &table->descriptors_by_bundle_count[bundle_count]; - descriptor = reset_descriptors->first; - if (descriptor && completions.v[descriptor->info.completion_queue_kind] >= descriptor->info.completion_queue_target) - { - DllQueueRemove(reset_descriptors->first, reset_descriptors->last, descriptor); - --reset_descriptors->count; - } - else - { - descriptor = G_D12_AcquireDescriptor(descriptor_heap_kind, bundle_count); - DllQueuePush(gpu_arena->descriptors.first, gpu_arena->descriptors.last, descriptor); - ++gpu_arena->descriptors.count; - descriptor->info.gpu_arena = gpu_arena; - } - } + ////////////////////////////// + //- Allocate GPU resource descriptor - ////////////////////////////// - //- Create views - - // TODO: Descriptor reuse - b32 can_reuse_descriptor = 0; - - if (!can_reuse_descriptor) - { - descriptor->info.resource = resource; - if (is_texture) + u64 descriptor_count = 0; + G_D12_Descriptor *descriptor = 0; { - descriptor->info.mips = RNGI32(0, resource->texture_mips - 1); - } - else if (is_buffer) - { - descriptor->info.buffer_element_offset = 0; - descriptor->info.buffer_element_count = memory_desc.buffer.count; - descriptor->info.buffer_element_stride = memory_desc.buffer.stride; - } - - { - //- Buffer views + G_QueueCompletions completions = G_CompletionValuesFromQueues(G_QueueMask_All); + G_D12_DescriptorHeapKind descriptor_heap_kind = 0; if (is_buffer) { - // base index + 0: Structured SRV - // base index + 1: Structured UAV - // base index + 2: Raw SRV - // base index + 3: Raw UAV - for (u32 descriptor_idx_offset = 0; descriptor_idx_offset < 4; ++descriptor_idx_offset) + descriptor_count = 4; + descriptor_heap_kind = G_D12_DescriptorHeapKind_CbvSrvUav; + } + else if (is_texture) + { + // 0: SRV, 1: UAV + descriptor_count = texture_mips_count * 2; + descriptor_heap_kind = G_D12_DescriptorHeapKind_CbvSrvUav; + } + else + { + descriptor_count = 1; + descriptor_heap_kind = G_D12_DescriptorHeapKind_Sampler; + } + descriptor = G_D12_AcquireDescriptor(descriptor_heap_kind, descriptor_count); + Atomic64Set(&descriptor->current_resource_ptr, (i64)resource); + } + + ////////////////////////////// + //- Create GPU views + + { + if (is_buffer) + { + // Base index + 0: Structured SRV + // Base index + 1: Structured UAV + // Base index + 2: Raw SRV + // Base index + 3: Raw UAV + for (u32 descriptor_idx_offset = 0; descriptor_idx_offset < descriptor_count; ++descriptor_idx_offset) { D3D12_CPU_DESCRIPTOR_HANDLE d3d_handle = { .ptr = descriptor->d3d_handle.ptr + descriptor_idx_offset * descriptor->heap->stride }; if (descriptor_idx_offset % 2 == 0) @@ -1868,17 +1621,17 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle srv.Format = DXGI_FORMAT_UNKNOWN; srv.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; srv.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - srv.Buffer.FirstElement = descriptor->info.buffer_element_offset; - srv.Buffer.NumElements = descriptor->info.buffer_element_count; - srv.Buffer.StructureByteStride = descriptor->info.buffer_element_stride; + srv.Buffer.FirstElement = resource->buffer_element_offset; + srv.Buffer.NumElements = resource->buffer_element_count; + srv.Buffer.StructureByteStride = resource->buffer_element_stride; if (descriptor_idx_offset >= 2) { // Raw srv.Format = DXGI_FORMAT_R32_TYPELESS; srv.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW; srv.Buffer.StructureByteStride = 0; - srv.Buffer.FirstElement = (descriptor->info.buffer_element_offset * descriptor->info.buffer_element_stride) / 4; - srv.Buffer.NumElements = (descriptor->info.buffer_element_count * descriptor->info.buffer_element_stride) / 4; + srv.Buffer.FirstElement = (resource->buffer_element_offset * resource->buffer_element_stride) / 4; + srv.Buffer.NumElements = (resource->buffer_element_count * resource->buffer_element_stride) / 4; } else if (srv.Buffer.StructureByteStride < 4) { @@ -1903,17 +1656,17 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle D3D12_UNORDERED_ACCESS_VIEW_DESC uav = Zi; uav.Format = DXGI_FORMAT_UNKNOWN; uav.ViewDimension = D3D12_UAV_DIMENSION_BUFFER; - uav.Buffer.FirstElement = descriptor->info.buffer_element_offset; - uav.Buffer.NumElements = descriptor->info.buffer_element_count; - uav.Buffer.StructureByteStride = descriptor->info.buffer_element_stride; + uav.Buffer.FirstElement = resource->buffer_element_offset; + uav.Buffer.NumElements = resource->buffer_element_count; + uav.Buffer.StructureByteStride = resource->buffer_element_stride; if (descriptor_idx_offset >= 2) { // Raw uav.Format = DXGI_FORMAT_R32_TYPELESS; uav.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW; uav.Buffer.StructureByteStride = 0; - uav.Buffer.FirstElement = (descriptor->info.buffer_element_offset * descriptor->info.buffer_element_stride) / 4; - uav.Buffer.NumElements = (descriptor->info.buffer_element_count * descriptor->info.buffer_element_stride) / 4; + uav.Buffer.FirstElement = (resource->buffer_element_offset * resource->buffer_element_stride) / 4; + uav.Buffer.NumElements = (resource->buffer_element_count * resource->buffer_element_stride) / 4; } else if (uav.Buffer.StructureByteStride < 4) { @@ -1937,14 +1690,14 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle //- Texture views if (is_texture) { - // base index + mip + 0: mip SRV - // base index + mip + 1: mip UAV + // Base index + Mip index + 0: mip SRV + // Base index + Mip index + 1: mip UAV // etc... - for (u32 descriptor_idx_offset = 0; descriptor_idx_offset < (u32)resource->texture_mips * 2; ++descriptor_idx_offset) + for (u32 descriptor_idx_offset = 0; descriptor_idx_offset < descriptor_count; ++descriptor_idx_offset) { D3D12_CPU_DESCRIPTOR_HANDLE d3d_handle = { .ptr = descriptor->d3d_handle.ptr + descriptor_idx_offset * descriptor->heap->stride }; - RngI32 mips = RNGI32(descriptor_idx_offset / 2, resource->texture_mips - 1); + RngI32 mips = RNGI32(descriptor_idx_offset / 2, resource->texture_mips.max); if (descriptor_idx_offset % 2 == 0) { @@ -2036,6 +1789,8 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle ID3D12Device_CreateSampler(G_D12.device, &sampler, descriptor->d3d_handle); } } + + resource->gpu_descriptor = descriptor; } @@ -2062,7 +1817,7 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle queue_kind != G_QueueKind_AsyncCopy ) { - G_SyncLayout(cl_handle, G_MakeTextureRef(descriptor->base_index), G_TextureLayout_Common); + G_SyncLayout(cl_handle, G_MakeTextureRef(resource->gpu_descriptor->base_index), G_TextureLayout_Common); } @@ -2073,12 +1828,12 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle { G_CopyCpuToBuffer( cl_handle, - G_MakeBufferRef(descriptor->base_index), 0, + G_MakeBufferRef(resource->gpu_descriptor->base_index), 0, memory_desc.buffer.cpu_src, RNGU64(0, memory_desc.buffer.stride * memory_desc.buffer.count) ); } - return descriptor->base_index; + return resource->gpu_descriptor->base_index; } @@ -2088,558 +1843,11 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle - - - -// G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle cl_handle, G_ResourceDesc desc) -// { -// Arena *perm = PermArena(); -// G_D12_Arena *gpu_arena = G_D12_ArenaFromHandle(arena_handle); -// G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle); -// G_QueueKind queue_kind = cl->queue_kind; -// G_D12_Resource *resource = 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_MemoryFlag flags = ( -// is_buffer ? desc.buffer.flags : -// is_texture ? desc.texture.flags : -// desc.sampler.flags -// ); -// String new_name = ( -// is_buffer ? desc.buffer.name : -// is_texture ? desc.texture.name : -// desc.sampler.name -// ); -// new_name.len = MinU64(new_name.len, G_D12_MaxNameLen); - -// ////////////////////////////// -// //- Initialize heap info - -// b32 can_reuse = !AnyBit(flags, G_MemoryFlag_ForceNoReuse); - -// D3D12_HEAP_FLAGS heap_flags = 0; -// D3D12_HEAP_PROPERTIES heap_props = Zi; -// b32 should_map = 0; -// if (is_buffer || is_texture) -// { -// G_D12_ResourceHeapKind heap_kind = G_D12_ResourceHeapKind_Gpu; -// // Heap flags -// if (flags & G_MemoryFlag_HostMemory) -// { -// heap_kind = G_D12_ResourceHeapKind_CpuWriteBack; -// if (flags & G_MemoryFlag_Uncached) -// { -// heap_kind = G_D12_ResourceHeapKind_CpuWriteCombined; -// } -// } -// if (flags & G_MemoryFlag_Zero) -// { -// can_reuse = 0; -// } -// else -// { -// heap_flags |= D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; -// } -// // Heap props -// if (heap_kind == G_D12_ResourceHeapKind_CpuWriteBack) -// { -// heap_props.Type = D3D12_HEAP_TYPE_CUSTOM; -// heap_props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_BACK; -// heap_props.MemoryPoolPreference = D3D12_MEMORY_POOL_L0; -// should_map = 1; -// } -// else if (heap_kind == G_D12_ResourceHeapKind_CpuWriteCombined) -// { -// heap_props.Type = D3D12_HEAP_TYPE_CUSTOM; -// heap_props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE; -// heap_props.MemoryPoolPreference = D3D12_MEMORY_POOL_L0; -// should_map = 1; -// } -// else -// { -// heap_props.Type = D3D12_HEAP_TYPE_DEFAULT; -// } -// } - -// ////////////////////////////// -// //- Initialize d3d resource desc - -// D3D12_CLEAR_VALUE clear_value = Zi; -// D3D12_RESOURCE_DESC1 d3d_desc = Zi; -// if (is_buffer) -// { -// u64 min_buffer_size = 1024; -// d3d_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; -// d3d_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; -// d3d_desc.Format = DXGI_FORMAT_UNKNOWN; -// d3d_desc.Width = NextPow2U64(MaxU64(desc.buffer.size, min_buffer_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(flags, G_MemoryFlag_AllowShaderReadWrite); -// } -// else if (is_texture) -// { -// i32 largest_dim = MaxI32(MaxI32(desc.texture.dims.x, desc.texture.dims.y), desc.texture.dims.z); -// i32 max_mips = MinI32(FloorF32(Log2F32(largest_dim)) + 1, G_MaxMips); -// 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 = ClampF32(desc.texture.max_mips, 1, max_mips); -// d3d_desc.SampleDesc.Count = 1; -// d3d_desc.SampleDesc.Quality = 0; -// d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS * AnyBit(flags, G_MemoryFlag_AllowShaderReadWrite); -// d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET * AnyBit(flags, G_MemoryFlag_AllowRenderTarget); -// d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL * AnyBit(flags, G_MemoryFlag_AllowTextureDepthStencil); -// d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS * (desc.texture.initial_layout == G_TextureLayout_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; -// } - -// ////////////////////////////// -// //- Check for reset-resource reusability - -// // Pop reset resource -// resource = gpu_arena->reset_resources.first; -// if (resource) -// { -// DllQueueRemove(gpu_arena->reset_resources.first, gpu_arena->reset_resources.last, resource); -// --gpu_arena->reset_resources.count; - -// D3D12_RESOURCE_DESC1 reset_d3d_desc = Zi; -// D3D12_RESOURCE_DESC1 compare_d3d_desc = Zi; -// CopyStruct(&reset_d3d_desc, &resource->d3d_desc); -// CopyStruct(&compare_d3d_desc, &reset_d3d_desc); - -// // Buffers can be reused if size fits -// if (d3d_desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && reset_d3d_desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) -// { -// if (reset_d3d_desc.Width >= d3d_desc.Width) -// { -// compare_d3d_desc.Width = d3d_desc.Width; -// } -// } - -// // TODO: Less stringent reuse constraints. We could even create textures as placed resources and reset their underlying heaps. -// can_reuse = can_reuse && MatchStruct(&compare_d3d_desc, &d3d_desc); -// if (!can_reuse) -// { -// // Push releasable to command list -// { -// G_D12_Releasable *release = 0; -// { -// Lock lock = LockE(&G_D12.free_releases_mutex); -// { -// release = G_D12.free_releases.first; -// if (release) -// { -// SllQueuePop(G_D12.free_releases.first, G_D12.free_releases.last); -// } -// else -// { -// release = PushStructNoZero(perm, G_D12_Releasable); -// } -// } -// Unlock(&lock); -// } -// ZeroStruct(release); -// SllQueuePush(cl->releases.first, cl->releases.last, release); -// release->d3d_resource = resource->d3d_resource; -// } -// ZeroStruct(resource); -// } -// } -// else -// { -// can_reuse = 0; -// resource = PushStruct(gpu_arena->arena, G_D12_Resource); -// } - -// if (!can_reuse) -// { -// resource->d3d_desc = d3d_desc; -// } - -// ////////////////////////////// -// //- Init resource - -// resource->flags = flags; - -// if (is_buffer) -// { -// resource->buffer_size = desc.buffer.size; -// resource->buffer_size_actual = d3d_desc.Width; -// } - -// if (is_texture) -// { -// resource->is_texture = is_texture; -// resource->texture_format = desc.texture.format; -// resource->texture_dims = desc.texture.dims; -// resource->texture_mips = d3d_desc.MipLevels; -// } - -// if (is_sampler) -// { -// resource->sampler_desc = desc.sampler; -// } - -// DllQueuePush(gpu_arena->resources.first, gpu_arena->resources.last, resource); -// ++gpu_arena->resources.count; - -// ////////////////////////////// -// //- Allocate D3D12 resource - -// if ((is_buffer || is_texture) && !resource->d3d_resource) -// { -// D3D12_CLEAR_VALUE *clear_value_arg = 0; -// if (d3d_desc.Flags & (D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL)) -// { -// clear_value_arg = &clear_value; -// } - -// D3D12_BARRIER_LAYOUT d3d_initial_layout = D3D12_BARRIER_LAYOUT_UNDEFINED; -// if (is_texture) -// { -// d3d_initial_layout = D3D12_BARRIER_LAYOUT_COMMON; -// if (desc.texture.initial_layout == G_TextureLayout_Family) -// { -// switch (queue_kind) -// { -// case G_QueueKind_Direct: d3d_initial_layout = D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COMMON; break; -// case G_QueueKind_AsyncCompute: d3d_initial_layout = D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COMMON; break; -// } -// } -// } - -// HRESULT hr = ID3D12Device10_CreateCommittedResource3( -// G_D12.device, -// &heap_props, -// heap_flags, -// &resource->d3d_desc, -// d3d_initial_layout, -// clear_value_arg, -// 0, // pProtectedSession -// 0, // NumCastableFormats -// 0, // pCastableFormats -// &IID_ID3D12Resource, -// (void **)&resource->d3d_resource -// ); -// Atomic64FetchAdd(&G_D12.cumulative_nonreuse_count, 1); -// resource->uid = Atomic64FetchAdd(&G_D12.resource_creation_gen.v, d3d_desc.MipLevels); - -// // Queue initial Rtv/Dsv discard -// if ( -// !AnyBit(flags, G_MemoryFlag_Zero) && -// AnyBit(d3d_desc.Flags, D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) -// ) -// { -// G_D12_Cmd *cmd = G_D12_PushCmd(cl); -// cmd->kind = G_D12_CmdKind_Discard; -// cmd->discard.resource = resource; -// } - -// if (!SUCCEEDED(hr)) -// { -// // TODO: Don't panic -// Panic(Lit("Failed to allocate D3D12 resource")); -// } - -// if (is_buffer) -// { -// resource->buffer_gpu_address = ID3D12Resource_GetGPUVirtualAddress(resource->d3d_resource); -// } -// } - -// if (should_map && !resource->mapped) -// { -// D3D12_RANGE read_range = Zi; -// HRESULT hr = ID3D12Resource_Map(resource->d3d_resource, 0, &read_range, &resource->mapped); - -// if (!SUCCEEDED(hr)) -// { -// // TODO: Don't panic -// Panic(Lit("Failed to map D3D12 resource")); -// } -// } - -// ////////////////////////////// -// //- Set debug information - -// String old_name = STRING(resource->name_len, (u8 *)resource->name_cstr); -// if (!MatchString(old_name, new_name)) -// { -// resource->name_len = new_name.len; -// CopyBytes(resource->name_cstr, new_name.text, new_name.len); -// resource->name_cstr[new_name.len] = 0; -// if (resource->d3d_resource) -// { -// G_D12_SetObjectName((ID3D12Object *)resource->d3d_resource, new_name); -// } -// } - -// ////////////////////////////// -// //- Transition reused resources to common - -// G_ResourceHandle resource_handle = G_D12_MakeHandle(G_ResourceHandle, resource); -// if ( -// can_reuse && -// desc.texture.initial_layout == G_TextureLayout_Common && -// queue_kind != G_QueueKind_AsyncCopy -// ) -// { -// G_SyncLayout(cl_handle, resource_handle, G_TextureLayout_Common); -// } - -// return resource_handle; -// } - - - - - - - - -//////////////////////////////////////////////////////////// -//~ @hookimpl Shader resource reference - -// u32 G_PushRef(G_ArenaHandle arena_handle, G_ResourceHandle resource_handle, G_RefDesc ref_desc) -// { -// G_D12_Arena *gpu_arena = G_D12_ArenaFromHandle(arena_handle); -// G_D12_Resource *resource = G_D12_ResourceFromHandle(resource_handle); -// u32 result = 0; - -// G_RefKind kind = ref_desc.kind; -// b32 is_buffer = ( -// kind == G_RefKind_StructuredBuffer || -// kind == G_RefKind_ByteAddressBuffer -// ); -// b32 is_sampler = kind == G_RefKind_SamplerState; -// b32 is_texture = !is_buffer && !is_sampler; -// b32 is_raw = kind == G_RefKind_ByteAddressBuffer; -// b32 is_writable = resource->flags & G_MemoryFlag_AllowShaderReadWrite; - -// G_D12_Descriptor *descriptor = 0; -// if (is_buffer || is_texture) -// { -// descriptor = G_D12_PushDescriptor(gpu_arena, G_D12_DescriptorHeapKind_CbvSrvUav); - -// G_D12_DescriptorHeap *heap = &G_D12.descriptor_heaps[G_D12_DescriptorHeapKind_CbvSrvUav]; -// Assert(heap->per_batch_count >= 2); -// D3D12_CPU_DESCRIPTOR_HANDLE readonly_handle = descriptor->first_handle; -// D3D12_CPU_DESCRIPTOR_HANDLE readwrite_handle = descriptor->first_handle; -// readwrite_handle.ptr += heap->stride; - -// b32 srv_ok = 0; -// b32 uav_ok = 0; - -// D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = Zi; -// D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc = Zi; - -// if (is_buffer) -// { -// if (is_raw) -// { -// ref_desc.element_size = 4; -// ref_desc.element_offset /= 4; -// } - -// 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; - -// //- Create buffer SRV -// { -// { -// srv_desc.Format = DXGI_FORMAT_UNKNOWN; -// srv_desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; -// srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; -// srv_desc.Buffer.FirstElement = ref_desc.element_offset; -// srv_desc.Buffer.NumElements = num_elements_after_offset; -// srv_desc.Buffer.StructureByteStride = ref_desc.element_size; -// srv_desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE; -// } -// if (is_raw) -// { -// srv_desc.Format = DXGI_FORMAT_R32_TYPELESS; -// srv_desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW; -// srv_desc.Buffer.StructureByteStride = 0; -// } -// srv_ok = 1; -// } -// //- Create buffer UAV -// { -// { -// uav_desc.Format = DXGI_FORMAT_UNKNOWN; -// uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER; -// uav_desc.Buffer.FirstElement = ref_desc.element_offset; -// uav_desc.Buffer.NumElements = num_elements_after_offset; -// uav_desc.Buffer.StructureByteStride = ref_desc.element_size; -// uav_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE; -// } -// if (is_raw) -// { -// uav_desc.Format = DXGI_FORMAT_R32_TYPELESS; -// uav_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW; -// uav_desc.Buffer.StructureByteStride = 0; -// } -// } -// if (num_elements_after_offset > 0) -// { -// srv_ok = 1; -// if (is_writable) -// { -// uav_ok = 1; -// } -// } -// } -// else if (is_texture) -// { -// // DXGI_FORMAT format = G_D12_DxgiFormatFromGpuFormat(resource->texture_format); -// RngI32 mips = ref_desc.mips; -// mips.min = ClampI32(mips.min, 0, resource->texture_mips - 1); -// mips.max = ClampI32(mips.max, mips.min, resource->texture_mips - 1); -// //- Create texture SRV -// { -// srv_desc.Format = DXGI_FORMAT_UNKNOWN; -// srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; -// if (ref_desc.kind == G_RefKind_Texture1D) -// { -// srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D; -// srv_desc.Texture1D.MostDetailedMip = mips.min; -// srv_desc.Texture1D.MipLevels = mips.max - mips.min + 1; -// } -// else if (ref_desc.kind == G_RefKind_Texture2D) -// { -// srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; -// srv_desc.Texture2D.MostDetailedMip = mips.min; -// srv_desc.Texture2D.MipLevels = mips.max - mips.min + 1; -// } -// else if (ref_desc.kind == G_RefKind_Texture3D) -// { -// srv_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D; -// srv_desc.Texture3D.MostDetailedMip = mips.min; -// srv_desc.Texture3D.MipLevels = mips.max - mips.min + 1; -// } -// } -// //- Create texture UAV -// { -// uav_desc.Format = DXGI_FORMAT_UNKNOWN; -// if (ref_desc.kind == G_RefKind_Texture1D) -// { -// uav_desc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE1D; -// uav_desc.Texture1D.MipSlice = mips.min; -// } -// else if (ref_desc.kind == G_RefKind_Texture2D) -// { -// uav_desc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D; -// uav_desc.Texture2D.MipSlice = mips.min; -// } -// else if (ref_desc.kind == G_RefKind_Texture3D) -// { -// uav_desc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE3D; -// uav_desc.Texture3D.MipSlice = mips.min; -// uav_desc.Texture3D.WSize = U32Max; -// } -// } - -// srv_ok = 1; -// if (is_writable) -// { -// uav_ok = 1; -// } - -// if (!uav_ok) -// { -// uav_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; -// } -// } - -// if (srv_ok) -// { -// ID3D12Device_CreateShaderResourceView(G_D12.device, resource->d3d_resource, &srv_desc, readonly_handle); -// } -// else -// { -// ID3D12Device_CreateShaderResourceView(G_D12.device, 0, &srv_desc, readonly_handle); -// } - -// if (uav_ok) -// { -// ID3D12Device_CreateUnorderedAccessView(G_D12.device, resource->d3d_resource, 0, &uav_desc, readwrite_handle); -// } -// else -// { -// ID3D12Device_CreateUnorderedAccessView(G_D12.device, 0, 0, &uav_desc, readwrite_handle); -// } -// } -// else if (is_sampler) -// { -// descriptor = G_D12_PushDescriptor(gpu_arena, G_D12_DescriptorHeapKind_Sampler); -// G_SamplerDesc sampler_desc = resource->sampler_desc; -// D3D12_SAMPLER_DESC d3d_desc = Zi; -// { -// d3d_desc.Filter = (D3D12_FILTER)sampler_desc.filter; -// d3d_desc.AddressU = (D3D12_TEXTURE_ADDRESS_MODE)sampler_desc.x; -// d3d_desc.AddressV = (D3D12_TEXTURE_ADDRESS_MODE)sampler_desc.y; -// d3d_desc.AddressW = (D3D12_TEXTURE_ADDRESS_MODE)sampler_desc.z; -// d3d_desc.MipLODBias = sampler_desc.mip_lod_bias; -// d3d_desc.MaxAnisotropy = MaxU32(sampler_desc.max_anisotropy, 1); -// d3d_desc.ComparisonFunc = (D3D12_COMPARISON_FUNC)sampler_desc.comparison; -// d3d_desc.BorderColor[0] = sampler_desc.border_color.x; -// d3d_desc.BorderColor[1] = sampler_desc.border_color.y; -// d3d_desc.BorderColor[2] = sampler_desc.border_color.z; -// d3d_desc.BorderColor[3] = sampler_desc.border_color.w; -// d3d_desc.MinLOD = sampler_desc.min_lod; -// d3d_desc.MaxLOD = sampler_desc.max_lod; -// } -// if (d3d_desc.AddressU == 0) d3d_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; -// if (d3d_desc.AddressV == 0) d3d_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; -// if (d3d_desc.AddressW == 0) d3d_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; -// if (d3d_desc.MaxLOD >= Inf) -// { -// d3d_desc.MaxLOD = D3D12_FLOAT32_MAX; -// } -// ID3D12Device_CreateSampler(G_D12.device, &d3d_desc, descriptor->first_handle); -// } - -// return descriptor->index; -// } - //- Count -u64 G_CountBufferStride(G_BufferRef buffer) +u64 G_CountStride(G_BufferRef buffer) { - return G_D12_DescriptorFromBufferRef(buffer)->info.buffer_element_stride; -} - -u64 G_CountBuffer(G_BufferRef buffer) -{ - return G_D12_DescriptorFromBufferRef(buffer)->info.buffer_element_count; -} - -u64 G_CountBufferBytes(G_BufferRef buffer) -{ - return G_D12_DescriptorFromBufferRef(buffer)->info.buffer_element_count * G_D12_DescriptorFromBufferRef(buffer)->info.buffer_element_stride; + return G_D12_ResourceFromBufferRef(buffer)->buffer_element_stride; } i32 G_Count1D(G_TextureRef texture) @@ -2686,8 +1894,8 @@ i32 G_CountDepth(G_TextureRef texture) i32 G_CountMips(G_TextureRef texture) { - G_D12_Descriptor *descriptor = G_D12_DescriptorFromTextureRef(texture); - i32 result = descriptor->info.mips.max - descriptor->info.mips.min + 1; + G_D12_Resource *resource = G_D12_ResourceFromTextureRef(texture); + i32 result = resource->texture_mips.max - resource->texture_mips.min + 1; return result; } @@ -2835,7 +2043,7 @@ G_D12_StagingRegionNode *G_D12_PushStagingRegion(G_D12_CmdList *cl, u64 size) ring->buffer = G_PushStructs( G_D12_MakeHandle(G_CommandListHandle, cl), gpu_arena_handle, u8, new_ring_size, - .flags = G_MemoryFlag_HostUncached + .flags = G_MemoryFlag_CpuWrite ); ring->base = G_Deref(ring->buffer, u8); } @@ -2903,6 +2111,35 @@ G_D12_StagingRegionNode *G_D12_PushStagingRegion(G_D12_CmdList *cl, u64 size) return result; } +void G_D12_InitRtvDescriptor(G_D12_Descriptor *descriptor, G_D12_Resource *resource, i32 mip) +{ + DXGI_FORMAT format = G_D12_DxgiFormatFromGpuFormat(resource->texture_format); + D3D12_RESOURCE_DESC res_d3d_desc = Zi; + { + ID3D12Resource_GetDesc(resource->d3d_resource, &res_d3d_desc); + } + D3D12_RENDER_TARGET_VIEW_DESC rtv_desc = Zi; + { + rtv_desc.Format = res_d3d_desc.Format; + if (res_d3d_desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D) + { + rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE1D; + rtv_desc.Texture1D.MipSlice = mip; + } + else if (res_d3d_desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D) + { + rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + rtv_desc.Texture2D.MipSlice = mip; + } + else if (res_d3d_desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) + { + rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE3D; + rtv_desc.Texture3D.MipSlice = mip; + } + } + ID3D12Device_CreateRenderTargetView(G_D12.device, resource->d3d_resource, &rtv_desc, descriptor->d3d_handle); +} + //////////////////////////////////////////////////////////// //~ Instrumentation @@ -3271,12 +2508,12 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) if (is_rtv) { batch->contains_rtv = 1; - G_D12_UpdateTrackedUsage(scratch.arena, batch, resource, RNGI32(0, resource->texture_mips - 1), G_D12_TrackedUsageKind_RenderTarget); + G_D12_UpdateTrackedUsage(scratch.arena, batch, resource, resource->texture_mips, G_D12_TrackedUsageKind_RenderTarget); } else if (is_dsv) { batch->contains_dsv_write = 1; - G_D12_UpdateTrackedUsage(scratch.arena, batch, resource, RNGI32(0, resource->texture_mips - 1), G_D12_TrackedUsageKind_DepthStencilReadWrite); + G_D12_UpdateTrackedUsage(scratch.arena, batch, resource, resource->texture_mips, G_D12_TrackedUsageKind_DepthStencilReadWrite); } } else if (cmd_kind == G_D12_CmdKind_CopyBytes || cmd_kind == G_D12_CmdKind_CopyTexels) @@ -3299,11 +2536,11 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) { if (cmd->barrier.acquire) { - G_D12_UpdateTrackedUsage(scratch.arena, batch, resource, RNGI32(0, resource->texture_mips - 1), G_D12_TrackedUsageKind_Acquire); + G_D12_UpdateTrackedUsage(scratch.arena, batch, resource, resource->texture_mips, G_D12_TrackedUsageKind_Acquire); } else { - G_D12_UpdateTrackedUsage(scratch.arena, batch, resource, RNGI32(0, resource->texture_mips - 1), G_D12_TrackedUsageKind_Release); + G_D12_UpdateTrackedUsage(scratch.arena, batch, resource, resource->texture_mips, G_D12_TrackedUsageKind_Release); } } } @@ -3338,7 +2575,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) { G_D12_Resource *resource = trn->resource; - for (i32 mip_idx = 0; mip_idx < resource->texture_mips; ++mip_idx) + for (i32 mip_idx = resource->texture_mips.min; mip_idx <= resource->texture_mips.max; ++mip_idx) { G_D12_TrackedMip *mip = &trn->mips[mip_idx]; @@ -3699,29 +2936,27 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) } // Create ibv - u32 indices_count = G_CountBuffer(cmd->draw.indices); + u32 indices_count = cmd->draw.indices.count; D3D12_INDEX_BUFFER_VIEW ibv = Zi; + if (indices_count > 0) { - if (indices_count > 0) + G_D12_Resource *indices_resource = G_D12_ResourceFromBufferRef(cmd->draw.indices.buffer); + u32 stride = indices_resource->buffer_element_stride; + ibv.BufferLocation = indices_resource->buffer_gpu_address; + ibv.SizeInBytes = indices_count * stride; + if (stride == 2) { - G_D12_Resource *indices_resource = G_D12_ResourceFromBufferRef(cmd->draw.indices); - u32 stride = G_CountBufferStride(cmd->draw.indices); - ibv.BufferLocation = indices_resource->buffer_gpu_address; - ibv.SizeInBytes = indices_count * stride; - if (stride == 2) - { - ibv.Format = DXGI_FORMAT_R16_UINT; - } - else if (stride == 4) - { - ibv.Format = DXGI_FORMAT_R32_UINT; - } - else - { - indices_count = 0; - ZeroStruct(&ibv); - Assert(0); // Invalid index size - } + ibv.Format = DXGI_FORMAT_R16_UINT; + } + else if (stride == 4) + { + ibv.Format = DXGI_FORMAT_R32_UINT; + } + else + { + indices_count = 0; + ZeroStruct(&ibv); + Assert(0); // Invalid index size } } @@ -3892,8 +3127,8 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) { G_D12_Resource *resource = cmd->discard.resource; D3D12_DISCARD_REGION region = Zi; - region.FirstSubresource = 0; - region.NumSubresources = resource->texture_mips; + region.FirstSubresource = resource->texture_mips.min; + region.NumSubresources = resource->texture_mips.max + 1; G_D12_InsertEvent(d3d_cl, G_D12_EventKind_Marker, STRING(resource->name_len, (u8 *)resource->name_cstr)); ID3D12GraphicsCommandList_DiscardResource(d3d_cl, resource->d3d_resource, 0); } break; @@ -3917,35 +3152,15 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) } ////////////////////////////// - //- Attach completion info to reset descriptors - - for (G_D12_Descriptor *descriptor = cl->reset_descriptors.first; descriptor;) - { - G_D12_Descriptor *next = descriptor->next; - { - G_D12_Arena *gpu_arena = descriptor->info.gpu_arena; - descriptor->info.completion_queue_kind = queue_kind; - descriptor->info.completion_queue_target = completion_target; - G_D12_DescriptorTable *dst_table = &gpu_arena->reset_descriptor_tables_by_heap[descriptor->heap->kind]; - G_D12_DescriptorList *dst_list = &dst_table->descriptors_by_bundle_count[descriptor->bundle_count]; - DllQueuePush(dst_list->first, dst_list->last, descriptor); - ++dst_list->count; - } - descriptor = next; - } - - ////////////////////////////// - //- Attach completion info to releasables & submit for release + //- Submit releases to release queue if (cl->releases.first) { - // Attach completion info for (G_D12_Releasable *release = cl->releases.first; release; release = release->next) { release->completion_queue_kind = queue_kind; release->completion_queue_target = completion_target; } - // Submit releass Lock lock = LockE(&G_D12.pending_releases_mutex); { if (G_D12.pending_releases.last) @@ -3961,26 +3176,6 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) Unlock(&lock); } - - - - - // // Attach completion info to resources - // for (G_D12_Resource *r = cl->reset_resources.first; r;) - // { - // G_D12_Resource *next = r->next; - // { - // G_D12_ResourceHeap *heap = r->heap; - // G_D12_Arena *gpu_arena = >heap->gpu_arena; - // r->completion_queue_kind = queue->kind; - // r->completion_queue_target = completion_target; - // G_D12_ResourceList *heap_reset_resources_list = &heap->reset_resources; - // DllQueuePush(heap_reset_resources_list->first, heap_reset_resourecs_list->last, r); - // ++heap_reset_resources_list->count; - // } - // r = next; - // } - ////////////////////////////// //- Finish @@ -4246,7 +3441,7 @@ void G_CopyTextureToTexture(G_CommandListHandle cl_handle, G_TextureRef dst_ref, void G_CopyTextureToBuffer(G_CommandListHandle cl_handle, G_BufferRef dst, Vec3I32 dst_offset, G_TextureRef src, Rng3I32 src_copy_range) { - // TODO + // TODO: Implement Assert(0); } @@ -4269,13 +3464,13 @@ void G_ComputeEx(G_CommandListHandle cl_handle, ComputeShaderDesc cs, Vec3I32 th void G_Draw( G_CommandListHandle cl_handle, VertexShaderDesc vs, PixelShaderDesc ps, - u32 instances_count, G_BufferRef indices, + u32 instances_count, G_IndexBufferDesc indices, u32 render_targets_count, G_RenderTargetDesc *render_targets, Rng3 viewport, Rng2 scissor, G_DrawMode draw_mode ) { - if (instances_count > 0 && G_CountBuffer(indices) > 0) + if (instances_count > 0 && indices.count > 0) { G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle); G_D12_Cmd *cmd = G_D12_PushCmd(cl); @@ -4452,7 +3647,8 @@ G_SwapchainHandle G_AcquireSwapchain(u64 os_window_handle) void G_ReleaseSwapchain(G_SwapchainHandle swapchain_handle) { - // TODO + // TODO: Implement + Assert(0); } G_BackbufferHandle G_PrepareBackbuffer(G_SwapchainHandle swapchain_handle, G_Format format, Vec2I32 size) @@ -4568,42 +3764,6 @@ G_BackbufferHandle G_PrepareBackbuffer(G_SwapchainHandle swapchain_handle, G_For // Initialize backbuffers { - // for (u32 backbuffer_idx = 0; backbuffer_idx < countof(swapchain->backbuffers); ++backbuffer_idx) - // { - // G_D12_Resource *backbuffer = &swapchain->backbuffers[backbuffer_idx]; - // if (!backbuffer->d3d_resource) - // { - // ID3D12Resource *d3d_resource = 0; - // HRESULT hr = IDXGISwapChain3_GetBuffer(swapchain->d3d_swapchain, backbuffer_idx, &IID_ID3D12Resource, (void **)&d3d_resource); - // if (FAILED(hr)) - // { - // // TODO: Don't panic - // Panic(Lit("Failed to retrieve swapchain buffer")); - // } - // ZeroStruct(backbuffer); - // // backbuffer->flags = G_MemoryFlag_AllowTextureDraw; - // backbuffer->uid = Atomic64FetchAdd(&G_D12.resource_creation_gen.v, 1) + 1; - - // ID3D12Resource_GetDesc(d3d_resource, (D3D12_RESOURCE_DESC *)&backbuffer->d3d_desc); - // backbuffer->d3d_resource = d3d_resource; - - // backbuffer->is_texture = 1; - // backbuffer->texture_format = format; - // backbuffer->texture_dims = VEC3I32(size.x, size.y, 1); - // backbuffer->texture_mips = 1; - // backbuffer->swapchain = swapchain; - - // String name = StringF(scratch.arena, "Backbuffer [%F]", FmtUint(backbuffer_idx)); - // name.len = MinU64(name.len, G_D12_MaxNameLen); - // { - // backbuffer->name_len = name.len; - // CopyBytes(backbuffer->name_cstr, name.text, name.len); - // backbuffer->name_cstr[name.len] = 0; - // G_D12_SetObjectName((ID3D12Object *)backbuffer->d3d_resource, name); - // } - // } - // } - for (u32 backbuffer_idx = 0; backbuffer_idx < countof(swapchain->backbuffers); ++backbuffer_idx) { G_D12_Backbuffer *backbuffer = &swapchain->backbuffers[backbuffer_idx]; @@ -4742,13 +3902,6 @@ void G_CommitBackbuffer(G_BackbufferHandle backbuffer_handle, Vec2I32 dst_offset G_D12_CommitRawCommandList(rcl); } - - - - - - - u32 present_flags = 0; if (G_D12_TearingIsAllowed && vsync == 0) { @@ -5048,6 +4201,10 @@ void G_D12_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame if (completions.v[release->completion_queue_kind] >= release->completion_queue_target) { SllQueuePop(async->pending_releases.first, async->pending_releases.last); + if (release->gpu_descriptor) + { + G_D12_ReleaseDescriptor(release->gpu_descriptor); + } if (release->d3d_resource) { ID3D12Resource_Release(release->d3d_resource); diff --git a/src/gpu/gpu_dx12/gpu_dx12_core.h b/src/gpu/gpu_dx12/gpu_dx12_core.h index d3bf0ed7..29c8278e 100644 --- a/src/gpu/gpu_dx12/gpu_dx12_core.h +++ b/src/gpu/gpu_dx12/gpu_dx12_core.h @@ -78,14 +78,21 @@ Struct(G_D12_Resource) // D3D12 resource D3D12_RESOURCE_DESC1 d3d_desc; ID3D12Resource *d3d_resource; - D3D12_GPU_VIRTUAL_ADDRESS buffer_gpu_address; void *mapped; + struct G_D12_Descriptor *gpu_descriptor; + + // Buffer info + D3D12_GPU_VIRTUAL_ADDRESS buffer_gpu_address; + u64 buffer_element_offset; + u64 buffer_element_stride; + u64 buffer_element_count; + // Texture info b32 is_texture; G_Format texture_format; Vec3I32 texture_dims; - i32 texture_mips; + RngI32 texture_mips; // Sampler info G_SamplerDesc sampler_desc; @@ -123,32 +130,14 @@ Struct(G_D12_Descriptor) G_D12_Descriptor *next; G_D12_Descriptor *prev; - // Persistent data - struct G_D12_DescriptorHeap *heap; D3D12_CPU_DESCRIPTOR_HANDLE d3d_handle; u32 base_index; u64 bundle_count; - // Per-resource data - - struct - { - struct G_D12_Arena *gpu_arena; - struct G_D12_Resource *resource; - - u64 buffer_element_offset; - u64 buffer_element_count; - u64 buffer_element_stride; - - RngI32 mips; - - G_QueueKind completion_queue_kind; - i64 completion_queue_target; - } info; + Atomic64 current_resource_ptr; }; - Struct(G_D12_DescriptorList) { u64 count; @@ -167,7 +156,7 @@ Struct(G_D12_DescriptorHeap) Mutex mutex; Arena *arena; - Arena *indices_to_descriptors_arena; + Arena *gpu_visible_indices_to_descriptors_arena; D3D12_DESCRIPTOR_HEAP_TYPE type; ID3D12DescriptorHeap *d3d_heap; @@ -195,10 +184,6 @@ Enum(G_D12_ResourceHeapKind) Struct(G_D12_Arena) { Arena *arena; - - G_D12_DescriptorList descriptors; - G_D12_DescriptorTable reset_descriptor_tables_by_heap[G_D12_DescriptorHeapKind_COUNT]; - G_D12_ResourceList resources; G_D12_ResourceList reset_resources; }; @@ -299,22 +284,7 @@ Struct(G_D12_Releasable) i64 completion_queue_target; ID3D12Resource *d3d_resource; - - - - - - - - - - // FIXME: Release descriptors as well - - - - - - + G_D12_Descriptor *gpu_descriptor; }; Struct(G_D12_ReleasableList) @@ -402,7 +372,7 @@ Struct(G_D12_Cmd) VertexShaderDesc vs; PixelShaderDesc ps; u32 instances_count; - G_BufferRef indices; + G_IndexBufferDesc indices; G_RenderTargetDesc render_target_descs[G_MaxRenderTargets]; Rng3 viewport; Rng2 scissor; @@ -435,7 +405,6 @@ Struct(G_D12_CmdList) G_QueueKind queue_kind; Arena *arena; - G_D12_DescriptorList reset_descriptors; G_D12_ReleasableList releases; G_D12_StagingRegionNode *first_staging_region; @@ -753,18 +722,22 @@ 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); - G_D12_Descriptor *G_D12_AcquireDescriptor(G_D12_DescriptorHeapKind heap_kind, u64 bundle_count); +void G_D12_ReleaseDescriptor(G_D12_Descriptor *descriptor); -void G_D12_InitRtvDescriptor(G_D12_Descriptor *descriptor, G_D12_Resource *resource, i32 mip); +G_D12_Descriptor *G_D12_DescriptorFromBufferRef(G_BufferRef ref); +G_D12_Descriptor *G_D12_DescriptorFromTextureRef(G_TextureRef ref); +G_D12_Descriptor *G_D12_DescriptorFromSamplerRef(G_SamplerRef ref); +G_D12_Resource *G_D12_ResourceFromBufferRef(G_BufferRef ref); +G_D12_Resource *G_D12_ResourceFromTextureRef(G_TextureRef ref); +G_D12_Resource *G_D12_ResourceFromSamplerRef(G_SamplerRef ref); //////////////////////////////////////////////////////////// //~ Command helpers G_D12_Cmd *G_D12_PushCmd(G_D12_CmdList *cl); G_D12_StagingRegionNode *G_D12_PushStagingRegion(G_D12_CmdList *cl, u64 size); +void G_D12_InitRtvDescriptor(G_D12_Descriptor *descriptor, G_D12_Resource *resource, i32 mip); //////////////////////////////////////////////////////////// //~ Instrumentation diff --git a/src/gpu/gpu_shared.cgh b/src/gpu/gpu_shared.cgh index d05128b7..8e3fed34 100644 --- a/src/gpu/gpu_shared.cgh +++ b/src/gpu/gpu_shared.cgh @@ -149,22 +149,18 @@ Enum(G_BasicSamplerKind) #endif //////////////////////////////////////////////////////////// -//~ Resource countof +//~ Texture dimensions #define G_MaxMips 16 #define G_MaxRenderTargets 8 #if IsGpu - template u32 countof(StructuredBuffer obj) { u32 result; obj.GetDimensions(result); return result; } - template u32 countof(RWStructuredBuffer obj) { u32 result; u32 stride; obj.GetDimensions(result, stride); return result; } - u32 countof(ByteAddressBuffer obj) { u32 result; obj.GetDimensions(result); return result; } - u32 countof(RWByteAddressBuffer obj) { u32 result; obj.GetDimensions(result); return result; } - template u32 countof(Texture1D obj) { u32 result; obj.GetDimensions(result); return result; } - template u32 countof(RWTexture1D obj) { u32 result; obj.GetDimensions(result); return result; } - template Vec2U32 countof(Texture2D obj) { Vec2U32 result; obj.GetDimensions(result.x, result.y); return result; } - template Vec2U32 countof(RWTexture2D obj) { Vec2U32 result; obj.GetDimensions(result.x, result.y); return result; } - template Vec3U32 countof(Texture3D obj) { Vec3U32 result; obj.GetDimensions(result.x, result.y, result.z); return result; } - template Vec3U32 countof(RWTexture3D obj) { Vec3U32 result; obj.GetDimensions(result.x, result.y, result.z); return result; } + template u32 G_Count1D(Texture1D obj) { u32 result; obj.GetDimensions(result); return result; } + template u32 G_Count1D(RWTexture1D obj) { u32 result; obj.GetDimensions(result); return result; } + template Vec2U32 G_Count2D(Texture2D obj) { Vec2U32 result; obj.GetDimensions(result.x, result.y); return result; } + template Vec2U32 G_Count2D(RWTexture2D obj) { Vec2U32 result; obj.GetDimensions(result.x, result.y); return result; } + template Vec3U32 G_Count3D(Texture3D obj) { Vec3U32 result; obj.GetDimensions(result.x, result.y, result.z); return result; } + template Vec3U32 G_Count3D(RWTexture3D obj) { Vec3U32 result; obj.GetDimensions(result.x, result.y, result.z); return result; } #endif //////////////////////////////////////////////////////////// @@ -280,7 +276,7 @@ Struct(G_FmtArg) base += 4; // Offset for success counter base += 4; // Offset for overflow counter - if ((base + alloc_size) < countof(rw)) + if ((base + alloc_size) < GPU_SHADER_PRINT_BUFFER_SIZE) { // Increment success counter rw.InterlockedAdd(4, 1); diff --git a/src/proto/proto.c b/src/proto/proto.c index c563c590..7635d5a1 100644 --- a/src/proto/proto.c +++ b/src/proto/proto.c @@ -58,7 +58,7 @@ void PT_RunForever(WaveLaneCtx *lane) cl, PT_BlitVS, PT_BlitPS, 1, G_QuadIndices(), - 1, &G_Rt(frame->screen, G_BlendMode_CompositeStraightAlpha), + 1, &G_RT(frame->screen, G_BlendMode_CompositeStraightAlpha), G_ViewportFromTexture(frame->screen), G_ScissorFromTexture(frame->screen), G_DrawMode_TriangleList ); diff --git a/src/proto/proto_gpu.g b/src/proto/proto_gpu.g index 0b60494f..8deaa97f 100644 --- a/src/proto/proto_gpu.g +++ b/src/proto/proto_gpu.g @@ -6,10 +6,10 @@ ComputeShader(PT_TestCS) PT_SharedFrame frame = G_UniformDeref(PT_ShaderConst_Frame)[0]; RWTexture2D target_tex = G_UniformDerefRW2D(frame.compute_target); - Vec2U32 target_tex_size = countof(target_tex); + Vec2U32 target_tex_size = G_Count2D(target_tex); Vec2I32 id = SV_DispatchThreadID; - if (id.x < target_tex_size.x && id.y < target_tex_size.y) + if (all(id < G_Count2D(target_tex))) { target_tex[id] = Vec4(0, 1, 0, 1); }