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 }; }
private void CreateDeviceResources() { Guid iid; #if DEBUG { using ComPtr <ID3D12Debug> debugController = null; iid = D3D12.IID_ID3D12Debug; if (SUCCEEDED(D3D12.D3D12GetDebugInterface(&iid, (void **)debugController.GetAddressOf()))) { debugController.Ptr->EnableDebugLayer(); } } #endif iid = DXGI.IID_IDXGIFactory4; IDXGIFactory4 *dxgiFactory; DirectXHelper.ThrowIfFailed(DXGI.CreateDXGIFactory1(&iid, (void **)&dxgiFactory)); _dxgiFactory = dxgiFactory; using ComPtr <IDXGIAdapter1> adapter = null; GetHardwareAdapter(adapter.ReleaseGetAddressOf()); ID3D12Device *d3dDevice; iid = D3D12.IID_ID3D12Device; HRESULT hr; { hr = D3D12.D3D12CreateDevice( adapter, D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_11_0, &iid, (void **)&d3dDevice ); #if DEBUG if (FAILED(hr)) { using ComPtr <IDXGIAdapter> warpAdapter = null; iid = DXGI.IID_IDXGIAdapter; DirectXHelper.ThrowIfFailed(_dxgiFactory.Ptr->EnumWarpAdapter(&iid, (void **)warpAdapter.GetAddressOf())); iid = D3D12.IID_ID3D12Device1; hr = D3D12.D3D12CreateDevice( warpAdapter, D3D_FEATURE_LEVEL.D3D_FEATURE_LEVEL_11_0, &iid, (void **)&d3dDevice ); } #endif } _d3dDevice = d3dDevice; DirectXHelper.ThrowIfFailed(hr); D3D12_COMMAND_QUEUE_DESC queueDesc; queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAGS.D3D12_COMMAND_QUEUE_FLAG_NONE; queueDesc.Type = D3D12_COMMAND_LIST_TYPE.D3D12_COMMAND_LIST_TYPE_DIRECT; ID3D12CommandQueue *commandQueue; { iid = D3D12.IID_ID3D12CommandQueue; DirectXHelper.ThrowIfFailed(_d3dDevice.Ptr->CreateCommandQueue(&queueDesc, &iid, (void **)&commandQueue)); } _commandQueue = commandQueue; DirectXHelper.NameObject(_commandQueue, nameof(_commandQueue)); D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc; rtvHeapDesc.NumDescriptors = FrameCount; rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE.D3D12_DESCRIPTOR_HEAP_TYPE_RTV; rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAGS.D3D12_DESCRIPTOR_HEAP_FLAG_NONE; ID3D12DescriptorHeap *rtvHeap; { iid = D3D12.IID_ID3D12DescriptorHeap; DirectXHelper.ThrowIfFailed(_d3dDevice.Ptr->CreateDescriptorHeap(&rtvHeapDesc, &iid, (void **)&rtvHeap)); } _rtvHeap = rtvHeap; DirectXHelper.NameObject(_rtvHeap, nameof(_rtvHeap)); _rtvDescriptorSize = _d3dDevice.Ptr->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE .D3D12_DESCRIPTOR_HEAP_TYPE_RTV); D3D12_DESCRIPTOR_HEAP_DESC dsvHeapDesc; dsvHeapDesc.NumDescriptors = 1; dsvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE.D3D12_DESCRIPTOR_HEAP_TYPE_DSV; dsvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAGS.D3D12_DESCRIPTOR_HEAP_FLAG_NONE; ID3D12DescriptorHeap *dsvHeap; { iid = D3D12.IID_ID3D12DescriptorHeap; DirectXHelper.ThrowIfFailed(_d3dDevice.Ptr->CreateDescriptorHeap(&dsvHeapDesc, &iid, (void **)&dsvHeap)); } _dsvHeap = dsvHeap; DirectXHelper.NameObject(_dsvHeap, nameof(_dsvHeap)); fixed(CommandAllocators_e__FixedBuffer *pBuffer = &_commandAllocators) { var p = (ID3D12CommandAllocator **)pBuffer; iid = D3D12.IID_ID3D12CommandAllocator; for (var n = 0; n < FrameCount; n++) { DirectXHelper.ThrowIfFailed(_d3dDevice.Ptr->CreateCommandAllocator( D3D12_COMMAND_LIST_TYPE.D3D12_COMMAND_LIST_TYPE_DIRECT, &iid, (void **)(p + n))); } } ID3D12Fence *fence; { iid = D3D12.IID_ID3D12Fence; DirectXHelper.ThrowIfFailed( _d3dDevice.Ptr->CreateFence(_fenceValues[_currentFrame], D3D12_FENCE_FLAGS.D3D12_FENCE_FLAG_NONE, &iid, (void **)&fence)); _fenceValues[_currentFrame]++; } _fence = fence; DirectXHelper.NameObject(_fence, nameof(_fence)); _fenceEvent = Kernel32.CreateEvent(null, FALSE, FALSE, null); if (_fenceEvent == IntPtr.Zero) { DirectXHelper.ThrowIfFailed(Marshal.GetLastWin32Error()); } }