Пример #1
0
        private void CreateDXGI()
        {
            var res = CreateDXGIFactory1 <IDXGIFactory4>(out factory);

            device = CreateDevice(factory);
            if (device == null)
            {
                throw new InvalidOperationException("device cannot be null");
            }
            commandQueue = CreateCommandQueue(device);
            swapChain    = CreateSwapChain(factory, commandQueue, Format.R8G8B8A8_UNorm);

            rtvHeap.usedEntries = 0;
            rtvHeap.Heap        = CreateDescriptorHeap(device, rtvHeapSize, DescriptorHeapType.RenderTargetView, false);

            frameObjects = new FrameObject[DefaultSwapChainBuffers];
            for (int i = 0; i < DefaultSwapChainBuffers; i++)
            {
                frameObjects[i] = new FrameObject();

                frameObjects[i].cmdAllocator    = device.CreateCommandAllocator(CommandListType.Direct);
                frameObjects[i].swapChainBuffer = swapChain.GetBuffer <ID3D12Resource>(i);
                frameObjects[i].rtvHandle       = CreateRenderTargetView(device, frameObjects[i].swapChainBuffer, rtvHeap.Heap,
                                                                         ref rtvHeap.usedEntries, Format.R8G8B8A8_UNorm_SRgb);
            }

            var cmdList = device.CreateCommandList(0, CommandListType.Direct, frameObjects[0].cmdAllocator, null);

            commandList = cmdList.QueryInterface <ID3D12GraphicsCommandList4>();

            fence      = device.CreateFence(0, FenceFlags.None);
            fenceEvent = new EventWaitHandle(false, EventResetMode.AutoReset);
        }
Пример #2
0
        private void CreateSwapChainForDesktop()
        {
            ModeDescription BackBufferDesc = new ModeDescription()
            {
                Width       = Description.BackBufferWidth,
                Height      = Description.BackBufferHeight,
                Format      = Format.R8G8B8A8_UNorm,
                RefreshRate = new Rational()
                {
                    Numerator   = 60,
                    Denominator = 1
                },
                ScanlineOrdering = ModeScanlineOrder.Unspecified,
                Scaling          = ModeScaling.Unspecified,
            };

            SampleDescription sampleDescription = new SampleDescription()
            {
                Count   = 1,
                Quality = 0
            };

            SwapChainFlags Flags = Description.Settings.Fullscreen ? SwapChainFlags.None : SwapChainFlags.AllowModeSwitch;



            SwapChainDescription swapChainDesc = new SwapChainDescription()      // Initialize the swap chain description.
            {
                BufferCount       = bufferCount,                                 // Set to a single back buffer.
                BufferDescription = BackBufferDesc,                              // Set the width and height of the back buffer.
                Usage             = Usage.Backbuffer | Usage.RenderTargetOutput, // Set the usage of the back buffer.
                OutputWindow      = Description.DeviceHandle,                    // Set the handle for the window to render to.
                SampleDescription = sampleDescription,                           // Turn multisampling off.
                IsWindowed        = true,                                        // Set to full screen or windowed mode.
                Flags             = Flags,                                       // Don't set the advanced flags.
                SwapEffect        = SwapEffect.FlipDiscard,                      // Discard the back buffer content after presenting.
            };



            IDXGIFactory4 Factory = GraphicsDevice.NativeAdapter.NativeFactory;

            IDXGISwapChain swapChain = Factory.CreateSwapChain(GraphicsDevice.NativeDirectCommandQueue.Queue, swapChainDesc);

            if (Description.Settings.Fullscreen)
            {
                // Before fullscreen switch
                swapChain.ResizeTarget(BackBufferDesc);

                // Switch to full screen
                swapChain.SetFullscreenState(true, default);

                // This is really important to call ResizeBuffers AFTER switching to IsFullScreen
                swapChain.ResizeBuffers(3, Description.BackBufferWidth, Description.BackBufferHeight, Format.R8G8B8A8_UNorm, SwapChainFlags.AllowModeSwitch);
            }



            NativeSwapChain = swapChain.QueryInterface <IDXGISwapChain3>();
        }
Пример #3
0
 public void Dispose()
 {
     m_swapChain?.Dispose();
     m_swapChain = null;
     foreach (var tex in m_renderTargets)
     {
         tex.Dispose();
     }
     m_renderTargets = null;
 }
Пример #4
0
        public SwapChainGraphicsPresenter(GraphicsDevice device, PresentationParameters presentationParameters, IDXGISwapChain3 swapChain)
            : base(device, presentationParameters)
        {
            SwapChain = swapChain;

            if (GraphicsDevice.RenderTargetViewAllocator.DescriptorHeap.Description.DescriptorCount != BufferCount)
            {
                GraphicsDevice.RenderTargetViewAllocator.Dispose();
                GraphicsDevice.RenderTargetViewAllocator = new DescriptorAllocator(GraphicsDevice, DescriptorHeapType.RenderTargetView, BufferCount);
            }

            CreateRenderTargets();
        }
Пример #5
0
        internal void Resize()
        {
            // 等到以前的所有 GPU 工作完成。
            device.WaitForGpu();

            // 清除特定于先前窗口大小的内容。
            for (int n = 0; n < c_frameCount; n++)
            {
                m_renderTargets[n]?.Dispose();
                m_renderTargets[n]            = null;
                renderTargetResourceStates[n] = ResourceStates.Common;
            }

            if (m_swapChain != null)
            {
                // 如果交换链已存在,请调整其大小。
                Result hr = m_swapChain.ResizeBuffers(c_frameCount, this.width, this.height, format, SwapChainFlags.AllowTearing);

                ThrowIfFailed(hr);
            }
            else
            {
                // 否则,使用与现有 Direct3D 设备相同的适配器新建一个。
                SwapChainDescription1 swapChainDescription1 = new SwapChainDescription1();

                swapChainDescription1.Width  = this.width;                     // 匹配窗口的大小。
                swapChainDescription1.Height = this.height;
                swapChainDescription1.Format = format;
                swapChainDescription1.Stereo = false;
                swapChainDescription1.SampleDescription.Count   = 1;                       // 请不要使用多采样。
                swapChainDescription1.SampleDescription.Quality = 0;
                swapChainDescription1.BufferUsage = Usage.RenderTargetOutput;
                swapChainDescription1.BufferCount = c_frameCount;                   // 使用三重缓冲最大程度地减小延迟。
                swapChainDescription1.SwapEffect  = SwapEffect.FlipSequential;
                swapChainDescription1.Flags       = SwapChainFlags.AllowTearing;
                swapChainDescription1.Scaling     = Scaling.Stretch;
                swapChainDescription1.AlphaMode   = AlphaMode.Ignore;

                var swapChain = device.m_dxgiFactory.CreateSwapChainForHwnd(device.commandQueue, hwnd, swapChainDescription1);
                m_swapChain?.Dispose();
                m_swapChain = swapChain.QueryInterface <IDXGISwapChain3>();
                swapChain.Dispose();
            }

            for (int n = 0; n < c_frameCount; n++)
            {
                ThrowIfFailed(m_swapChain.GetBuffer(n, out m_renderTargets[n]));
            }
        }
Пример #6
0
        public IDXGISwapChain3 CreateDXGISwapChain(IDXGIFactory4 pFactory, IntPtr hwnd, int width, int height, Vortice.DXGI.Format format, ID3D12CommandQueue pCommandQueue)
        {
            SwapChainDescription1 swapChainDesc = new SwapChainDescription1();

            swapChainDesc.BufferCount       = kDefaultSwapChainBuffers;
            swapChainDesc.Width             = width;
            swapChainDesc.Height            = height;
            swapChainDesc.Format            = format;
            swapChainDesc.Usage             = Usage.RenderTargetOutput;
            swapChainDesc.SwapEffect        = SwapEffect.FlipDiscard;
            swapChainDesc.SampleDescription = new SampleDescription(1, 0);

            // CreateSwapChainForHwnd() doesn't accept IDXGISwapChain3 (Why MS? Why?)
            IDXGISwapChain1 pSwapChain  = pFactory.CreateSwapChainForHwnd(pCommandQueue, hwnd, swapChainDesc);
            IDXGISwapChain3 pSwapChain3 = pSwapChain.QueryInterface <IDXGISwapChain3>();

            return(pSwapChain3);
        }
Пример #7
0
        private void InitDXR(IntPtr winHandle, int winWidth, int winHeight)
        {
            mHwnd = winHandle;
            this.mSwapChainRect = new Rect(0, 0, winWidth, winHeight);

            // Initialize the debug layer for debug builds
#if DEBUG
            if (D3D12.D3D12GetDebugInterface <ID3D12Debug>(out var pDx12Debug).Success)
            {
                pDx12Debug.EnableDebugLayer();
            }
#endif
            // Create the DXGI factory
            IDXGIFactory4 pDXGIFactory;
            DXGI.CreateDXGIFactory1 <IDXGIFactory4>(out pDXGIFactory);
            mpDevice    = this.context.CreateDevice(pDXGIFactory);
            mpCmdQueue  = this.context.CreateCommandQueue(mpDevice);
            mpSwapChain = this.context.CreateDXGISwapChain(pDXGIFactory, mHwnd, winWidth, winHeight, Format.R8G8B8A8_UNorm, mpCmdQueue);

            // Create a RTV descriptor heap
            mRtvHeap.Heap = this.context.CreateDescriptorHeap(mpDevice, kRtvHeapSize, DescriptorHeapType.RenderTargetView, false);

            // Create the per-frame objects
            this.mFrameObjects = new FrameObject[this.context.kDefaultSwapChainBuffers];
            for (int i = 0; i < this.context.kDefaultSwapChainBuffers; i++)
            {
                mFrameObjects[i].pCmdAllocator    = mpDevice.CreateCommandAllocator(CommandListType.Direct);
                mFrameObjects[i].pSwapChainBuffer = mpSwapChain.GetBuffer <ID3D12Resource>(i);
                mFrameObjects[i].rtvHandle        = context.CreateRTV(mpDevice, mFrameObjects[i].pSwapChainBuffer, mRtvHeap.Heap, ref mRtvHeap.usedEntries, Format.R8G8B8A8_UNorm_SRgb);
            }

            // Create the command-list
            var cmdList = mpDevice.CreateCommandList(0, CommandListType.Direct, mFrameObjects[0].pCmdAllocator, null);
            this.mpCmdList = cmdList.QueryInterface <ID3D12GraphicsCommandList4>();

            // Create a fence and the event
            this.mpFence     = mpDevice.CreateFence(0, FenceFlags.None);
            this.mFenceEvent = new EventWaitHandle(false, EventResetMode.AutoReset);
        }
Пример #8
0
        private static IDXGISwapChain3 CreateSwapChain(GraphicsDevice device, PresentationParameters presentationParameters, SwapChainPanel swapChainPanel)
        {
            SwapChainDescription1 swapChainDescription = new SwapChainDescription1
            {
                Width             = presentationParameters.BackBufferWidth,
                Height            = presentationParameters.BackBufferHeight,
                SampleDescription = new Vortice.DXGI.SampleDescription(1, 0),
                Stereo            = presentationParameters.Stereo,
                Usage             = Usage.RenderTargetOutput,
                BufferCount       = BufferCount,
                Scaling           = Scaling.Stretch,
                SwapEffect        = SwapEffect.FlipSequential,
                Format            = (Format)presentationParameters.BackBufferFormat.ToNonSRgb(),
                Flags             = SwapChainFlags.None,
                AlphaMode         = AlphaMode.Unspecified
            };

            swapChainDescription.AlphaMode = AlphaMode.Premultiplied;

            DXGI.CreateDXGIFactory2(false, out IDXGIFactory2 factory);
            Direct3DInterop.ISwapChainPanelNative nativePanel = (Direct3DInterop.ISwapChainPanelNative)swapChainPanel;
            using IDXGISwapChain1 tempSwapChain = factory.CreateSwapChainForComposition(device.DirectCommandQueue.NativeCommandQueue, swapChainDescription);
            factory.Dispose();

            IDXGISwapChain3 swapChain = tempSwapChain.QueryInterface <IDXGISwapChain3>();

            nativePanel.SetSwapChain(swapChain.NativePointer);

            swapChain.MatrixTransform = new Matrix3x2
            {
                M11 = 1.0f / swapChainPanel.CompositionScaleX,
                M22 = 1.0f / swapChainPanel.CompositionScaleY
            };

            return(swapChain);
        }
Пример #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);
        }