Esempio n. 1
0
        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
            };
        }