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);
        }
Exemple #5
0
        /// <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);
        }
Exemple #7
0
        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)
            };
        }
Exemple #8
0
        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);
        }
Exemple #10
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
            };
        }