Ejemplo n.º 1
0
        MainStageHierarchyState GetStoredHierarchyState(SceneHierarchyWindow hierarchyWindow)
        {
            Hash128 key = StageUtility.CreateWindowAndStageIdentifier(hierarchyWindow.windowGUID, this);

            return(s_StateCache.GetState(key));
        }
Ejemplo n.º 2
0
        private ContentUpdateScript.ContentUpdateContext GetContentUpdateContext(string contentUpdateTestAssetGUID, string contentUpdateTestCachedAssetHash,
                                                                                 string contentUpdateTestNewInternalBundleName, string contentUpdateTestNewBundleName, string contentUpdateTestCachedBundlePath, string contentUpdateTestGroupGuid, string contentUpdateTestFileName)
        {
            Dictionary <string, string> bundleToInternalBundle = new Dictionary <string, string>()
            {
                {
                    contentUpdateTestNewInternalBundleName,
                    contentUpdateTestNewBundleName
                }
            };

            Dictionary <string, CachedAssetState> guidToCachedState = new Dictionary <string, CachedAssetState>()
            {
                //entry 1
                {
                    contentUpdateTestAssetGUID, new CachedAssetState()
                    {
                        bundleFileId = contentUpdateTestCachedBundlePath,
                        asset        = new AssetState()
                        {
                            guid = new GUID(contentUpdateTestAssetGUID),
                            hash = Hash128.Parse(contentUpdateTestCachedAssetHash)
                        },
                        dependencies = new AssetState[] { },
                        data         = null,
                        groupGuid    = contentUpdateTestGroupGuid
                    }
                }
            };

            Dictionary <string, ContentCatalogDataEntry> idToCatalogEntryMap = new Dictionary <string, ContentCatalogDataEntry>()
            {
                //bundle entry
                { contentUpdateTestNewBundleName,
                  new ContentCatalogDataEntry(typeof(IAssetBundleResource), contentUpdateTestNewBundleName,
                                              typeof(AssetBundleProvider).FullName, new [] { contentUpdateTestNewBundleName }) },
                //asset entry
                {
                    contentUpdateTestAssetGUID,
                    new ContentCatalogDataEntry(typeof(IResourceLocation), contentUpdateTestAssetGUID, typeof(BundledAssetProvider).FullName, new [] { contentUpdateTestAssetGUID })
                }
            };

            IBundleWriteData writeData = new BundleWriteData();

            writeData.AssetToFiles.Add(new GUID(contentUpdateTestAssetGUID), new List <string>()
            {
                contentUpdateTestFileName
            });
            writeData.FileToBundle.Add(contentUpdateTestFileName, contentUpdateTestNewInternalBundleName);

            ContentUpdateScript.ContentUpdateContext context = new ContentUpdateScript.ContentUpdateContext()
            {
                WriteData = writeData,
                BundleToInternalBundleIdMap = bundleToInternalBundle,
                GuidToPreviousAssetStateMap = guidToCachedState,
                IdToCatalogDataEntryMap     = idToCatalogEntryMap,
                ContentState = new AddressablesContentState(),
                PreviousAssetStateCarryOver = new List <CachedAssetState>(),
                Registry = new FileRegistry()
            };
            return(context);
        }
Ejemplo n.º 3
0
 public Transaction(Hash128 guid, int state, long timestamp)
 {
     this.timestamp = timestamp;
     this.guid      = guid;
     this.state     = state;
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Gets a graphics shader program from the shader cache.
        /// This includes all the specified shader stages.
        /// </summary>
        /// <remarks>
        /// This automatically translates, compiles and adds the code to the cache if not present.
        /// </remarks>
        /// <param name="state">Current GPU state</param>
        /// <param name="addresses">Addresses of the shaders for each stage</param>
        /// <returns>Compiled graphics shader code</returns>
        public ShaderBundle GetGraphicsShader(GpuState state, ShaderAddresses addresses)
        {
            bool isCached = _gpPrograms.TryGetValue(addresses, out List <ShaderBundle> list);

            if (isCached)
            {
                foreach (ShaderBundle cachedGpShaders in list)
                {
                    if (IsShaderEqual(cachedGpShaders, addresses))
                    {
                        return(cachedGpShaders);
                    }
                }
            }

            TranslatorContext[] shaderContexts = new TranslatorContext[Constants.ShaderStages + 1];

            TransformFeedbackDescriptor[] tfd = GetTransformFeedbackDescriptors(state);

            TranslationFlags flags = DefaultFlags;

            if (tfd != null)
            {
                flags |= TranslationFlags.Feedback;
            }

            TranslationCounts counts = new TranslationCounts();

            if (addresses.VertexA != 0)
            {
                shaderContexts[0] = DecodeGraphicsShader(state, counts, flags | TranslationFlags.VertexA, ShaderStage.Vertex, addresses.VertexA);
            }

            shaderContexts[1] = DecodeGraphicsShader(state, counts, flags, ShaderStage.Vertex, addresses.Vertex);
            shaderContexts[2] = DecodeGraphicsShader(state, counts, flags, ShaderStage.TessellationControl, addresses.TessControl);
            shaderContexts[3] = DecodeGraphicsShader(state, counts, flags, ShaderStage.TessellationEvaluation, addresses.TessEvaluation);
            shaderContexts[4] = DecodeGraphicsShader(state, counts, flags, ShaderStage.Geometry, addresses.Geometry);
            shaderContexts[5] = DecodeGraphicsShader(state, counts, flags, ShaderStage.Fragment, addresses.Fragment);

            bool isShaderCacheEnabled  = _cacheManager != null;
            bool isShaderCacheReadOnly = false;

            Hash128 programCodeHash = default;

            GuestShaderCacheEntry[] shaderCacheEntries = null;

            // Current shader cache doesn't support bindless textures
            for (int i = 0; i < shaderContexts.Length; i++)
            {
                if (shaderContexts[i] != null && shaderContexts[i].UsedFeatures.HasFlag(FeatureFlags.Bindless))
                {
                    isShaderCacheEnabled = false;
                    break;
                }
            }

            if (isShaderCacheEnabled)
            {
                isShaderCacheReadOnly = _cacheManager.IsReadOnly;

                // Compute hash and prepare data for shader disk cache comparison.
                shaderCacheEntries = CacheHelper.CreateShaderCacheEntries(_context.MemoryManager, shaderContexts);
                programCodeHash    = CacheHelper.ComputeGuestHashFromCache(shaderCacheEntries, tfd);
            }

            ShaderBundle gpShaders;

            // Search for the program hash in loaded shaders.
            if (!isShaderCacheEnabled || !_gpProgramsDiskCache.TryGetValue(programCodeHash, out gpShaders))
            {
                if (isShaderCacheEnabled)
                {
                    Logger.Debug?.Print(LogClass.Gpu, $"Shader {programCodeHash} not in cache, compiling!");
                }

                // The shader isn't currently cached, translate it and compile it.
                ShaderCodeHolder[] shaders = new ShaderCodeHolder[Constants.ShaderStages];

                shaders[0] = TranslateShader(shaderContexts[1], shaderContexts[0]);
                shaders[1] = TranslateShader(shaderContexts[2]);
                shaders[2] = TranslateShader(shaderContexts[3]);
                shaders[3] = TranslateShader(shaderContexts[4]);
                shaders[4] = TranslateShader(shaderContexts[5]);

                List <IShader> hostShaders = new List <IShader>();

                for (int stage = 0; stage < Constants.ShaderStages; stage++)
                {
                    ShaderProgram program = shaders[stage]?.Program;

                    if (program == null)
                    {
                        continue;
                    }

                    IShader hostShader = _context.Renderer.CompileShader(program.Stage, program.Code);

                    shaders[stage].HostShader = hostShader;

                    hostShaders.Add(hostShader);
                }

                IProgram hostProgram = _context.Renderer.CreateProgram(hostShaders.ToArray(), tfd);

                hostProgram.CheckProgramLink(true);

                byte[] hostProgramBinary = HostShaderCacheEntry.Create(hostProgram.GetBinary(), shaders);

                gpShaders = new ShaderBundle(hostProgram, shaders);

                if (isShaderCacheEnabled)
                {
                    _gpProgramsDiskCache.Add(programCodeHash, gpShaders);

                    if (!isShaderCacheReadOnly)
                    {
                        _cacheManager.SaveProgram(ref programCodeHash, CacheHelper.CreateGuestProgramDump(shaderCacheEntries, tfd), hostProgramBinary);
                    }
                }
            }

            if (!isCached)
            {
                list = new List <ShaderBundle>();

                _gpPrograms.Add(addresses, list);
            }

            list.Add(gpShaders);

            return(gpShaders);
        }
 public LiveLinkConnection(int playerId, string name, LiveLinkConnectionStatus status, Hash128 buildConfigurationGuid)
 {
     PlayerId = playerId;
     Name     = name;
     m_Status = status;
     BuildConfigurationGuid = buildConfigurationGuid;
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Creates a new table entry.
 /// </summary>
 /// <param name="name">Name of the Macro function</param>
 /// <param name="hash">Hash of the original binary Macro function code</param>
 /// <param name="length">Size (in bytes) of the original binary Macro function code</param>
 public TableEntry(MacroHLEFunctionName name, Hash128 hash, int length)
 {
     Name   = name;
     Hash   = hash;
     Length = length;
 }
 extern static internal bool GetPVRAtlasHash(int instanceID, out Hash128 atlasHash);
Ejemplo n.º 8
0
 public static string GenCacheTempFilePath(string cacheDirectory, Hash128 key) => Path.Combine(GetCacheTempDataPath(cacheDirectory), key.ToString());
 extern static internal bool GetInstanceHash(Renderer renderer, out Hash128 instanceHash);
 extern static internal bool GetPVRInstanceHash(int instanceID, out Hash128 instanceHash);
 extern static internal bool GetInputSystemHash(int instanceID, out Hash128 inputSystemHash);
 internal static extern float GetGBufferMemory(ref Hash128 gbufferHash);
 internal static extern bool GetGBufferHash(int lightmapIndex, out Hash128 gbufferHash);
 /// <summary>
 ///   <para>Simple versioned constructor. Caches downloaded asset bundles.</para>
 /// </summary>
 /// <param name="url">The nominal (pre-redirect) URL at which the asset bundle is located.</param>
 /// <param name="crc">A checksum to compare to the downloaded data for integrity checking, or zero to skip integrity checking.</param>
 /// <param name="version">Current version number of the asset bundle at url. Increment to redownload.</param>
 public DownloadHandlerAssetBundle(string url, uint version, uint crc)
 {
   Hash128 hash = new Hash128(0U, 0U, 0U, version);
   this.InternalCreateWebStream(url, hash, crc);
 }
 extern static internal bool GetGeometryHash(Renderer renderer, out Hash128 geometryHash);
Ejemplo n.º 16
0
 public Transaction(string guid, int state)
 {
     timestamp  = DateTime.Now.ToBinary();
     this.guid  = Hash128.Parse(guid);
     this.state = state;
 }
Ejemplo n.º 17
0
            public void SetHeaderHash()
            {
                Span <OuterHeader> spanHeader = MemoryMarshal.CreateSpan(ref this, 1);

                HeaderHash = XXHash128.ComputeHash(MemoryMarshal.AsBytes(spanHeader).Slice(0, Unsafe.SizeOf <OuterHeader>() - Unsafe.SizeOf <Hash128>()));
            }
Ejemplo n.º 18
0
 /// <summary>
 ///   <para>Creates a UnityWebRequest optimized for downloading a Unity Asset Bundle via HTTP GET.</para>
 /// </summary>
 /// <param name="uri">The URI of the asset bundle to download.</param>
 /// <param name="crc">If nonzero, this number will be compared to the checksum of the downloaded asset bundle data. If the CRCs do not match, an error will be logged and the asset bundle will not be loaded. If set to zero, CRC checking will be skipped.</param>
 /// <param name="version">An integer version number, which will be compared to the cached version of the asset bundle to download. Increment this number to force Unity to redownload a cached asset bundle.
 ///
 /// Analogous to the version parameter for WWW.LoadFromCacheOrDownload.</param>
 /// <param name="hash">A version hash. If this hash does not match the hash for the cached version of this asset bundle, the asset bundle will be redownloaded.</param>
 /// <returns>
 ///   <para>A UnityWebRequest configured to downloading a Unity Asset Bundle.</para>
 /// </returns>
 public static UnityWebRequest GetAssetBundle(string uri, Hash128 hash, uint crc)
 {
     return(new UnityWebRequest(uri, "GET", new DownloadHandlerAssetBundle(uri, hash, crc), null));
 }
        public TreeViewItem BuildDuplicatesTree(PackedMemorySnapshot snapshot, BuildArgs buildArgs)
        {
            m_Snapshot           = snapshot;
            m_UniqueId           = 1;
            m_NativeObjectsCount = 0;
            m_NativeObjectsSize  = 0;

            var root = new TreeViewItem {
                id = 0, depth = -1, displayName = "Root"
            };

            if (m_Snapshot == null)
            {
                root.AddChild(new TreeViewItem {
                    id = 1, depth = -1, displayName = ""
                });
                return(root);
            }

            var dupesLookup = new Dictionary <Hash128, List <int> >();

            for (int n = 0, nend = m_Snapshot.nativeObjects.Length; n < nend; ++n)
            {
                var no = m_Snapshot.nativeObjects[n];
                if (!no.isPersistent)
                {
                    continue;
                }

                if (!buildArgs.CanAdd(no))
                {
                    continue;
                }

                if (no.nativeTypesArrayIndex == -1)
                {
                    continue;
                }

                var nativeType = m_Snapshot.nativeTypes[no.nativeTypesArrayIndex];
                if (nativeType.managedTypeArrayIndex == -1)
                {
                    continue;
                }

                if (m_Snapshot.IsSubclassOf(m_Snapshot.managedTypes[nativeType.managedTypeArrayIndex], m_Snapshot.coreTypes.unityEngineComponent))
                {
                    continue;
                }

                if (m_Snapshot.IsSubclassOf(m_Snapshot.managedTypes[nativeType.managedTypeArrayIndex], m_Snapshot.coreTypes.unityEngineGameObject))
                {
                    continue;
                }

                var hash = new Hash128((uint)no.nativeTypesArrayIndex, (uint)no.size, (uint)no.name.GetHashCode(), 0);

                List <int> list;
                if (!dupesLookup.TryGetValue(hash, out list))
                {
                    dupesLookup[hash] = list = new List <int>();
                }

                list.Add(n);
            }

            // int=typeIndex
            var groupLookup = new Dictionary <Hash128, GroupItem>();

            foreach (var dupePair in dupesLookup)
            {
                for (int n = 0, nend = dupePair.Value.Count; n < nend; ++n)
                {
                    var list = dupePair.Value;
                    if (list.Count <= 1)
                    {
                        continue;
                    }

                    var no = m_Snapshot.nativeObjects[list[n]];

                    GroupItem group;
                    if (!groupLookup.TryGetValue(dupePair.Key, out group))
                    {
                        group = new GroupItem
                        {
                            id          = m_UniqueId++,
                            depth       = root.depth + 1,
                            displayName = no.name
                        };
                        group.Initialize(m_Snapshot, no.nativeTypesArrayIndex);

                        groupLookup[dupePair.Key] = group;
                        root.AddChild(group);
                    }

                    var item = new NativeObjectItem
                    {
                        id          = m_UniqueId++,
                        depth       = group.depth + 1,
                        displayName = ""
                    };
                    item.Initialize(this, no);

                    m_NativeObjectsCount++;
                    m_NativeObjectsSize += item.size;

                    group.AddChild(item);
                }
            }

            SortItemsRecursive(root, OnSortItem);

            if (!root.hasChildren)
            {
                root.AddChild(new TreeViewItem {
                    id = 1, depth = -1, displayName = ""
                });
            }

            return(root);
        }
Ejemplo n.º 20
0
            public void Append(string value)
            {
                var tempHash = Hash128.Compute(value);

                HashUtilities.AppendHash(ref tempHash, ref m_Hash);
            }
Ejemplo n.º 21
0
        public void SetDataOld(List <ResourceLocationData> locations, List <string> labels)
        {
            var           tmpEntries             = new List <Entry>(locations.Count);
            var           providers              = new List <string>(10);
            var           providerIndices        = new Dictionary <string, int>(10);
            var           countEstimate          = locations.Count * 2 + labels.Count;
            var           internalIdToEntryIndex = new Dictionary <string, int>(countEstimate);
            var           internalIdList         = new List <string>(countEstimate);
            List <object> keys = new List <object>(countEstimate);

            var keyToIndex = new Dictionary <object, int>(countEstimate);
            var tmpBuckets = new Dictionary <int, List <int> >(countEstimate);

            for (int i = 0; i < locations.Count; i++)
            {
                var rld           = locations[i];
                int providerIndex = 0;
                if (!providerIndices.TryGetValue(rld.m_provider, out providerIndex))
                {
                    providerIndices.Add(rld.m_provider, providerIndex = providers.Count);
                    providers.Add(rld.m_provider);
                }

                int internalIdIndex = 0;
                if (!internalIdToEntryIndex.TryGetValue(rld.m_internalId, out internalIdIndex))
                {
                    internalIdToEntryIndex.Add(rld.m_internalId, internalIdIndex = internalIdList.Count);
                    internalIdList.Add(rld.m_internalId);
                }

                var e = new Entry()
                {
                    internalId = internalIdIndex, providerIndex = (byte)providerIndex, dependency = -1
                };
                if (rld.m_type == ResourceLocationData.LocationType.Int)
                {
                    AddToBucket(tmpBuckets, keyToIndex, keys, int.Parse(rld.m_address), tmpEntries.Count, 1);
                }
                else if (rld.m_type == ResourceLocationData.LocationType.String)
                {
                    AddToBucket(tmpBuckets, keyToIndex, keys, rld.m_address, tmpEntries.Count, 1);
                }
                if (!string.IsNullOrEmpty(rld.m_guid))
                {
                    AddToBucket(tmpBuckets, keyToIndex, keys, Hash128.Parse(rld.m_guid), tmpEntries.Count, 1);
                }
                if (rld.m_labelMask != 0)
                {
                    for (int t = 0; t < labels.Count; t++)
                    {
                        if ((rld.m_labelMask & (1 << t)) != 0)
                        {
                            AddToBucket(tmpBuckets, keyToIndex, keys, labels[t], tmpEntries.Count, 100);
                        }
                    }
                }

                tmpEntries.Add(e);
            }

            for (int i = 0; i < locations.Count; i++)
            {
                var rld        = locations[i];
                int dependency = -1;
                if (rld.m_dependencies != null && rld.m_dependencies.Length > 0)
                {
                    if (rld.m_dependencies.Length == 1)
                    {
                        dependency = keyToIndex[rld.m_dependencies[0]];
                    }
                    else
                    {
                        System.Text.StringBuilder sb = new System.Text.StringBuilder();
                        foreach (var d in rld.m_dependencies)
                        {
                            sb.Append(d);
                        }
                        var key      = sb.ToString().GetHashCode();
                        int keyIndex = -1;
                        foreach (var d in rld.m_dependencies)
                        {
                            var ki        = keyToIndex[d];
                            var depBucket = tmpBuckets[ki];
                            keyIndex = AddToBucket(tmpBuckets, keyToIndex, keys, key, depBucket[0], 10);
                        }
                        dependency = keyIndex;
                    }
                    var e = tmpEntries[i];
                    e.dependency  = dependency;
                    tmpEntries[i] = e;
                }
            }

            m_internalIds = internalIdList.ToArray();
            m_providerIds = providers.ToArray();
            var entryData = new byte[tmpEntries.Count * 4 * 3 + 4];
            var offset    = Serialize(entryData, tmpEntries.Count, 0);

            for (int i = 0; i < tmpEntries.Count; i++)
            {
                var e = tmpEntries[i];
                offset = Serialize(entryData, e.internalId, offset);
                offset = Serialize(entryData, e.providerIndex, offset);
                offset = Serialize(entryData, e.dependency, offset);
            }
            m_entryDataString = Convert.ToBase64String(entryData);

            int bucketEntryCount = 0;
            var bucketList       = new List <Bucket>(keys.Count);

            for (int i = 0; i < keys.Count; i++)
            {
                var        bucketIndex = keyToIndex[keys[i]];
                List <int> entries     = tmpBuckets[bucketIndex];
                bucketList.Add(new Bucket()
                {
                    entries = entries.ToArray()
                });
                bucketEntryCount += entries.Count;
            }

            var keyData = new List <byte>(bucketList.Count * 10);

            keyData.AddRange(BitConverter.GetBytes(bucketList.Count));
            int dataOffset = 4;

            for (int i = 0; i < bucketList.Count; i++)
            {
                var bucket = bucketList[i];
                bucket.dataOffset = dataOffset;
                bucketList[i]     = bucket;
                var key = keys[i];
                var kt  = key.GetType();
                if (kt == typeof(string))
                {
                    string str  = key as string;
                    byte[] tmp  = System.Text.Encoding.Unicode.GetBytes(str);
                    byte[] tmp2 = System.Text.Encoding.ASCII.GetBytes(str);
                    if (System.Text.Encoding.Unicode.GetString(tmp) == System.Text.Encoding.ASCII.GetString(tmp2))
                    {
                        keyData.Add((byte)KeyType.ASCIIString);
                        keyData.AddRange(tmp2);
                        dataOffset += tmp2.Length + 1;
                    }
                    else
                    {
                        keyData.Add((byte)KeyType.UnicodeString);
                        keyData.AddRange(tmp);
                        dataOffset += tmp.Length + 1;
                    }
                }
                else if (kt == typeof(UInt32))
                {
                    byte[] tmp = BitConverter.GetBytes((UInt32)key);
                    keyData.Add((byte)KeyType.UInt32);
                    keyData.AddRange(tmp);
                    dataOffset += tmp.Length + 1;
                }
                else if (kt == typeof(UInt16))
                {
                    byte[] tmp = BitConverter.GetBytes((UInt16)key);
                    keyData.Add((byte)KeyType.UInt16);
                    keyData.AddRange(tmp);
                    dataOffset += tmp.Length + 1;
                }
                else if (kt == typeof(Int32))
                {
                    byte[] tmp = BitConverter.GetBytes((Int32)key);
                    keyData.Add((byte)KeyType.Int32);
                    keyData.AddRange(tmp);
                    dataOffset += tmp.Length + 1;
                }
                else if (kt == typeof(int))
                {
                    byte[] tmp = BitConverter.GetBytes((UInt32)key);
                    keyData.Add((byte)KeyType.UInt32);
                    keyData.AddRange(tmp);
                    dataOffset += tmp.Length + 1;
                }
                else if (kt == typeof(Hash128))
                {
                    var    guid = (Hash128)key;
                    byte[] tmp  = System.Text.Encoding.ASCII.GetBytes(guid.ToString());
                    keyData.Add((byte)KeyType.Hash128);
                    keyData.AddRange(tmp);
                    dataOffset += tmp.Length + 1;
                }
            }
            m_keyDataString = Convert.ToBase64String(keyData.ToArray());

            var bucketData = new byte[4 + bucketList.Count * 8 + bucketEntryCount * 4];

            offset = Serialize(bucketData, bucketList.Count, 0);
            for (int i = 0; i < bucketList.Count; i++)
            {
                offset = Serialize(bucketData, bucketList[i].dataOffset, offset);
                offset = Serialize(bucketData, bucketList[i].entries.Length, offset);
                foreach (var e in bucketList[i].entries)
                {
                    offset = Serialize(bucketData, e, offset);
                }
            }
            m_bucketDataString = Convert.ToBase64String(bucketData);

#if SERIALIZE_CATALOG_AS_BINARY
            //TODO: investigate saving catalog as binary - roughly 20% size decrease, still needs a provider implementation
            var stream = new System.IO.MemoryStream();
            var bw     = new System.IO.BinaryWriter(stream);
            foreach (var i in m_internalIds)
            {
                bw.Write(i);
            }
            foreach (var p in m_providerIds)
            {
                bw.Write(p);
            }
            bw.Write(entryData);
            bw.Write(keyData.ToArray());
            bw.Write(bucketData);
            bw.Flush();
            bw.Close();
            stream.Flush();
            System.IO.File.WriteAllBytes("Library/catalog_binary.bytes", stream.ToArray());
            System.IO.File.WriteAllText("Library/catalog_binary.txt", Convert.ToBase64String(stream.ToArray()));
            stream.Close();
#endif
        }
Ejemplo n.º 22
0
 public Transaction(string guid, int state, long timestamp)
     : this(Hash128.Parse(guid), state, timestamp)
 {
 }
        public AssetBundleDownloadRequest(string assetBundleName, string absoluteRootUrl, Hash128 hash) : base(assetBundleName, absoluteRootUrl)
        {
#if UNITY_2018
            m_request = UnityWebRequestAssetBundle.GetAssetBundle(assetBundleUrl, hash, 0);
#else
            m_request = UnityWebRequest.GetAssetBundle(assetBundleUrl, hash, 0);
#endif
            m_request.SendWebRequest();
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Gets a compute shader from the cache.
        /// </summary>
        /// <remarks>
        /// This automatically translates, compiles and adds the code to the cache if not present.
        /// </remarks>
        /// <param name="state">Current GPU state</param>
        /// <param name="gpuVa">GPU virtual address of the binary shader code</param>
        /// <param name="localSizeX">Local group size X of the computer shader</param>
        /// <param name="localSizeY">Local group size Y of the computer shader</param>
        /// <param name="localSizeZ">Local group size Z of the computer shader</param>
        /// <param name="localMemorySize">Local memory size of the compute shader</param>
        /// <param name="sharedMemorySize">Shared memory size of the compute shader</param>
        /// <returns>Compiled compute shader code</returns>
        public ShaderBundle GetComputeShader(
            GpuState state,
            ulong gpuVa,
            int localSizeX,
            int localSizeY,
            int localSizeZ,
            int localMemorySize,
            int sharedMemorySize)
        {
            bool isCached = _cpPrograms.TryGetValue(gpuVa, out List <ShaderBundle> list);

            if (isCached)
            {
                foreach (ShaderBundle cachedCpShader in list)
                {
                    if (IsShaderEqual(cachedCpShader, gpuVa))
                    {
                        return(cachedCpShader);
                    }
                }
            }

            TranslatorContext[] shaderContexts = new TranslatorContext[1];

            shaderContexts[0] = DecodeComputeShader(
                state,
                gpuVa,
                localSizeX,
                localSizeY,
                localSizeZ,
                localMemorySize,
                sharedMemorySize);

            bool isShaderCacheEnabled  = _cacheManager != null;
            bool isShaderCacheReadOnly = false;

            Hash128 programCodeHash = default;

            GuestShaderCacheEntry[] shaderCacheEntries = null;

            // Current shader cache doesn't support bindless textures
            if (shaderContexts[0].UsedFeatures.HasFlag(FeatureFlags.Bindless))
            {
                isShaderCacheEnabled = false;
            }

            if (isShaderCacheEnabled)
            {
                isShaderCacheReadOnly = _cacheManager.IsReadOnly;

                // Compute hash and prepare data for shader disk cache comparison.
                shaderCacheEntries = CacheHelper.CreateShaderCacheEntries(_context.MemoryManager, shaderContexts);
                programCodeHash    = CacheHelper.ComputeGuestHashFromCache(shaderCacheEntries);
            }

            ShaderBundle cpShader;

            // Search for the program hash in loaded shaders.
            if (!isShaderCacheEnabled || !_cpProgramsDiskCache.TryGetValue(programCodeHash, out cpShader))
            {
                if (isShaderCacheEnabled)
                {
                    Logger.Debug?.Print(LogClass.Gpu, $"Shader {programCodeHash} not in cache, compiling!");
                }

                // The shader isn't currently cached, translate it and compile it.
                ShaderCodeHolder shader = TranslateShader(shaderContexts[0]);

                shader.HostShader = _context.Renderer.CompileShader(ShaderStage.Compute, shader.Program.Code);

                IProgram hostProgram = _context.Renderer.CreateProgram(new IShader[] { shader.HostShader }, null);

                hostProgram.CheckProgramLink(true);

                byte[] hostProgramBinary = HostShaderCacheEntry.Create(hostProgram.GetBinary(), new ShaderCodeHolder[] { shader });

                cpShader = new ShaderBundle(hostProgram, shader);

                if (isShaderCacheEnabled)
                {
                    _cpProgramsDiskCache.Add(programCodeHash, cpShader);

                    if (!isShaderCacheReadOnly)
                    {
                        _cacheManager.SaveProgram(ref programCodeHash, CacheHelper.CreateGuestProgramDump(shaderCacheEntries), hostProgramBinary);
                    }
                }
            }

            if (!isCached)
            {
                list = new List <ShaderBundle>();

                _cpPrograms.Add(gpuVa, list);
            }

            list.Add(cpShader);

            return(cpShader);
        }
Ejemplo n.º 25
0
 /// <summary>
 /// Add a host shader program not present in the program cache.
 /// </summary>
 /// <param name="programCodeHash">Target program code hash</param>
 /// <param name="data">Host program raw data</param>
 public void AddHostProgram(ref Hash128 programCodeHash, byte[] data)
 {
     _hostProgramCache.AddValue(ref programCodeHash, data);
 }
Ejemplo n.º 26
0
        /// <summary>
        /// Initialize the cache.
        /// </summary>
        internal void Initialize()
        {
            if (GraphicsConfig.EnableShaderCache && GraphicsConfig.TitleId != null)
            {
                _cacheManager = new CacheManager(CacheGraphicsApi.OpenGL, CacheHashType.XxHash128, "glsl", GraphicsConfig.TitleId, ShaderCodeGenVersion);

                bool isReadOnly = _cacheManager.IsReadOnly;

                HashSet <Hash128> invalidEntries = null;

                if (isReadOnly)
                {
                    Logger.Warning?.Print(LogClass.Gpu, "Loading shader cache in read-only mode (cache in use by another program!)");
                }
                else
                {
                    invalidEntries = new HashSet <Hash128>();
                }

                ReadOnlySpan <Hash128> guestProgramList = _cacheManager.GetGuestProgramList();

                using AutoResetEvent progressReportEvent = new AutoResetEvent(false);

                _shaderCount      = 0;
                _totalShaderCount = guestProgramList.Length;

                ShaderCacheStateChanged?.Invoke(ShaderCacheState.Start, _shaderCount, _totalShaderCount);
                Thread progressReportThread = null;

                if (guestProgramList.Length > 0)
                {
                    progressReportThread = new Thread(ReportProgress)
                    {
                        Name         = "ShaderCache.ProgressReporter",
                        Priority     = ThreadPriority.Lowest,
                        IsBackground = true
                    };

                    progressReportThread.Start(progressReportEvent);
                }

                // Make sure these are initialized before doing compilation.
                Capabilities caps = _context.Capabilities;

                int maxTaskCount = Math.Min(Environment.ProcessorCount, 8);
                int programIndex = 0;
                List <ShaderCompileTask> activeTasks = new List <ShaderCompileTask>();

                AutoResetEvent taskDoneEvent = new AutoResetEvent(false);

                // This thread dispatches tasks to do shader translation, and creates programs that OpenGL will link in the background.
                // The program link status is checked in a non-blocking manner so that multiple shaders can be compiled at once.

                while (programIndex < guestProgramList.Length || activeTasks.Count > 0)
                {
                    if (activeTasks.Count < maxTaskCount && programIndex < guestProgramList.Length)
                    {
                        // Begin a new shader compilation.
                        Hash128 key = guestProgramList[programIndex];

                        byte[] hostProgramBinary = _cacheManager.GetHostProgramByHash(ref key);
                        bool   hasHostCache      = hostProgramBinary != null;

                        IProgram hostProgram = null;

                        // If the program sources aren't in the cache, compile from saved guest program.
                        byte[] guestProgram = _cacheManager.GetGuestProgramByHash(ref key);

                        if (guestProgram == null)
                        {
                            Logger.Error?.Print(LogClass.Gpu, $"Ignoring orphan shader hash {key} in cache (is the cache incomplete?)");

                            // Should not happen, but if someone messed with the cache it's better to catch it.
                            invalidEntries?.Add(key);

                            _shaderCount = ++programIndex;

                            continue;
                        }

                        ReadOnlySpan <byte> guestProgramReadOnlySpan = guestProgram;

                        ReadOnlySpan <GuestShaderCacheEntry> cachedShaderEntries = GuestShaderCacheEntry.Parse(ref guestProgramReadOnlySpan, out GuestShaderCacheHeader fileHeader);

                        if (cachedShaderEntries[0].Header.Stage == ShaderStage.Compute)
                        {
                            Debug.Assert(cachedShaderEntries.Length == 1);

                            GuestShaderCacheEntry entry = cachedShaderEntries[0];

                            HostShaderCacheEntry[] hostShaderEntries = null;

                            // Try loading host shader binary.
                            if (hasHostCache)
                            {
                                hostShaderEntries = HostShaderCacheEntry.Parse(hostProgramBinary, out ReadOnlySpan <byte> hostProgramBinarySpan);
                                hostProgramBinary = hostProgramBinarySpan.ToArray();
                                hostProgram       = _context.Renderer.LoadProgramBinary(hostProgramBinary);
                            }

                            ShaderCompileTask task = new ShaderCompileTask(taskDoneEvent);
                            activeTasks.Add(task);

                            task.OnCompiled(hostProgram, (bool isHostProgramValid, ShaderCompileTask task) =>
                            {
                                ShaderProgram program = null;
                                ShaderProgramInfo shaderProgramInfo = null;

                                if (isHostProgramValid)
                                {
                                    // Reconstruct code holder.

                                    program           = new ShaderProgram(entry.Header.Stage, "");
                                    shaderProgramInfo = hostShaderEntries[0].ToShaderProgramInfo();

                                    ShaderCodeHolder shader = new ShaderCodeHolder(program, shaderProgramInfo, entry.Code);

                                    _cpProgramsDiskCache.Add(key, new ShaderBundle(hostProgram, shader));

                                    return(true);
                                }
                                else
                                {
                                    // If the host program was rejected by the gpu driver or isn't in cache, try to build from program sources again.

                                    Task compileTask = Task.Run(() =>
                                    {
                                        IGpuAccessor gpuAccessor = new CachedGpuAccessor(_context, entry.Code, entry.Header.GpuAccessorHeader, entry.TextureDescriptors);

                                        program = Translator.CreateContext(0, gpuAccessor, DefaultFlags | TranslationFlags.Compute).Translate(out shaderProgramInfo);
                                    });

                                    task.OnTask(compileTask, (bool _, ShaderCompileTask task) =>
                                    {
                                        ShaderCodeHolder shader = new ShaderCodeHolder(program, shaderProgramInfo, entry.Code);

                                        Logger.Info?.Print(LogClass.Gpu, $"Host shader {key} got invalidated, rebuilding from guest...");

                                        // Compile shader and create program as the shader program binary got invalidated.
                                        shader.HostShader = _context.Renderer.CompileShader(ShaderStage.Compute, shader.Program.Code);
                                        hostProgram       = _context.Renderer.CreateProgram(new IShader[] { shader.HostShader }, null);

                                        task.OnCompiled(hostProgram, (bool isNewProgramValid, ShaderCompileTask task) =>
                                        {
                                            // As the host program was invalidated, save the new entry in the cache.
                                            hostProgramBinary = HostShaderCacheEntry.Create(hostProgram.GetBinary(), new ShaderCodeHolder[] { shader });

                                            if (!isReadOnly)
                                            {
                                                if (hasHostCache)
                                                {
                                                    _cacheManager.ReplaceHostProgram(ref key, hostProgramBinary);
                                                }
                                                else
                                                {
                                                    Logger.Warning?.Print(LogClass.Gpu, $"Add missing host shader {key} in cache (is the cache incomplete?)");

                                                    _cacheManager.AddHostProgram(ref key, hostProgramBinary);
                                                }
                                            }

                                            _cpProgramsDiskCache.Add(key, new ShaderBundle(hostProgram, shader));

                                            return(true);
                                        });

                                        return(false); // Not finished: still need to compile the host program.
                                    });

                                    return(false); // Not finished: translating the program.
                                }
                            });
                        }
                        else
                        {
                            Debug.Assert(cachedShaderEntries.Length == Constants.ShaderStages);

                            ShaderCodeHolder[]   shaders        = new ShaderCodeHolder[cachedShaderEntries.Length];
                            List <ShaderProgram> shaderPrograms = new List <ShaderProgram>();

                            TransformFeedbackDescriptor[] tfd = CacheHelper.ReadTransformFeedbackInformation(ref guestProgramReadOnlySpan, fileHeader);

                            TranslationFlags flags = DefaultFlags;

                            if (tfd != null)
                            {
                                flags |= TranslationFlags.Feedback;
                            }

                            TranslationCounts counts = new TranslationCounts();

                            HostShaderCacheEntry[] hostShaderEntries = null;

                            // Try loading host shader binary.
                            if (hasHostCache)
                            {
                                hostShaderEntries = HostShaderCacheEntry.Parse(hostProgramBinary, out ReadOnlySpan <byte> hostProgramBinarySpan);
                                hostProgramBinary = hostProgramBinarySpan.ToArray();
                                hostProgram       = _context.Renderer.LoadProgramBinary(hostProgramBinary);
                            }

                            ShaderCompileTask task = new ShaderCompileTask(taskDoneEvent);
                            activeTasks.Add(task);

                            GuestShaderCacheEntry[] entries = cachedShaderEntries.ToArray();

                            task.OnCompiled(hostProgram, (bool isHostProgramValid, ShaderCompileTask task) =>
                            {
                                Task compileTask = Task.Run(() =>
                                {
                                    // Reconstruct code holder.
                                    for (int i = 0; i < entries.Length; i++)
                                    {
                                        GuestShaderCacheEntry entry = entries[i];

                                        if (entry == null)
                                        {
                                            continue;
                                        }

                                        ShaderProgram program;

                                        if (entry.Header.SizeA != 0)
                                        {
                                            ShaderProgramInfo shaderProgramInfo;

                                            if (isHostProgramValid)
                                            {
                                                program           = new ShaderProgram(entry.Header.Stage, "");
                                                shaderProgramInfo = hostShaderEntries[i].ToShaderProgramInfo();
                                            }
                                            else
                                            {
                                                IGpuAccessor gpuAccessor = new CachedGpuAccessor(_context, entry.Code, entry.Header.GpuAccessorHeader, entry.TextureDescriptors);

                                                TranslatorContext translatorContext  = Translator.CreateContext(0, gpuAccessor, flags, counts);
                                                TranslatorContext translatorContext2 = Translator.CreateContext((ulong)entry.Header.Size, gpuAccessor, flags | TranslationFlags.VertexA, counts);

                                                program = translatorContext.Translate(out shaderProgramInfo, translatorContext2);
                                            }

                                            // NOTE: Vertex B comes first in the shader cache.
                                            byte[] code  = entry.Code.AsSpan().Slice(0, entry.Header.Size).ToArray();
                                            byte[] code2 = entry.Code.AsSpan().Slice(entry.Header.Size, entry.Header.SizeA).ToArray();

                                            shaders[i] = new ShaderCodeHolder(program, shaderProgramInfo, code, code2);
                                        }
                                        else
                                        {
                                            ShaderProgramInfo shaderProgramInfo;

                                            if (isHostProgramValid)
                                            {
                                                program           = new ShaderProgram(entry.Header.Stage, "");
                                                shaderProgramInfo = hostShaderEntries[i].ToShaderProgramInfo();
                                            }
                                            else
                                            {
                                                IGpuAccessor gpuAccessor = new CachedGpuAccessor(_context, entry.Code, entry.Header.GpuAccessorHeader, entry.TextureDescriptors);

                                                program = Translator.CreateContext(0, gpuAccessor, flags, counts).Translate(out shaderProgramInfo);
                                            }

                                            shaders[i] = new ShaderCodeHolder(program, shaderProgramInfo, entry.Code);
                                        }

                                        shaderPrograms.Add(program);
                                    }
                                });

                                task.OnTask(compileTask, (bool _, ShaderCompileTask task) =>
                                {
                                    // If the host program was rejected by the gpu driver or isn't in cache, try to build from program sources again.
                                    if (!isHostProgramValid)
                                    {
                                        Logger.Info?.Print(LogClass.Gpu, $"Host shader {key} got invalidated, rebuilding from guest...");

                                        List <IShader> hostShaders = new List <IShader>();

                                        // Compile shaders and create program as the shader program binary got invalidated.
                                        for (int stage = 0; stage < Constants.ShaderStages; stage++)
                                        {
                                            ShaderProgram program = shaders[stage]?.Program;

                                            if (program == null)
                                            {
                                                continue;
                                            }

                                            IShader hostShader = _context.Renderer.CompileShader(program.Stage, program.Code);

                                            shaders[stage].HostShader = hostShader;

                                            hostShaders.Add(hostShader);
                                        }

                                        hostProgram = _context.Renderer.CreateProgram(hostShaders.ToArray(), tfd);

                                        task.OnCompiled(hostProgram, (bool isNewProgramValid, ShaderCompileTask task) =>
                                        {
                                            // As the host program was invalidated, save the new entry in the cache.
                                            hostProgramBinary = HostShaderCacheEntry.Create(hostProgram.GetBinary(), shaders);

                                            if (!isReadOnly)
                                            {
                                                if (hasHostCache)
                                                {
                                                    _cacheManager.ReplaceHostProgram(ref key, hostProgramBinary);
                                                }
                                                else
                                                {
                                                    Logger.Warning?.Print(LogClass.Gpu, $"Add missing host shader {key} in cache (is the cache incomplete?)");

                                                    _cacheManager.AddHostProgram(ref key, hostProgramBinary);
                                                }
                                            }

                                            _gpProgramsDiskCache.Add(key, new ShaderBundle(hostProgram, shaders));

                                            return(true);
                                        });

                                        return(false); // Not finished: still need to compile the host program.
                                    }
                                    else
                                    {
                                        _gpProgramsDiskCache.Add(key, new ShaderBundle(hostProgram, shaders));

                                        return(true);
                                    }
                                });

                                return(false); // Not finished: translating the program.
                            });
                        }

                        _shaderCount = ++programIndex;
                    }

                    // Process the queue.
                    for (int i = 0; i < activeTasks.Count; i++)
                    {
                        ShaderCompileTask task = activeTasks[i];

                        if (task.IsDone())
                        {
                            activeTasks.RemoveAt(i--);
                        }
                    }

                    if (activeTasks.Count == maxTaskCount)
                    {
                        // Wait for a task to be done, or for 1ms.
                        // Host shader compilation cannot signal when it is done,
                        // so the 1ms timeout is required to poll status.

                        taskDoneEvent.WaitOne(1);
                    }
                }

                if (!isReadOnly)
                {
                    // Remove entries that are broken in the cache
                    _cacheManager.RemoveManifestEntries(invalidEntries);
                    _cacheManager.FlushToArchive();
                    _cacheManager.Synchronize();
                }

                progressReportEvent.Set();
                progressReportThread?.Join();

                ShaderCacheStateChanged?.Invoke(ShaderCacheState.Loaded, _shaderCount, _totalShaderCount);

                Logger.Info?.Print(LogClass.Gpu, $"Shader cache loaded {_shaderCount} entries.");
            }
        }
Ejemplo n.º 27
0
 /// <summary>
 /// Replace a host shader program present in the program cache.
 /// </summary>
 /// <param name="programCodeHash">Target program code hash</param>
 /// <param name="data">Host program raw data</param>
 public void ReplaceHostProgram(ref Hash128 programCodeHash, byte[] data)
 {
     _hostProgramCache.ReplaceValue(ref programCodeHash, data);
 }
Ejemplo n.º 28
0
 public void SetGlobalHash(Hash128 hash)
 {
     m_GlobalHash = hash;
 }
Ejemplo n.º 29
0
 /// <summary>
 /// Get a guest program by hash.
 /// </summary>
 /// <param name="hash">The given hash</param>
 /// <returns>The guest program if present or null</returns>
 public byte[] GetGuestProgramByHash(ref Hash128 hash)
 {
     return(_guestProgramCache.GetValueRaw(ref hash));
 }
Ejemplo n.º 30
0
    public T LoadResource <T>(string resName, string resPath, string resType, string exResPath = "", bool isInstantiate = false, bool isForever = false) where T : UnityEngine.Object
    {
        if (string.IsNullOrEmpty(resName))
        {
            return(null);
        }

        if (string.IsNullOrEmpty(resPath) && !string.IsNullOrEmpty(exResPath))
        {
            int index = exResPath.IndexOf('/');
            resPath = exResPath.Substring(0, (index == -1 ? exResPath.Length : index));
        }

        UnityEngine.Object tempObject = C_MonoSingleton <C_PoolMgr> .GetInstance().Spawn(resName, resType);

        if (tempObject != null)
        {
            return(tempObject as T);
        }

        //关卡a是内置资源包,需要使用内置资源
        if (GameConfig.LocalResources == 0)
        {
            string assetBundleName     = GetAssetBundleName(resName, resPath, resType, exResPath);
            string assetBundleFilePath = GetAssetBundleFilePath(assetBundleName);

            T temp1 = C_ResMgr.GetAssetBundleFormCache <T>(resName, assetBundleFilePath, isInstantiate, isForever);
            if (temp1 != null)
            {
                return(temp1);
            }

            if (m_AssetBundleManifest != null && Hash128.Parse("0") != m_AssetBundleManifest.GetAssetBundleHash(assetBundleName))
            {
                List <string> dpsList = new List <string>();

                if (!resName.Contains(".ogg"))
                {
                    dpsList = GetAllDependencies(assetBundleName);
                }
                //Debug.LogError("load bundle"+resName);
                T temp2 = C_ResMgr.LoadAssetBundle <T>(resName, assetBundleFilePath, dpsList, isInstantiate, isForever);
                if (temp2 != null)
                {
                    return(temp2);
                }
            }
        }

        string resourcePath = "";

        if (string.IsNullOrEmpty(exResPath))
        {
            resourcePath = "PackagingResources/" + resPath + "/" + resType + "/";
        }
        else
        {
            resourcePath = "PackagingResources/" + exResPath;
        }

        T resObject = C_ResMgr.LoadResource <T>(resName, resourcePath);

        if (isInstantiate && resObject != null)
        {
            resObject = GameObject.Instantiate(resObject);
        }

        if (resObject == null)
        {
            C_DebugHelper.LogError("-----------------------------------resName = " + resName + ", exResPath = " + exResPath + ", is null");
        }

        return(resObject);
    }
Ejemplo n.º 31
0
 /// <summary>
 /// Save a shader program not present in the program cache.
 /// </summary>
 /// <param name="programCodeHash">Target program code hash</param>
 /// <param name="guestProgram">Guest program raw data</param>
 /// <param name="hostProgram">Host program raw data</param>
 public void SaveProgram(ref Hash128 programCodeHash, byte[] guestProgram, byte[] hostProgram)
 {
     _guestProgramCache.AddValue(ref programCodeHash, guestProgram);
     _hostProgramCache.AddValue(ref programCodeHash, hostProgram);
 }
 /// <summary>
 ///   <para>Versioned constructor. Caches downloaded asset bundles.</para>
 /// </summary>
 /// <param name="url">The nominal (pre-redirect) URL at which the asset bundle is located.</param>
 /// <param name="crc">A checksum to compare to the downloaded data for integrity checking, or zero to skip integrity checking.</param>
 /// <param name="hash">A hash object defining the version of the asset bundle.</param>
 public DownloadHandlerAssetBundle(string url, Hash128 hash, uint crc)
 {
   this.InternalCreateWebStream(url, hash, crc);
 }
Ejemplo n.º 33
0
 /// <summary>
 ///   <para>Creates a UnityWebRequest optimized for downloading a Unity Asset Bundle via HTTP GET.</para>
 /// </summary>
 /// <param name="uri">The URI of the asset bundle to download.</param>
 /// <param name="crc">If nonzero, this number will be compared to the checksum of the downloaded asset bundle data. If the CRCs do not match, an error will be logged and the asset bundle will not be loaded. If set to zero, CRC checking will be skipped.</param>
 /// <param name="version">An integer version number, which will be compared to the cached version of the asset bundle to download. Increment this number to force Unity to redownload a cached asset bundle.
 /// 
 /// Analogous to the version parameter for WWW.LoadFromCacheOrDownload.</param>
 /// <param name="hash">A version hash. If this hash does not match the hash for the cached version of this asset bundle, the asset bundle will be redownloaded.</param>
 /// <returns>
 ///   <para>A UnityWebRequest configured to downloading a Unity Asset Bundle.</para>
 /// </returns>
 public static UnityWebRequest GetAssetBundle(string uri, Hash128 hash, uint crc)
 {
   return new UnityWebRequest(uri, "GET", (DownloadHandler) new DownloadHandlerAssetBundle(uri, hash, crc), (UploadHandler) null);
 }