public void CreateAccelerationStructures() { acs = new AccelerationStructures(); long mTlasSize = 0; ID3D12Resource[] mpVertexBuffer = new ID3D12Resource[2]; mpVertexBuffer[0] = acs.CreateTriangleVB(mpDevice); mpVertexBuffer[1] = acs.CreatePlaneVB(mpDevice); // The first bottom-level buffer is for the plane and the triangle int[] vertexCount = new int[] { 3, 6 }; // Triangle has 3 vertices, plane has 6 AccelerationStructureBuffers[] bottomLevelBuffers = new AccelerationStructureBuffers[2]; bottomLevelBuffers[0] = acs.CreateBottomLevelAS(mpDevice, mpCmdList, mpVertexBuffer, vertexCount, 2); mpBottomLevelAS = new ID3D12Resource[2]; mpBottomLevelAS[0] = bottomLevelBuffers[0].pResult; // The second bottom-level buffer is for the triangle only bottomLevelBuffers[1] = acs.CreateBottomLevelAS(mpDevice, mpCmdList, mpVertexBuffer, vertexCount, 1); mpBottomLevelAS[1] = bottomLevelBuffers[1].pResult; // Create the TLAS AccelerationStructureBuffers topLevelBuffers = acs.CreateTopLevelAS(mpDevice, mpCmdList, mpBottomLevelAS, ref mTlasSize); // The tutorial doesn't have any resource lifetime management, so we flush and sync here. This is not required by the DXR spec - you can submit the list whenever you like as long as you take care of the resources lifetime. mFenceValue = context.SubmitCommandList(mpCmdList, mpCmdQueue, mpFence, mFenceValue); mpFence.SetEventOnCompletion(mFenceValue, mFenceEvent); mFenceEvent.WaitOne(); int bufferIndex = mpSwapChain.GetCurrentBackBufferIndex(); mpCmdList.Reset(mFrameObjects[0].pCmdAllocator, null); // Store the AS buffers. The rest of the buffers will be released once we exit the function mpTopLevelAS = topLevelBuffers.pResult; }
public SwapChain(GraphicsDevice graphicsDevice) { GraphicsDevice = graphicsDevice; Description = graphicsDevice.NativeParameters; CreateSwapChain(); BackBufferIndex = NativeSwapChain.GetCurrentBackBufferIndex(); BackBuffer = new Texture(GraphicsDevice); BackBuffer.InitializeFromImpl(NativeSwapChain.GetBuffer <ID3D12Resource>(BackBufferIndex)); }
public void CreateAccelerationStructures() { acs = new AccelerationStructures(); AccelerationStructureBuffers bottomLevelBuffers = acs.CreateBottomLevelAS(mpDevice, mpCmdList); AccelerationStructureBuffers topLevelBuffers = acs.CreateTopLevelAS(mpDevice, mpCmdList, bottomLevelBuffers.pResult, ref mTlasSize); // The tutorial doesn't have any resource lifetime management, so we flush and sync here. This is not required by the DXR spec - you can submit the list whenever you like as long as you take care of the resources lifetime. mFenceValue = context.SubmitCommandList(mpCmdList, mpCmdQueue, mpFence, mFenceValue); mpFence.SetEventOnCompletion(mFenceValue, mFenceEvent); mFenceEvent.WaitOne(); int bufferIndex = mpSwapChain.GetCurrentBackBufferIndex(); mpCmdList.Reset(mFrameObjects[0].pCmdAllocator, null); // Store the AS buffers. The rest of the buffers will be released once we exit the function mpTopLevelAS = topLevelBuffers.pResult; mpBottomLevelAS = bottomLevelBuffers.pResult; }
private void EndFrame(int rtvIndex) { context.ResourceBarrier(mpCmdList, mFrameObjects[rtvIndex].swapChainBuffer, ResourceStates.RenderTarget, ResourceStates.Present); mFenceValue = context.SubmitCommandList(mpCmdList, mpCmdQueue, mpFence, mFenceValue); mpSwapChain.Present(0, 0); // Prepare the command list for the next frame int bufferIndex = mpSwapChain.GetCurrentBackBufferIndex(); // Make sure we have the new back-buffer is ready if (mFenceValue > context.kDefaultSwapChainBuffers) { mpFence.SetEventOnCompletion(mFenceValue - context.kDefaultSwapChainBuffers + 1, mFenceEvent); this.mFenceEvent.WaitOne(); } mFrameObjects[bufferIndex].pCmdAllocator.Reset(); mpCmdList.Reset(mFrameObjects[bufferIndex].pCmdAllocator, null); }
private int BeginFrame() { commandList.SetDescriptorHeaps(1, new ID3D12DescriptorHeap[] { srvUavHeap }); return(swapChain.GetCurrentBackBufferIndex()); }
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); }