void FD3D11Viewport::Resize(uint32 InSizeX,uint32 InSizeY,bool bInIsFullscreen) { // Unbind any dangling references to resources D3DRHI->ClearState(); if (IsValidRef(CustomPresent)) { CustomPresent->OnBackBufferResize(); } // Release our backbuffer reference, as required by DXGI before calling ResizeBuffers. if (IsValidRef(BackBuffer)) { check(BackBuffer->GetRefCount() == 1); checkComRefCount(BackBuffer->GetResource(),1); checkComRefCount(BackBuffer->GetRenderTargetView(0, -1),1); checkComRefCount(BackBuffer->GetShaderResourceView(),1); } BackBuffer.SafeRelease(); if(SizeX != InSizeX || SizeY != InSizeY) { SizeX = InSizeX; SizeY = InSizeY; check(SizeX > 0); check(SizeY > 0); // Resize the swap chain. VERIFYD3D11RESULT_EX(SwapChain->ResizeBuffers(1,SizeX,SizeY,(DXGI_FORMAT)FD3D11Viewport::GetBackBufferFormat(),DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH), D3DRHI->GetDevice()); if(bInIsFullscreen) { DXGI_MODE_DESC BufferDesc = SetupDXGI_MODE_DESC(); if (FAILED(SwapChain->ResizeTarget(&BufferDesc))) { ConditionalResetSwapChain(true); } } } if(bIsFullscreen != bInIsFullscreen) { bIsFullscreen = bInIsFullscreen; bIsValid = false; // Use ConditionalResetSwapChain to call SetFullscreenState, to handle the failure case. // Ignore the viewport's focus state; since Resize is called as the result of a user action we assume authority without waiting for Focus. ConditionalResetSwapChain(true); } // Create a RHI surface to represent the viewport's back buffer. BackBuffer = GetSwapChainSurface(D3DRHI,SwapChain); }
FD3D11Viewport::FD3D11Viewport(FD3D11DynamicRHI* InD3DRHI,HWND InWindowHandle,uint32 InSizeX,uint32 InSizeY,bool bInIsFullscreen, EPixelFormat InPreferredPixelFormat): D3DRHI(InD3DRHI), LastFlipTime(0), LastFrameComplete(0), LastCompleteTime(0), SyncCounter(0), bSyncedLastFrame(false), WindowHandle(InWindowHandle), MaximumFrameLatency(3), SizeX(InSizeX), SizeY(InSizeY), bIsFullscreen(bInIsFullscreen), PixelFormat(InPreferredPixelFormat), bIsValid(true), FrameSyncEvent(InD3DRHI) { check(IsInGameThread()); D3DRHI->Viewports.Add(this); // Ensure that the D3D device has been created. D3DRHI->InitD3DDevice(); // Create a backbuffer/swapchain for each viewport TRefCountPtr<IDXGIDevice> DXGIDevice; VERIFYD3D11RESULT(D3DRHI->GetDevice()->QueryInterface( IID_IDXGIDevice, (void**)DXGIDevice.GetInitReference() )); // Create the swapchain. DXGI_SWAP_CHAIN_DESC SwapChainDesc; FMemory::Memzero( &SwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC) ); SwapChainDesc.BufferDesc = SetupDXGI_MODE_DESC(); // MSAA Sample count SwapChainDesc.SampleDesc.Count = 1; SwapChainDesc.SampleDesc.Quality = 0; SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT; // 1:single buffering, 2:double buffering, 3:triple buffering SwapChainDesc.BufferCount = 1; SwapChainDesc.OutputWindow = WindowHandle; SwapChainDesc.Windowed = !bIsFullscreen; // DXGI_SWAP_EFFECT_DISCARD / DXGI_SWAP_EFFECT_SEQUENTIAL SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; SwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; VERIFYD3D11RESULT(D3DRHI->GetFactory()->CreateSwapChain(DXGIDevice,&SwapChainDesc,SwapChain.GetInitReference())); // Set the DXGI message hook to not change the window behind our back. D3DRHI->GetFactory()->MakeWindowAssociation(WindowHandle,DXGI_MWA_NO_WINDOW_CHANGES); // Create a RHI surface to represent the viewport's back buffer. BackBuffer = GetSwapChainSurface(D3DRHI, PixelFormat, SwapChain); // Tell the window to redraw when they can. // @todo: For Slate viewports, it doesn't make sense to post WM_PAINT messages (we swallow those.) ::PostMessage( WindowHandle, WM_PAINT, 0, 0 ); BeginInitResource(&FrameSyncEvent); }