LogShaderLibrary: Display: Using ../../../TestProject/Content/ShaderArchive-TestProject-GLSL_ES3_1_ANDROID.ushaderbytecode for material shader code. Total 3053 unique shaders. LogShaderLibrary: Display: Cooked Context: Using Shared Shader Library TestProject LogRHI: Display: Opened pipeline cache after state change and enqueued 0 of 0 tasks for precompile. LogRHI: Base name for record PSOs is ../../../TestProject/Saved/CollectedPSOs/++UE4+Release-4.25-CL-13942748-TestProject_GLSL_ES3_1_ANDROID_00087B4B08D905BBC5A827F40CA03A0C.rec.upipelinecache LogRHI: FPipelineCacheFile Header Game Version: 13942748 LogRHI: FPipelineCacheFile Header Engine Data Version: 17 LogRHI: FPipelineCacheFile Header TOC Offset: 38155 LogRHI: FPipelineCacheFile File Size: 51011 Bytes LogRHI: Opened FPipelineCacheFile: ../../../TestProject/Content/PipelineCaches/Android/TestProject_GLSL_ES3_1_ANDROID.stable.upipelinecache (GUID: 00000000000000000000000000000000) with 102 entries. LogRHI: Scanning Binary program cache, using Shader Pipeline Cache version 6988202F47BA858F3F0DE483D7DB0606 LogRHI: AndroidEGL:SwapBuffers eglGetCompositorTimingANDROID EGL_COMPOSITE_DEADLINE_ANDROID=2718926192606265, EGL_COMPOSITE_INTERVAL_ANDROID=16559027, EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID=14559027
// Shader library if (bSuccess && StableMap.Num() > 0) { // Write to a intermediate file FString IntermediateFormatPath = GetStableInfoArchiveFilename(FPaths::ProjectSavedDir() / TEXT("Shaders") / FormatName.ToString(), LibraryName, FormatName);
// Write directly to the file { // PipelineCacheUtilities 用这里的方法去保存文件了 if (!UE::PipelineCacheUtilities::SaveStableKeysFile(IntermediateFormatPath, StableMap)) { UE_LOG(LogShaderLibrary, Error, TEXT("Could not save stable map to file '%s'"), *IntermediateFormatPath); }
// PipelineCacheUtilities.h /** * Saves stable shader keys file (using a proprietary format). Stable key is a way to identify a shader independently of its output hash * * @param Filename filename (with path if needed) * @param Values values to be saved * @return true if successful */ RENDERCORE_API boolSaveStableKeysFile(const FStringView& Filename, const TSet<FStableShaderKeyAndValue>& Values);
// go through all the hashes and index them // 这里要拿所有的ShaderHash和对应的Index TArray<FSHAHash> Hashes; TMap<FSHAHash, int32> HashToIndex; // 填充HashToIndex的Map的方法(感觉lambda流行了起来…… auto IndexHash = [&Hashes, &HashToIndex](const FSHAHash& Hash) { if (HashToIndex.Find(Hash) == nullptr) { Hashes.Add(Hash); HashToIndex.Add(Hash, Hashes.Num() - 1); } };
// save the rest of the properties for (const FStableShaderKeyAndValue& ConstItem : Values) { // serialization unfortunately needs non-const and this is easier than const-casting every field FStableShaderKeyAndValue& Item = const_cast<FStableShaderKeyAndValue&>(ConstItem);