Beispiel #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);
	}
}
Beispiel #2
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;
}
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;
}
Beispiel #5
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);
		}
	}
}