diff --git a/src/gpu/gpu_dx12/gpu_dx12.c b/src/gpu/gpu_dx12/gpu_dx12.c index 3918a91f..15cddb21 100644 --- a/src/gpu/gpu_dx12/gpu_dx12.c +++ b/src/gpu/gpu_dx12/gpu_dx12.c @@ -751,386 +751,6 @@ void GPU_D12_CommitRawCommandList(GPU_D12_RawCommandList *cl) // ID3D12CommandQueue_Wait(queue_a->d3d_queue, b_fence, b_target_fence_value); // } -//////////////////////////////////////////////////////////// -//~ @hookimpl Resource hooks - -#if 0 - -GPU_Resource *GPU_AcquireResource(GPU_ResourceDesc desc) -{ - GPU_D12_SharedState *g = &GPU_D12_shared_state; - GPU_D12_Resource *r = 0; - - if (desc.kind == GPU_ResourceKind_Unknown) - { - Panic(Lit("Unknown gpu resource type")); - } - - u64 buffer_size = 0; - if (desc.kind == GPU_ResourceKind_Buffer) - { - desc.buffer.stride = MaxU32(desc.buffer.stride, 1); - buffer_size = MaxU64(AlignU64ToNextPow2(desc.buffer.count * desc.buffer.stride), Kibi(64)); - } - - u64 reuse_hash = GPU_D12_ReuseHashFromResourceDesc(desc, buffer_size); - /* Grab reusable */ - { - u64 bin_index = reuse_hash % countof(g->resource_reuse_bins); - GPU_D12_ResourceReuseListBin *bin = &g->resource_reuse_bins[bin_index]; - { - Lock lock = LockE(&bin->mutex); - { - GPU_D12_ResourceReuseList *list = bin->first; - for (; list; list = list->next) - { - if (list->hash == reuse_hash) break; - } - if (list) - { - r = list->first; - list->first = r->next_free; - if (!list->first) - { - DllQueueRemove(bin->first, bin->last, list); - SllStackPush(bin->first_free, list); - list->prev = 0; - } - r->next_free = 0; - } - } - Unlock(&lock); - } - } - - /* Grab from free list */ - if (!r) - { - { - Lock lock = LockE(&g->free_resources_mutex); - r = g->first_free_resource; - if (r) - { - g->first_free_resource = r->next_free; - } - Unlock(&lock); - } - if (r) - { - ZeroStruct(r); - } - } - - /* Push new */ - if (!r) - { - Arena *perm = PermArena(); - PushAlign(perm, CachelineSize); - r = PushStruct(perm, GPU_D12_Resource); - PushAlign(perm, CachelineSize); - } - - /* Create d3d resource */ - if (!r->d3d_resource) - { - switch (desc.kind) - { - default: break; - - /* Buffer */ - case GPU_ResourceKind_Buffer: - { - D3D12_HEAP_FLAGS heap_flags = 0; - if (!(desc.flags & GPU_ResourceFlag_Zeroed)) - { - heap_flags |= D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; - } - - D3D12_HEAP_PROPERTIES heap_props = { - .Type = desc.buffer.heap_kind == GPU_HeapKind_Upload ? D3D12_HEAP_TYPE_UPLOAD - : desc.buffer.heap_kind == GPU_HeapKind_Download ? D3D12_HEAP_TYPE_READBACK - : D3D12_HEAP_TYPE_DEFAULT - }; - Assert(!(desc.flags & GPU_ResourceFlag_Rasterizable)); - D3D12_RESOURCE_DESC 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.Alignment = 0; - d3d_desc.Width = 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(desc.flags, GPU_ResourceFlag_Writable); - r->state = desc.buffer.heap_kind == GPU_HeapKind_Download ? D3D12_RESOURCE_STATE_COPY_DEST : D3D12_RESOURCE_STATE_COMMON; - HRESULT hr = ID3D12Device_CreateCommittedResource(g->device, &heap_props, heap_flags, &d3d_desc, r->state, 0, &IID_ID3D12Resource, (void **)&r->d3d_resource); - Atomic64FetchAdd(&g->driver_resources_allocated, 1); - if (FAILED(hr)) - { - /* TODO: Don't panic */ - Panic(Lit("Failed to create buffer resource")); - } - r->buffer_gpu_address = ID3D12Resource_GetGPUVirtualAddress(r->d3d_resource); - } break; - - /* Texture */ - case GPU_ResourceKind_Texture1D: - case GPU_ResourceKind_Texture2D: - case GPU_ResourceKind_Texture3D: - { - D3D12_HEAP_FLAGS heap_flags = 0; - if (!(desc.flags & GPU_ResourceFlag_Zeroed)) - { - heap_flags |= D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; - } - - D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_DEFAULT }; - D3D12_RESOURCE_DESC d3d_desc = ZI; - d3d_desc.Dimension = desc.kind == GPU_ResourceKind_Texture1D ? D3D12_RESOURCE_DIMENSION_TEXTURE1D - : desc.kind == GPU_ResourceKind_Texture2D ? D3D12_RESOURCE_DIMENSION_TEXTURE2D - : D3D12_RESOURCE_DIMENSION_TEXTURE3D; - d3d_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; - d3d_desc.Format = GPU_D12_DxgiFormatFromGpuFormat(desc.texture.format); - d3d_desc.Alignment = 0; - d3d_desc.Width = MaxI32(desc.texture.size.x, 1); - d3d_desc.Height = MaxI32(desc.texture.size.y, 1); - d3d_desc.DepthOrArraySize = MaxI32(desc.texture.size.z, 1); - d3d_desc.MipLevels = (desc.flags & GPU_ResourceFlag_MaxMipLevels) ? 0 : 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(desc.flags, GPU_ResourceFlag_Writable); - d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET * AnyBit(desc.flags, GPU_ResourceFlag_Rasterizable); - d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS * (desc.initial_layout == GPU_Layout_Simultaneous); - r->state = D3D12_RESOURCE_STATE_COMMON; - D3D12_CLEAR_VALUE clear_value = { .Format = d3d_desc.Format, .Color = { 0 } }; - clear_value.Color[0] = desc.clear_color.x; - clear_value.Color[1] = desc.clear_color.y; - clear_value.Color[2] = desc.clear_color.z; - clear_value.Color[3] = desc.clear_color.w; - D3D12_CLEAR_VALUE *clear_value_ptr = d3d_desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET ? &clear_value : 0; - HRESULT hr = ID3D12Device_CreateCommittedResource(g->device, &heap_props, heap_flags, &d3d_desc, r->state, clear_value_ptr, &IID_ID3D12Resource, (void **)&r->d3d_resource); - Atomic64FetchAdd(&g->driver_resources_allocated, 1); - if (FAILED(hr)) - { - /* TODO: Don't panic */ - Panic(Lit("Failed to create buffer resource")); - } - } break; - } - } - - r->srv_descriptor = &GPU_D12_NilDescriptor; - r->uav_descriptor = &GPU_D12_NilDescriptor; - r->rtv_descriptor = &GPU_D12_NilDescriptor; - r->sampler_descriptor = &GPU_D12_NilDescriptor; - - /* Create texture srv descriptor */ - if (desc.kind == GPU_ResourceKind_Texture1D - || desc.kind == GPU_ResourceKind_Texture2D - || desc.kind == GPU_ResourceKind_Texture3D) - { - if (!r->srv_descriptor->valid) - { - r->srv_descriptor = GPU_D12_AcquireDescriptor(g->cbv_srv_uav_heap); - } - ID3D12Device_CreateShaderResourceView(g->device, r->d3d_resource, 0, r->srv_descriptor->handle); - } - - /* Create buffer srv descriptor */ - if (desc.kind == GPU_ResourceKind_Buffer - && desc.buffer.heap_kind != GPU_HeapKind_Download - && desc.buffer.count > 0) - { - if (!r->srv_descriptor->valid) - { - r->srv_descriptor = GPU_D12_AcquireDescriptor(g->cbv_srv_uav_heap); - } - D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = ZI; - 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 = 0; - srv_desc.Buffer.NumElements = desc.buffer.count; - srv_desc.Buffer.StructureByteStride = desc.buffer.stride; - srv_desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE; - ID3D12Device_CreateShaderResourceView(g->device, r->d3d_resource, &srv_desc, r->srv_descriptor->handle); - } - - /* Create uav descriptor */ - if (desc.flags & GPU_ResourceFlag_Writable) - { - if (!r->uav_descriptor->valid) - { - r->uav_descriptor = GPU_D12_AcquireDescriptor(g->cbv_srv_uav_heap); - } - ID3D12Device_CreateUnorderedAccessView(g->device, r->d3d_resource, 0, 0, r->uav_descriptor->handle); - } - - /* Create rtv descriptor */ - if (desc.flags & GPU_ResourceFlag_Rasterizable) - { - if (!r->rtv_descriptor->valid) - { - r->rtv_descriptor = GPU_D12_AcquireDescriptor(g->rtv_heap); - } - ID3D12Device_CreateRenderTargetView(g->device, r->d3d_resource, 0, r->rtv_descriptor->handle); - } - - /* Create sampler descriptor */ - if (desc.kind == GPU_ResourceKind_Sampler) - { - if (!r->sampler_descriptor->valid) - { - r->sampler_descriptor = GPU_D12_AcquireDescriptor(g->sampler_heap); - } - D3D12_SAMPLER_DESC d3d_desc = ZI; - d3d_desc.Filter = (D3D12_FILTER)desc.sampler.filter; - d3d_desc.AddressU = (D3D12_TEXTURE_ADDRESS_MODE)desc.sampler.x; - d3d_desc.AddressV = (D3D12_TEXTURE_ADDRESS_MODE)desc.sampler.y; - d3d_desc.AddressW = (D3D12_TEXTURE_ADDRESS_MODE)desc.sampler.z; - d3d_desc.MipLODBias = desc.sampler.mip_lod_bias; - d3d_desc.MaxAnisotropy = MaxU32(desc.sampler.max_anisotropy, 1); - d3d_desc.ComparisonFunc = (D3D12_COMPARISON_FUNC)desc.sampler.comparison; - d3d_desc.BorderColor[0] = desc.sampler.border_color.x; - d3d_desc.BorderColor[1] = desc.sampler.border_color.y; - d3d_desc.BorderColor[2] = desc.sampler.border_color.z; - d3d_desc.BorderColor[3] = desc.sampler.border_color.w; - d3d_desc.MinLOD = desc.sampler.min_lod; - d3d_desc.MaxLOD = desc.sampler.max_lod; - - /* Defaults */ - 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 >= F32Infinity) - { - d3d_desc.MaxLOD = D3D12_FLOAT32_MAX; - } - ID3D12Device_CreateSampler(g->device, &d3d_desc, r->sampler_descriptor->handle); - } - - r->desc = desc; - r->buffer_size = buffer_size; - - return (GPU_Resource *)r; -} - -void GPU_ReleaseResource(GPU_Resource *gpu_resource, GPU_ReleaseFlag flags) -{ - GPU_D12_SharedState *g = &GPU_D12_shared_state; - GPU_D12_Resource *r = (GPU_D12_Resource *)gpu_resource; - - if (r->srv_descriptor->valid) - { - GPU_D12_ReleaseDescriptor(r->srv_descriptor); - } - if (r->uav_descriptor->valid) - { - GPU_D12_ReleaseDescriptor(r->uav_descriptor); - } - if (r->rtv_descriptor->valid) - { - GPU_D12_ReleaseDescriptor(r->rtv_descriptor); - } - if (r->sampler_descriptor->valid) - { - GPU_D12_ReleaseDescriptor(r->sampler_descriptor); - } - - if (flags & GPU_ReleaseFlag_Reuse) - { - GPU_ResourceDesc desc = r->desc; - u64 buffer_size = r->buffer_size; - u64 reuse_hash = GPU_D12_ReuseHashFromResourceDesc(desc, buffer_size); - u64 bin_index = reuse_hash % countof(g->resource_reuse_bins); - GPU_D12_ResourceReuseListBin *bin = &g->resource_reuse_bins[bin_index]; - { - Lock lock = LockE(&bin->mutex); - { - GPU_D12_ResourceReuseList *list = bin->first; - for (; list; list = list->next) - { - if (list->hash == reuse_hash) break; - } - if (!list) - { - list = bin->first_free; - if (list) - { - bin->first_free = list->next; - } - else - { - Arena *perm = PermArena(); - PushAlign(perm, CachelineSize); - list = PushStruct(perm, GPU_D12_ResourceReuseList); - PushAlign(perm, CachelineSize); - } - list->hash = reuse_hash; - DllQueuePush(bin->first, bin->last, list); - } - SllStackPushN(list->first, r, next_free); - } - Unlock(&lock); - } - } - else - { - switch (r->desc.kind) - { - default: break; - case GPU_ResourceKind_Buffer: - case GPU_ResourceKind_Texture1D: - case GPU_ResourceKind_Texture2D: - case GPU_ResourceKind_Texture3D: - { - ID3D12Resource_Release(r->d3d_resource); - Atomic64FetchAdd(&g->driver_resources_allocated, -1); - } break; - } - Lock lock = LockE(&g->free_resources_mutex); - r->next_free = g->first_free_resource; - g->first_free_resource = r; - Unlock(&lock); - } - -} - -Vec2I32 GPU_GetTextureSize2D(GPU_Resource *gpu_resource) -{ - GPU_D12_Resource *resource = (GPU_D12_Resource *)gpu_resource; - return VEC2I32(resource->desc.texture.size.x, resource->desc.texture.size.y); -} - -Vec3I32 GPU_GetTextureSize3D(GPU_Resource *gpu_resource) -{ - GPU_D12_Resource *resource = (GPU_D12_Resource *)gpu_resource; - return resource->desc.texture.size; -} - -u64 GPU_GetFootprintSize(GPU_Resource *gpu_resource) -{ - GPU_D12_SharedState *g = &GPU_D12_shared_state; - D3D12_RESOURCE_DESC desc = ZI; - D3D12_PLACED_SUBRESOURCE_FOOTPRINT placed_footprint = ZI; - ID3D12Resource_GetDesc(((GPU_D12_Resource *)gpu_resource)->d3d_resource, &desc); - u64 footprint_size = 0; - u64 upload_row_size = 0; - u32 upload_num_rows = 0; - ID3D12Device_GetCopyableFootprints(g->device, &desc, 0, 1, 0, &placed_footprint, &upload_num_rows, &upload_row_size, &footprint_size); - return footprint_size; -} - -u64 GPU_GetBufferCount(GPU_Resource *gpu_resource) -{ - GPU_D12_Resource *resource = (GPU_D12_Resource *)gpu_resource; - return resource->desc.buffer.count; -} - -#endif - //////////////////////////////////////////////////////////// //~ @hookimpl Arena @@ -2767,14 +2387,50 @@ void GPU_ProfN(GPU_CommandListHandle cl, String name) //////////////////////////////////////////////////////////// //~ @hookimpl Synchronization -void GPU_SyncQueue(GPU_QueueKind completion_queue, GPU_QueueKind waiter_queue) +void GPU_SyncQueue(GPU_QueueKind completion_queue_kind, GPU_QueueKind waiter_queue_kind) { - /* TODO */ + if (completion_queue_kind != waiter_queue_kind) + { + GPU_D12_Queue *completion_queue = GPU_D12_QueueFromKind(completion_queue_kind); + GPU_D12_Queue *waiter_queue = GPU_D12_QueueFromKind(waiter_queue_kind); + ID3D12Fence *d3d_fence = completion_queue->commit_fence; + u64 fence_target = 0; + { + Lock lock = LockS(&completion_queue->commit_mutex); + fence_target = completion_queue->commit_fence_target; + Unlock(&lock); + } + if (ID3D12Fence_GetCompletedValue(d3d_fence) < fence_target) + { + ID3D12CommandQueue_Wait(waiter_queue->d3d_queue, d3d_fence, fence_target); + } + } } -void GPU_SyncAllQueues(GPU_QueueKind completion_queue) +void GPU_SyncAllQueues(GPU_QueueKind completion_queue_kind) { - /* TODO */ + if (GPU_MultiQueueIsEnabled) + { + GPU_D12_Queue *completion_queue = GPU_D12_QueueFromKind(completion_queue_kind); + ID3D12Fence *d3d_fence = completion_queue->commit_fence; + u64 fence_target = 0; + { + Lock lock = LockS(&completion_queue->commit_mutex); + fence_target = completion_queue->commit_fence_target; + Unlock(&lock); + } + if (ID3D12Fence_GetCompletedValue(d3d_fence) < fence_target) + { + for (GPU_QueueKind waiter_queue_kind = 0; waiter_queue_kind < GPU_NumQueues; ++waiter_queue_kind) + { + if (waiter_queue_kind != completion_queue_kind) + { + GPU_D12_Queue *waiter_queue = GPU_D12_QueueFromKind(waiter_queue_kind); + ID3D12CommandQueue_Wait(waiter_queue->d3d_queue, d3d_fence, fence_target); + } + } + } + } } ////////////////////////////////////////////////////////////