void RestoreGlobalShaderMap(const FGlobalShaderBackupData& GlobalShaderBackup) { for (int32 i = (int32)ERHIFeatureLevel::ES2; i < (int32)ERHIFeatureLevel::Num; ++i) { EShaderPlatform ShaderPlatform = GetFeatureLevelShaderPlatform((ERHIFeatureLevel::Type)i); if (GlobalShaderBackup.FeatureLevelShaderData[i] != nullptr && ShaderPlatform < EShaderPlatform::SP_NumPlatforms && GGlobalShaderMap[ShaderPlatform] != nullptr) { FMemoryReader Ar(*GlobalShaderBackup.FeatureLevelShaderData[i]); GGlobalShaderMap[ShaderPlatform]->SerializeInline(Ar, true, true); } } }
void BackupGlobalShaderMap(FGlobalShaderBackupData& OutGlobalShaderBackup) { for (int32 i = (int32)ERHIFeatureLevel::ES2; i < (int32)ERHIFeatureLevel::Num; ++i) { EShaderPlatform ShaderPlatform = GetFeatureLevelShaderPlatform((ERHIFeatureLevel::Type)i); if (ShaderPlatform < EShaderPlatform::SP_NumPlatforms && GGlobalShaderMap[ShaderPlatform] != nullptr) { TArray<uint8>* ShaderData = new TArray<uint8>(); FMemoryWriter Ar(*ShaderData); GGlobalShaderMap[ShaderPlatform]->SerializeInline(Ar, true, true); GGlobalShaderMap[ShaderPlatform]->Empty(); OutGlobalShaderBackup.FeatureLevelShaderData[i] = ShaderData; } } // Remove cached references to global shaders for (TLinkedList<FGlobalBoundShaderStateResource*>::TIterator It(FGlobalBoundShaderStateResource::GetGlobalBoundShaderStateList()); It; It.Next()) { BeginUpdateResourceRHI(*It); } }
/** * Build Shaders to compute tex coord scale per texture. * * @param InWorld The world to build streaming for. * @param QualityLevel The quality level for the shaders. * @param FeatureLevel The feature level for the shaders. * @param TexCoordScales The map to store material interfaces used by the current primitive world. * @param MaterialToLevels The map to bind a material to all levels where primitives are refering it. * @param bIncremental true if the build should only update components that have no data. * @return true if the operation is a success, false if it was canceled. */ ENGINE_API bool BuildTextureStreamingShaders(UWorld* InWorld, EMaterialQualityLevel::Type QualityLevel, ERHIFeatureLevel::Type FeatureLevel, OUT FTexCoordScaleMap& TexCoordScales, OUT FMaterialToLevelsMap& MaterialToLevels, bool bIncremental, FSlowTask& BuildTextureStreamingTask) { #if WITH_EDITORONLY_DATA if (!InWorld || !GShaderCompilingManager) return false; const bool bUseNewMetrics = CVarStreamingUseNewMetrics.GetValueOnGameThread() != 0; const double StartTime = FPlatformTime::Seconds(); FlushRenderingCommands(); if (!WaitForShaderCompilation(LOCTEXT("TextureStreamingBuild_FinishPendingShadersCompilation", "Waiting For Pending Shaders Compilation"), BuildTextureStreamingTask)) { return false; } if (!bIncremental) { FDebugViewModeMaterialProxy::ClearAllShaders(); } else // Otherwise, if there are no shaders, then we need to rebuild them all. { bIncremental = FDebugViewModeMaterialProxy::HasAnyShaders(); } // Without the new metrics, the shaders will are not compiled, making the texcoord scale viewmode non functional. if (bUseNewMetrics && AllowDebugViewPS(DVSM_MaterialTexCoordScalesAnalysis, GetFeatureLevelShaderPlatform(FeatureLevel))) { const float NumPrimitiveComponents = (float)GetNumTextureStreamingPrimitives(InWorld); { FScopedSlowTask SlowTask(NumPrimitiveComponents, (LOCTEXT("TextureStreamingBuild_ParsingPrimitiveMaterials ", "Parsing Primitive Materials"))); for (int32 LevelIndex = 0; LevelIndex < InWorld->GetNumLevels(); LevelIndex++) { ULevel* Level = InWorld->GetLevel(LevelIndex); TArray<UPrimitiveComponent*> Components; GetTextureStreamingPrimitives(Level, Components); for (UPrimitiveComponent* Primitive : Components) { SlowTask.EnterProgressFrame(); BuildTextureStreamingTask.EnterProgressFrame(1.f / NumPrimitiveComponents); if (GWarn->ReceivedUserCancel()) { FDebugViewModeMaterialProxy::ClearAllShaders(); return false; } // When only updating (viewmode path), skip primitives that already have data. if (bIncremental && Primitive->HasStreamingSectionData(true)) continue; TArray<UMaterialInterface*> Materials; Primitive->GetUsedMaterials(Materials); for (UMaterialInterface* MaterialInterface : Materials) { if (!MaterialInterface) continue; // Landscape material resources can not be used. See logic in FLandscapeMaterialResource::ShouldCache(). const FMaterial* Material = MaterialInterface->GetMaterialResource(FeatureLevel); if (!Material || Material->IsUsedWithLandscape()) { UE_LOG(TextureStreamingBuild, Verbose, TEXT("Landscape material %s not supported, skipping shader"), *MaterialInterface->GetName()); continue; } if (!TexCoordScales.Contains(MaterialInterface)) { TexCoordScales.Add(MaterialInterface); FDebugViewModeMaterialProxy::AddShader(MaterialInterface, QualityLevel, FeatureLevel, EMaterialShaderMapUsage::DebugViewModeTexCoordScale); } MaterialToLevels.FindOrAdd(MaterialInterface).AddUnique(Level); } } } } if (WaitForShaderCompilation(LOCTEXT("TextureStreamingBuild_CompTexCoordScaleShaders", "Compiling Shaders For TexCoord Scale Analysis "), BuildTextureStreamingTask)) { // Check The validity of all shaders, removing invalid entries FDebugViewModeMaterialProxy::ValidateAllShaders(TexCoordScales); return true; } else { FDebugViewModeMaterialProxy::ClearAllShaders(); return false; } } else { return true; // Nothing to build but this is not an error. } #else UE_LOG(TextureStreamingBuild, Fatal,TEXT("Build Texture Streaming Shaders should not be called on a console")); return false; #endif }