void FShaderType::Initialize(const TMap<FString, TArray<const TCHAR*> >& ShaderFileToUniformBufferVariables) { if (!FPlatformProperties::RequiresCookedData()) { for(TLinkedList<FShaderType*>::TIterator It(FShaderType::GetTypeList()); It; It.Next()) { FShaderType* Type = *It; GenerateReferencedUniformBuffers(Type->SourceFilename, Type->Name, ShaderFileToUniformBufferVariables, Type->ReferencedUniformBufferStructsCache); // Cache serialization history for each shader type // This history is used to detect when shader serialization changes without a corresponding .usf change { // Construct a temporary shader, which is initialized to safe values for serialization FShader* TempShader = Type->ConstructForDeserialization(); check(TempShader != NULL); TempShader->Type = Type; // Serialize the temp shader to memory and record the number and sizes of serializations TArray<uint8> TempData; FMemoryWriter Ar(TempData, true); FShaderSaveArchive SaveArchive(Ar, Type->SerializationHistory); TempShader->SerializeBase(SaveArchive, false); // Destroy the temporary shader delete TempShader; } } } bInitializedSerializationHistory = true; }
void FVertexFactoryType::Initialize(const TMap<FString, TArray<const TCHAR*> >& ShaderFileToUniformBufferVariables) { if (!FPlatformProperties::RequiresCookedData()) { // Cache serialization history for each VF type // This history is used to detect when shader serialization changes without a corresponding .usf change for(TLinkedList<FVertexFactoryType*>::TIterator It(FVertexFactoryType::GetTypeList()); It; It.Next()) { FVertexFactoryType* Type = *It; GenerateReferencedUniformBuffers(Type->ShaderFilename, Type->Name, ShaderFileToUniformBufferVariables, Type->ReferencedUniformBufferStructsCache); for (int32 Frequency = 0; Frequency < SF_NumFrequencies; Frequency++) { // Construct a temporary shader parameter instance, which is initialized to safe values for serialization FVertexFactoryShaderParameters* Parameters = Type->CreateShaderParameters((EShaderFrequency)Frequency); if (Parameters) { // Serialize the temp shader to memory and record the number and sizes of serializations TArray<uint8> TempData; FMemoryWriter Ar(TempData, true); FShaderSaveArchive SaveArchive(Ar, Type->SerializationHistory[Frequency]); Parameters->Serialize(SaveArchive); delete Parameters; } } } } bInitializedSerializationHistory = true; }
void FGlobalShaderMapId::AppendKeyString(FString& KeyString) const { TMap<const TCHAR*,FCachedUniformBufferDeclaration> ReferencedUniformBuffers; for (int32 ShaderIndex = 0; ShaderIndex < ShaderTypeDependencies.Num(); ShaderIndex++) { KeyString += TEXT("_"); const FShaderTypeDependency& ShaderTypeDependency = ShaderTypeDependencies[ShaderIndex]; KeyString += ShaderTypeDependency.ShaderType->GetName(); // Add the type's source hash so that we can invalidate cached shaders when .usf changes are made KeyString += ShaderTypeDependency.SourceHash.ToString(); // Add the serialization history to the key string so that we can detect changes to global shader serialization without a corresponding .usf change ShaderTypeDependency.ShaderType->GetSerializationHistory().AppendKeyString(KeyString); const TMap<const TCHAR*,FCachedUniformBufferDeclaration>& ReferencedUniformBufferStructsCache = ShaderTypeDependency.ShaderType->GetReferencedUniformBufferStructsCache(); // Gather referenced uniform buffers for (TMap<const TCHAR*,FCachedUniformBufferDeclaration>::TConstIterator It(ReferencedUniformBufferStructsCache); It; ++It) { ReferencedUniformBuffers.Add(It.Key(), It.Value()); } } { TArray<uint8> TempData; FSerializationHistory SerializationHistory; FMemoryWriter Ar(TempData, true); FShaderSaveArchive SaveArchive(Ar, SerializationHistory); // Save uniform buffer member info so we can detect when layout has changed SerializeUniformBufferInfo(SaveArchive, ReferencedUniformBuffers); SerializationHistory.AppendKeyString(KeyString); } }