void BeginRecompileGlobalShaders(const TArray<FShaderType*>& OutdatedShaderTypes, EShaderPlatform ShaderPlatform) { if( !FPlatformProperties::RequiresCookedData() ) { // Flush pending accesses to the existing global shaders. FlushRenderingCommands(); TShaderMap<FGlobalShaderType>* GlobalShaderMap = GetGlobalShaderMap(ShaderPlatform); for (int32 TypeIndex = 0; TypeIndex < OutdatedShaderTypes.Num(); TypeIndex++) { FGlobalShaderType* CurrentGlobalShaderType = OutdatedShaderTypes[TypeIndex]->GetGlobalShaderType(); if (CurrentGlobalShaderType) { UE_LOG(LogShaders, Log, TEXT("Flushing Global Shader %s"), CurrentGlobalShaderType->GetName()); GlobalShaderMap->RemoveShaderType(CurrentGlobalShaderType); //invalidate global bound shader states so they will be created with the new shaders the next time they are set (in SetGlobalBoundShaderState) for(TLinkedList<FGlobalBoundShaderStateResource*>::TIterator It(FGlobalBoundShaderStateResource::GetGlobalBoundShaderStateList());It;It.Next()) { BeginUpdateResourceRHI(*It); } } } VerifyGlobalShaders(ShaderPlatform, false); } }
bool IsGlobalShaderMapComplete(const TCHAR* TypeNameSubstring) { for (int32 i = 0; i < SP_NumPlatforms; ++i) { EShaderPlatform Platform = (EShaderPlatform)i; TShaderMap<FGlobalShaderType>* GlobalShaderMap = GGlobalShaderMap[Platform]; if (GlobalShaderMap) { for (TLinkedList<FShaderType*>::TIterator ShaderTypeIt(FShaderType::GetTypeList()); ShaderTypeIt; ShaderTypeIt.Next()) { FGlobalShaderType* GlobalShaderType = ShaderTypeIt->GetGlobalShaderType(); if (GlobalShaderType && (TypeNameSubstring == nullptr || (FPlatformString::Strstr(GlobalShaderType->GetName(), TypeNameSubstring) != nullptr)) && GlobalShaderType->ShouldCache(Platform)) { if (!GlobalShaderMap->HasShader(GlobalShaderType)) { return false; } } } } } return true; }
bool AreGlobalShadersComplete(const TCHAR* TypeNameSubstring) { EShaderPlatform Platform = GRHIShaderPlatform; TShaderMap<FGlobalShaderType>* GlobalShaderMap = GGlobalShaderMap[Platform]; if (GlobalShaderMap) { for(TLinkedList<FShaderType*>::TIterator ShaderTypeIt(FShaderType::GetTypeList());ShaderTypeIt;ShaderTypeIt.Next()) { FGlobalShaderType* GlobalShaderType = ShaderTypeIt->GetGlobalShaderType(); if (GlobalShaderType && FPlatformString::Strstr(GlobalShaderType->GetName(), TypeNameSubstring) != NULL && GlobalShaderType->ShouldCache(Platform)) { if (!GlobalShaderMap->HasShader(GlobalShaderType)) { return false; } } } return true; } return false; }
bool IsGlobalShaderMapComplete() { EShaderPlatform Platform = GRHIShaderPlatform; TShaderMap<FGlobalShaderType>* GlobalShaderMap = GGlobalShaderMap[Platform]; if (GlobalShaderMap) { for(TLinkedList<FShaderType*>::TIterator ShaderTypeIt(FShaderType::GetTypeList());ShaderTypeIt;ShaderTypeIt.Next()) { FGlobalShaderType* GlobalShaderType = ShaderTypeIt->GetGlobalShaderType(); if (GlobalShaderType && GlobalShaderType->ShouldCache(Platform)) { if (!GlobalShaderMap->HasShader(GlobalShaderType)) { return false; } } } return true; } return false; }
/** * Makes sure all global shaders are loaded and/or compiled for the passed in platform. * Note: if compilation is needed, this only kicks off the compile. * * @param Platform Platform to verify global shaders for */ void VerifyGlobalShaders(EShaderPlatform Platform, bool bLoadedFromCacheFile) { check(IsInGameThread()); check(!FPlatformProperties::IsServerOnly()); check(GGlobalShaderMap[Platform]); UE_LOG(LogShaders, Log, TEXT("Verifying Global Shaders for %s"), *LegacyShaderPlatformToShaderFormat(Platform).ToString()); // Ensure that the global shader map contains all global shader types. TShaderMap<FGlobalShaderType>* GlobalShaderMap = GetGlobalShaderMap(Platform); const bool bEmptyMap = GlobalShaderMap->IsEmpty(); if (bEmptyMap) { UE_LOG(LogShaders, Warning, TEXT(" Empty global shader map, recompiling all global shaders")); } TArray<FShaderCompileJob*> GlobalShaderJobs; for(TLinkedList<FShaderType*>::TIterator ShaderTypeIt(FShaderType::GetTypeList());ShaderTypeIt;ShaderTypeIt.Next()) { FGlobalShaderType* GlobalShaderType = ShaderTypeIt->GetGlobalShaderType(); if(GlobalShaderType && GlobalShaderType->ShouldCache(Platform)) { if(!GlobalShaderMap->HasShader(GlobalShaderType)) { bool bErrorOnMissing = bLoadedFromCacheFile; if (FPlatformProperties::RequiresCookedData()) { // We require all shaders to exist on cooked platforms because we can't compile them. bErrorOnMissing = true; } if (bErrorOnMissing) { UE_LOG(LogShaders, Fatal,TEXT("Missing global shader %s, Please make sure cooking was successful."), GlobalShaderType->GetName()); } if (!bEmptyMap) { UE_LOG(LogShaders, Warning, TEXT(" %s"), GlobalShaderType->GetName()); } // Compile this global shader type. GlobalShaderType->BeginCompileShader(Platform, GlobalShaderJobs); } } } if (GlobalShaderJobs.Num() > 0) { GShaderCompilingManager->AddJobs(GlobalShaderJobs, true, true); const bool bAllowAsynchronousGlobalShaderCompiling = // OpenGL requires that global shader maps are compiled before attaching // primitives to the scene as it must be able to find FNULLPS. // TODO_OPENGL: Allow shaders to be compiled asynchronously. !IsOpenGLPlatform(GMaxRHIShaderPlatform) && GShaderCompilingManager->AllowAsynchronousShaderCompiling(); if (!bAllowAsynchronousGlobalShaderCompiling) { TArray<int32> ShaderMapIds; ShaderMapIds.Add(GlobalShaderMapId); GShaderCompilingManager->FinishCompilation(TEXT("Global"), ShaderMapIds); } } }