/** * Handles recompiling the renderer module, including removing all references, recompiling the dll and restoring references. */ void RecompileRenderer(const TArray<FString>& Args) { // So that we can see the slow task dialog FSlateApplication::Get().DismissAllMenus(); GWarn->BeginSlowTask( NSLOCTEXT("Renderer", "BeginRecompileRendererTask", "Recompiling Rendering Module..."), true); const double StartTime = FPlatformTime::Seconds(); double EndShutdownTime; double EndRecompileTime; { // Deregister all components from their renderer scenes FGlobalComponentReregisterContext ReregisterContext; // Shut down the rendering thread so that the game thread will process all rendering commands during this scope SCOPED_SUSPEND_RENDERING_THREAD(true); TMap<UWorld*, bool> WorldsToUpdate; TMap<FMaterialShaderMap*, TScopedPointer<TArray<uint8> > > ShaderMapToSerializedShaderData; TScopedPointer<TArray<uint8> > GlobalShaderData; TMap<FShaderType*, FString> ShaderTypeNames; TMap<FVertexFactoryType*, FString> VertexFactoryTypeNames; ClearReferencesToRendererModuleClasses(WorldsToUpdate, ShaderMapToSerializedShaderData, GlobalShaderData, ShaderTypeNames, VertexFactoryTypeNames); EndShutdownTime = FPlatformTime::Seconds(); UE_LOG(LogShaders, Warning, TEXT("Shutdown complete %.1fs"),(float)(EndShutdownTime - StartTime)); RecompileRendererModule(); EndRecompileTime = FPlatformTime::Seconds(); UE_LOG(LogShaders, Warning, TEXT("Recompile complete %.1fs"),(float)(EndRecompileTime - EndShutdownTime)); RestoreReferencesToRendererModuleClasses(WorldsToUpdate, ShaderMapToSerializedShaderData, GlobalShaderData, ShaderTypeNames, VertexFactoryTypeNames); } #if WITH_EDITOR // Refresh viewports FEditorSupportDelegates::RedrawAllViewports.Broadcast(); #endif const double EndTime = FPlatformTime::Seconds(); UE_LOG(LogShaders, Warning, TEXT("Recompile of Renderer module complete \n") TEXT(" Total = %.1fs, Shutdown = %.1fs, Recompile = %.1fs, Reload = %.1fs"), (float)(EndTime - StartTime), (float)(EndShutdownTime - StartTime), (float)(EndRecompileTime - EndShutdownTime), (float)(EndTime - EndRecompileTime)); GWarn->EndSlowTask(); }
void FSceneViewport::UpdateViewportRHI(bool bDestroyed, uint32 NewSizeX, uint32 NewSizeY, EWindowMode::Type NewWindowMode) { { SCOPED_SUSPEND_RENDERING_THREAD(true); // Update the viewport attributes. // This is done AFTER the command flush done by UpdateViewportRHI, to avoid disrupting rendering thread accesses to the old viewport size. SizeX = NewSizeX; SizeY = NewSizeY; WindowMode = NewWindowMode; // Release the viewport's resources. BeginReleaseResource(this); if( !bDestroyed ) { BeginInitResource(this); if( !bUseSeparateRenderTarget ) { // Get the viewport for this window from the renderer so we can render directly to the backbuffer TSharedPtr<FSlateRenderer> Renderer = FSlateApplication::Get().GetRenderer(); FWidgetPath WidgetPath; void* ViewportResource = Renderer->GetViewportResource( *FSlateApplication::Get().FindWidgetWindow( ViewportWidget.Pin().ToSharedRef(), WidgetPath ) ); if( ViewportResource ) { ViewportRHI = *((FViewportRHIRef*)ViewportResource); } } ViewportResizedEvent.Broadcast(this, 0); } else { // Enqueue a render command to delete the handle. It must be deleted on the render thread after the resource is released ENQUEUE_UNIQUE_RENDER_COMMAND_TWOPARAMETER(DeleteSlateRenderTarget, TArray<FSlateRenderTargetRHI*>&, BufferedSlateHandles, BufferedSlateHandles, FSlateRenderTargetRHI*&, RenderThreadSlateTexture, RenderThreadSlateTexture, { for (int32 i = 0; i < BufferedSlateHandles.Num(); ++i) { delete BufferedSlateHandles[i]; BufferedSlateHandles[i] = nullptr; delete RenderThreadSlateTexture; RenderThreadSlateTexture = nullptr; } }); } }
void FSceneViewport::UpdateViewportRHI(bool bDestroyed, uint32 NewSizeX, uint32 NewSizeY, EWindowMode::Type NewWindowMode) { // Make sure we're not in the middle of streaming textures. (*GFlushStreamingFunc)(); { SCOPED_SUSPEND_RENDERING_THREAD(true); // Update the viewport attributes. // This is done AFTER the command flush done by UpdateViewportRHI, to avoid disrupting rendering thread accesses to the old viewport size. SizeX = NewSizeX; SizeY = NewSizeY; WindowMode = NewWindowMode; // Release the viewport's resources. BeginReleaseResource(this); if( !bDestroyed ) { BeginInitResource(this); if( !bUseSeparateRenderTarget ) { // Get the viewport for this window from the renderer so we can render directly to the backbuffer TSharedPtr<FSlateRenderer> Renderer = FSlateApplication::Get().GetRenderer(); FWidgetPath WidgetPath; void* ViewportResource = Renderer->GetViewportResource( *FSlateApplication::Get().FindWidgetWindow( ViewportWidget.Pin().ToSharedRef(), WidgetPath ) ); if( ViewportResource ) { ViewportRHI = *((FViewportRHIRef*)ViewportResource); } } ViewportResizedEvent.Broadcast(this, 0); } else { // Enqueue a render command to delete the handle. It must be deleted on the render thread after the resource is released ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER(DeleteSlateRenderTarget, FSlateRenderTargetRHI*&, SlateRenderTargetHandle, SlateRenderTargetHandle, { delete SlateRenderTargetHandle; SlateRenderTargetHandle = NULL; }); } }
void FD3D11DynamicRHI::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) { UE_LOG(LogD3D11RHI, Log, TEXT("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(LogD3D11RHI, Fatal, TEXT("The Direct3D 11 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) { UE_LOG(LogD3D11RHI, Log, TEXT("!Direct3DDevice")); check(!GIsRHIInitialized); // Clear shadowed shader resources. ClearState(); // 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; uint32 DeviceFlags = D3D11RHI_ShouldAllowAsyncResourceCreation() ? 0 : D3D11_CREATE_DEVICE_SINGLETHREADED; // Use a debug device if specified on the command line. const bool bWithD3DDebug = D3D11RHI_ShouldCreateWithD3DDebug(); if (bWithD3DDebug) { DeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; UE_LOG(LogD3D11RHI, Log, TEXT("InitD3DDevice: -D3DDebug = %s"), bWithD3DDebug ? TEXT("on") : TEXT("off")); } GTexturePoolSize = 0; TRefCountPtr<IDXGIAdapter> EnumAdapter; if(DXGIFactory1->EnumAdapters(ChosenAdapter,EnumAdapter.GetInitReference()) != DXGI_ERROR_NOT_FOUND) { if (EnumAdapter)// && EnumAdapter->CheckInterfaceSupport(__uuidof(ID3D11Device),NULL) == S_OK) { DXGI_ADAPTER_DESC AdapterDesc; if (SUCCEEDED(EnumAdapter->GetDesc(&AdapterDesc))) { Adapter = EnumAdapter; GRHIAdapterName = AdapterDesc.Description; GRHIVendorId = AdapterDesc.VendorId; // Issue: 32bit windows doesn't report 64bit value, we take what we get. FD3D11GlobalStats::GDedicatedVideoMemory = int64(AdapterDesc.DedicatedVideoMemory); FD3D11GlobalStats::GDedicatedSystemMemory = int64(AdapterDesc.DedicatedSystemMemory); FD3D11GlobalStats::GSharedSystemMemory = int64(AdapterDesc.SharedSystemMemory); // Total amount of system memory, clamped to 8 GB int64 TotalPhysicalMemory = FMath::Min(int64(FPlatformMemory::GetConstants().TotalPhysicalGB), 8ll) * (1024ll * 1024ll * 1024ll); // Consider 50% of the shared memory but max 25% of total system memory. int64 ConsideredSharedSystemMemory = FMath::Min( FD3D11GlobalStats::GSharedSystemMemory / 2ll, TotalPhysicalMemory / 4ll ); FD3D11GlobalStats::GTotalGraphicsMemory = 0; if ( IsRHIDeviceIntel() ) { // It's all system memory. FD3D11GlobalStats::GTotalGraphicsMemory = FD3D11GlobalStats::GDedicatedVideoMemory; FD3D11GlobalStats::GTotalGraphicsMemory += FD3D11GlobalStats::GDedicatedSystemMemory; FD3D11GlobalStats::GTotalGraphicsMemory += ConsideredSharedSystemMemory; } else if ( FD3D11GlobalStats::GDedicatedVideoMemory >= 200*1024*1024 ) { // Use dedicated video memory, if it's more than 200 MB FD3D11GlobalStats::GTotalGraphicsMemory = FD3D11GlobalStats::GDedicatedVideoMemory; } else if ( FD3D11GlobalStats::GDedicatedSystemMemory >= 200*1024*1024 ) { // Use dedicated system memory, if it's more than 200 MB FD3D11GlobalStats::GTotalGraphicsMemory = FD3D11GlobalStats::GDedicatedSystemMemory; } else if ( FD3D11GlobalStats::GSharedSystemMemory >= 400*1024*1024 ) { // Use some shared system memory, if it's more than 400 MB FD3D11GlobalStats::GTotalGraphicsMemory = ConsideredSharedSystemMemory; } else { // Otherwise consider 25% of total system memory for graphics. FD3D11GlobalStats::GTotalGraphicsMemory = TotalPhysicalMemory / 4ll; } if ( sizeof(SIZE_T) < 8 ) { // Clamp to 1 GB if we're less than 64-bit FD3D11GlobalStats::GTotalGraphicsMemory = FMath::Min( FD3D11GlobalStats::GTotalGraphicsMemory, 1024ll * 1024ll * 1024ll ); } else { // Clamp to 1.9 GB if we're 64-bit FD3D11GlobalStats::GTotalGraphicsMemory = FMath::Min( FD3D11GlobalStats::GTotalGraphicsMemory, 1945ll * 1024ll * 1024ll ); } if ( GPoolSizeVRAMPercentage > 0 ) { float PoolSize = float(GPoolSizeVRAMPercentage) * 0.01f * float(FD3D11GlobalStats::GTotalGraphicsMemory); // Truncate GTexturePoolSize to MB (but still counted in bytes) GTexturePoolSize = int64(FGenericPlatformMath::TruncToFloat(PoolSize / 1024.0f / 1024.0f)) * 1024 * 1024; UE_LOG(LogRHI,Log,TEXT("Texture pool is %llu MB (%d%% of %llu MB)"), GTexturePoolSize / 1024 / 1024, GPoolSizeVRAMPercentage, FD3D11GlobalStats::GTotalGraphicsMemory / 1024 / 1024); } const bool bIsPerfHUD = !FCString::Stricmp(AdapterDesc.Description,TEXT("NVIDIA PerfHUD")); if(bIsPerfHUD) { DriverType = D3D_DRIVER_TYPE_REFERENCE; } } else { check(!"Internal error, GetDesc() failed but before it worked") } } } else {
int32 EditorInit( IEngineLoop& EngineLoop ) { // Create debug exec. GDebugToolExec = new FDebugToolExec; DECLARE_SCOPE_CYCLE_COUNTER(TEXT("Editor Initialized"), STAT_EditorStartup, STATGROUP_LoadTime); FScopedSlowTask SlowTask(100, NSLOCTEXT("EngineLoop", "EngineLoop_Loading", "Loading...")); SlowTask.EnterProgressFrame(50); int32 ErrorLevel = EngineLoop.Init(); if( ErrorLevel != 0 ) { FPlatformSplash::Hide(); return 0; } // Let the analytics know that the editor has started if ( FEngineAnalytics::IsAvailable() ) { TArray<FAnalyticsEventAttribute> EventAttributes; EventAttributes.Add(FAnalyticsEventAttribute(TEXT("MachineID"), FPlatformMisc::GetMachineId().ToString(EGuidFormats::Digits).ToLower())); EventAttributes.Add(FAnalyticsEventAttribute(TEXT("AccountID"), FPlatformMisc::GetEpicAccountId())); EventAttributes.Add(FAnalyticsEventAttribute(TEXT("GameName"), FApp::GetGameName())); EventAttributes.Add(FAnalyticsEventAttribute(TEXT("CommandLine"), FCommandLine::Get())); FEngineAnalytics::GetProvider().RecordEvent(TEXT("Editor.ProgramStarted"), EventAttributes); } SlowTask.EnterProgressFrame(40); // Initialize the misc editor FUnrealEdMisc::Get().OnInit(); SlowTask.EnterProgressFrame(10); // Prime our array of default directories for loading and saving content files to FEditorDirectories::Get().LoadLastDirectories(); // Set up the actor folders singleton FActorFolders::Init(); // =================== CORE EDITOR INIT FINISHED =================== // Hide the splash screen now that everything is ready to go FPlatformSplash::Hide(); // Are we in immersive mode? const bool bIsImmersive = FPaths::IsProjectFilePathSet() && FParse::Param( FCommandLine::Get(), TEXT( "immersive" ) ); // Do final set up on the editor frame and show it { // Tear down rendering thread once instead of doing it for every window being resized. SCOPED_SUSPEND_RENDERING_THREAD(true); // Startup Slate main frame and other editor windows { const bool bStartImmersive = bIsImmersive; const bool bStartPIE = bIsImmersive; IMainFrameModule& MainFrameModule = FModuleManager::LoadModuleChecked<IMainFrameModule>(TEXT("MainFrame")); MainFrameModule.CreateDefaultMainFrame( bStartImmersive, bStartPIE ); } } // Go straight to VR mode if we were asked to { if( !bIsImmersive && FParse::Param( FCommandLine::Get(), TEXT( "VREditor" ) ) ) { IVREditorModule& VREditorModule = IVREditorModule::Get(); VREditorModule.EnableVREditor( true ); } else if( FParse::Param( FCommandLine::Get(), TEXT( "ForceVREditor" ) ) ) { GEngine->DeferredCommands.Add( TEXT( "VREd.ForceVRMode" ) ); } } // Check for automated build/submit option const bool bDoAutomatedMapBuild = FParse::Param( FCommandLine::Get(), TEXT("AutomatedMapBuild") ); // Prompt to update the game project file to the current version, if necessary if ( FPaths::IsProjectFilePathSet() ) { FGameProjectGenerationModule::Get().CheckForOutOfDateGameProjectFile(); FGameProjectGenerationModule::Get().CheckAndWarnProjectFilenameValid(); } // =================== EDITOR STARTUP FINISHED =================== // Stat tracking { const float StartupTime = (float)( FPlatformTime::Seconds() - GStartTime ); if( FEngineAnalytics::IsAvailable() ) { FEngineAnalytics::GetProvider().RecordEvent( TEXT( "Editor.Performance.Startup" ), TEXT( "Duration" ), FString::Printf( TEXT( "%.3f" ), StartupTime ) ); } } FModuleManager::LoadModuleChecked<IModuleInterface>(TEXT("HierarchicalLODOutliner")); // this will be ultimately returned from main(), so no error should be 0. return 0; }