public void CreateWindowSizeDependentResources() { Size outputSize = _deviceResources.OutputSize; var aspectRatio = (float)outputSize.Width / (float)outputSize.Height; var fovAngleY = 70.0F * (float)Math.PI / 180.0F; D3D12_VIEWPORT viewport = _deviceResources.ScreenViewport; _scissorRect = new D3D12_RECT { left = 0, top = 0, right = (int)viewport.Width, bottom = (int)viewport.Height }; if (aspectRatio < 1) { fovAngleY *= 2; } Matrix4x4 perspectiveMatrix = Matrix4x4.CreatePerspectiveFieldOfView( fovAngleY, aspectRatio, 0.01F, 100.0F ); Matrix4x4 orientation = _deviceResources.OrientationTransform3D; _constantBufferData.projection = Matrix4x4.Transpose(perspectiveMatrix * orientation); _constantBufferData.view = Matrix4x4.Transpose(Matrix4x4.CreateLookAt(Eye, At, Up)); }
public DX12Panel(int width, int height, bool useWarpDevice = false) : base() { if (width <= 0 || height <= 0) { throw new ArgumentException("width and height must be positive and non-zero"); } Width = width; Height = height; _assetsPath = GetAssetsPath(); _aspectRatio = width / ((float)height); _renderTargets = new ID3D12Resource *[FrameCount]; _viewport = new D3D12_VIEWPORT { TopLeftX = 0, TopLeftY = 0, Width = width, Height = height, MinDepth = D3D12_MIN_DEPTH, MaxDepth = D3D12_MAX_DEPTH }; _scissorRect = new RECT { left = 0, top = 0, right = unchecked ((int)width), bottom = unchecked ((int)height) }; _useWarpDevice = useWarpDevice; _isOnColorToggle = false; OnInit(); }
/// <summary>Begins a new frame for rendering.</summary> /// <param name="backgroundColor">A color to which the background should be cleared.</param> public void BeginFrame(ColorRgba backgroundColor) { var frameIndex = SwapChain->GetCurrentBackBufferIndex(); _frameIndex = frameIndex; WaitForFence(Fences[frameIndex], FenceEvents[frameIndex], FenceValues[frameIndex]); var commandAllocator = CommandAllocators[frameIndex]; ThrowExternalExceptionIfFailed(nameof(ID3D12CommandAllocator.Reset), commandAllocator->Reset()); var graphicsCommandList = GraphicsCommandLists[frameIndex]; ThrowExternalExceptionIfFailed(nameof(ID3D12GraphicsCommandList.Reset), graphicsCommandList->Reset(commandAllocator, pInitialState: null)); var renderTargetDescriptorSize = Device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); var renderTargetHandle = RenderTargetsHeap->GetCPUDescriptorHandleForHeapStart(); _ = renderTargetHandle.Offset((int)frameIndex, renderTargetDescriptorSize); graphicsCommandList->OMSetRenderTargets(1, &renderTargetHandle, RTsSingleHandleToDescriptorRange: TRUE, pDepthStencilDescriptor: null); var viewport = new D3D12_VIEWPORT { TopLeftX = 0.0f, TopLeftY = 0.0f, Width = _graphicsSurface.Width, Height = _graphicsSurface.Height, MinDepth = 0.0f, MaxDepth = 1.0f, }; graphicsCommandList->RSSetViewports(1, &viewport); var scissorRect = new RECT { left = 0, top = 0, right = (int)_graphicsSurface.Width, bottom = (int)_graphicsSurface.Height, }; graphicsCommandList->RSSetScissorRects(1, &scissorRect); var barrier = new D3D12_RESOURCE_BARRIER { Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE, Anonymous = new D3D12_RESOURCE_BARRIER._Anonymous_e__Union { Transition = new D3D12_RESOURCE_TRANSITION_BARRIER { pResource = RenderTargets[frameIndex], Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, StateBefore = D3D12_RESOURCE_STATE_PRESENT, StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET, }, }, }; graphicsCommandList->ResourceBarrier(1, &barrier); graphicsCommandList->ClearRenderTargetView(renderTargetHandle, (float *)&backgroundColor, NumRects: 0, pRects: null); }
public virtual void RSSetViewports( uint NumViewports, ref D3D12_VIEWPORT pViewports ) { var fp = GetFunctionPointer(21); if (m_RSSetViewportsFunc == null) { m_RSSetViewportsFunc = (RSSetViewportsFunc)Marshal.GetDelegateForFunctionPointer(fp, typeof(RSSetViewportsFunc)); } m_RSSetViewportsFunc(m_ptr, NumViewports, ref pViewports); }
/// <inheritdoc /> public override void BeginFrame(ColorRgba backgroundColor) { var graphicsFence = D3D12GraphicsFence; graphicsFence.Wait(); graphicsFence.Reset(); var commandAllocator = D3D12CommandAllocator; ThrowExternalExceptionIfFailed(nameof(ID3D12CommandAllocator.Reset), commandAllocator->Reset()); var graphicsCommandList = D3D12GraphicsCommandList; ThrowExternalExceptionIfFailed(nameof(ID3D12GraphicsCommandList.Reset), graphicsCommandList->Reset(commandAllocator, pInitialState: null)); var renderTargetResourceBarrier = D3D12_RESOURCE_BARRIER.InitTransition(D3D12RenderTargetResource, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET); graphicsCommandList->ResourceBarrier(1, &renderTargetResourceBarrier); var renderTargetView = D3D12RenderTargetView; graphicsCommandList->OMSetRenderTargets(1, &renderTargetView, RTsSingleHandleToDescriptorRange: TRUE, pDepthStencilDescriptor: null); var graphicsSurface = D3D12GraphicsDevice.GraphicsSurface; var graphicsSurfaceWidth = graphicsSurface.Width; var graphicsSurfaceHeight = graphicsSurface.Height; var viewport = new D3D12_VIEWPORT { Width = graphicsSurfaceWidth, Height = graphicsSurfaceHeight, MinDepth = D3D12_MIN_DEPTH, MaxDepth = D3D12_MAX_DEPTH, }; graphicsCommandList->RSSetViewports(1, &viewport); var scissorRect = new RECT { right = (int)graphicsSurfaceWidth, bottom = (int)graphicsSurfaceHeight, }; graphicsCommandList->RSSetScissorRects(1, &scissorRect); graphicsCommandList->ClearRenderTargetView(renderTargetView, (float *)&backgroundColor, NumRects: 0, pRects: null); graphicsCommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); }
/// <inheritdoc /> public override void BeginDrawing(ColorRgba backgroundColor) { var graphicsCommandList = D3D12GraphicsCommandList; var renderTargetResourceBarrier = D3D12_RESOURCE_BARRIER.InitTransition(D3D12RenderTargetResource, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET); graphicsCommandList->ResourceBarrier(1, &renderTargetResourceBarrier); var renderTargetView = D3D12RenderTargetView; graphicsCommandList->OMSetRenderTargets(1, &renderTargetView, RTsSingleHandleToDescriptorRange: TRUE, pDepthStencilDescriptor: null); var graphicsSurface = D3D12GraphicsDevice.GraphicsSurface; var graphicsSurfaceWidth = graphicsSurface.Width; var graphicsSurfaceHeight = graphicsSurface.Height; var viewport = new D3D12_VIEWPORT { Width = graphicsSurfaceWidth, Height = graphicsSurfaceHeight, MinDepth = D3D12_MIN_DEPTH, MaxDepth = D3D12_MAX_DEPTH, }; graphicsCommandList->RSSetViewports(1, &viewport); var scissorRect = new RECT { right = (int)graphicsSurfaceWidth, bottom = (int)graphicsSurfaceHeight, }; graphicsCommandList->RSSetScissorRects(1, &scissorRect); graphicsCommandList->ClearRenderTargetView(renderTargetView, (float *)&backgroundColor, NumRects: 0, pRects: null); graphicsCommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); var descriptorHeaps = stackalloc ID3D12DescriptorHeap *[1] { D3D12GraphicsDevice.D3D12ShaderResourceDescriptorHeap, }; graphicsCommandList->SetDescriptorHeaps(1, descriptorHeaps); }
public HelloBundles12(uint width, uint height, string name) : base(width, height, name) { _renderTargets = new ID3D12Resource *[FrameCount]; _viewport = new D3D12_VIEWPORT { TopLeftX = 0, TopLeftY = 0, Width = width, Height = height, MinDepth = D3D12_MIN_DEPTH, MaxDepth = D3D12_MAX_DEPTH }; _scissorRect = new RECT { left = 0, top = 0, right = unchecked ((int)width), bottom = unchecked ((int)height) }; }
protected override void CreateWindowSizeDependentResources() { // Wait until all previous GPU work is complete. WaitForGpu(moveToNextFrame: false); // Clear the previous window size specific content and update the tracked fence values. for (var i = 0u; i < FrameCount; i++) { _renderTargets[i] = null; _fenceValues[i] = _fenceValues[FrameIndex]; } if (_swapChain != null) { ThrowIfFailed(nameof(IDXGISwapChain3.ResizeBuffers), _swapChain->ResizeBuffers(FrameCount, (uint)Size.Width, (uint)Size.Height, BackBufferFormat, 0)); } else { _swapChain = CreateSwapChain(); } CreateResourceViews(); _viewport = new D3D12_VIEWPORT { TopLeftX = 0, TopLeftY = 0, Width = Size.Width, Height = Size.Height, MinDepth = D3D12_MIN_DEPTH, MaxDepth = D3D12_MAX_DEPTH }; _scissorRect = new RECT { left = 0, top = 0, right = Size.Width, bottom = Size.Height }; IDXGISwapChain3 *CreateSwapChain() { using ComPtr <IDXGISwapChain1> swapChain = null; var swapChainDesc = new DXGI_SWAP_CHAIN_DESC1 { BufferCount = FrameCount, Width = (uint)Size.Width, Height = (uint)Size.Height, Format = BackBufferFormat, BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT, SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD, SampleDesc = new DXGI_SAMPLE_DESC(count: 1, quality: 0), }; ThrowIfFailed(nameof(IDXGIFactory4.CreateSwapChainForHwnd), DxgiFactory->CreateSwapChainForHwnd( (IUnknown *)_commandQueue, // Swap chain needs the queue so that it can force a flush on it. Hwnd, &swapChainDesc, pFullscreenDesc: null, pRestrictToOutput: null, swapChain.GetAddressOf() )); IDXGISwapChain3 *swapChain3; var iid = IID_IDXGISwapChain3; ThrowIfFailed(nameof(IDXGISwapChain1.QueryInterface), swapChain.Get()->QueryInterface(&iid, (void **)&swapChain3)); return(swapChain3); } }
public unsafe bool Render() { if (!_loadingComplete) { return(false); } ThrowIfFailed(_deviceResources.CommandAllocator->Reset()); ThrowIfFailed(_commandList.Ptr->Reset(_deviceResources.CommandAllocator, _pipelineState.Ptr)); { _commandList.Ptr->SetGraphicsRootSignature(_rootSignature.Ptr); const uint ppHeapsCount = 1; ID3D12DescriptorHeap **ppHeaps = stackalloc ID3D12DescriptorHeap *[(int)ppHeapsCount] { _cbvHeap.Ptr }; _commandList.Ptr->SetDescriptorHeaps(ppHeapsCount, ppHeaps); D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle; _cbvHeap.Ptr->GetGPUDescriptorHandleForHeapStart(&gpuHandle); gpuHandle.ptr += _deviceResources.CurrentFrameIndex * _cbvDescriptorSize; _commandList.Ptr->SetGraphicsRootDescriptorTable(0, gpuHandle); D3D12_VIEWPORT viewport = _deviceResources.ScreenViewport; _commandList.Ptr->RSSetViewports(1, &viewport); D3D12_RECT rect = _scissorRect; _commandList.Ptr->RSSetScissorRects(1, &rect); D3D12_RESOURCE_BARRIER renderTargetResourceBarrier = CD3DX12_RESOURCE_BARRIER.Transition( _deviceResources.RenderTarget, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET ); _commandList.Ptr->ResourceBarrier(1, &renderTargetResourceBarrier); D3D12_CPU_DESCRIPTOR_HANDLE renderTargetView = _deviceResources.RenderTargetView; D3D12_CPU_DESCRIPTOR_HANDLE depthStencilView = _deviceResources.DepthStencilView; _commandList.Ptr->ClearRenderTargetView(renderTargetView, CornflowerBlue, 0, null); _commandList.Ptr->ClearDepthStencilView(depthStencilView, D3D12_CLEAR_FLAG_DEPTH, 1, 0, 0, null); _commandList.Ptr->OMSetRenderTargets(1, &renderTargetView, FALSE, &depthStencilView); _commandList.Ptr->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); D3D12_VERTEX_BUFFER_VIEW vertexBufferView = _vertexBufferView; D3D12_INDEX_BUFFER_VIEW indexBufferView = _indexBufferView; _commandList.Ptr->IASetVertexBuffers(0, 1, &vertexBufferView); _commandList.Ptr->IASetIndexBuffer(&indexBufferView); _commandList.Ptr->DrawIndexedInstanced(36, 1, 0, 0, 0); D3D12_RESOURCE_BARRIER presentResourceBarrier = CD3DX12_RESOURCE_BARRIER.Transition( _deviceResources.RenderTarget, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT); _commandList.Ptr->ResourceBarrier(1, &presentResourceBarrier); } ThrowIfFailed(_commandList.Ptr->Close()); const uint ppCommandListsCount = 1; ID3D12CommandList **ppCommandLists = stackalloc ID3D12CommandList *[(int)ppCommandListsCount] { (ID3D12CommandList *)_commandList.Ptr }; _deviceResources.CommandQueue->ExecuteCommandLists(ppCommandListsCount, ppCommandLists); return(true); }
public void CreateWindowSizeDependentResources() { WaitForGpu(); for (int n = 0; n < FrameCount; n++) { DirectXHelper.ReleaseCom(_renderTargets[n]); _renderTargets[n] = null; _fenceValues[n] = _fenceValues[_currentFrame]; } UpdateRenderTargetSize(); DXGI_MODE_ROTATION displayRotation = ComputeDisplayRotation(); bool swapDimensions = displayRotation == DXGI_MODE_ROTATION.DXGI_MODE_ROTATION_ROTATE90 || displayRotation == DXGI_MODE_ROTATION.DXGI_MODE_ROTATION_ROTATE270; _d3dRenderTargetSize.Width = swapDimensions ? _outputSize.Height : _outputSize.Width; _d3dRenderTargetSize.Height = swapDimensions ? _outputSize.Width : _outputSize.Height; uint backBufferWidth = (uint)Math.Round(_d3dRenderTargetSize.Width, MidpointRounding.AwayFromZero); uint backBufferHeight = (uint)Math.Round(_d3dRenderTargetSize.Height, MidpointRounding.AwayFromZero); if (_swapChain != null) { HRESULT hr = _swapChain.Ptr->ResizeBuffers(FrameCount, backBufferWidth, backBufferHeight, _backBufferFormat, 0); if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) { _deviceRemoved = true; return; } else { DirectXHelper.ThrowIfFailed(hr); } } else { DXGI_SCALING scaling = DisplayMetrics.SupportHighResolutions ? DXGI_SCALING.DXGI_SCALING_NONE : DXGI_SCALING.DXGI_SCALING_STRETCH; DXGI_SWAP_CHAIN_DESC1 swapChainDesc; swapChainDesc.Width = backBufferWidth; swapChainDesc.Height = backBufferHeight; swapChainDesc.Format = _backBufferFormat; swapChainDesc.Stereo = 0; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.BufferUsage = DXGI.DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = FrameCount; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT.DXGI_SWAP_EFFECT_FLIP_DISCARD; swapChainDesc.Flags = 0; swapChainDesc.Scaling = scaling; swapChainDesc.AlphaMode = DXGI_ALPHA_MODE.DXGI_ALPHA_MODE_IGNORE; { using ComPtr <IDXGISwapChain1> swapChain = null; IntPtr pWindow = Marshal.GetIUnknownForObject(_window); DirectXHelper.ThrowIfFailed( _dxgiFactory.Ptr->CreateSwapChainForCoreWindow( _commandQueue, (IUnknown *)pWindow, &swapChainDesc, null, swapChain.GetAddressOf())); IDXGISwapChain3 *swapChain3; Guid iid = DXGI.IID_IDXGISwapChain3; DirectXHelper.ThrowIfFailed(swapChain.Ptr->QueryInterface(&iid, (void **)&swapChain3)); _swapChain = swapChain3; } } switch (displayRotation) { case DXGI_MODE_ROTATION.DXGI_MODE_ROTATION_IDENTITY: _orientationTransform3D = ScreenRotation.Rotation0; break; case DXGI_MODE_ROTATION.DXGI_MODE_ROTATION_ROTATE90: _orientationTransform3D = ScreenRotation.Rotation270; break; case DXGI_MODE_ROTATION.DXGI_MODE_ROTATION_ROTATE180: _orientationTransform3D = ScreenRotation.Rotation180; break; case DXGI_MODE_ROTATION.DXGI_MODE_ROTATION_ROTATE270: _orientationTransform3D = ScreenRotation.Rotation90; break; } DirectXHelper.ThrowIfFailed(_swapChain.Ptr->SetRotation(displayRotation)); { _currentFrame = (int)_swapChain.Ptr->GetCurrentBackBufferIndex(); D3D12_CPU_DESCRIPTOR_HANDLE rtvDescriptor = _rtvHeap.Ptr->GetCPUDescriptorHandleForHeapStart(); fixed(void *pBuffer = & _renderTargets) { var p = (ID3D12Resource **)pBuffer; Guid iid = D3D12.IID_ID3D12Resource; for (var n = 0; n < FrameCount; n++) { DirectXHelper.ThrowIfFailed(_swapChain.Ptr->GetBuffer((uint)n, &iid, (void **)&p[n])); _d3dDevice.Ptr->CreateRenderTargetView( _renderTargets[n], null, rtvDescriptor); rtvDescriptor.Offset((int)_rtvDescriptorSize); DirectXHelper.NameObject(_renderTargets[n], $"{nameof(_renderTargets)}[{n}]"); // _renderTargets[n] } } } { D3D12_HEAP_PROPERTIES depthHeapProperties = CD3DX12_HEAP_PROPERTIES.Create(D3D12_HEAP_TYPE.D3D12_HEAP_TYPE_DEFAULT); D3D12_RESOURCE_DESC depthResourceDesc = CD3DX12_RESOURCE_DESC.Tex2D(_depthBufferFormat, backBufferWidth, backBufferHeight, 1, 1); depthResourceDesc.Flags |= D3D12_RESOURCE_FLAGS.D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; D3D12_CLEAR_VALUE depthOptimizedClearValue = CD3DX12_CLEAR_VALUE.Create(_depthBufferFormat, 1, 0); fixed(ID3D12Resource **p = _depthStencil) { Guid iid = D3D12.IID_ID3D12Resource; DirectXHelper.ThrowIfFailed(_d3dDevice.Ptr->CreateCommittedResource( &depthHeapProperties, D3D12_HEAP_FLAGS.D3D12_HEAP_FLAG_NONE, &depthResourceDesc, D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_DEPTH_WRITE, &depthOptimizedClearValue, &iid, (void **)p )); DirectXHelper.NameObject(_depthStencil, nameof(_depthStencil)); D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = default; dsvDesc.Format = _depthBufferFormat; dsvDesc.ViewDimension = D3D12_DSV_DIMENSION.D3D12_DSV_DIMENSION_TEXTURE2D; dsvDesc.Flags = D3D12_DSV_FLAGS.D3D12_DSV_FLAG_NONE; D3D12_CPU_DESCRIPTOR_HANDLE handle = _dsvHeap.Ptr->GetCPUDescriptorHandleForHeapStart(); _d3dDevice.Ptr->CreateDepthStencilView(_depthStencil.Ptr, &dsvDesc, handle); } } // 0.0f, 0.0f, m_d3dRenderTargetSize.Width, m_d3dRenderTargetSize.Height, 0.0f, 1.0f _screenViewport = new D3D12_VIEWPORT { TopLeftX = 0, TopLeftY = 0, Width = (float)_d3dRenderTargetSize.Width, Height = (float)_d3dRenderTargetSize.Height, MinDepth = 0, MaxDepth = 1 }; }