Ejemplo n.º 1
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);
                    }
                }
            }
        }
Ejemplo n.º 2
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);
                                }
                            }
                        }
                    }
                }