void FSlateD3DRenderer::Private_CreateViewport( TSharedRef<SWindow> InWindow, const FVector2D &WindowSize ) { TSharedRef< FGenericWindow > NativeWindow = InWindow->GetNativeWindow().ToSharedRef(); bool bFullscreen = IsViewportFullscreen( *InWindow ); bool bWindowed = true;//@todo implement fullscreen: !bFullscreen; DXGI_SWAP_CHAIN_DESC SwapChainDesc; FMemory::Memzero(&SwapChainDesc, sizeof(SwapChainDesc) ); SwapChainDesc.BufferCount = 1; SwapChainDesc.BufferDesc.Width = FMath::TruncToInt(WindowSize.X); SwapChainDesc.BufferDesc.Height = FMath::TruncToInt(WindowSize.Y); SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; SwapChainDesc.BufferDesc.RefreshRate.Numerator = 0; SwapChainDesc.BufferDesc.RefreshRate.Denominator = 1; SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; SwapChainDesc.OutputWindow = (HWND)NativeWindow->GetOSWindowHandle(); SwapChainDesc.SampleDesc.Count = 1; SwapChainDesc.SampleDesc.Quality = 0; SwapChainDesc.Windowed = bWindowed; SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; SwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; TRefCountPtr<IDXGIDevice> DXGIDevice; HRESULT Hr = GD3DDevice->QueryInterface( __uuidof(IDXGIDevice), (void**)DXGIDevice.GetInitReference() ); check( SUCCEEDED(Hr) ); TRefCountPtr<IDXGIAdapter> DXGIAdapter; Hr = DXGIDevice->GetParent(__uuidof(IDXGIAdapter), (void **)DXGIAdapter.GetInitReference() ); check( SUCCEEDED(Hr) ); TRefCountPtr<IDXGIFactory> DXGIFactory; DXGIAdapter->GetParent(__uuidof(IDXGIFactory), (void **)DXGIFactory.GetInitReference() ); check( SUCCEEDED(Hr) ); FSlateD3DViewport Viewport; Hr = DXGIFactory->CreateSwapChain(DXGIDevice.GetReference(), &SwapChainDesc, Viewport.D3DSwapChain.GetInitReference() ); check( SUCCEEDED(Hr) ); Hr = DXGIFactory->MakeWindowAssociation((HWND)NativeWindow->GetOSWindowHandle(),DXGI_MWA_NO_ALT_ENTER); check(SUCCEEDED(Hr)); uint32 Width = FMath::TruncToInt(WindowSize.X); uint32 Height = FMath::TruncToInt(WindowSize.Y); Viewport.ViewportInfo.MaxDepth = 1.0f; Viewport.ViewportInfo.MinDepth = 0.0f; Viewport.ViewportInfo.Width = Width; Viewport.ViewportInfo.Height = Height; Viewport.ViewportInfo.TopLeftX = 0; Viewport.ViewportInfo.TopLeftY = 0; CreateBackBufferResources( Viewport.D3DSwapChain, Viewport.BackBufferTexture, Viewport.RenderTargetView ); Viewport.ProjectionMatrix = CreateProjectionMatrixD3D( Width, Height ); WindowToViewportMap.Add( &InWindow.Get(), Viewport ); }
void FD3D12Device::InitD3DDevice() { check(IsInGameThread()); // Wait for the rendering thread to go idle. SCOPED_SUSPEND_RENDERING_THREAD(false); // If the device we were using has been removed, release it and the resources we created for it. if (bDeviceRemoved) { check(Direct3DDevice); HRESULT hRes = Direct3DDevice->GetDeviceRemovedReason(); const TCHAR* Reason = TEXT("?"); switch (hRes) { case DXGI_ERROR_DEVICE_HUNG: Reason = TEXT("HUNG"); break; case DXGI_ERROR_DEVICE_REMOVED: Reason = TEXT("REMOVED"); break; case DXGI_ERROR_DEVICE_RESET: Reason = TEXT("RESET"); break; case DXGI_ERROR_DRIVER_INTERNAL_ERROR: Reason = TEXT("INTERNAL_ERROR"); break; case DXGI_ERROR_INVALID_CALL: Reason = TEXT("INVALID_CALL"); break; } bDeviceRemoved = false; // Cleanup the D3D device. CleanupD3DDevice(); // We currently don't support removed devices because FTexture2DResource can't recreate its RHI resources from scratch. // We would also need to recreate the viewport swap chains from scratch. UE_LOG(LogD3D12RHI, Fatal, TEXT("The Direct3D 12 device that was being used has been removed (Error: %d '%s'). Please restart the game."), hRes, Reason); } // If we don't have a device yet, either because this is the first viewport, or the old device was removed, create a device. if (!Direct3DDevice) { // Determine the adapter and device type to use. TRefCountPtr<IDXGIAdapter> Adapter; // In Direct3D 11, if you are trying to create a hardware or a software device, set pAdapter != NULL which constrains the other inputs to be: // DriverType must be D3D_DRIVER_TYPE_UNKNOWN // Software must be NULL. D3D_DRIVER_TYPE DriverType = D3D_DRIVER_TYPE_UNKNOWN; // Use a debug device if specified on the command line. const bool bWithD3DDebug = D3D12RHI_ShouldCreateWithD3DDebug(); if (bWithD3DDebug) { TRefCountPtr<ID3D12Debug> DebugController; VERIFYD3D11RESULT(D3D12GetDebugInterface(IID_PPV_ARGS(DebugController.GetInitReference()))); DebugController->EnableDebugLayer(); UE_LOG(LogD3D12RHI, Log, TEXT("InitD3DDevice: -D3DDebug = %s"), bWithD3DDebug ? TEXT("on") : TEXT("off")); } TRefCountPtr<IDXGIAdapter> EnumAdapter; if (DXGIFactory->EnumAdapters(GetAdapterIndex(), EnumAdapter.GetInitReference()) != DXGI_ERROR_NOT_FOUND) { if (EnumAdapter) { if (SUCCEEDED(EnumAdapter->GetDesc(&AdapterDesc))) { Adapter = EnumAdapter; const bool bIsPerfHUD = !FCString::Stricmp(AdapterDesc.Description, TEXT("NVIDIA PerfHUD")); if (bIsPerfHUD) { DriverType = D3D_DRIVER_TYPE_REFERENCE; } VERIFYD3D11RESULT(EnumAdapter->QueryInterface(_uuidof(DxgiAdapter3), (void **)DxgiAdapter3.GetInitReference())); } else { check(!"Internal error, GetDesc() failed but before it worked") } } } else {