/// <summary> /// Executes a <see cref="CommandList"/> and, signals and retrieves the following fence value /// </summary> /// <param name="commandList">The input <see cref="CommandList"/> to execute</param> /// <returns>The value of the new fence to wait for</returns> private long GetFenceValueForCommandList(CommandList commandList) { CommandAllocatorPool commandAllocatorPool; ID3D12CommandQueue commandQueue; ID3D12Fence fence; long fenceValue; switch (commandList.CommandListType) { case CommandListType.Compute: commandAllocatorPool = ComputeAllocatorPool; commandQueue = NativeComputeCommandQueue; fence = NativeComputeFence; fenceValue = NextComputeFenceValue; NextComputeFenceValue++; break; case CommandListType.Copy: commandAllocatorPool = CopyAllocatorPool; commandQueue = NativeCopyCommandQueue; fence = NativeCopyFence; fenceValue = NextCopyFenceValue; NextCopyFenceValue++; break; case CommandListType.Direct: commandAllocatorPool = DirectAllocatorPool; commandQueue = NativeDirectCommandQueue; fence = NativeDirectFence; fenceValue = NextDirectFenceValue; NextDirectFenceValue++; break; default: throw new NotSupportedException($"Unsupported command list of type {commandList.CommandListType}"); } commandAllocatorPool.Enqueue(commandList.CommandAllocator, fenceValue); commandQueue.ExecuteCommandLists(commandList.NativeCommandList); commandQueue.Signal(fence, fenceValue); return(fenceValue); }
/// <summary> /// Executes a <see cref="CommandList"/> and waits for the GPU to finish processing it /// </summary> /// <param name="commandList">The input <see cref="CommandList"/> to execute</param> internal void ExecuteCommandList(CommandList commandList) { ID3D12Fence fence = commandList.CommandListType switch { CommandListType.Direct => NativeDirectFence, CommandListType.Compute => NativeComputeFence, CommandListType.Copy => NativeCopyFence, _ => throw new NotSupportedException("This command list type is not supported.") }; long fenceValue = GetFenceValueForCommandList(commandList); if (fenceValue <= fence.CompletedValue) { return; } fence.SetEventOnCompletion(fenceValue, default(IntPtr)); }
/// <summary> /// Executes a <see cref="CommandList"/> and waits for the GPU to finish processing it /// </summary> /// <param name="commandList">The input <see cref="CommandList"/> to execute</param> internal void ExecuteCommandList(CommandList commandList) { ID3D12Fence fence = commandList.CommandListType switch { CommandListType.Direct => NativeDirectFence, CommandListType.Compute => NativeComputeFence, CommandListType.Copy => NativeCopyFence, _ => throw new NotSupportedException("This command list type is not supported.") }; long fenceValue = GetFenceValueForCommandList(commandList); if (fenceValue <= fence.CompletedValue) { return; } lock (fence) { fence.SetEventOnCompletion(fenceValue, AutoResetEvent.SafeWaitHandle.DangerousGetHandle()); AutoResetEvent.WaitOne(); } }