protected override void OnUpdate() { var simpleMeshContext = new BlobAssetComputationContext <UMeshSettings, SimpleMeshData>(BlobAssetStore, 128, Allocator.Temp); var litMeshContext = new BlobAssetComputationContext <UMeshSettings, LitMeshData>(BlobAssetStore, 128, Allocator.Temp); JobHandle combinedJH = new JobHandle(); int simpleIndex = 0; int litIndex = 0; // Init blobasset arrays Entities.ForEach((UnityEngine.Mesh uMesh) => { CheckForMeshLimitations(uMesh); var entity = GetPrimaryEntity(uMesh); if (DstEntityManager.HasComponent <SimpleMeshRenderData>(entity)) { simpleIndex++; } if (DstEntityManager.HasComponent <LitMeshRenderData>(entity)) { litIndex++; } }); NativeArray <BlobAssetReference <SimpleMeshData> > simpleblobs = new NativeArray <BlobAssetReference <SimpleMeshData> >(simpleIndex, Allocator.TempJob); NativeArray <BlobAssetReference <LitMeshData> > litblobs = new NativeArray <BlobAssetReference <LitMeshData> >(litIndex, Allocator.TempJob); simpleIndex = 0; litIndex = 0; // Check which blob assets to re-compute Entities.ForEach((UnityEngine.Mesh uMesh) => { var hash = new Hash128((uint)uMesh.GetHashCode(), (uint)uMesh.vertexCount.GetHashCode(), (uint)uMesh.subMeshCount.GetHashCode(), 0); var entity = GetPrimaryEntity(uMesh); //Schedule blob asset recomputation jobs if (DstEntityManager.HasComponent <SimpleMeshRenderData>(entity)) { simpleMeshContext.AssociateBlobAssetWithUnityObject(hash, uMesh); if (simpleMeshContext.NeedToComputeBlobAsset(hash)) { var singleMeshData = new UMeshDataCache(); singleMeshData.RetrieveSimpleMeshData(uMesh); UMeshSettings uMeshSettings = new UMeshSettings(hash, uMesh, simpleIndex++); simpleMeshContext.AddBlobAssetToCompute(hash, uMeshSettings); var job = new SimpleMeshConversionJob(uMeshSettings, singleMeshData, simpleblobs); combinedJH = JobHandle.CombineDependencies(combinedJH, job.Schedule(combinedJH)); } } if (DstEntityManager.HasComponent <LitMeshRenderData>(entity)) { litMeshContext.AssociateBlobAssetWithUnityObject(hash, uMesh); if (litMeshContext.NeedToComputeBlobAsset(hash)) { var litMeshData = new UMeshDataCache(); if (DstEntityManager.HasComponent <NeedGenerateGPUSkinnedMeshRenderer>(entity)) { litMeshData.RetrieveLitSkinnedMeshData(uMesh, entity, DstEntityManager); } else { litMeshData.RetrieveLitMeshData(uMesh); } UMeshSettings uMeshSettings = new UMeshSettings(hash, uMesh, litIndex++); litMeshContext.AddBlobAssetToCompute(hash, uMeshSettings); var job = new LitMeshConversionJob(uMeshSettings, litMeshData, litblobs); combinedJH = JobHandle.CombineDependencies(combinedJH, job.Schedule(combinedJH)); } } }); // Re-compute the new blob assets combinedJH.Complete(); // Update the BlobAssetStore using (var simpleMeshSettings = simpleMeshContext.GetSettings(Allocator.TempJob)) { for (int i = 0; i < simpleMeshSettings.Length; i++) { simpleMeshContext.AddComputedBlobAsset(simpleMeshSettings[i].hash, simpleblobs[simpleMeshSettings[i].blobIndex]); } } using (var litMeshSettings = litMeshContext.GetSettings(Allocator.TempJob)) { for (int i = 0; i < litMeshSettings.Length; i++) { litMeshContext.AddComputedBlobAsset(litMeshSettings[i].hash, litblobs[litMeshSettings[i].blobIndex]); } } // Use blob assets in the conversion Entities.ForEach((UnityEngine.Mesh uMesh) => { var entity = GetPrimaryEntity(uMesh); bool addBounds = false; if (DstEntityManager.HasComponent <SimpleMeshRenderData>(entity)) { simpleMeshContext.GetBlobAsset(new Hash128((uint)uMesh.GetHashCode(), (uint)uMesh.vertexCount.GetHashCode(), (uint)uMesh.subMeshCount.GetHashCode(), 0), out var blob); DstEntityManager.AddComponentData(entity, new SimpleMeshRenderData() { Mesh = blob }); addBounds = true; } if (DstEntityManager.HasComponent <LitMeshRenderData>(entity)) { litMeshContext.GetBlobAsset(new Hash128((uint)uMesh.GetHashCode(), (uint)uMesh.vertexCount.GetHashCode(), (uint)uMesh.subMeshCount.GetHashCode(), 0), out var blob); DstEntityManager.AddComponentData(entity, new LitMeshRenderData() { Mesh = blob }); addBounds = true; } if (addBounds) { DstEntityManager.AddComponentData(entity, new MeshBounds { Bounds = new AABB { Center = uMesh.bounds.center, Extents = uMesh.bounds.extents } }); } }); simpleMeshContext.Dispose(); litMeshContext.Dispose(); simpleblobs.Dispose(); litblobs.Dispose(); }
protected override void OnUpdate() { if (GetEntityQuery(ComponentType.ReadOnly <UnityEngine.Shader>()).CalculateEntityCount() == 0) { return; } if (!TryGetBuildConfigurationComponent <DotsRuntimeBuildProfile>(out var profile)) { return; } bool includeAllPlatform = false; if (TryGetBuildConfigurationComponent <TinyShaderSettings>(out var shaderSettings)) { includeAllPlatform = shaderSettings.PackageShadersForAllPlatforms; } var platforms = ShaderCompilerClient.GetSupportedPlatforms(profile.Target, includeAllPlatform); var context = new BlobAssetComputationContext <ShaderSettings, PrecompiledShaderPipeline>(BlobAssetStore, 128, Allocator.Temp); Entities.ForEach((UnityEngine.Shader uShader) => { if (MaterialConversion.GetMaterialType(uShader) != MaterialConversion.SupportedMaterialType.Custom) { return; } var entity = GetPrimaryEntity(uShader); // Note: all shader stages are in a single source file string filepath = Path.GetFullPath(AssetDatabase.GetAssetPath(uShader)); if (!File.Exists(filepath)) { throw new InvalidDataException($"Could not open shader file '{filepath}'"); } string shaderSrc = File.ReadAllText(filepath); if (m_Client == null) { InitShaderCompiler(); } m_Client.Preprocess(shaderSrc, filepath, uShader.name, out string hlslSrc, out int startLine, out uint[] includeHash); Hash128 includeHash128 = new Hash128(includeHash[0], includeHash[1], includeHash[2], includeHash[3]); Hash128 hash = new Hash128(); unsafe { fixed(char *p = shaderSrc) { UnityEngine.HashUnsafeUtilities.ComputeHash128(p, (ulong)shaderSrc.Length, &hash); UnityEngine.HashUtilities.AppendHash(ref includeHash128, ref hash); } } context.AssociateBlobAssetWithUnityObject(hash, uShader); if (context.NeedToComputeBlobAsset(hash)) { context.AddBlobAssetToCompute(hash, default); var blobAsset = m_Client.CompileShaderForPlatforms(hlslSrc, platforms, filepath, startLine, uShader.name); if (!blobAsset.IsCreated) { return; } context.AddComputedBlobAsset(hash, blobAsset); } context.GetBlobAsset(hash, out var shaderBlob); DstEntityManager.AddComponentData(entity, new CustomShader { Status = ShaderStatus.Invalid, Name = Path.GetFileNameWithoutExtension(filepath) }); DstEntityManager.AddComponentData(entity, new ShaderBinData { shaders = shaderBlob }); }); ShutdownShaderCompiler(); context.Dispose(); }
protected override void OnUpdate() { var simpleMeshContext = new BlobAssetComputationContext <UMeshSettings, SimpleMeshData>(BlobAssetStore, 128, Allocator.Temp); var litMeshContext = new BlobAssetComputationContext <UMeshSettings, LitMeshData>(BlobAssetStore, 128, Allocator.Temp); var blendShapeContext = new BlobAssetComputationContext <UMeshSettings, BlendShapeData>(BlobAssetStore, 128, Allocator.Temp); var skinnedMeshContext = new BlobAssetComputationContext <UMeshSettings, SkinnedMeshData>(BlobAssetStore, 128, Allocator.Temp); JobHandle combinedJH = new JobHandle(); int simpleIndex = 0; int litIndex = 0; int blendShapeIndex = 0; int skinnedMeshIndex = 0; // Init blobasset arrays Entities.ForEach((UnityEngine.Mesh uMesh) => { CheckForMeshLimitations(uMesh); var entity = GetPrimaryEntity(uMesh); if (DstEntityManager.HasComponent <SimpleMeshRenderData>(entity)) { simpleIndex++; } if (DstEntityManager.HasComponent <LitMeshRenderData>(entity)) { litIndex++; } if (uMesh.blendShapeCount > 0) { blendShapeIndex++; } if (uMesh.boneWeights.Length > 0) { skinnedMeshIndex++; } }); NativeArray <BlobAssetReference <SimpleMeshData> > simpleblobs = new NativeArray <BlobAssetReference <SimpleMeshData> >(simpleIndex, Allocator.TempJob); NativeArray <BlobAssetReference <LitMeshData> > litblobs = new NativeArray <BlobAssetReference <LitMeshData> >(litIndex, Allocator.TempJob); NativeArray <BlobAssetReference <BlendShapeData> > blendshapeblobs = new NativeArray <BlobAssetReference <BlendShapeData> >(blendShapeIndex, Allocator.TempJob); NativeArray <BlobAssetReference <SkinnedMeshData> > skinnedMeshBlobs = new NativeArray <BlobAssetReference <SkinnedMeshData> >(litIndex, Allocator.TempJob); simpleIndex = 0; litIndex = 0; blendShapeIndex = 0; skinnedMeshIndex = 0; // Check which blob assets to re-compute Entities.ForEach((UnityEngine.Mesh uMesh) => { var verticesHash = new Hash128((uint)uMesh.GetHashCode(), (uint)uMesh.vertexCount.GetHashCode(), (uint)uMesh.subMeshCount.GetHashCode(), 0); uint boneCount = (uint)uMesh.bindposes.Length; var skinnedDataHash = new Hash128((uint)uMesh.GetHashCode(), (uint)uMesh.vertexCount.GetHashCode(), (uint)uMesh.subMeshCount.GetHashCode(), (uint)boneCount.GetHashCode()); var entity = GetPrimaryEntity(uMesh); //Schedule blob asset recomputation jobs if (DstEntityManager.HasComponent <SimpleMeshRenderData>(entity)) { simpleMeshContext.AssociateBlobAssetWithUnityObject(verticesHash, uMesh); if (simpleMeshContext.NeedToComputeBlobAsset(verticesHash)) { var simpleMeshData = new UMeshDataCache(); if (boneCount > 0) { simpleMeshData.RetrieveSkinnedMeshData(uMesh, entity, DstEntityManager, false); if (skinnedMeshContext.NeedToComputeBlobAsset(skinnedDataHash)) { UMeshSettings uSkinnedMeshSettings = new UMeshSettings(skinnedDataHash, uMesh, skinnedMeshIndex++); skinnedMeshContext.AddBlobAssetToCompute(skinnedDataHash, uSkinnedMeshSettings); var skinningJob = new SkinningDataConversionJob(simpleMeshData, uSkinnedMeshSettings.blobIndex, skinnedMeshBlobs); combinedJH = JobHandle.CombineDependencies(combinedJH, skinningJob.Schedule(combinedJH)); } } else { simpleMeshData.RetrieveSimpleMeshData(uMesh); } UMeshSettings uMeshSettings = new UMeshSettings(verticesHash, uMesh, simpleIndex++); simpleMeshContext.AddBlobAssetToCompute(verticesHash, uMeshSettings); var job = new SimpleMeshConversionJob(simpleMeshData, uMeshSettings.blobIndex, simpleblobs); combinedJH = JobHandle.CombineDependencies(combinedJH, job.Schedule(combinedJH)); } } if (DstEntityManager.HasComponent <LitMeshRenderData>(entity)) { litMeshContext.AssociateBlobAssetWithUnityObject(verticesHash, uMesh); if (litMeshContext.NeedToComputeBlobAsset(verticesHash)) { var litMeshData = new UMeshDataCache(); if (boneCount > 0) { litMeshData.RetrieveSkinnedMeshData(uMesh, entity, DstEntityManager, true); if (skinnedMeshContext.NeedToComputeBlobAsset(skinnedDataHash)) { UMeshSettings uSkinnedMeshSettings = new UMeshSettings(skinnedDataHash, uMesh, skinnedMeshIndex++); skinnedMeshContext.AddBlobAssetToCompute(skinnedDataHash, uSkinnedMeshSettings); var skinningJob = new SkinningDataConversionJob(litMeshData, uSkinnedMeshSettings.blobIndex, skinnedMeshBlobs); combinedJH = JobHandle.CombineDependencies(combinedJH, skinningJob.Schedule(combinedJH)); } } else { litMeshData.RetrieveLitMeshData(uMesh); } UMeshSettings uMeshSettings = new UMeshSettings(verticesHash, uMesh, litIndex++); litMeshContext.AddBlobAssetToCompute(verticesHash, uMeshSettings); var job = new LitMeshConversionJob(litMeshData, uMeshSettings.blobIndex, litblobs); combinedJH = JobHandle.CombineDependencies(combinedJH, job.Schedule(combinedJH)); } } if (uMesh.blendShapeCount > 0) { verticesHash = new Hash128((uint)uMesh.GetHashCode(), (uint)uMesh.vertexCount.GetHashCode(), (uint)uMesh.subMeshCount.GetHashCode(), (uint)uMesh.blendShapeCount); blendShapeContext.AssociateBlobAssetWithUnityObject(verticesHash, uMesh); if (blendShapeContext.NeedToComputeBlobAsset(verticesHash)) { var blendShapeDataCache = new UBlendShapeDataCache(); blendShapeDataCache.RetrieveBlendShapeData(uMesh); UMeshSettings uMeshSettings = new UMeshSettings(verticesHash, uMesh, blendShapeIndex++); blendShapeContext.AddBlobAssetToCompute(verticesHash, uMeshSettings); var job = new BlendShapeConversionJob(uMeshSettings, blendShapeDataCache, blendshapeblobs); combinedJH = JobHandle.CombineDependencies(combinedJH, job.Schedule(combinedJH)); } } }); // Re-compute the new blob assets combinedJH.Complete(); // Update the BlobAssetStore using (var simpleMeshSettings = simpleMeshContext.GetSettings(Allocator.TempJob)) { for (int i = 0; i < simpleMeshSettings.Length; i++) { simpleMeshContext.AddComputedBlobAsset(simpleMeshSettings[i].hash, simpleblobs[simpleMeshSettings[i].blobIndex]); } } using (var litMeshSettings = litMeshContext.GetSettings(Allocator.TempJob)) { for (int i = 0; i < litMeshSettings.Length; i++) { litMeshContext.AddComputedBlobAsset(litMeshSettings[i].hash, litblobs[litMeshSettings[i].blobIndex]); } } using (var meshSettings = blendShapeContext.GetSettings(Allocator.TempJob)) { for (int i = 0; i < meshSettings.Length; i++) { blendShapeContext.AddComputedBlobAsset(meshSettings[i].hash, blendshapeblobs[meshSettings[i].blobIndex]); } } using (var meshSettings = skinnedMeshContext.GetSettings(Allocator.TempJob)) { for (int i = 0; i < meshSettings.Length; i++) { skinnedMeshContext.AddComputedBlobAsset(meshSettings[i].hash, skinnedMeshBlobs[meshSettings[i].blobIndex]); } } // Use blob assets in the conversion Entities.ForEach((UnityEngine.Mesh uMesh) => { var entity = GetPrimaryEntity(uMesh); bool addBounds = false; if (DstEntityManager.HasComponent <SimpleMeshRenderData>(entity)) { Hash128 hash128 = new Hash128((uint)uMesh.GetHashCode(), (uint)uMesh.vertexCount.GetHashCode(), (uint)uMesh.subMeshCount.GetHashCode(), 0); simpleMeshContext.GetBlobAsset(hash128, out var blob); DstEntityManager.AddComponentData(entity, new SimpleMeshRenderData() { Mesh = blob }); addBounds = true; } if (DstEntityManager.HasComponent <LitMeshRenderData>(entity)) { Hash128 hash128 = new Hash128((uint)uMesh.GetHashCode(), (uint)uMesh.vertexCount.GetHashCode(), (uint)uMesh.subMeshCount.GetHashCode(), 0); litMeshContext.GetBlobAsset(hash128, out var blob); DstEntityManager.AddComponentData(entity, new LitMeshRenderData() { Mesh = blob }); addBounds = true; } if (addBounds) { DstEntityManager.AddComponentData(entity, new MeshBounds { Bounds = new AABB { Center = uMesh.bounds.center, Extents = uMesh.bounds.extents } }); } if (uMesh.blendShapeCount > 0) { Hash128 hash128 = new Hash128((uint)uMesh.GetHashCode(), (uint)uMesh.vertexCount.GetHashCode(), (uint)uMesh.subMeshCount.GetHashCode(), (uint)uMesh.blendShapeCount); blendShapeContext.GetBlobAsset(hash128, out var blendShapeBlob); DstEntityManager.AddComponentData(entity, new MeshBlendShapeData() { BlendShapeDataRef = blendShapeBlob }); } if (uMesh.bindposes.Length > 0) { var skinnedDataHash = new Hash128((uint)uMesh.GetHashCode(), (uint)uMesh.vertexCount.GetHashCode(), (uint)uMesh.subMeshCount.GetHashCode(), (uint)uMesh.bindposes.Length.GetHashCode()); skinnedMeshContext.GetBlobAsset(skinnedDataHash, out var skinnedMeshBlob); DstEntityManager.AddComponentData(entity, new SkinnedMeshRenderData() { SkinnedMeshDataRef = skinnedMeshBlob }); } }); simpleMeshContext.Dispose(); litMeshContext.Dispose(); blendShapeContext.Dispose(); simpleblobs.Dispose(); litblobs.Dispose(); blendshapeblobs.Dispose(); skinnedMeshBlobs.Dispose(); }