예제 #1
0
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);
	}
}
예제 #2
0
void ProcessCompiledGlobalShaders(const TArray<FShaderCompileJob*>& CompilationResults)
{
	UE_LOG(LogShaders, Warning, TEXT("Compiled %u global shaders"), CompilationResults.Num());

	TArray<EShaderPlatform> ShaderPlatformsProcessed;

	for (int32 ResultIndex = 0; ResultIndex < CompilationResults.Num(); ResultIndex++)
	{
		const FShaderCompileJob& CurrentJob = *CompilationResults[ResultIndex];
		FGlobalShaderType* GlobalShaderType = CurrentJob.ShaderType->GetGlobalShaderType();
		check(GlobalShaderType);
		FShader* Shader = GlobalShaderType->FinishCompileShader(CurrentJob);

		if (Shader)
		{
			// Add the new global shader instance to the global shader map.
			EShaderPlatform Platform = (EShaderPlatform)CurrentJob.Input.Target.Platform;
			GGlobalShaderMap[Platform]->AddShader(GlobalShaderType,Shader);
			ShaderPlatformsProcessed.AddUnique(Platform);
		}
		else
		{
			UE_LOG(LogShaders, Fatal,TEXT("Failed to compile global shader %s.  Enable 'r.ShaderDevelopmentMode' in ConsoleVariables.ini for retries."), GlobalShaderType->GetName());
		}
	}

	for (int32 PlatformIndex = 0; PlatformIndex < ShaderPlatformsProcessed.Num(); PlatformIndex++)
	{
		// Save the global shader map for any platforms that were recompiled
		SaveGlobalShaderMapToDerivedDataCache(ShaderPlatformsProcessed[PlatformIndex]);
	}
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
FGlobalShaderMapId::FGlobalShaderMapId(EShaderPlatform Platform)
{
	TArray<FShaderType*> ShaderTypes;

	for (TLinkedList<FShaderType*>::TIterator ShaderTypeIt(FShaderType::GetTypeList()); ShaderTypeIt; ShaderTypeIt.Next())
	{
		FGlobalShaderType* GlobalShaderType = ShaderTypeIt->GetGlobalShaderType();

		if (GlobalShaderType && GlobalShaderType->ShouldCache(Platform))
		{
			ShaderTypes.Add(GlobalShaderType);
		}
	}

	ShaderTypes.Sort(FCompareShaderTypes());

	for (int32 TypeIndex = 0; TypeIndex < ShaderTypes.Num(); TypeIndex++)
	{
		FShaderTypeDependency Dependency;
		Dependency.ShaderType = ShaderTypes[TypeIndex];
		Dependency.SourceHash = ShaderTypes[TypeIndex]->GetSourceHash();
		ShaderTypeDependencies.Add(Dependency);
	}
}
예제 #7
0
/**
 * 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);
		}
	}
}