コード例 #1
0
        /// <summary>
        /// Tries to check or create a warp <see cref="ID3D12Device"/> object.
        /// </summary>
        /// <param name="d3D12Device">A pointer to the <see cref="ID3D12Device"/> object to create, or <see langword="null"/>.</param>
        /// <param name="dxgiAdapter">A pointer to the <see cref="IDXGIAdapter"/> object used to create <paramref name="d3D12Device"/>, or <see langword="null"/>.</param>
        /// <param name="dxgiDescription1">A pointer to the <see cref="DXGI_ADAPTER_DESC1"/> value for the device found.</param>
        /// <returns>Whether a warp device was created successfully.</returns>
        private static unsafe bool TryGetWarpDevice(ID3D12Device **d3D12Device, IDXGIAdapter **dxgiAdapter, DXGI_ADAPTER_DESC1 *dxgiDescription1)
        {
            using ComPtr <IDXGIFactory4> dxgiFactory4 = default;

            EnableDebugMode();

            FX.CreateDXGIFactory2(IDXGIFactoryCreationFlags, FX.__uuidof <IDXGIFactory4>(), dxgiFactory4.GetVoidAddressOf()).Assert();

            using ComPtr <IDXGIAdapter1> dxgiAdapter1 = default;

            dxgiFactory4.Get()->EnumWarpAdapter(FX.__uuidof <IDXGIAdapter1>(), dxgiAdapter1.GetVoidAddressOf()).Assert();

            dxgiAdapter1.Get()->GetDesc1(dxgiDescription1).Assert();

            HRESULT createDeviceResult = FX.D3D12CreateDevice(
                dxgiAdapter1.AsIUnknown().Get(),
                D3D_FEATURE_LEVEL_11_0,
                FX.__uuidof <ID3D12Device>(),
                (void **)d3D12Device);

            dxgiAdapter1.CopyTo(dxgiAdapter);

            return(FX.SUCCEEDED(createDeviceResult));
        }
コード例 #2
0
        /// <inheritdoc/>
        public override unsafe void OnInitialize(HWND hwnd)
        {
            // Get the underlying ID3D12Device in use
            fixed(ID3D12Device **d3D12Device = this.d3D12Device)
            {
                _ = InteropServices.TryGetID3D12Device(Gpu.Default, FX.__uuidof <ID3D12Device>(), (void **)d3D12Device);
            }

            // Create the direct command queue to use
            fixed(ID3D12CommandQueue **d3D12CommandQueue = this.d3D12CommandQueue)
            {
                D3D12_COMMAND_QUEUE_DESC d3D12CommandQueueDesc;

                d3D12CommandQueueDesc.Type     = D3D12_COMMAND_LIST_TYPE.D3D12_COMMAND_LIST_TYPE_DIRECT;
                d3D12CommandQueueDesc.Priority = (int)D3D12_COMMAND_QUEUE_PRIORITY.D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
                d3D12CommandQueueDesc.Flags    = D3D12_COMMAND_QUEUE_FLAGS.D3D12_COMMAND_QUEUE_FLAG_NONE;
                d3D12CommandQueueDesc.NodeMask = 0;

                _ = d3D12Device.Get()->CreateCommandQueue(
                    &d3D12CommandQueueDesc,
                    FX.__uuidof <ID3D12CommandQueue>(),
                    (void **)d3D12CommandQueue);
            }

            // Create the direct fence
            fixed(ID3D12Fence **d3D12Fence = this.d3D12Fence)
            {
                _ = this.d3D12Device.Get()->CreateFence(
                    0,
                    D3D12_FENCE_FLAGS.D3D12_FENCE_FLAG_NONE,
                    FX.__uuidof <ID3D12Fence>(),
                    (void **)d3D12Fence);
            }

            // Create the swap chain to display frames
            fixed(IDXGISwapChain1 **dxgiSwapChain1 = this.dxgiSwapChain1)
            {
                using ComPtr <IDXGIFactory2> dxgiFactory2 = default;

                _ = FX.CreateDXGIFactory2(FX.DXGI_CREATE_FACTORY_DEBUG, FX.__uuidof <IDXGIFactory2>(), (void **)dxgiFactory2.GetAddressOf());

                DXGI_SWAP_CHAIN_DESC1 dxgiSwapChainDesc1 = default;

                dxgiSwapChainDesc1.AlphaMode   = DXGI_ALPHA_MODE.DXGI_ALPHA_MODE_IGNORE;
                dxgiSwapChainDesc1.BufferCount = 2;
                dxgiSwapChainDesc1.Flags       = 0;
                dxgiSwapChainDesc1.Format      = DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM;
                dxgiSwapChainDesc1.Width       = 0;
                dxgiSwapChainDesc1.Height      = 0;
                dxgiSwapChainDesc1.SampleDesc  = new DXGI_SAMPLE_DESC(count: 1, quality: 0);
                dxgiSwapChainDesc1.Scaling     = DXGI_SCALING.DXGI_SCALING_STRETCH;
                dxgiSwapChainDesc1.Stereo      = 0;
                dxgiSwapChainDesc1.SwapEffect  = DXGI_SWAP_EFFECT.DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;

                _ = dxgiFactory2.Get()->CreateSwapChainForHwnd(
                    (IUnknown *)d3D12CommandQueue.Get(),
                    hwnd,
                    &dxgiSwapChainDesc1,
                    null,
                    null,
                    dxgiSwapChain1);
            }

            // Create the command allocator to use
            fixed(ID3D12CommandAllocator **d3D12CommandAllocator = this.d3D12CommandAllocator)
            {
                this.d3D12Device.Get()->CreateCommandAllocator(
                    D3D12_COMMAND_LIST_TYPE.D3D12_COMMAND_LIST_TYPE_DIRECT,
                    FX.__uuidof <ID3D12CommandAllocator>(),
                    (void **)d3D12CommandAllocator);
            }

            // Create the reusable command list to copy data to the back buffers
            fixed(ID3D12GraphicsCommandList **d3D12GraphicsCommandList = this.d3D12GraphicsCommandList)
            {
                this.d3D12Device.Get()->CreateCommandList(
                    0,
                    D3D12_COMMAND_LIST_TYPE.D3D12_COMMAND_LIST_TYPE_DIRECT,
                    d3D12CommandAllocator,
                    null,
                    FX.__uuidof <ID3D12GraphicsCommandList>(),
                    (void **)d3D12GraphicsCommandList);
            }

            // Close the command list to prepare it for future use
            this.d3D12GraphicsCommandList.Get()->Close();
        }
コード例 #3
0
        /// <summary>
        /// Tries to check or create a default <see cref="ID3D12Device"/> object.
        /// </summary>
        /// <param name="d3D12Device">A pointer to the <see cref="ID3D12Device"/> object to create, or <see langword="null"/>.</param>
        /// <param name="dxgiAdapter">A pointer to the <see cref="IDXGIAdapter"/> object used to create <paramref name="d3D12Device"/>, or <see langword="null"/>.</param>
        /// <param name="dxgiDescription1">A pointer to the <see cref="DXGI_ADAPTER_DESC1"/> value for the device found.</param>
        /// <returns>Whether a default device was found with the requested feature level.</returns>
        private static unsafe bool TryGetDefaultDevice(ID3D12Device **d3D12Device, IDXGIAdapter **dxgiAdapter, DXGI_ADAPTER_DESC1 *dxgiDescription1)
        {
            using ComPtr <IDXGIFactory4> dxgiFactory4 = default;

            EnableDebugMode();

            FX.CreateDXGIFactory2(IDXGIFactoryCreationFlags, FX.__uuidof <IDXGIFactory4>(), dxgiFactory4.GetVoidAddressOf()).Assert();

            uint i = 0;

            while (true)
            {
                using ComPtr <IDXGIAdapter1> dxgiAdapter1 = default;

                HRESULT enumAdapters1Result = dxgiFactory4.Get()->EnumAdapters1(i++, dxgiAdapter1.GetAddressOf());

                if (enumAdapters1Result == FX.DXGI_ERROR_NOT_FOUND)
                {
                    return(false);
                }

                enumAdapters1Result.Assert();

                dxgiAdapter1.Get()->GetDesc1(dxgiDescription1).Assert();

                if (dxgiDescription1->VendorId == MicrosoftVendorId &&
                    dxgiDescription1->DeviceId == WarpDeviceId)
                {
                    continue;
                }

                // Explicit paths for when a device is being retrieved or not, with special handling
                // for the additional check that is required for the SM6 level. This can't be checked
                // without creating a device first, so the path for when the target device pointer is
                // null is useful to do an initial filtering using D3D12CreateDevice to avoid creating
                // a device for adapters that would've failed at the FL11 check already.
                if (d3D12Device == null)
                {
                    HRESULT createDeviceResult = FX.D3D12CreateDevice(
                        dxgiAdapter1.AsIUnknown().Get(),
                        D3D_FEATURE_LEVEL_11_0,
                        FX.__uuidof <ID3D12Device>(),
                        null);

                    if (FX.SUCCEEDED(createDeviceResult))
                    {
                        using ComPtr <ID3D12Device> d3D12DeviceCandidate = default;

                        createDeviceResult = FX.D3D12CreateDevice(
                            dxgiAdapter1.AsIUnknown().Get(),
                            D3D_FEATURE_LEVEL_11_0,
                            FX.__uuidof <ID3D12Device>(),
                            d3D12DeviceCandidate.GetVoidAddressOf());

                        if (FX.SUCCEEDED(createDeviceResult) &&
                            d3D12DeviceCandidate.Get()->IsShaderModelSupported(D3D_SHADER_MODEL_6_0))
                        {
                            return(true);
                        }
                    }
                }
                else
                {
                    using ComPtr <ID3D12Device> d3D12DeviceCandidate = default;

                    HRESULT createDeviceResult = FX.D3D12CreateDevice(
                        dxgiAdapter1.AsIUnknown().Get(),
                        D3D_FEATURE_LEVEL_11_0,
                        FX.__uuidof <ID3D12Device>(),
                        d3D12DeviceCandidate.GetVoidAddressOf());

                    if (FX.SUCCEEDED(createDeviceResult) &&
                        d3D12DeviceCandidate.Get()->IsShaderModelSupported(D3D_SHADER_MODEL_6_0))
                    {
                        d3D12DeviceCandidate.CopyTo(d3D12Device);
                        dxgiAdapter1.CopyTo(dxgiAdapter);

                        return(true);
                    }
                }
            }
        }
コード例 #4
0
                /// <inheritdoc/>
                public bool MoveNext()
                {
                    if (!this.isInitialized)
                    {
                        this.isInitialized = true;

                        fixed(IDXGIFactory4 **dxgiFactory4 = this.dxgiFactory4)
                        {
                            EnableDebugMode();

                            FX.CreateDXGIFactory2(IDXGIFactoryCreationFlags, FX.__uuidof <IDXGIFactory4>(), (void **)dxgiFactory4).Assert();
                        }
                    }

                    if (this.isCompleted)
                    {
                        return(false);
                    }

                    while (true)
                    {
                        using ComPtr <IDXGIAdapter1> dxgiAdapter1 = default;

                        HRESULT enumAdapters1Result = this.dxgiFactory4.Get()->EnumAdapters1(this.index, dxgiAdapter1.GetAddressOf());

                        if (enumAdapters1Result == FX.DXGI_ERROR_NOT_FOUND)
                        {
                            this.dxgiFactory4.Get()->EnumWarpAdapter(FX.__uuidof <IDXGIAdapter1>(), dxgiAdapter1.GetVoidAddressOf()).Assert();

                            DXGI_ADAPTER_DESC1 dxgiDescription1;

                            dxgiAdapter1.Get()->GetDesc1(&dxgiDescription1).Assert();

                            HRESULT createDeviceResult = FX.D3D12CreateDevice(
                                dxgiAdapter1.AsIUnknown().Get(),
                                D3D_FEATURE_LEVEL_11_0,
                                FX.__uuidof <ID3D12Device>(),
                                null);

                            if (FX.SUCCEEDED(createDeviceResult) &&
                                this.predicate(new GraphicsDeviceInfo(&dxgiDescription1)))
                            {
                                using ComPtr <ID3D12Device> d3D12Device = default;

                                FX.D3D12CreateDevice(
                                    dxgiAdapter1.AsIUnknown().Get(),
                                    D3D_FEATURE_LEVEL_11_0,
                                    FX.__uuidof <ID3D12Device>(),
                                    d3D12Device.GetVoidAddressOf()).Assert();

                                this.graphicsDevice = GetOrCreateDevice(d3D12Device.Get(), (IDXGIAdapter *)dxgiAdapter1.Get(), &dxgiDescription1);
                                this.isCompleted    = true;

                                return(true);
                            }

                            return(false);
                        }
                        else
                        {
                            enumAdapters1Result.Assert();

                            this.index++;

                            DXGI_ADAPTER_DESC1 dxgiDescription1;

                            dxgiAdapter1.Get()->GetDesc1(&dxgiDescription1).Assert();

                            if (dxgiDescription1.VendorId == MicrosoftVendorId &&
                                dxgiDescription1.DeviceId == WarpDeviceId)
                            {
                                continue;
                            }

                            HRESULT createDeviceResult = FX.D3D12CreateDevice(
                                dxgiAdapter1.AsIUnknown().Get(),
                                D3D_FEATURE_LEVEL_11_0,
                                FX.__uuidof <ID3D12Device>(),
                                null);

                            if (FX.SUCCEEDED(createDeviceResult) &&
                                this.predicate(new GraphicsDeviceInfo(&dxgiDescription1)))
                            {
                                using ComPtr <ID3D12Device> d3D12Device = default;

                                FX.D3D12CreateDevice(
                                    dxgiAdapter1.AsIUnknown().Get(),
                                    D3D_FEATURE_LEVEL_11_0,
                                    FX.__uuidof <ID3D12Device>(),
                                    d3D12Device.GetVoidAddressOf()).Assert();

                                if (d3D12Device.Get()->IsShaderModelSupported(D3D_SHADER_MODEL_6_0))
                                {
                                    this.graphicsDevice = GetOrCreateDevice(d3D12Device.Get(), (IDXGIAdapter *)dxgiAdapter1.Get(), &dxgiDescription1);

                                    return(true);
                                }
                            }
                        }
                    }
                }