/// <summary> /// Rents a <see cref="ID3D12GraphicsCommandList"/> and <see cref="ID3D12CommandAllocator"/> pair. /// </summary> /// <param name="d3D12Device">The <see cref="ID3D12Device"/> renting the command list.</param> /// <param name="d3D12PipelineState">The <see cref="ID3D12PipelineState"/> instance to use for the new command list.</param> /// <param name="d3D12CommandList">The resulting <see cref="ID3D12GraphicsCommandList"/> value.</param> /// <param name="d3D12CommandAllocator">The resulting <see cref="ID3D12CommandAllocator"/> value.</param> public void Rent(ID3D12Device *d3D12Device, ID3D12PipelineState *d3D12PipelineState, out ID3D12GraphicsCommandList *d3D12CommandList, out ID3D12CommandAllocator *d3D12CommandAllocator) { lock (this.d3D12CommandListBundleQueue) { if (this.d3D12CommandListBundleQueue.TryDequeue(out D3D12CommandListBundle d3D12CommandListBundle)) { d3D12CommandList = d3D12CommandListBundle.D3D12CommandList; d3D12CommandAllocator = d3D12CommandListBundle.D3D12CommandAllocator; } else { d3D12CommandAllocator = null; d3D12CommandList = null; } } // Reset the command allocator and command list outside of the lock, or create a new pair if one to be reused // wasn't available. These operations are relatively expensive, so doing so here reduces thread contention // when multiple shader executions are being dispatched in parallel on the same device. if (d3D12CommandAllocator is not null) { d3D12CommandAllocator->Reset().Assert(); d3D12CommandList->Reset(d3D12CommandAllocator, d3D12PipelineState).Assert(); } else { CreateCommandListAndAllocator(d3D12Device, d3D12PipelineState, out d3D12CommandList, out d3D12CommandAllocator); } }
public static ID3D12PipelineState *GetLatestD3D12PipelineState(ID3D12PipelineState *d3d12PipelineState, out uint d3d12PipelineStateVersion) { ID3D12PipelineState *result; d3d12PipelineStateVersion = 0; result = d3d12PipelineState; return(result); }
private void CreateCommandListAndAllocator(ID3D12Device *d3D12Device, ID3D12PipelineState *d3D12PipelineState, out ID3D12GraphicsCommandList *d3D12CommandList, out ID3D12CommandAllocator *d3D12CommandAllocator) { using ComPtr <ID3D12CommandAllocator> d3D12CommandAllocatorComPtr = d3D12Device->CreateCommandAllocator(this.d3D12CommandListType); using ComPtr <ID3D12GraphicsCommandList> d3D12CommandListComPtr = d3D12Device->CreateCommandList(this.d3D12CommandListType, d3D12CommandAllocatorComPtr.Get(), d3D12PipelineState); fixed(ID3D12GraphicsCommandList **d3D12CommandListPtr = &d3D12CommandList) fixed(ID3D12CommandAllocator **d3D12CommandAllocatorPtr = &d3D12CommandAllocator) { d3D12CommandListComPtr.CopyTo(d3D12CommandListPtr); d3D12CommandAllocatorComPtr.CopyTo(d3D12CommandAllocatorPtr); } }
public ListCreationParams( ExecutionContext context, ID3D12CommandAllocator *allocator, ID3D12PipelineState *pso ) { Debug.Assert(allocator != null); Type = (D3D12_COMMAND_LIST_TYPE)context; Allocator = allocator; Pso = pso; }
/// <summary> /// Creates a new <see cref="CommandList"/> instance with the specified parameters. /// </summary> /// <param name="device">The target <see cref="GraphicsDevice"/> instance to use.</param> /// <param name="d3D12PipelineState">The <see cref="ID3D12PipelineState"/> instance to use for the new command list.</param> public CommandList(GraphicsDevice device, ID3D12PipelineState *d3D12PipelineState) { this.device = device; this.d3D12CommandListType = D3D12_COMMAND_LIST_TYPE_COMPUTE; Unsafe.SkipInit(out this.d3D12GraphicsCommandList); Unsafe.SkipInit(out this.d3D12CommandAllocator); device.GetCommandListAndAllocator( d3D12PipelineState, out *(ID3D12GraphicsCommandList **)Unsafe.AsPointer(ref this.d3D12GraphicsCommandList), out *(ID3D12CommandAllocator **)Unsafe.AsPointer(ref this.d3D12CommandAllocator)); // Set the heap descriptor for the command list device.SetDescriptorHeapForCommandList(this.d3D12GraphicsCommandList); }
public void ClearState([NativeTypeName("ID3D12PipelineState *")] ID3D12PipelineState *pPipelineState) { ((delegate * stdcall <ID3D12GraphicsCommandList4 *, ID3D12PipelineState *, void>)(lpVtbl[11]))((ID3D12GraphicsCommandList4 *)Unsafe.AsPointer(ref this), pPipelineState); }
public int Reset([NativeTypeName("ID3D12CommandAllocator *")] ID3D12CommandAllocator *pAllocator, [NativeTypeName("ID3D12PipelineState *")] ID3D12PipelineState *pInitialState) { return(((delegate * stdcall <ID3D12GraphicsCommandList4 *, ID3D12CommandAllocator *, ID3D12PipelineState *, int>)(lpVtbl[10]))((ID3D12GraphicsCommandList4 *)Unsafe.AsPointer(ref this), pAllocator, pInitialState)); }
public void SetPipelineState([NativeTypeName("ID3D12PipelineState *")] ID3D12PipelineState *pPipelineState) { ((delegate * unmanaged <ID3D12GraphicsCommandList1 *, ID3D12PipelineState *, void>)(lpVtbl[25]))((ID3D12GraphicsCommandList1 *)Unsafe.AsPointer(ref this), pPipelineState); }
/// <summary> /// Creates a new <see cref="PipelineData"/> instance with the specified parameters. /// </summary> /// <param name="d3D12RootSignature">The <see cref="ID3D12RootSignature"/> value for the current shader.</param> /// <param name="d3D12PipelineState">The compiled pipeline state to reuse for the current shader.</param> public PipelineData(ID3D12RootSignature *d3D12RootSignature, ID3D12PipelineState *d3D12PipelineState) { this.d3D12RootSignature = new ComPtr <ID3D12RootSignature>(d3D12RootSignature); this.d3D12PipelineState = new ComPtr <ID3D12PipelineState>(d3D12PipelineState); }
public UniqueComPtr <ID3D12GraphicsCommandList> Rent( ExecutionContext context, ID3D12CommandAllocator *allocator, ID3D12PipelineState *pso ) => Rent(new ListCreationParams(context, allocator, pso));
public int CreateCommandList([NativeTypeName("UINT")] uint nodeMask, D3D12_COMMAND_LIST_TYPE type, [NativeTypeName("ID3D12CommandAllocator *")] ID3D12CommandAllocator *pCommandAllocator, [NativeTypeName("ID3D12PipelineState *")] ID3D12PipelineState *pInitialState, [NativeTypeName("const IID &")] Guid *riid, [NativeTypeName("void **")] void **ppCommandList) { return(((delegate * unmanaged <ID3D12Device *, uint, D3D12_COMMAND_LIST_TYPE, ID3D12CommandAllocator *, ID3D12PipelineState *, Guid *, void **, int>)(lpVtbl[12]))((ID3D12Device *)Unsafe.AsPointer(ref this), nodeMask, type, pCommandAllocator, pInitialState, riid, ppCommandList)); }
protected override void DestroyDeviceDependentResources() { DestroyAssets(); DestroyGraphicsCommandLists(); DestroyPipelineState(); DestroyRootSignature(); DestroyFenceEvent(); DestroyFence(); DestroyCommandAllocators(); DestroyDescriptorHeaps(); DestroyCommandQueue(); DestroyD3DDevice(); DestroyDxgiAdapter(); DestroyDxgiFactory(); void DestroyCommandAllocators() { for (var i = 0; i < _commandAllocators.Length; i++) { var commandAllocator = _commandAllocators[i]; if (commandAllocator != null) { _commandAllocators[i] = null; _ = commandAllocator->Release(); } } } void DestroyCommandQueue() { var commandQueue = _commandQueue; if (commandQueue != null) { _commandQueue = null; _ = commandQueue->Release(); } } void DestroyD3DDevice() { var d3dDevice = _d3dDevice; if (d3dDevice != null) { _d3dDevice = null; _ = d3dDevice->Release(); } } void DestroyDxgiAdapter() { var dxgiAdapter = _dxgiAdapter; if (dxgiAdapter != null) { _dxgiAdapter = null; _ = dxgiAdapter->Release(); } } void DestroyDxgiFactory() { var dxgiFactory = _dxgiFactory; if (dxgiFactory != null) { _dxgiFactory = null; _ = dxgiFactory->Release(); } } void DestroyFence() { var fence = _fence; if (fence != null) { _fence = null; _ = fence->Release(); } } void DestroyFenceEvent() { var fenceEvent = _fenceEvent; if (fenceEvent != IntPtr.Zero) { _fenceEvent = IntPtr.Zero; _ = CloseHandle(_fenceEvent); } } void DestroyGraphicsCommandLists() { for (var i = 0; i < _graphicsCommandLists.Length; i++) { var graphicsCommandList = _graphicsCommandLists[i]; if (graphicsCommandList != null) { _graphicsCommandLists[i] = null; _ = graphicsCommandList->Release(); } } } void DestroyPipelineState() { var pipelineState = _pipelineState; if (pipelineState != null) { _pipelineState = null; _ = pipelineState->Release(); } } void DestroyRootSignature() { var rootSignature = _rootSignature; if (rootSignature != null) { _rootSignature = null; _ = rootSignature->Release(); } } }
protected override void CreateDeviceDependentResources() { _dxgiFactory = CreateDxgiFactory(); _dxgiAdapter = GetDxgiAdapter(); _d3dDevice = CreateD3DDevice(); _commandQueue = CreateCommandQueue(); CreateDescriptorHeaps(); for (int i = 0; i < FrameCount; i++) { _commandAllocators[i] = CreateCommandAllocator(); } _fence = CreateFence(); _fenceValues = CreateFenceValues(); _fenceEvent = CreateFenceEvent(); _rootSignature = CreateRootSignature(); _pipelineState = CreatePipelineState(); _graphicsCommandLists = CreateGraphicsCommandLists(); ThrowIfFailed(nameof(ID3D12CommandAllocator.Reset), CommandAllocator->Reset()); ThrowIfFailed(nameof(ID3D12GraphicsCommandList.Reset), GraphicsCommandList->Reset(CommandAllocator, PipelineState)); CreateAssets(); ID3D12CommandAllocator *CreateCommandAllocator() { ID3D12CommandAllocator *commandAllocator; var iid = IID_ID3D12CommandAllocator; ThrowIfFailed(nameof(ID3D12Device.CreateCommandAllocator), D3DDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, &iid, (void **)&commandAllocator)); return(commandAllocator); } ID3D12CommandQueue *CreateCommandQueue() { var queueDesc = new D3D12_COMMAND_QUEUE_DESC(); ID3D12CommandQueue *commandQueue; var iid = IID_ID3D12CommandQueue; ThrowIfFailed(nameof(ID3D12Device.CreateCommandQueue), D3DDevice->CreateCommandQueue(&queueDesc, &iid, (void **)&commandQueue)); return(commandQueue); } ID3D12Device *CreateD3DDevice() { ID3D12Device *d3dDevice; var iid = IID_ID3D12Device; ThrowIfFailed(nameof(D3D12CreateDevice), D3D12CreateDevice((IUnknown *)_dxgiAdapter, D3D_FEATURE_LEVEL_11_0, &iid, (void **)&d3dDevice)); return(d3dDevice); } IDXGIFactory4 *CreateDxgiFactory() { var dxgiFactoryFlags = TryEnableDebugLayer() ? DXGI_CREATE_FACTORY_DEBUG : 0u; IDXGIFactory4 *dxgiFactory; var iid = IID_IDXGIFactory4; ThrowIfFailed(nameof(CreateDXGIFactory2), CreateDXGIFactory2(dxgiFactoryFlags, &iid, (void **)&dxgiFactory)); return(dxgiFactory); } ID3D12Fence *CreateFence() { ID3D12Fence *fence; var iid = IID_ID3D12Fence; ThrowIfFailed(nameof(ID3D12Device.CreateFence), D3DDevice->CreateFence(InitialValue: 0, D3D12_FENCE_FLAG_NONE, &iid, (void **)&fence)); return(fence); } IntPtr CreateFenceEvent() { var fenceEvent = CreateEventW(lpEventAttributes: null, bManualReset: FALSE, bInitialState: FALSE, lpName: null); if (fenceEvent == IntPtr.Zero) { var hr = Marshal.GetHRForLastWin32Error(); Marshal.ThrowExceptionForHR(hr); } return(fenceEvent); } ulong[] CreateFenceValues() { var fenceValues = new ulong[FrameCount]; fenceValues[0] = 1; return(fenceValues); } ID3D12GraphicsCommandList *[] CreateGraphicsCommandLists() { var graphicsCommandLists = new ID3D12GraphicsCommandList *[FrameCount]; for (uint i = 0u; i < FrameCount; i++) { ID3D12GraphicsCommandList *graphicsCommandList; var iid = IID_ID3D12GraphicsCommandList; ThrowIfFailed(nameof(ID3D12Device.CreateCommandList), D3DDevice->CreateCommandList(nodeMask: 0, D3D12_COMMAND_LIST_TYPE_DIRECT, _commandAllocators[i], PipelineState, &iid, (void **)&graphicsCommandList)); ThrowIfFailed(nameof(ID3D12GraphicsCommandList.Close), graphicsCommandList->Close()); graphicsCommandLists[i] = graphicsCommandList; } return(graphicsCommandLists); } IDXGIAdapter1 *GetDxgiAdapter() { if (UseWarpDevice) { IDXGIAdapter1 *adapter; var iid = IID_IDXGIAdapter; ThrowIfFailed(nameof(IDXGIFactory4.EnumWarpAdapter), _dxgiFactory->EnumWarpAdapter(&iid, (void **)&adapter)); return(adapter); } else { return(GetHardwareAdapter((IDXGIFactory1 *)_dxgiFactory)); } } bool TryEnableDebugLayer() { #if DEBUG // Enable the debug layer (requires the Graphics Tools "optional feature"). // NOTE: Enabling the debug layer after device creation will invalidate the active device. using ComPtr <ID3D12Debug> debugController = null; var iid = IID_ID3D12Debug; if (SUCCEEDED(D3D12GetDebugInterface(&iid, (void **)&debugController))) { debugController.Get()->EnableDebugLayer(); return(true); } #endif return(false); } }
public void SetPipelineState(ID3D12PipelineState *pPipelineState) { ((delegate * unmanaged[Stdcall] < ID3D12GraphicsCommandList *, ID3D12PipelineState *, void >)(lpVtbl[25]))((ID3D12GraphicsCommandList *)Unsafe.AsPointer(ref this), pPipelineState); }
public int Reset(ID3D12CommandAllocator *pAllocator, ID3D12PipelineState *pInitialState) { return(((delegate * unmanaged <ID3D12GraphicsCommandList2 *, ID3D12CommandAllocator *, ID3D12PipelineState *, int>)(lpVtbl[10]))((ID3D12GraphicsCommandList2 *)Unsafe.AsPointer(ref this), pAllocator, pInitialState)); }
public void ClearState(ID3D12PipelineState *pPipelineState) { ((delegate * unmanaged <ID3D12GraphicsCommandList2 *, ID3D12PipelineState *, void>)(lpVtbl[11]))((ID3D12GraphicsCommandList2 *)Unsafe.AsPointer(ref this), pPipelineState); }
protected override void Dispose(bool isDisposing) { var swapChain = _swapChain; if (swapChain != null) { _swapChain = null; _ = swapChain->Release(); } var device = _device; if (device != null) { _device = null; _ = device->Release(); } for (var index = 0; index < FrameCount; index++) { var renderTarget = _renderTargets[index]; if (renderTarget != null) { _renderTargets[index] = null; _ = renderTarget->Release(); } } var commandAllocator = _commandAllocator; if (commandAllocator != null) { _commandAllocator = null; _ = commandAllocator->Release(); } var bundleAllocator = _bundleAllocator; if (bundleAllocator != null) { _bundleAllocator = null; _ = bundleAllocator->Release(); } var commandQueue = _commandQueue; if (commandQueue != null) { _commandQueue = null; _ = commandQueue->Release(); } var rootSignature = _rootSignature; if (rootSignature != null) { _rootSignature = null; _ = rootSignature->Release(); } var rtvHeap = _rtvHeap; if (rtvHeap != null) { _rtvHeap = null; _ = rtvHeap->Release(); } var pipelineState = _pipelineState; if (pipelineState != null) { _pipelineState = null; _ = pipelineState->Release(); } var commandList = _commandList; if (commandList != null) { _commandList = null; _ = commandList->Release(); } var bundle = _bundle; if (bundle != null) { _bundle = null; _ = bundle->Release(); } var vertexBuffer = _vertexBuffer; if (vertexBuffer != null) { _vertexBuffer = null; _ = vertexBuffer->Release(); } var fence = _fence; if (fence != null) { _fence = null; _ = fence->Release(); } base.Dispose(isDisposing); }
public int StorePipeline([NativeTypeName("LPCWSTR")] ushort *pName, [NativeTypeName("ID3D12PipelineState *")] ID3D12PipelineState *pPipeline) { return(((delegate * unmanaged <ID3D12PipelineLibrary *, ushort *, ID3D12PipelineState *, int>)(lpVtbl[8]))((ID3D12PipelineLibrary *)Unsafe.AsPointer(ref this), pName, pPipeline)); }
protected override void CreateDeviceDependentResources() { _dxgiFactory = CreateDxgiFactory(); _dxgiAdapter = GetDxgiAdapter(); _d3dDevice = CreateD3DDevice(); StartInfoPump(); _commandQueue = CreateCommandQueue(); CreateDescriptorHeaps(); for (int i = 0; i < FrameCount; i++) { _commandAllocators[i] = CreateCommandAllocator(); } _fence = CreateFence(); _fenceValues = CreateFenceValues(); _fenceEvent = CreateFenceEvent(); _rootSignature = CreateRootSignature(); _pipelineState = CreatePipelineState(); _graphicsCommandLists = CreateGraphicsCommandLists(); SilkMarshal.ThrowHResult(CommandAllocator->Reset()); SilkMarshal.ThrowHResult(GraphicsCommandList->Reset(CommandAllocator, PipelineState)); CreateAssets(); ID3D12CommandAllocator *CreateCommandAllocator() { ID3D12CommandAllocator *commandAllocator; var iid = ID3D12CommandAllocator.Guid; SilkMarshal.ThrowHResult ( D3DDevice->CreateCommandAllocator (CommandListType.CommandListTypeDirect, &iid, (void **)&commandAllocator) ); return(commandAllocator); } ID3D12CommandQueue *CreateCommandQueue() { var queueDesc = new CommandQueueDesc(); ID3D12CommandQueue *commandQueue; var iid = ID3D12CommandQueue.Guid; SilkMarshal.ThrowHResult(D3DDevice->CreateCommandQueue(&queueDesc, &iid, (void **)&commandQueue)); return(commandQueue); } ID3D12Device *CreateD3DDevice() { ID3D12Device *d3dDevice; var iid = ID3D12Device.Guid; SilkMarshal.ThrowHResult ( D3D12.CreateDevice ((IUnknown *)_dxgiAdapter, D3DFeatureLevel.D3DFeatureLevel110, &iid, (void **)&d3dDevice) ); return(d3dDevice); } IDXGIFactory4 *CreateDxgiFactory() { var dxgiFactoryFlags = TryEnableDebugLayer() ? 0x01 : 0u; IDXGIFactory4 *dxgiFactory; var iid = IDXGIFactory4.Guid; SilkMarshal.ThrowHResult(Dxgi.CreateDXGIFactory2(dxgiFactoryFlags, &iid, (void **)&dxgiFactory)); return(dxgiFactory); } ID3D12Fence *CreateFence() { ID3D12Fence *fence; var iid = ID3D12Fence.Guid; SilkMarshal.ThrowHResult (D3DDevice->CreateFence(InitialValue: 0, FenceFlags.FenceFlagNone, &iid, (void **)&fence)); return(fence); } IntPtr CreateFenceEvent() { var fenceEvent = SilkMarshal.CreateWindowsEvent(null, false, false, null); if (fenceEvent == IntPtr.Zero) { var hr = Marshal.GetHRForLastWin32Error(); Marshal.ThrowExceptionForHR(hr); } return(fenceEvent); } ulong[] CreateFenceValues() { var fenceValues = new ulong[FrameCount]; fenceValues[0] = 1; return(fenceValues); } ID3D12GraphicsCommandList *[] CreateGraphicsCommandLists() { var graphicsCommandLists = new ID3D12GraphicsCommandList *[FrameCount]; for (uint i = 0u; i < FrameCount; i++) { ID3D12GraphicsCommandList *graphicsCommandList; var iid = ID3D12GraphicsCommandList.Guid; SilkMarshal.ThrowHResult ( D3DDevice->CreateCommandList ( nodeMask: 0, CommandListType.CommandListTypeDirect, _commandAllocators[i], PipelineState, &iid, (void **)&graphicsCommandList ) ); SilkMarshal.ThrowHResult(graphicsCommandList->Close()); graphicsCommandLists[i] = graphicsCommandList; } return(graphicsCommandLists); } IDXGIAdapter1 *GetDxgiAdapter() { if (UseWarpDevice) { IDXGIAdapter1 *adapter; var iid = IDXGIAdapter.Guid; SilkMarshal.ThrowHResult(_dxgiFactory->EnumWarpAdapter(&iid, (void **)&adapter)); return(adapter); } else { return(GetHardwareAdapter((IDXGIFactory1 *)_dxgiFactory)); } } bool TryEnableDebugLayer() { #if DEBUG // Enable the debug layer (requires the Graphics Tools "optional feature"). // NOTE: Enabling the debug layer after device creation will invalidate the active device. using ComPtr <ID3D12Debug> debugController = null; var iid = ID3D12Debug.Guid; var hr = D3D12.GetDebugInterface(&iid, (void **)&debugController); if (HResult.IndicatesSuccess(hr)) { debugController.Get().EnableDebugLayer(); Log.LogInformation("Debug layer enabled"); return(_debug = true); } else { Log.LogWarning ( Marshal.GetExceptionForHR(hr), $"Failed to enable debug layer, failed with result {hr} (0x{hr:x8})" ); } #endif return(false); } void StartInfoPump() { #if DEBUG if (!_debug) { Log.LogInformation("Skipped creation of info pump due to the debug layer not being enabled."); return; } var iid = ID3D12InfoQueue.Guid; fixed(ID3D12InfoQueue ** @out = &_infoQueue) { SilkMarshal.ThrowHResult(D3DDevice->QueryInterface(&iid, (void **)@out)); } _infoPumpCancellationToken = new(); _infoPump = Task.Run ( () => { Log.LogInformation("Info queue pump started"); while (!_infoPumpCancellationToken.Token.IsCancellationRequested) { var numMessages = _infoQueue->GetNumStoredMessages(); if (numMessages == 0) { continue; } for (var i = 0ul; i < numMessages; i++) { nuint msgByteLength; SilkMarshal.ThrowHResult(_infoQueue->GetMessageA(i, null, &msgByteLength)); using var memory = GlobalMemory.Allocate((int)msgByteLength); SilkMarshal.ThrowHResult ( _infoQueue->GetMessageA(i, memory.AsPtr <Message>(), &msgByteLength) ); ref var msg = ref memory.AsRef <Message>(); var descBytes = new Span <byte>(msg.PDescription, (int)msg.DescriptionByteLength); var desc = Encoding.UTF8.GetString(descBytes[..^ 1]); var eid = new EventId((int)msg.ID, msg.ID.ToString()["MessageID".Length..]);