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); }
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>(); }
public void Dispose() { m_swapChain?.Dispose(); m_swapChain = null; foreach (var tex in m_renderTargets) { tex.Dispose(); } m_renderTargets = null; }
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(); }
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])); } }
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); }
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); }
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); }
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); }