Beispiel #1
0
 public void Dispose()
 {
     if (_factory != null)
     {
         Marshal.ReleaseComObject(_factory);
     }
     _factory = null;
 }
Beispiel #2
0
        public Direct3D12Prober()
        {
            if (CreateDXGIFactory2(0, IID_DXGIFactory2, out var factory) != 0)
            {
                return;
            }

            _factory = factory as IDXGIFactory2;
        }
        public ID3D11Texture2D GetBackbuffer(ID3D11Device device, IntPtr hWnd)
        {
            if (!m_swapChain)
            {
                using (var dxgiDevice = new IDXGIDevice2())
                {
                    device.QueryInterface(ref IDXGIDevice2.IID, out dxgiDevice.PtrForNew).ThrowIfFailed();

                    dxgiDevice.GetAdapter(out IDXGIAdapter dxgiAdapter).ThrowIfFailed();
                    using (dxgiAdapter)
                    {
                        using (var dxgiFactory = new IDXGIFactory2())
                        {
                            dxgiAdapter.GetParent(ref IDXGIFactory2.IID, out dxgiFactory.PtrForNew).ThrowIfFailed();

                            var desc = new DXGI_SWAP_CHAIN_DESC1
                            {
                                Format      = DXGI_FORMAT._B8G8R8A8_UNORM,
                                AlphaMode   = DXGI_ALPHA_MODE._UNSPECIFIED,
                                BufferUsage = DXGI_USAGE._RENDER_TARGET_OUTPUT,
                                Scaling     = DXGI_SCALING._NONE,
                                BufferCount = 2,
                                SwapEffect  = DXGI_SWAP_EFFECT._FLIP_SEQUENTIAL,
                                SampleDesc  = new DXGI_SAMPLE_DESC
                                {
                                    Count   = 1,
                                    Quality = 0,
                                },
                            };

                            var fs_desc = new DXGI_SWAP_CHAIN_FULLSCREEN_DESC
                            {
                                Windowed = 1,
                            };

                            var hr = dxgiFactory.CreateSwapChainForHwnd(device, hWnd, ref desc, ref fs_desc, null, out m_swapChain);
                            hr.ThrowIfFailed();
                        }
                    }
                }
            }

            var texture = new ID3D11Texture2D();

            m_swapChain.GetBuffer(0, ref ID3D11Texture2D.IID, out texture.PtrForNew).ThrowIfFailed();
            return(texture);
        }
        public static IComObject <T> CreateSwapChainForComposition <T>(this IDXGIFactory2 factory,
                                                                       IDXGIDevice1 device,
                                                                       DXGI_SWAP_CHAIN_DESC1 desc,
                                                                       IDXGIOutput1 restrictToOutput = null) where T : IDXGISwapChain1
        {
            if (factory == null)
            {
                throw new ArgumentNullException(nameof(factory));
            }

            if (device == null)
            {
                throw new ArgumentNullException(nameof(device));
            }

            factory.CreateSwapChainForComposition(device, ref desc, restrictToOutput, out var swapChain).ThrowOnError();
            return(new ComObject <T>((T)swapChain));
        }
Beispiel #5
0
        public static IDXGISwapChain1 CreateSwapChainForHwnd(
            ID3D11Device device,
            IntPtr hwnd)
        {
            IDXGIDevice           dxgiDevice  = device.QueryInterface <IDXGIDevice>();
            IDXGIFactory2         dxgiFactory = dxgiDevice.GetAdapter().GetParent <IDXGIFactory2>();
            SwapChainDescription1 dxgiDesc    = new()
            {
                Format            = Format.B8G8R8A8_UNorm,
                SampleDescription = new SampleDescription(1, 0),
                BufferUsage       = Usage.RenderTargetOutput,
                BufferCount       = 2,
            };

            return(dxgiFactory.CreateSwapChainForHwnd(
                       device,
                       hwnd,
                       dxgiDesc));
        }
Beispiel #6
0
        public static ComObject <T> CreateSwapChainForHwnd <T>(this IDXGIFactory2 factory,
                                                               IDXGIDevice1 device,
                                                               IntPtr hwnd,
                                                               DXGI_SWAP_CHAIN_DESC1 desc,
                                                               DXGI_SWAP_CHAIN_FULLSCREEN_DESC?fullScreenDesc = null,
                                                               IDXGIOutput1 restrictToOutput = null) where T : IDXGISwapChain1
        {
            if (factory == null)
            {
                throw new ArgumentNullException(nameof(factory));
            }

            if (device == null)
            {
                throw new ArgumentNullException(nameof(device));
            }

            using (var mem = fullScreenDesc.StructureToMemory())
            {
                factory.CreateSwapChainForHwnd(device, hwnd, ref desc, mem.Pointer, restrictToOutput, out var swapChain).ThrowOnError();
                return(new ComObject <T>((T)swapChain));
            }
        }
Beispiel #7
0
    private D3D11GraphicsDevice(Window?window, SizeI size, Format depthStencilFormat = Format.D32_Float)
    {
        Window = window;
        Size   = size;

        Factory = CreateDXGIFactory1 <IDXGIFactory2>();

        using (IDXGIAdapter1 adapter = GetHardwareAdapter())
        {
            DeviceCreationFlags creationFlags = DeviceCreationFlags.BgraSupport;
#if DEBUG
            if (SdkLayersAvailable())
            {
                creationFlags |= DeviceCreationFlags.Debug;
            }
#endif

            if (D3D11CreateDevice(
                    adapter,
                    DriverType.Unknown,
                    creationFlags,
                    s_featureLevels,
                    out ID3D11Device tempDevice, out FeatureLevel, out ID3D11DeviceContext tempContext).Failure)
            {
                // If the initialization fails, fall back to the WARP device.
                // For more information on WARP, see:
                // http://go.microsoft.com/fwlink/?LinkId=286690
                D3D11CreateDevice(
                    IntPtr.Zero,
                    DriverType.Warp,
                    creationFlags,
                    s_featureLevels,
                    out tempDevice, out FeatureLevel, out tempContext).CheckError();
            }

            Device        = tempDevice.QueryInterface <ID3D11Device1>();
            DeviceContext = tempContext.QueryInterface <ID3D11DeviceContext1>();
            tempContext.Dispose();
            tempDevice.Dispose();
        }

        if (window != null)
        {
            IntPtr hwnd = window.Handle;

            SwapChainDescription1 swapChainDescription = new()
            {
                Width             = window.ClientSize.Width,
                Height            = window.ClientSize.Height,
                Format            = Format.R8G8B8A8_UNorm,
                BufferCount       = FrameCount,
                BufferUsage       = Usage.RenderTargetOutput,
                SampleDescription = SampleDescription.Default,
                Scaling           = Scaling.Stretch,
                SwapEffect        = SwapEffect.FlipDiscard,
                AlphaMode         = AlphaMode.Ignore
            };

            SwapChainFullscreenDescription fullscreenDescription = new SwapChainFullscreenDescription
            {
                Windowed = true
            };

            SwapChain = Factory.CreateSwapChainForHwnd(Device, hwnd, swapChainDescription, fullscreenDescription);
            Factory.MakeWindowAssociation(hwnd, WindowAssociationFlags.IgnoreAltEnter);

            BackBufferTexture = SwapChain.GetBuffer <ID3D11Texture2D>(0);
            RenderTargetView  = Device.CreateRenderTargetView(BackBufferTexture);
        }
        else
        {
            // Create offscreen texture
            OffscreenTexture = Device.CreateTexture2D(Format.R8G8B8A8_UNorm, Size.Width, Size.Height, 1, 1, null, BindFlags.ShaderResource | BindFlags.RenderTarget);
            RenderTargetView = Device.CreateRenderTargetView(OffscreenTexture);
        }

        if (depthStencilFormat != Format.Unknown)
        {
            DepthStencilTexture = Device.CreateTexture2D(depthStencilFormat, Size.Width, Size.Height, 1, 1, null, BindFlags.DepthStencil);
            DepthStencilView    = Device.CreateDepthStencilView(DepthStencilTexture !, new DepthStencilViewDescription(DepthStencilTexture, DepthStencilViewDimension.Texture2D));
        }

        ReadOnlySpan <VertexPositionColor> triangleVertices = stackalloc VertexPositionColor[]
        {
            new VertexPositionColor(new Vector3(0f, 0.5f, 0.0f), new Color4(1.0f, 0.0f, 0.0f, 1.0f)),
            new VertexPositionColor(new Vector3(0.5f, -0.5f, 0.0f), new Color4(0.0f, 1.0f, 0.0f, 1.0f)),
            new VertexPositionColor(new Vector3(-0.5f, -0.5f, 0.0f), new Color4(0.0f, 0.0f, 1.0f, 1.0f))
        };

        bool dynamic = false;
        if (dynamic)
        {
            _vertexBuffer = Device.CreateBuffer(VertexPositionColor.SizeInBytes * 3, BindFlags.VertexBuffer, ResourceUsage.Dynamic, CpuAccessFlags.Write);
            MappedSubresource mappedSubresource = DeviceContext.Map(_vertexBuffer, 0, MapMode.WriteDiscard);
            triangleVertices.CopyTo(mappedSubresource.AsSpan <VertexPositionColor>(3));
            DeviceContext.Unmap(_vertexBuffer, 0);
        }
        else
        {
            _vertexBuffer = Device.CreateBuffer(triangleVertices, BindFlags.VertexBuffer);
        }

        InputElementDescription[] inputElementDescs = new[]
        {
            new InputElementDescription("POSITION", 0, Format.R32G32B32_Float, 0, 0),
            new InputElementDescription("COLOR", 0, Format.R32G32B32A32_Float, 12, 0)
        };

        Span <byte> vertexShaderByteCode = CompileBytecode("Triangle.hlsl", "VSMain", "vs_4_0");
        Span <byte> pixelShaderByteCode  = CompileBytecode("Triangle.hlsl", "PSMain", "ps_4_0");

        _vertexShader = Device.CreateVertexShader(vertexShaderByteCode);
        _pixelShader  = Device.CreatePixelShader(pixelShaderByteCode);
        _inputLayout  = Device.CreateInputLayout(inputElementDescs, vertexShaderByteCode);
    }
Beispiel #8
0
        void EnsureDevice(IntPtr hWnd)
        {
            if (m_device)
            {
                return;
            }

            // D3D
            Span <D3D_FEATURE_LEVEL> levels = stackalloc D3D_FEATURE_LEVEL[]
            {
                D3D_FEATURE_LEVEL._11_1,
                D3D_FEATURE_LEVEL._11_0,
                D3D_FEATURE_LEVEL._10_1,
                D3D_FEATURE_LEVEL._10_0,
                D3D_FEATURE_LEVEL._9_3,
                D3D_FEATURE_LEVEL._9_2,
                D3D_FEATURE_LEVEL._9_1
            };
            var flags =
                D3D11_CREATE_DEVICE_FLAG._DEBUG |
                D3D11_CREATE_DEVICE_FLAG._BGRA_SUPPORT;
            var level = default(D3D_FEATURE_LEVEL);

            d3d11.D3D11CreateDevice(
                null,
                D3D_DRIVER_TYPE._HARDWARE,
                IntPtr.Zero,
                (uint)flags,
                ref MemoryMarshal.GetReference(levels),
                (uint)levels.Length,
                Constants.D3D11_SDK_VERSION,
                out m_device,
                out level,
                out m_context).ThrowIfFailed();

            // D2D
            using (var dxgiDevice = new IDXGIDevice())
            {
                m_device.QueryInterface(ref IDXGIDevice.IID, out dxgiDevice.PtrForNew).ThrowIfFailed();

                using (var d2dFactory = new ID2D1Factory1())
                {
                    var factory_opt = new D2D1_FACTORY_OPTIONS
                    {
                    };
                    d2d1.D2D1CreateFactory(D2D1_FACTORY_TYPE._SINGLE_THREADED,
                                           ref ID2D1Factory1.IID, ref factory_opt, out d2dFactory.PtrForNew).ThrowIfFailed();

                    d2dFactory.GetDesktopDpi(out float x, out float y);

                    // using (var d2dDevice = new ())
                    {
                        var prop = new D2D1_CREATION_PROPERTIES
                        {
                        };
                        d2dFactory.CreateDevice(dxgiDevice, out ID2D1Device d2dDevice).ThrowIfFailed();
                        using (d2dDevice)
                            d2dDevice.CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS._NONE, out m_d2dContext).ThrowIfFailed();
                    }
                }

                // SWAPChain
                // using (var adapter = new ())
                {
                    dxgiDevice.GetAdapter(out IDXGIAdapter adapter).ThrowIfFailed();
                    using (adapter)
                        using (var dxgiFactory = new IDXGIFactory2())
                        {
                            adapter.GetParent(ref IDXGIFactory2.IID, out dxgiFactory.PtrForNew).ThrowIfFailed();

                            var swapChainDesc = new DXGI_SWAP_CHAIN_DESC1
                            {
                                Width  = 0,
                                Height = 0,
                                Format = DXGI_FORMAT._B8G8R8A8_UNORM,
                                Stereo = 0
                            };
                            swapChainDesc.SampleDesc.Count   = 1;
                            swapChainDesc.SampleDesc.Quality = 0;
                            swapChainDesc.BufferUsage        = DXGI_USAGE._RENDER_TARGET_OUTPUT;
                            swapChainDesc.BufferCount        = 2;
                            //swapChainDesc.Scaling = DXGI_SCALING_NONE;
                            swapChainDesc.Scaling = DXGI_SCALING._STRETCH;
                            //swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
                            swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT._DISCARD;
                            swapChainDesc.AlphaMode  = DXGI_ALPHA_MODE._UNSPECIFIED;

                            var fs = new DXGI_SWAP_CHAIN_FULLSCREEN_DESC
                            {
                                Windowed = 1,
                            };
                            dxgiFactory.CreateSwapChainForHwnd(
                                dxgiDevice,
                                hWnd,
                                ref swapChainDesc,
                                ref fs,
                                null,
                                out m_swapchain).ThrowIfFailed();

                            Console.Write("CreateSwapchain");
                        }
                }
            }

            // Dwrite
            dwrite.DWriteCreateFactory(DWRITE_FACTORY_TYPE._SHARED, ref IDWriteFactory.IID, out m_dwriteFactory.PtrForNew).ThrowIfFailed();
        }
Beispiel #9
0
        protected Application(bool useDirect3D12)
        {
            _wndProc = ProcessWindowMessage;
            var wndClassEx = new WNDCLASSEX
            {
                Size                  = Unsafe.SizeOf <WNDCLASSEX>(),
                Styles                = WindowClassStyles.CS_HREDRAW | WindowClassStyles.CS_VREDRAW | WindowClassStyles.CS_OWNDC,
                WindowProc            = _wndProc,
                InstanceHandle        = HInstance,
                CursorHandle          = LoadCursor(IntPtr.Zero, SystemCursor.IDC_ARROW),
                BackgroundBrushHandle = IntPtr.Zero,
                IconHandle            = IntPtr.Zero,
                ClassName             = WndClassName,
            };

            var atom = RegisterClassEx(ref wndClassEx);

            if (atom == 0)
            {
                throw new InvalidOperationException(
                          $"Failed to register window class. Error: {Marshal.GetLastWin32Error()}"
                          );
            }

            Window = new Window("Vortice", 800, 600);

            if (useDirect3D12 &&
                !ID3D12Device.IsSupported(null, FeatureLevel.Level_11_0))
            {
                useDirect3D12 = false;
            }

            var debugFactory = false;

#if DEBUG
            if (useDirect3D12)
            {
                if (D3D12GetDebugInterface <ID3D12Debug>(out var debug).Success)
                {
                    debug.EnableDebugLayer();
                    debugFactory = true;
                }
            }
#endif

            if (useDirect3D12)
            {
                if (CreateDXGIFactory2(debugFactory, out IDXGIFactory4 dxgiFactory4).Failure)
                {
                    throw new InvalidOperationException("Cannot create IDXGIFactory4");
                }

                _dxgiFactory = dxgiFactory4;
            }
            else
            {
                if (CreateDXGIFactory2(debugFactory, out _dxgiFactory).Failure)
                {
                    throw new InvalidOperationException("Cannot create IDXGIFactory4");
                }
            }

            if (useDirect3D12)
            {
                Debug.Assert(D3D12CreateDevice(null, FeatureLevel.Level_11_0, out _d3d12Device).Success);

                _d3d12CommandQueue = _d3d12Device.CreateCommandQueue(new CommandQueueDescription(CommandListType.Direct, CommandQueuePriority.Normal));
            }
            else
            {
                var featureLevels = new FeatureLevel[]
                {
                    FeatureLevel.Level_11_1,
                    FeatureLevel.Level_11_0
                };
                Debug.Assert(ID3D11Device.TryCreate(
                                 null,
                                 DriverType.Hardware,
                                 DeviceCreationFlags.BgraSupport,
                                 featureLevels,
                                 out _d3d11Device,
                                 out _d3d11DeviceContext).Success);
            }

            var swapChainDesc = new SwapChainDescription1
            {
                BufferCount       = FrameCount,
                Width             = Window.Width,
                Height            = Window.Height,
                Format            = Format.B8G8R8A8_UNorm,
                Usage             = Vortice.Usage.RenderTargetOutput,
                SwapEffect        = SwapEffect.FlipDiscard,
                SampleDescription = new SampleDescription(1, 0)
            };

            SwapChain = DXGIFactory.CreateSwapChainForHwnd(_d3d12CommandQueue, Window.Handle, swapChainDesc);
            DXGIFactory.MakeWindowAssociation(Window.Handle, WindowAssociationFlags.IgnoreAltEnter);

            if (useDirect3D12)
            {
                SwapChain3  = SwapChain.QueryInterface <IDXGISwapChain3>();
                _frameIndex = SwapChain3.GetCurrentBackBufferIndex();
            }

            _rtvHeap           = _d3d12Device.CreateDescriptorHeap(new DescriptorHeapDescription(DescriptorHeapType.RenderTargetView, FrameCount));
            _rtvDescriptorSize = _d3d12Device.GetDescriptorHandleIncrementSize(DescriptorHeapType.RenderTargetView);

            // Create frame resources.
            {
                var rtvHandle = _rtvHeap.GetCPUDescriptorHandleForHeapStart();

                // Create a RTV for each frame.
                _renderTargets = new ID3D12Resource[FrameCount];
                for (var i = 0; i < FrameCount; i++)
                {
                    _renderTargets[i] = SwapChain.GetBuffer <ID3D12Resource>(i);
                    _d3d12Device.CreateRenderTargetView(_renderTargets[i], null, rtvHandle);
                    rtvHandle += _rtvDescriptorSize;
                }
            }

            _commandAllocator = _d3d12Device.CreateCommandAllocator(CommandListType.Direct);
            _commandList      = _d3d12Device.CreateCommandList(CommandListType.Direct, _commandAllocator);
            _commandList.Close();

            // Create synchronization objects.
            _d3d12Fence = _d3d12Device.CreateFence(0);
            _fenceValue = 1;
            _fenceEvent = new AutoResetEvent(false);
        }