Beispiel #1
0
        public ID3D12Device5 CreateDevice(IDXGIFactory4 pDxgiFactory)
        {
            // Find the HW adapter
            IDXGIAdapter1 pAdapter;

            var adapters = pDxgiFactory.EnumAdapters1();

            for (uint i = 0; i < adapters.Length; i++)
            {
                pAdapter = adapters[i];
                AdapterDescription1 desc = pAdapter.Description1;

                // Skip SW adapters
                if (desc.Flags.HasFlag(AdapterFlags.Software))
                {
                    continue;
                }
#if DEBUG
                if (D3D12.D3D12GetDebugInterface <ID3D12Debug>(out var pDx12Debug).Success)
                {
                    pDx12Debug.EnableDebugLayer();
                }
#endif
                var res = D3D12.D3D12CreateDevice(pAdapter, Vortice.Direct3D.FeatureLevel.Level_12_0, out ID3D12Device pDevice);
                FeatureDataD3D12Options5 features5 = pDevice.CheckFeatureSupport <FeatureDataD3D12Options5>(Vortice.Direct3D12.Feature.Options5);
                if (features5.RaytracingTier == RaytracingTier.NotSupported)
                {
                    throw new NotSupportedException("Raytracing is not supported on this device.Make sure your GPU supports DXR(such as Nvidia's Volta or Turing RTX) and you're on the latest drivers.The DXR fallback layer is not supported.");
                }

                return(pDevice.QueryInterface <ID3D12Device5>());
            }

            return(null);
        }
Beispiel #2
0
        private void GetHardwareAdapter(IDXGIAdapter1 **ppAdapter)
        {
            using ComPtr <IDXGIAdapter1> adapter = null;
            *ppAdapter = null;

            for (uint adapterIndex = 0;
                 DXGI_ERROR_NOT_FOUND != _dxgiFactory.Ptr->EnumAdapters1(adapterIndex, adapter.GetAddressOf());
                 adapterIndex++)
            {
                DXGI_ADAPTER_DESC1 desc;
                adapter.Ptr->GetDesc1(&desc);

                if (((DXGI_ADAPTER_FLAG)desc.Flags & DXGI_ADAPTER_FLAG.DXGI_ADAPTER_FLAG_SOFTWARE) != 0)
                {
                    continue;
                }

                Guid iid = D3D12.IID_ID3D12Device;
                if (SUCCEEDED(D3D12.D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_11_0, &iid, null)))
                {
                    Debug.WriteLine(new string(desc.Description));
                    break;
                }
            }

            *ppAdapter = adapter.Detach();
        }
Beispiel #3
0
 public D3D12GraphicsContext(int winWidth, int winHeight)
 {
     if (!D3D12.IsSupported(Vortice.Direct3D.FeatureLevel.Level_12_0))
     {
         throw new InvalidOperationException("Direct3D12 is not supported on current OS");
     }
 }
Beispiel #4
0
        protected override unsafe ID3D12RootSignature *CreateRootSignature()
        {
            using ComPtr <ID3D10Blob> signature = null;
            using ComPtr <ID3D10Blob> error     = null;

            var rootSignatureDesc = new RootSignatureDesc
            {
                Flags = RootSignatureFlags.RootSignatureFlagAllowInputAssemblerInputLayout
            };

            SilkMarshal.ThrowHResult
            (
                D3D12.SerializeRootSignature
                (
                    &rootSignatureDesc, D3DRootSignatureVersion.D3DRootSignatureVersion1, signature.GetAddressOf(),
                    error.GetAddressOf()
                )
            );

            ID3D12RootSignature *rootSignature;

            var iid = ID3D12RootSignature.Guid;

            SilkMarshal.ThrowHResult
            (
                D3DDevice->CreateRootSignature
                (
                    nodeMask: 0, signature.Get().GetBufferPointer(), signature.Get().GetBufferSize(), &iid,
                    (void **)&rootSignature
                )
            );

            return(rootSignature);
        }
Beispiel #5
0
        public void Initialize()
        {
#if DEBUG
            if (D3D12.D3D12GetDebugInterface <ID3D12Debug>(out var pDx12Debug).Success)
            {
                pDx12Debug.EnableDebugLayer();
            }
#endif
            ThrowIfFailed(DXGI.CreateDXGIFactory1(out dxgiFactory));
            int index1 = 0;
            while (true)
            {
                var hr = dxgiFactory.EnumAdapterByGpuPreference(index1, GpuPreference.HighPerformance, out adapter);
                if (hr == SharpGen.Runtime.Result.Ok)
                {
                    break;
                }
                index1++;
            }
            ThrowIfFailed(D3D12.D3D12CreateDevice(this.adapter, out device));
            CommandQueueDescription description;
            description.Flags    = CommandQueueFlags.None;
            description.Type     = CommandListType.Direct;
            description.NodeMask = 0;
            description.Priority = 0;
            ThrowIfFailed(device.CreateCommandQueue(description, out commandQueue));
            DescriptorHeapDescription descriptorHeapDescription;
            descriptorHeapDescription.DescriptorCount = CBVSRVUAVDescriptorCount;
            descriptorHeapDescription.Type            = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView;
            descriptorHeapDescription.Flags           = DescriptorHeapFlags.ShaderVisible;
            descriptorHeapDescription.NodeMask        = 0;
            ThrowIfFailed(device.CreateDescriptorHeap(descriptorHeapDescription, out cbvsrvuavHeap));

            descriptorHeapDescription.DescriptorCount = 16;
            descriptorHeapDescription.Type            = DescriptorHeapType.DepthStencilView;
            descriptorHeapDescription.Flags           = DescriptorHeapFlags.None;
            ThrowIfFailed(device.CreateDescriptorHeap(descriptorHeapDescription, out dsvHeap));

            descriptorHeapDescription.DescriptorCount = 16;
            descriptorHeapDescription.Type            = DescriptorHeapType.RenderTargetView;
            descriptorHeapDescription.Flags           = DescriptorHeapFlags.None;
            ThrowIfFailed(device.CreateDescriptorHeap(descriptorHeapDescription, out rtvHeap));
            waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);

            cbvsrvuavHeapIncrementSize = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            dsvHeapIncrementSize       = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.DepthStencilView);
            rtvHeapIncrementSize       = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.RenderTargetView);
            commandAllocators          = new List <ID3D12CommandAllocator>();
            for (int i = 0; i < bufferCount; i++)
            {
                ThrowIfFailed(device.CreateCommandAllocator(CommandListType.Direct, out ID3D12CommandAllocator commandAllocator));
                commandAllocators.Add(commandAllocator);
            }
            ThrowIfFailed(device.CreateFence(executeCount, FenceFlags.None, out fence));
            executeCount++;
        }
        public GraphicsDevice(FeatureLevel minFeatureLevel = FeatureLevel.Level11_0, bool enableDebugLayer = false)
        {
#if DEBUG
            if (enableDebugLayer)
            {
                Result debugResult = D3D12.D3D12GetDebugInterface(out ID3D12Debug debugInterface);

                using ID3D12Debug debug = debugInterface;

                if (debugResult.Success)
                {
                    debug.EnableDebugLayer();
                }
            }
#endif
            FeatureLevel = minFeatureLevel < FeatureLevel.Level11_0 ? FeatureLevel.Level11_0 : minFeatureLevel;

            Result result = D3D12.D3D12CreateDevice(null, (Vortice.Direct3D.FeatureLevel)FeatureLevel, out ID3D12Device device);

            if (result.Failure)
            {
                throw new COMException("Device creation failed.", result.Code);
            }

            NativeDevice = device;

            NativeComputeCommandQueue = NativeDevice.CreateCommandQueue(new CommandQueueDescription(Vortice.Direct3D12.CommandListType.Compute));
            NativeCopyCommandQueue    = NativeDevice.CreateCommandQueue(new CommandQueueDescription(Vortice.Direct3D12.CommandListType.Copy));
            NativeDirectCommandQueue  = NativeDevice.CreateCommandQueue(new CommandQueueDescription(Vortice.Direct3D12.CommandListType.Direct));

            BundleAllocatorPool  = new CommandAllocatorPool(this, CommandListType.Bundle);
            ComputeAllocatorPool = new CommandAllocatorPool(this, CommandListType.Compute);
            CopyAllocatorPool    = new CommandAllocatorPool(this, CommandListType.Copy);
            DirectAllocatorPool  = new CommandAllocatorPool(this, CommandListType.Direct);

            NativeComputeFence = NativeDevice.CreateFence(0, FenceFlags.None);
            NativeCopyFence    = NativeDevice.CreateFence(0, FenceFlags.None);
            NativeDirectFence  = NativeDevice.CreateFence(0, FenceFlags.None);

            DepthStencilViewAllocator   = new DescriptorAllocator(this, DescriptorHeapType.DepthStencilView, 1);
            RenderTargetViewAllocator   = new DescriptorAllocator(this, DescriptorHeapType.RenderTargetView, 2);
            ShaderResourceViewAllocator = new DescriptorAllocator(this, DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView, 4096);
            SamplerAllocator            = new DescriptorAllocator(this, DescriptorHeapType.Sampler, 256);

            ShaderVisibleShaderResourceViewAllocator = new DescriptorAllocator(this, DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView, 4096, DescriptorHeapFlags.ShaderVisible);
            ShaderVisibleSamplerAllocator            = new DescriptorAllocator(this, DescriptorHeapType.Sampler, 256, DescriptorHeapFlags.ShaderVisible);

            CommandList = new CommandList(this, CommandListType.Direct);
            CommandList.Close();

            CopyCommandList = new CommandList(this, CommandListType.Copy);
            CopyCommandList.Close();
        }
        /// <summary>
        /// Checks if given DirectX12 backend is supported.
        /// </summary>
        /// <returns>True if supported, false otherwise.</returns>
        public static bool IsSupported()
        {
            if (s_isSupported.HasValue)
            {
                return(s_isSupported.Value);
            }

            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                s_isSupported = false;
                return(false);
            }

            if (CreateDXGIFactory1(out IDXGIFactory1 tempDXGIFactory1).Failure)
            {
                s_isSupported = false;
                return(false);
            }

            var adapters = tempDXGIFactory1.EnumAdapters1();

            for (var i = 0; i < adapters.Length; i++)
            {
                var adapter = adapters[i];
                var desc    = adapter.Description1;

                // Don't select the Basic Render Driver adapter.
                if ((desc.Flags & AdapterFlags.Software) != AdapterFlags.None)
                {
                    continue;
                }

                if (D3D12.IsSupported(adapter, FeatureLevel.Level_11_0))
                {
                    s_isSupported = true;
                    return(true);
                }
            }

            s_isSupported = true;
            return(true);
        }
Beispiel #8
0
        public unsafe GraphicsDevice(FeatureLevel minFeatureLevel = FeatureLevel.Level11_0, bool enableDebugLayer = false)
        {
            if (enableDebugLayer)
            {
                Result debugResult = D3D12.D3D12GetDebugInterface(out ID3D12Debug debugInterface);

                if (debugResult.Success)
                {
                    ID3D12Debug1 debug = debugInterface.QueryInterface <ID3D12Debug1>();

                    debug.EnableDebugLayer();
                }
            }

            FeatureLevel = minFeatureLevel < FeatureLevel.Level11_0 ? FeatureLevel.Level11_0 : minFeatureLevel;

            Result result = D3D12.D3D12CreateDevice(null, (Vortice.Direct3D.FeatureLevel)FeatureLevel, out ID3D12Device device);

            if (result.Failure)
            {
                throw new COMException("Device creation failed.", result.Code);
            }

            NativeDevice = device;

            DirectCommandQueue  = new CommandQueue(this, CommandListType.Direct);
            ComputeCommandQueue = new CommandQueue(this, CommandListType.Compute);
            CopyCommandQueue    = new CommandQueue(this, CommandListType.Copy);

            DepthStencilViewAllocator   = new DescriptorAllocator(this, DescriptorHeapType.DepthStencilView, 1);
            RenderTargetViewAllocator   = new DescriptorAllocator(this, DescriptorHeapType.RenderTargetView, 2);
            ShaderResourceViewAllocator = new DescriptorAllocator(this, DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView, 4096);
            SamplerAllocator            = new DescriptorAllocator(this, DescriptorHeapType.Sampler, 256);

            ShaderVisibleShaderResourceViewAllocator = new DescriptorAllocator(this, DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView, 4096, DescriptorHeapFlags.ShaderVisible);
            ShaderVisibleSamplerAllocator            = new DescriptorAllocator(this, DescriptorHeapType.Sampler, 256, DescriptorHeapFlags.ShaderVisible);

            CommandList = new CommandList(this, CommandListType.Direct);
            CommandList.Close();
        }
 public static bool IsSupported()
 {
     return(D3D12.IsSupported(FeatureLevel.Level_11_0));
 }
Beispiel #10
0
 public static bool IsSupported() => D3D12.IsSupported(FeatureLevel.Level_12_0);
Beispiel #11
0
    public HelloDml()
    {
        if (!IsSupported())
        {
            throw new InvalidOperationException("Direct3D12 is not supported on current OS");
        }

        bool validation = false;

#if DEBUG
        if (D3D12.D3D12GetDebugInterface(out ID3D12Debug? debug).Success)
        {
            debug !.EnableDebugLayer();
            debug !.Dispose();
            validation = true;
        }
#endif

        DXGIFactory = DXGI.CreateDXGIFactory2 <IDXGIFactory4>(validation);

        ID3D12Device2?device = default;

        for (int adapterIndex = 0; DXGIFactory.EnumAdapters1(adapterIndex, out IDXGIAdapter1 adapter).Success; adapterIndex++)
        {
            AdapterDescription1 desc = adapter.Description1;

            // Don't select the Basic Render Driver adapter.
            if ((desc.Flags & AdapterFlags.Software) != AdapterFlags.None)
            {
                adapter.Dispose();

                continue;
            }

            if (D3D12.D3D12CreateDevice(adapter, Vortice.Direct3D.FeatureLevel.Level_11_0, out device).Success)
            {
                adapter.Dispose();

                break;
            }
        }

        if (device == null)
        {
            throw new InvalidOperationException("Direct3D12 device could not be created");
        }

        D3D12Device = device !;

        CommandQueueDescription commandQueueDesc = new()
        {
            Type  = CommandListType.Direct,
            Flags = CommandQueueFlags.None,
        };

        D3D12CommandQueue     = D3D12Device.CreateCommandQueue(commandQueueDesc);
        D3D12CommandAllocator = D3D12Device.CreateCommandAllocator(CommandListType.Direct);
        D3D12CommandList      = D3D12Device.CreateCommandList <ID3D12GraphicsCommandList4>(CommandListType.Direct, D3D12CommandAllocator);

        var createFlags = CreateDeviceFlags.None;

#if DEBUG
        createFlags |= CreateDeviceFlags.Debug;
#endif
        DMLDevice = DMLCreateDevice(D3D12Device, createFlags);

        Console.WriteLine($"Highest supported feature level: {DMLDevice.HighestFeatureLevel}");
    }
Beispiel #12
0
 public bool IsSupported() => D3D12.IsSupported(Vortice.Direct3D.FeatureLevel.Level_12_0);
Beispiel #13
0
        private async void CreateDeviceDependentResources()
        {
            unsafe
            {
                ID3D12Device *d3dDevice = _deviceResources.D3DDevice;

                {
                    D3D12_DESCRIPTOR_RANGE range =
                        CD3DX12_DESCRIPTOR_RANGE.Create(D3D12_DESCRIPTOR_RANGE_TYPE.D3D12_DESCRIPTOR_RANGE_TYPE_CBV, 1, 0);
                    CD3DX12_ROOT_PARAMETER.InitAsDescriptorTable(out D3D12_ROOT_PARAMETER parameter, 1, &range,
                                                                 D3D12_SHADER_VISIBILITY.D3D12_SHADER_VISIBILITY_VERTEX);

                    D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags =
                        D3D12_ROOT_SIGNATURE_FLAGS
                        .D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |     // Only the input assembler stage needs access to the constant buffer.
                        D3D12_ROOT_SIGNATURE_FLAGS.D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
                        D3D12_ROOT_SIGNATURE_FLAGS.D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS |
                        D3D12_ROOT_SIGNATURE_FLAGS.D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
                        D3D12_ROOT_SIGNATURE_FLAGS.D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS;

                    CD3DX12_ROOT_SIGNATURE_DESC.Init(out D3D12_ROOT_SIGNATURE_DESC descRootSignature, 1, &parameter, 0,
                                                     null, rootSignatureFlags);

                    var pSignature = new ComPtrField <ID3DBlob>();
                    var pError     = new ComPtrField <ID3DBlob>();

                    ThrowIfFailed(D3D12.D3D12SerializeRootSignature(&descRootSignature,
                                                                    D3D_ROOT_SIGNATURE_VERSION.D3D_ROOT_SIGNATURE_VERSION_1, pSignature.DangerousGetAddressOf(),
                                                                    pError.DangerousGetAddressOf()));

                    Guid iid = D3D12.IID_ID3D12RootSignature;
                    ID3D12RootSignature *rootSignature;
                    ThrowIfFailed(d3dDevice->CreateRootSignature(0, pSignature.Ptr->GetBufferPointer(),
                                                                 pSignature.Ptr->GetBufferSize(), &iid, (void **)&rootSignature));
                    _rootSignature = rootSignature;
                    DX.NameD3D12Object(_rootSignature.Ptr, nameof(_rootSignature));
                }
            }

            Task vertexShaderRead = ((Func <Task>)(async() =>
            {
                const string fileName = "Content/SampleVertexShader.cso";

                var size = (UIntPtr) new FileInfo(fileName).Length;
                byte[] shader = await File.ReadAllBytesAsync(fileName);

                unsafe
                {
                    CopyBytesToBlob(out _vertexShader.GetPinnableReference(), size, shader);
                }
            }))();

            Task pixelShaderRead = ((Func <Task>)(async() =>
            {
                const string fileName = "Content/SamplePixelShader.cso";

                var size = (UIntPtr) new FileInfo(fileName).Length;
                byte[] shader = await File.ReadAllBytesAsync(fileName);

                unsafe
                {
                    CopyBytesToBlob(out _pixelShader.GetPinnableReference(), size, shader);
                }
            }))();

            await CreatePipelineState(vertexShaderRead, pixelShaderRead).ContinueWith(CreateRendererAssets);
        }
Beispiel #14
0
        private void CreateDeviceResources()
        {
            Guid iid;

#if DEBUG
            {
                using ComPtr <ID3D12Debug> debugController = null;

                iid = D3D12.IID_ID3D12Debug;
                if (SUCCEEDED(D3D12.D3D12GetDebugInterface(&iid, (void **)debugController.GetAddressOf())))
                {
                    debugController.Ptr->EnableDebugLayer();
                }
            }
#endif
            iid = DXGI.IID_IDXGIFactory4;
            IDXGIFactory4 *dxgiFactory;
            DirectXHelper.ThrowIfFailed(DXGI.CreateDXGIFactory1(&iid, (void **)&dxgiFactory));
            _dxgiFactory = dxgiFactory;

            using ComPtr <IDXGIAdapter1> adapter = null;
            GetHardwareAdapter(adapter.ReleaseGetAddressOf());

            ID3D12Device *d3dDevice;
            iid = D3D12.IID_ID3D12Device;
            HRESULT hr;
            {
                hr = D3D12.D3D12CreateDevice(
                    adapter,
                    D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_11_0,
                    &iid,
                    (void **)&d3dDevice
                    );

#if DEBUG
                if (FAILED(hr))
                {
                    using ComPtr <IDXGIAdapter> warpAdapter = null;

                    iid = DXGI.IID_IDXGIAdapter;
                    DirectXHelper.ThrowIfFailed(_dxgiFactory.Ptr->EnumWarpAdapter(&iid, (void **)warpAdapter.GetAddressOf()));

                    iid = D3D12.IID_ID3D12Device1;
                    hr  = D3D12.D3D12CreateDevice(
                        warpAdapter,
                        D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_11_0,
                        &iid,
                        (void **)&d3dDevice
                        );
                }
#endif
            }
            _d3dDevice = d3dDevice;

            DirectXHelper.ThrowIfFailed(hr);

            D3D12_COMMAND_QUEUE_DESC queueDesc;
            queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAGS.D3D12_COMMAND_QUEUE_FLAG_NONE;
            queueDesc.Type  = D3D12_COMMAND_LIST_TYPE.D3D12_COMMAND_LIST_TYPE_DIRECT;

            ID3D12CommandQueue *commandQueue;
            {
                iid = D3D12.IID_ID3D12CommandQueue;
                DirectXHelper.ThrowIfFailed(_d3dDevice.Ptr->CreateCommandQueue(&queueDesc, &iid, (void **)&commandQueue));
            }
            _commandQueue = commandQueue;
            DirectXHelper.NameObject(_commandQueue, nameof(_commandQueue));

            D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc;
            rtvHeapDesc.NumDescriptors = FrameCount;
            rtvHeapDesc.Type           = D3D12_DESCRIPTOR_HEAP_TYPE.D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
            rtvHeapDesc.Flags          = D3D12_DESCRIPTOR_HEAP_FLAGS.D3D12_DESCRIPTOR_HEAP_FLAG_NONE;

            ID3D12DescriptorHeap *rtvHeap;
            {
                iid = D3D12.IID_ID3D12DescriptorHeap;
                DirectXHelper.ThrowIfFailed(_d3dDevice.Ptr->CreateDescriptorHeap(&rtvHeapDesc, &iid, (void **)&rtvHeap));
            }
            _rtvHeap = rtvHeap;
            DirectXHelper.NameObject(_rtvHeap, nameof(_rtvHeap));

            _rtvDescriptorSize =
                _d3dDevice.Ptr->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE
                                                                 .D3D12_DESCRIPTOR_HEAP_TYPE_RTV);



            D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc;
            dsvHeapDesc.NumDescriptors = 1;
            dsvHeapDesc.Type           = D3D12_DESCRIPTOR_HEAP_TYPE.D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
            dsvHeapDesc.Flags          = D3D12_DESCRIPTOR_HEAP_FLAGS.D3D12_DESCRIPTOR_HEAP_FLAG_NONE;

            ID3D12DescriptorHeap *dsvHeap;
            {
                iid = D3D12.IID_ID3D12DescriptorHeap;
                DirectXHelper.ThrowIfFailed(_d3dDevice.Ptr->CreateDescriptorHeap(&dsvHeapDesc, &iid, (void **)&dsvHeap));
            }

            _dsvHeap = dsvHeap;
            DirectXHelper.NameObject(_dsvHeap, nameof(_dsvHeap));

            fixed(CommandAllocators_e__FixedBuffer *pBuffer = &_commandAllocators)
            {
                var p = (ID3D12CommandAllocator **)pBuffer;

                iid = D3D12.IID_ID3D12CommandAllocator;
                for (var n = 0; n < FrameCount; n++)
                {
                    DirectXHelper.ThrowIfFailed(_d3dDevice.Ptr->CreateCommandAllocator(
                                                    D3D12_COMMAND_LIST_TYPE.D3D12_COMMAND_LIST_TYPE_DIRECT,
                                                    &iid,
                                                    (void **)(p + n)));
                }
            }

            ID3D12Fence *fence;
            {
                iid = D3D12.IID_ID3D12Fence;
                DirectXHelper.ThrowIfFailed(
                    _d3dDevice.Ptr->CreateFence(_fenceValues[_currentFrame],
                                                D3D12_FENCE_FLAGS.D3D12_FENCE_FLAG_NONE,
                                                &iid,
                                                (void **)&fence));
                _fenceValues[_currentFrame]++;
            }
            _fence = fence;
            DirectXHelper.NameObject(_fence, nameof(_fence));

            _fenceEvent = Kernel32.CreateEvent(null, FALSE, FALSE, null);
            if (_fenceEvent == IntPtr.Zero)
            {
                DirectXHelper.ThrowIfFailed(Marshal.GetLastWin32Error());
            }
        }