public SwapChain(GraphicsDevice graphicsDevice) { GraphicsDevice = graphicsDevice; Description = graphicsDevice.NativeParameters; CreateSwapChain(); BackBufferIndex = NativeSwapChain.GetCurrentBackBufferIndex(); BackBuffer = new Texture(GraphicsDevice); BackBuffer.InitializeFromImpl(NativeSwapChain.GetBuffer <ID3D12Resource>(BackBufferIndex)); }
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); }
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])); } }
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); }