public void Dispose()
 {
     UnsafeUtility.Free(v1, Allocator.Persistent);
     UnsafeUtility.Free(v2, Allocator.Persistent);
     UnsafeUtility.Free(result, Allocator.Persistent);
 }
        public static void Initialize()
        {
            if (s_Types != null)
            {
                return;
            }

            ObjectOffset = UnsafeUtility.SizeOf <ObjectOffsetType>();

#if !UNITY_CSHARP_TINY
            s_CreateTypeLock     = new SpinLock();
            s_ManagedTypeToIndex = new Dictionary <Type, int>(1000);
#endif
            s_Types = new TypeInfo[MaximumTypesCount];

            #if !UNITY_CSHARP_TINY
            s_StableTypeHashToTypeIndex = new Dictionary <ulong, int>();
            #endif

            s_Count = 0;

            #if !UNITY_CSHARP_TINY
            s_Types[s_Count++] = new TypeInfo(null, 0, 0, TypeCategory.ComponentData, FastEquality.TypeInfo.Null, null, null, 0, -1, 0, 1, 0, null, 0, int.MaxValue);

            // This must always be first so that Entity is always index 0 in the archetype
            AddTypeInfoToTables(new TypeInfo(typeof(Entity), 1, sizeof(Entity), TypeCategory.EntityData,
                                             FastEquality.CreateTypeInfo <Entity>(), EntityRemapUtility.CalculateEntityOffsets <Entity>(), null, 0, -1, sizeof(Entity), UnsafeUtility.AlignOf <Entity>(), CalculateStableTypeHash(typeof(Entity)), null, 0, int.MaxValue));

            InitializeAllComponentTypes();
            #else
            StaticTypeRegistry.StaticTypeRegistry.RegisterStaticTypes();
            #endif
        }
 static void CalculatBlobAssetRefOffsetsRecurse(ref List <EntityOffsetInfo> offsets, Type type, int baseOffset)
 {
     if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(BlobAssetReference <>))
     {
         offsets.Add(new EntityOffsetInfo {
             Offset = baseOffset
         });
     }
     else
     {
         var fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
         foreach (var field in fields)
         {
             if (field.FieldType.IsValueType && !field.FieldType.IsPrimitive)
             {
                 CalculatBlobAssetRefOffsetsRecurse(ref offsets, field.FieldType, baseOffset + UnsafeUtility.GetFieldOffset(field));
             }
         }
     }
 }
Exemple #4
0
        /// <summary>
        /// Create an empty hash set with a given capacity
        /// </summary>
        ///
        /// <param name="capacity">
        /// Capacity of the hash set. If less than four, four is used.
        /// </param>
        ///
        /// <param name="allocator">
        /// Allocator to allocate unmanaged memory with. Must be valid.
        /// </param>
        public NativeHashSet(int capacity, Allocator allocator)
        {
            // Require a valid allocator
            if (allocator <= Allocator.None)
            {
                throw new ArgumentException(
                          "Allocator must be Temp, TempJob or Persistent",
                          "allocator");
            }

            RequireBlittable();

            // Insist on a minimum capacity
            if (capacity < 4)
            {
                capacity = 4;
            }

            m_Allocator = allocator;

            // Allocate the state
            NativeHashSetState *state = (NativeHashSetState *)UnsafeUtility.Malloc(
                sizeof(NativeHashSetState),
                UnsafeUtility.AlignOf <NativeHashSetState>(),
                allocator);

            state->ItemCapacity = capacity;

            // To reduce collisions, use twice as many buckets
            int bucketLength = capacity * 2;

            bucketLength = NextHigherPowerOfTwo(bucketLength);
            state->BucketCapacityMask = bucketLength - 1;

            // Allocate state arrays
            int nextOffset;
            int bucketOffset;
            int totalSize = CalculateDataLayout(
                capacity,
                bucketLength,
                out nextOffset,
                out bucketOffset);

            state->Items = (byte *)UnsafeUtility.Malloc(
                totalSize,
                JobsUtility.CacheLineSize,
                allocator);
            state->Next    = state->Items + nextOffset;
            state->Buckets = state->Items + bucketOffset;

            m_State = state;

#if ENABLE_UNITY_COLLECTIONS_CHECKS
#if UNITY_2018_3_OR_NEWER
            DisposeSentinel.Create(
                out m_Safety,
                out m_DisposeSentinel,
                1,
                allocator);
#else
            DisposeSentinel.Create(
                out m_Safety,
                out m_DisposeSentinel,
                1);
#endif
#endif

            Clear();
        }
Exemple #5
0
        /// <summary>
        /// Reallocate to grow the capacity of the set
        /// </summary>
        ///
        /// <param name="newCapacity">
        /// Capacity to grow to. Must be larger than the current capacity.
        /// </param>
        private void Reallocate(int newCapacity)
        {
            int newBucketCapacity = newCapacity * 2;

            newBucketCapacity = NextHigherPowerOfTwo(newBucketCapacity);

            // No change in capacity
            if (m_State->ItemCapacity == newCapacity &&
                m_State->BucketCapacityMask + 1 == newBucketCapacity)
            {
                return;
            }

            // Can't shrink
            if (newCapacity < m_State->ItemCapacity)
            {
                throw new Exception("NativeHashSet<T> can't shrink");
            }

            // Allocate new data
            int nextOffset;
            int bucketOffset;
            int totalSize = CalculateDataLayout(
                newCapacity,
                newBucketCapacity,
                out nextOffset,
                out bucketOffset);
            byte *newData = (byte *)UnsafeUtility.Malloc(
                totalSize,
                JobsUtility.CacheLineSize,
                m_Allocator);
            byte *newItems   = newData;
            byte *newNext    = newData + nextOffset;
            byte *newBuckets = newData + bucketOffset;

            // The items are taken from a free-list and might not be tightly
            // packed, copy all of the old capacity
            UnsafeUtility.MemCpy(
                newItems,
                m_State->Items,
                m_State->ItemCapacity * UnsafeUtility.SizeOf <T>());
            UnsafeUtility.MemCpy(
                newNext,
                m_State->Next,
                m_State->ItemCapacity * UnsafeUtility.SizeOf <int>());
            for (
                int emptyNext = m_State->ItemCapacity;
                emptyNext < newCapacity;
                ++emptyNext)
            {
                ((int *)newNext)[emptyNext] = -1;
            }

            // Re-hash the buckets, first clear the new bucket list, then insert
            // all values from the old list
            for (int bucket = 0; bucket < newBucketCapacity; ++bucket)
            {
                ((int *)newBuckets)[bucket] = -1;
            }
            for (int bucket = 0; bucket <= m_State->BucketCapacityMask; ++bucket)
            {
                int *buckets  = (int *)m_State->Buckets;
                int *nextPtrs = (int *)newNext;
                while (buckets[bucket] >= 0)
                {
                    int curEntry = buckets[bucket];
                    buckets[bucket] = nextPtrs[curEntry];
                    int newBucket = UnsafeUtility.ReadArrayElement <T>(
                        m_State->Items,
                        curEntry).GetHashCode() & (newBucketCapacity - 1);
                    nextPtrs[curEntry]             = ((int *)newBuckets)[newBucket];
                    ((int *)newBuckets)[newBucket] = curEntry;
                }
            }

            // Free the old state contents
            UnsafeUtility.Free(m_State->Items, m_Allocator);

            // Set the new state contents
            if (m_State->AllocatedIndexLength > m_State->ItemCapacity)
            {
                m_State->AllocatedIndexLength = m_State->ItemCapacity;
            }
            m_State->Items              = newData;
            m_State->Next               = newNext;
            m_State->Buckets            = newBuckets;
            m_State->ItemCapacity       = newCapacity;
            m_State->BucketCapacityMask = newBucketCapacity - 1;
        }
Exemple #6
0
        /// <inheritdoc />
        public override unsafe void WriteValueIntoState(TouchState value, void *statePtr)
        {
            var valuePtr = (TouchState *)((byte *)statePtr + (int)m_StateBlock.byteOffset);

            UnsafeUtility.MemCpy(valuePtr, UnsafeUtility.AddressOf(ref value), UnsafeUtility.SizeOf <TouchState>());
        }
Exemple #7
0
        public static unsafe int GrowBy <TValue>(ref NativeArray <TValue> array, int count, Allocator allocator = Allocator.Persistent)
            where TValue : struct
        {
            var length = array.Length;

            if (length == 0)
            {
                array = new NativeArray <TValue>(count, allocator);
                return(0);
            }

            var newArray = new NativeArray <TValue>(length + count, allocator);

            // CopyFrom() expects length to match. Copy manually.
            UnsafeUtility.MemCpy(newArray.GetUnsafePtr(), array.GetUnsafeReadOnlyPtr(), (long)length * UnsafeUtility.SizeOf <TValue>());
            array.Dispose();
            array = newArray;

            return(length);
        }
 static void CopyArrayToBuffer <T>(DynamicBuffer <T> buffer, void *source, int length, int sizeOfT) where T : struct
 {
     buffer.ResizeUninitialized(length);
     UnsafeUtility.MemCpy(buffer.GetUnsafePtr(), source, length * sizeOfT);
 }
Exemple #9
0
 public static unsafe void *ConstructRootPtr <T>(this BlobBuilder builder) where T : struct
 {
     return(UnsafeUtility.AddressOf(ref builder.ConstructRoot <T>()));
 }
 public void Dispose()
 {
     UnsafeUtility.Free(m1, Allocator.Persistent);
 }
        static unsafe void ReadEtlFile(string etlPath, IEnumerable <string> pdbWhitelist, out ProfilerTrace profTrace, Allocator allocator)
        {
            var monoFunctions     = new Dictionary <IntPtr, MonoJitInfo>();
            var discoveredModules = DiscoveredData <DiscoveredModule> .Make(DiscoveredModule.Invalid);

            var discoveredStackFrames = DiscoveredData <CallStackIndex> .Make(CallStackIndex.Invalid);

            var discoveredFunctions = DiscoveredData <DiscoveredFunction> .Make(DiscoveredFunction.Invalid);

            var discoveredThreads = DiscoveredData <ThreadIndex> .Make(ThreadIndex.Invalid);

            var options = new TraceLogOptions()
            {
                AlwaysResolveSymbols = true,
                LocalSymbolsOnly     = false,
                AllowUnsafeSymbols   = true,
#if UNITY_EDITOR
                AdditionalSymbolPath = Path.GetDirectoryName(EditorApplication.applicationPath),
#endif
                ShouldResolveSymbols = path =>
                {
                    path = path.ToLowerInvariant();
                    return(pdbWhitelist.Any(x => path.EndsWith(x)));
                }
            };

            profTrace = new ProfilerTrace();
            using (var trace = TraceLog.OpenOrConvert(etlPath, options))
            {
                var processIndex = FindUnityProcessIndex(trace.Processes);
                var processId    = trace.Processes[processIndex].ProcessID;

                profTrace.Header = new ProfilerTraceHeader
                {
                    SamplingInterval = trace.SampleProfileInterval.TotalMilliseconds,
                    SessionStart     = trace.SessionStartTime.Ticks,
                    SessionEnd       = trace.SessionEndTime.Ticks,
                };

                using (var samples = new NativeList <SampleData>(Allocator.Temp))
                {
                    SampleData sampleData = default;
                    foreach (var evt in trace.Events)
                    {
                        var sample = evt as SampledProfileTraceData;
                        if (sample == null || sample.ProcessID != processId)
                        {
                            continue;
                        }
                        sampleData.Address    = (long)sample.InstructionPointer;
                        sampleData.ThreadIdx  = discoveredThreads.AddData(sample.Thread()?.ThreadIndex ?? ThreadIndex.Invalid);
                        sampleData.TimeStamp  = sample.TimeStampRelativeMSec;
                        sampleData.StackTrace = discoveredStackFrames.AddData(sample.CallStackIndex());
                        var codeAddress = sample.IntructionPointerCodeAddress();
                        sampleData.Function = GetFunctionIndex(codeAddress);
                        samples.Add(sampleData);
                    }
                    profTrace.Samples = samples.ToArray(allocator);
                }

                using (var stackFrames = new NativeList <StackFrameData>(Allocator.Temp))
                {
                    StackFrameData stackTraceData = default;
                    // N.B. this loop adds more stack frames as it executes
                    for (int idx = 0; idx < discoveredStackFrames.Count; idx++)
                    {
                        var stack = trace.CallStacks[discoveredStackFrames.Data[idx]];
                        stackTraceData.Address          = (long)stack.CodeAddress.Address;
                        stackTraceData.Depth            = stack.Depth;
                        stackTraceData.CallerStackFrame = discoveredStackFrames.AddData(stack.Caller?.CallStackIndex ?? CallStackIndex.Invalid);
                        stackTraceData.Function         = GetFunctionIndex(stack.CodeAddress);
                        stackFrames.Add(stackTraceData);
                    }
                    profTrace.StackFrames = stackFrames.ToArray(allocator);
                }

                using (var functions = new NativeList <FunctionData>(Allocator.Temp))
                {
                    FunctionData funcData = default;
                    foreach (var func in discoveredFunctions.Data)
                    {
                        if (func.Index != MethodIndex.Invalid)
                        {
                            var method = trace.CodeAddresses.Methods[func.Index];
                            if (method.MethodRva > 0 && method.MethodModuleFile != null)
                            {
                                funcData.BaseAddress = method.MethodModuleFile.ImageBase + (ulong)method.MethodRva;
                            }
                            else
                            {
                                funcData.BaseAddress = 0;
                            }
                            funcData.Length = -1;
                            funcData.Module = discoveredModules.AddData(DiscoveredModule.FromIndex(method.MethodModuleFileIndex));
                            funcData.Name.CopyFrom(method.FullMethodName);
                        }
                        else
                        {
                            var jitData = func.MonoMethod;
                            funcData.BaseAddress = (ulong)jitData.CodeStart.ToInt64();
                            funcData.Length      = jitData.CodeSize;
                            funcData.Module      = discoveredModules.AddData(DiscoveredModule.FromMonoModule(jitData.Method.Module));

                            var fullName = MonoFunctionName(jitData.Method);
                            funcData.Name.CopyFrom(fullName);
                        }
                        functions.Add(funcData);
                    }
                    profTrace.Functions = functions.ToArray(allocator);
                }

                using (var modules = new NativeList <ModuleData>(Allocator.Temp))
                {
                    // make sure that all modules of the current process are included.
                    foreach (var module in trace.Processes[processIndex].LoadedModules)
                    {
                        discoveredModules.AddData(new DiscoveredModule {
                            Index = module.ModuleFile.ModuleFileIndex
                        });
                    }

                    ModuleData moduleData = default;
                    foreach (var dm in discoveredModules.Data)
                    {
                        if (dm.MonoModule != null)
                        {
                            moduleData          = default;
                            moduleData.IsMono   = true;
                            moduleData.FilePath = dm.MonoModule.Assembly.Location;
                        }
                        else
                        {
                            var module = trace.ModuleFiles[dm.Index];
                            moduleData.IsMono    = false;
                            moduleData.Checksum  = module.ImageChecksum;
                            moduleData.ImageBase = module.ImageBase;
                            moduleData.ImageEnd  = module.ImageEnd;
                            moduleData.PdbAge    = module.PdbAge;
                            moduleData.FilePath.CopyFrom(module.FilePath);
                            moduleData.PdbName.CopyFrom(module.PdbName);
                            var guidBytes = module.PdbSignature.ToByteArray();

                            fixed(byte *ptr = guidBytes)
                            UnsafeUtility.MemCpy(moduleData.PdbGuid, ptr, 16);
                        }
                        modules.Add(moduleData);
                    }
                    profTrace.Modules = modules.ToArray(allocator);
                }

                using (var threads = new NativeList <ThreadData>(Allocator.Temp))
                {
                    ThreadData threadData = default;
                    foreach (var t in discoveredThreads.Data)
                    {
                        var thread = trace.Threads[t];
                        threadData.ThreadName.CopyFrom(thread.ThreadInfo ?? "");
                        threads.Add(threadData);
                    }
                    profTrace.Threads = threads.ToArray(allocator);
                }
            }

            int GetFunctionIndex(TraceCodeAddress address)
            {
                var method = address.Method;

                if (method == null)
                {
                    var jit = Mono.GetJitInfoAnyDomain(new IntPtr((long)address.Address), out _);
                    if (jit.Method == null)
                    {
                        return(-1);
                    }
                    if (!monoFunctions.TryGetValue(jit.CodeStart, out var actualJit))
                    {
                        monoFunctions.Add(jit.CodeStart, jit);
                        actualJit = jit;
                    }
                    return(discoveredFunctions.AddData(DiscoveredFunction.FromMethod(actualJit)));
                }
                return(discoveredFunctions.AddData(new DiscoveredFunction
                {
                    Index = method.MethodIndex
                }));
            }

            string MonoFunctionName(MethodBase method)
            {
                if (method == null)
                {
                    return("???");
                }
                if (method.DeclaringType.DeclaringType == null)
                {
                    return(method.DeclaringType.Namespace + '.' + method.DeclaringType.Name + '.' + method.Name);
                }
                var outerMost = method.DeclaringType.DeclaringType;
                var outer     = method.DeclaringType;

                return(outerMost.Namespace + '.' + outerMost.Name + '+' + outer.Name + '.' + method.Name);
            }
        }
 public void Init()
 {
     m1 = (float4x4 *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <float4x4>() * 10000, UnsafeUtility.AlignOf <float4x4>(), Allocator.Persistent);
     for (int i = 0; i < 10000; ++i)
     {
         m1[i] = float4x4.identity;
     }
 }
 public static void Run <T>(this T jobData, int arrayLength) where T : struct, IJobFor
 {
     JobsUtility.JobScheduleParameters jobScheduleParameters = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf <T>(ref jobData), IJobForExtensions.ForJobStruct <T> .Initialize(), default(JobHandle), ScheduleMode.Run);
     JobsUtility.ScheduleParallelFor(ref jobScheduleParameters, arrayLength, arrayLength);
 }
 public static JobHandle ScheduleParallel <T>(this T jobData, int arrayLength, int innerloopBatchCount, JobHandle dependency) where T : struct, IJobFor
 {
     JobsUtility.JobScheduleParameters jobScheduleParameters = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf <T>(ref jobData), IJobForExtensions.ForJobStruct <T> .Initialize(), dependency, ScheduleMode.Batched);
     return(JobsUtility.ScheduleParallelFor(ref jobScheduleParameters, arrayLength, innerloopBatchCount));
 }
        unsafe static NativeArray <T> ArraySlice <T>(NativeArray <T> array, int startIndex, int count) where T : struct
        {
            var ptr    = (byte *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(array);
            var sliced = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>(ptr + startIndex * UnsafeUtility.SizeOf <T>(), count, Allocator.Invalid);

            NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref sliced, NativeArrayUnsafeUtility.GetAtomicSafetyHandle(array));
            return(sliced);
        }
        public override void FrameUpdate(PipelineCamera cam, ref PipelineCommandData data)
        {
            PipelineBaseBuffer baseBuffer;

            if (!SceneController.current.GetBaseBufferAndCheck(out baseBuffer))
            {
                return;
            }
            CommandBuffer buffer = data.buffer;

            cullJobHandler.Complete();
            UnsafeUtility.ReleaseGCObject(gcHandler);
            pointLightMaterial.SetBuffer(ShaderIDs.verticesBuffer, sphereBuffer);
            //Un Shadow Point light
            buffer.SetRenderTarget(cam.targets.renderTargetIdentifier, cam.targets.depthIdentifier);
            for (int c = 0; c < unShadowCount; c++)
            {
                var         i     = cullJob.indices[cullJob.length - c];
                MPointLight light = MPointLight.allPointLights[i];
                buffer.SetGlobalVector(ShaderIDs._LightColor, light.color);
                buffer.SetGlobalVector(ShaderIDs._LightPos, new Vector4(light.position.x, light.position.y, light.position.z, light.range));
                buffer.SetGlobalFloat(ShaderIDs._LightIntensity, light.intensity);
                buffer.DrawProceduralIndirect(Matrix4x4.identity, pointLightMaterial, 0, MeshTopology.Triangles, sphereIndirectBuffer, 0);
            }
            //TODO
            if (shadowCount > 0)
            {
                NativeArray <Vector4> positions = new NativeArray <Vector4>(shadowCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
                for (int i = 0; i < shadowCount; i++)
                {
                    MPointLight light = MPointLight.allPointLights[cullJob.indices[i]];
                    positions[i] = new Vector4(light.position.x, light.position.y, light.position.z, light.range);
                }
                CubeFunction.UpdateLength(ref cubeBuffer, shadowCount);
                var cullShader = data.resources.pointLightFrustumCulling;
                CubeFunction.UpdateData(ref cubeBuffer, baseBuffer, cullShader, buffer, positions);
                RenderClusterOptions opts = new RenderClusterOptions
                {
                    cullingShader      = cullShader,
                    proceduralMaterial = cubeDepthMaterial,
                    command            = buffer,
                    frustumPlanes      = null,
                    isOrtho            = false
                };
                for (int i = 0; i < shadowCount; i++)
                {
                    MPointLight light = MPointLight.allPointLights[cullJob.indices[i]];
                    SceneController.current.DrawCubeMap(light, ref opts, ref cubeBuffer, i);
                    buffer.SetRenderTarget(cam.targets.renderTargetIdentifier, cam.targets.depthIdentifier);
                    buffer.SetGlobalVector(ShaderIDs._LightColor, light.color);
                    buffer.SetGlobalVector(ShaderIDs._LightPos, positions[i]);
                    buffer.SetGlobalFloat(ShaderIDs._LightIntensity, light.intensity);
                    buffer.SetGlobalTexture(ShaderIDs._CubeShadowMap, light.shadowmapTexture);
                    buffer.DrawProceduralIndirect(Matrix4x4.identity, pointLightMaterial, 1, MeshTopology.Triangles, sphereIndirectBuffer, 0);
                }
                positions.Dispose();
            }
            //Shadow Point Light
            indicesArray.Dispose();
            data.ExecuteCommandBuffer();
        }
 public VStringNativeWrapper(string aStr)
 {
     m_Ptr    = (char *)(((byte *)UnsafeUtility.PinGCObjectAndGetAddress(aStr, out m_Handle)) + m_CharPtrOffset);
     m_Length = aStr.Length;
 }
        public BlobAssetReference <T> CreateBlobAssetReference <T>(Allocator allocator) where T : struct
        {
            Assert.AreEqual(16, sizeof(BlobAssetHeader));
            NativeArray <int> offsets = new NativeArray <int>(m_allocations.Length + 1, m_allocator);

            var sortedAllocs = new NativeArray <SortedIndex>(m_allocations.Length, m_allocator);

            offsets[0] = 0;
            for (int i = 0; i < m_allocations.Length; ++i)
            {
                offsets[i + 1]  = offsets[i] + m_allocations[i].size;
                sortedAllocs[i] = new SortedIndex {
                    p = m_allocations[i].p, index = i
                };
            }
            int dataSize = offsets[m_allocations.Length];

            sortedAllocs.Sort();
            var sortedPatches = new NativeArray <SortedIndex>(m_patches.Length, m_allocator);

            for (int i = 0; i < m_patches.Length; ++i)
            {
                sortedPatches[i] = new SortedIndex {
                    p = (byte *)m_patches[i].offsetPtr, index = i
                }
            }
            ;
            sortedPatches.Sort();

            byte *buffer = (byte *)UnsafeUtility.Malloc(sizeof(BlobAssetHeader) + dataSize, 16, allocator);
            byte *data   = buffer + sizeof(BlobAssetHeader);

            for (int i = 0; i < m_allocations.Length; ++i)
            {
                UnsafeUtility.MemCpy(data + offsets[i], m_allocations[i].p, m_allocations[i].size);
            }

            int iAlloc     = 0;
            var allocStart = m_allocations[sortedAllocs[0].index].p;
            var allocEnd   = allocStart + m_allocations[sortedAllocs[0].index].size;

            for (int i = 0; i < m_patches.Length; ++i)
            {
                int  patchIndex = sortedPatches[i].index;
                int *offsetPtr  = (int *)sortedPatches[i].p;

                while (offsetPtr > allocEnd)
                {
                    ++iAlloc;
                    allocStart = m_allocations[sortedAllocs[iAlloc].index].p;
                    allocEnd   = allocStart + m_allocations[sortedAllocs[iAlloc].index].size;
                }

                var patch = m_patches[patchIndex];

                int offsetPtrInData = offsets[sortedAllocs[iAlloc].index] + (int)((byte *)offsetPtr - allocStart);
                int targetPtrInData = offsets[patch.target.allocIndex] + patch.target.offset;

                *(int *)(data + offsetPtrInData) = targetPtrInData - offsetPtrInData;
                if (patch.length != 0)
                {
                    *(int *)(data + offsetPtrInData + 4) = patch.length;
                }
            }

            sortedPatches.Dispose();
            sortedAllocs.Dispose();

            BlobAssetHeader *header = (BlobAssetHeader *)buffer;

            *header = new BlobAssetHeader();
            header->Length    = (int)dataSize;
            header->Allocator = allocator;

            BlobAssetReference <T> blobAssetReference;

            header->ValidationPtr = blobAssetReference.m_data.m_Ptr = buffer + sizeof(BlobAssetHeader);

            return(blobAssetReference);
        }
Exemple #19
0
 public static unsafe long DeviceCommand <TCommand>(this IInputRuntime runtime, int deviceId, ref TCommand command)
     where TCommand : struct, IInputDeviceCommandInfo
 {
     return(runtime.DeviceCommand(deviceId, (InputDeviceCommand *)UnsafeUtility.AddressOf(ref command)));
 }
        public ref T ConstructRoot <T>() where T : struct
        {
            var allocation = Allocate(UnsafeUtility.SizeOf <T>(), UnsafeUtility.AlignOf <T>());

            return(ref UnsafeUtilityEx.AsRef <T>(AllocationToPointer(allocation)));
        }
        protected override JobHandle OnUpdate(JobHandle inputDeps)
        {
            var commandBuffer            = barrier.CreateCommandBuffer().ToConcurrent();
            var parentFromEntity         = GetComponentDataFromEntity <Parent>(true);
            var localToWorldFromEntity   = GetComponentDataFromEntity <LocalToWorld>(true);
            var jumpingFromEntity        = GetComponentDataFromEntity <NavJumping>(true);
            var avoidantFromEntity       = GetComponentDataFromEntity <NavAvoidant>(true);
            var pathBufferFromEntity     = GetBufferFromEntity <NavPathBufferElement>();
            var jumpBufferFromEntity     = GetBufferFromEntity <NavJumpBufferElement>();
            var navMeshQueryPointerArray = World.GetExistingSystem <NavMeshQuerySystem>().PointerArray;

            var job = Entities
                      .WithAll <NavPlanning, Parent, LocalToParent>()
                      .WithReadOnly(parentFromEntity)
                      .WithReadOnly(localToWorldFromEntity)
                      .WithReadOnly(jumpingFromEntity)
                      .WithReadOnly(avoidantFromEntity)
                      .WithNativeDisableParallelForRestriction(pathBufferFromEntity)
                      .WithNativeDisableParallelForRestriction(jumpBufferFromEntity)
                      .WithNativeDisableParallelForRestriction(navMeshQueryPointerArray)
                      .ForEach((Entity entity, int entityInQueryIndex, int nativeThreadIndex, ref NavAgent agent) =>
            {
                if (agent.Surface.Equals(Entity.Null))
                {
                    return;
                }

                var parent = parentFromEntity[agent.Surface].Value;

                if (!agent.DestinationSurface.Equals(Entity.Null))
                {
                    var destinationTransform = localToWorldFromEntity[agent.DestinationSurface].Value;
                    agent.WorldDestination   = NavUtil.MultiplyPoint3x4(destinationTransform, agent.LocalDestination);
                }

                var childTransform  = localToWorldFromEntity[entity];
                var parentTransform = localToWorldFromEntity[parent];

                var worldPosition    = childTransform.Position;
                var avoidant         = avoidantFromEntity.Exists(entity);
                var worldDestination = avoidant ? (Vector3)agent.AvoidanceDestination : (Vector3)agent.WorldDestination;

                var jumping = jumpingFromEntity.Exists(entity);

                if (jumping)
                {
                    worldPosition    = agent.WorldDestination;
                    worldDestination = childTransform.Position;
                }

                var navMeshQueryPointer = navMeshQueryPointerArray[nativeThreadIndex];
                UnsafeUtility.CopyPtrToStructure(navMeshQueryPointer.Value, out NavMeshQuery navMeshQuery);

                var status = navMeshQuery.BeginFindPath(
                    navMeshQuery.MapLocation(worldPosition, Vector3.one * NavConstants.PATH_SEARCH_MAX, agent.TypeID),
                    navMeshQuery.MapLocation(worldDestination, Vector3.one * NavConstants.PATH_SEARCH_MAX, agent.TypeID),
                    NavMesh.AllAreas
                    );

                while (status == PathQueryStatus.InProgress)
                {
                    status = navMeshQuery.UpdateFindPath(
                        NavConstants.ITERATION_MAX,
                        out int iterationsPerformed
                        );
                }

                if (status != PathQueryStatus.Success)
                {
                    return;
                }

                navMeshQuery.EndFindPath(out int pathLength);

                var polygonIdArray = new NativeArray <PolygonId>(
                    NavConstants.PATH_NODE_MAX,
                    Allocator.Temp
                    );

                navMeshQuery.GetPathResult(polygonIdArray);

                var len               = pathLength + 1;
                var straightPath      = new NativeArray <NavMeshLocation>(len, Allocator.Temp);
                var straightPathFlags = new NativeArray <StraightPathFlags>(len, Allocator.Temp);
                var vertexSide        = new NativeArray <float>(len, Allocator.Temp);
                var straightPathCount = 0;

                status = PathUtils.FindStraightPath(
                    navMeshQuery,
                    worldPosition,
                    worldDestination,
                    polygonIdArray,
                    pathLength,
                    ref straightPath,
                    ref straightPathFlags,
                    ref vertexSide,
                    ref straightPathCount,
                    NavConstants.PATH_NODE_MAX
                    );

                var jumpBuffer = !jumpBufferFromEntity.Exists(entity) ? commandBuffer.AddBuffer <NavJumpBufferElement>(entityInQueryIndex, entity) : jumpBufferFromEntity[entity];
                var pathBuffer = !pathBufferFromEntity.Exists(entity) ? commandBuffer.AddBuffer <NavPathBufferElement>(entityInQueryIndex, entity) : pathBufferFromEntity[entity];

                if (jumping)
                {
                    var lastValidPoint = float3.zero;
                    for (int j = 0; j < straightPath.Length; ++j)
                    {
                        if (navMeshQuery.IsValid(straightPath[j].polygon))
                        {
                            lastValidPoint = straightPath[j].position;
                        }
                        else
                        {
                            break;
                        }
                    }

                    jumpBuffer.Add(NavUtil.MultiplyPoint3x4(
                                       math.inverse(parentTransform.Value),
                                       (float3)lastValidPoint + agent.Offset
                                       ));

                    if (jumpBuffer.Length > 0)
                    {
                        commandBuffer.RemoveComponent <NavPlanning>(entityInQueryIndex, entity);
                        commandBuffer.AddComponent <NavLerping>(entityInQueryIndex, entity);
                    }
                }
                else if (status == PathQueryStatus.Success)
                {
                    pathBuffer.Clear();

                    for (int j = 0; j < straightPathCount; ++j)
                    {
                        pathBuffer.Add(NavUtil.MultiplyPoint3x4(
                                           math.inverse(parentTransform.Value),
                                           (float3)straightPath[j].position + agent.Offset
                                           ));
                    }

                    if (pathBuffer.Length > 0)
                    {
                        commandBuffer.RemoveComponent <NavPlanning>(entityInQueryIndex, entity);
                        commandBuffer.AddComponent <NavLerping>(entityInQueryIndex, entity);
                    }
                }

                polygonIdArray.Dispose();
                straightPath.Dispose();
                straightPathFlags.Dispose();
                vertexSide.Dispose();
            })
                      .WithName("NavPlanJob")
                      .Schedule(inputDeps);

            NavMeshWorld.GetDefaultWorld().AddDependency(job);
            barrier.AddJobHandleForProducer(job);

            return(job);
        }
Exemple #22
0
 /// <summary>
 /// Adds elements from a buffer to this list.
 /// </summary>
 /// <typeparam name="T">Source type of elements</typeparam>
 /// <param name="ptr">A pointer to the buffer.</param>
 /// <param name="length">The number of elements to add to the list.</param>
 /// <remarks>
 /// If the list has reached its current capacity, internal array won't be resized, and exception will be thrown.
 /// </remarks>
 public void AddRangeNoResize(void *ptr, int length)
 {
     AddRangeNoResize(UnsafeUtility.SizeOf <T>(), UnsafeUtility.AlignOf <T>(), ptr, length);
 }
Exemple #23
0
        /// <summary>
        /// Try to add an item to the set.
        ///
        /// This operation requires write access.
        /// </summary>
        ///
        /// <param name="item">
        /// Item to add
        /// </param>
        ///
        /// <returns>
        /// If the item was added to the set. This is false only if the item was
        /// already in the set.</returns>
        public bool TryAdd(T item)
        {
            RequireWriteAccess();

            NativeMultiHashSetIterator tempIt;

            if (TryGetFirstValueAtomic(m_State, item, out tempIt))
            {
                return(false);
            }

            // Allocate an entry from the free list
            int  idx;
            int *nextPtrs;

            if (m_State->AllocatedIndexLength >= m_State->ItemCapacity &&
                m_State->FirstFreeTLS[0] < 0)
            {
                for (int tls = 1; tls < JobsUtility.MaxJobThreadCount; ++tls)
                {
                    if (m_State->FirstFreeTLS[tls * NativeHashSetState.IntsPerCacheLine] >= 0)
                    {
                        idx      = m_State->FirstFreeTLS[tls * NativeHashSetState.IntsPerCacheLine];
                        nextPtrs = (int *)m_State->Next;
                        m_State->FirstFreeTLS[tls * NativeHashSetState.IntsPerCacheLine] = nextPtrs[idx];
                        nextPtrs[idx]            = -1;
                        m_State->FirstFreeTLS[0] = idx;
                        break;
                    }
                }
                if (m_State->FirstFreeTLS[0] < 0)
                {
                    int capacity    = m_State->ItemCapacity;
                    int newCapacity = capacity == 0 ? 1 : capacity * 2;

                    Reallocate(newCapacity);
                }
            }
            idx = m_State->FirstFreeTLS[0];
            if (idx >= 0)
            {
                m_State->FirstFreeTLS[0] = ((int *)m_State->Next)[idx];
            }
            else
            {
                idx = m_State->AllocatedIndexLength++;
            }

            // Write the new value to the entry
            UnsafeUtility.WriteArrayElement(m_State->Items, idx, item);

            int bucket = item.GetHashCode() & m_State->BucketCapacityMask;
            // Add the index to the hash-set
            int *buckets = (int *)m_State->Buckets;

            nextPtrs = (int *)m_State->Next;

            nextPtrs[idx]   = buckets[bucket];
            buckets[bucket] = idx;

            return(true);
        }
Exemple #24
0
 /// <summary>
 /// Adds elements from a list to this list.
 /// </summary>
 /// <typeparam name="T">Source type of elements</typeparam>
 /// <remarks>
 /// If the list has reached its current capacity, internal array won't be resized, and exception will be thrown.
 /// </remarks>
 public void AddRangeNoResize(UnsafeList list)
 {
     AddRangeNoResize(UnsafeUtility.SizeOf <T>(), UnsafeUtility.AlignOf <T>(), list.Ptr, list.Length);
 }
 public void ReadBytes(void *data, int bytes)
 {
     UnsafeUtility.MemCpy(data, (byte *)content.GetUnsafePtr() + position, bytes);
     position += bytes;
 }
 public override unsafe int GetHashCode()
 {
     unchecked
     {
         return((int)math.hash(
                    new uint3(polygons.Length == 0 ? 0 : math.hash(polygons.GetUnsafePtr(), UnsafeUtility.SizeOf <Polygon>() * polygons.Length),
                              localVertices.Length == 0 ? 0 : math.hash(localVertices.GetUnsafePtr(), UnsafeUtility.SizeOf <float3>() * localVertices.Length),
                              halfEdges.Length == 0 ? 0 : math.hash(halfEdges.GetUnsafePtr(), UnsafeUtility.SizeOf <HalfEdge>() * halfEdges.Length))));
     }
 }
        static void InitializeAllComponentTypes()
        {
            var componentTypeSet = new HashSet <Type>();

            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                if (!IsAssemblyReferencingEntities(assembly))
                {
                    continue;
                }

                foreach (var type in assembly.GetTypes())
                {
                    if (type.IsAbstract || !type.IsValueType)
                    {
                        continue;
                    }
                    if (!UnsafeUtility.IsUnmanaged(type))
                    {
                        continue;
                    }

                    if (typeof(IComponentData).IsAssignableFrom(type) ||
                        typeof(ISharedComponentData).IsAssignableFrom(type) ||
                        typeof(IBufferElementData).IsAssignableFrom(type))
                    {
                        componentTypeSet.Add(type);
                    }
                }
            }

            var lockTaken = false;

            try
            {
                s_CreateTypeLock.Enter(ref lockTaken);

                var componentTypeCount = componentTypeSet.Count;
                var componentTypes     = new Type[componentTypeCount];
                componentTypeSet.CopyTo(componentTypes);

                var typeIndexByType  = new Dictionary <Type, int>();
                var writeGroupByType = new Dictionary <int, HashSet <int> >();
                var startTypeIndex   = s_Count;

                for (int i = 0; i < componentTypes.Length; i++)
                {
                    typeIndexByType[componentTypes[i]] = startTypeIndex + i;
                }

                GatherWriteGroups(componentTypes, startTypeIndex, typeIndexByType, writeGroupByType);
                AddAllComponentTypes(componentTypes, startTypeIndex, writeGroupByType);
            }
            finally
            {
                if (lockTaken)
                {
                    s_CreateTypeLock.Exit(true);
                }
            }
        }
            public static unsafe void Execute(ref JobNativeMultiHashMapMergedSharedKeyIndicesProducer <TJob> jobProducer, IntPtr additionalPtr, IntPtr bufferRangePatchData, ref JobRanges ranges, int jobIndex)
            {
                while (true)
                {
                    int begin;
                    int end;

                    if (!JobsUtility.GetWorkStealingRange(ref ranges, jobIndex, out begin, out end))
                    {
                        return;
                    }

                    var bucketData = jobProducer.HashMap.GetUnsafeBucketData();
                    var buckets    = (int *)bucketData.buckets;
                    var nextPtrs   = (int *)bucketData.next;
                    var keys       = bucketData.keys;
                    var values     = bucketData.values;

                    for (int i = begin; i < end; i++)
                    {
                        int entryIndex = buckets[i];

                        while (entryIndex != -1)
                        {
                            var key   = UnsafeUtility.ReadArrayElement <int>(keys, entryIndex);
                            var value = UnsafeUtility.ReadArrayElement <int>(values, entryIndex);
                            int firstValue;

                            NativeParallelMultiHashMapIterator <int> it;
                            jobProducer.HashMap.TryGetFirstValue(key, out firstValue, out it);

                            // [macton] Didn't expect a usecase for this with multiple same values
                            // (since it's intended use was for unique indices.)
                            // https://forum.unity.com/threads/ijobnativemultihashmapmergedsharedkeyindices-unexpected-behavior.569107/#post-3788170
                            if (entryIndex == it.GetEntryIndex())
                            {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                                JobsUtility.PatchBufferMinMaxRanges(bufferRangePatchData, UnsafeUtility.AddressOf(ref jobProducer), value, 1);
#endif
                                jobProducer.JobData.ExecuteFirst(value);
                            }
                            else
                            {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                                var startIndex  = math.min(firstValue, value);
                                var lastIndex   = math.max(firstValue, value);
                                var rangeLength = (lastIndex - startIndex) + 1;

                                JobsUtility.PatchBufferMinMaxRanges(bufferRangePatchData, UnsafeUtility.AddressOf(ref jobProducer), startIndex, rangeLength);
#endif
                                jobProducer.JobData.ExecuteNext(firstValue, value);
                            }

                            entryIndex = nextPtrs[entryIndex];
                        }
                    }
                }
            }
        internal static TypeInfo BuildComponentType(Type type, int *writeGroups, int writeGroupCount)
        {
            var          componentSize = 0;
            TypeCategory category;
            var          typeInfo = FastEquality.TypeInfo.Null;

            EntityOffsetInfo[] entityOffsets       = null;
            EntityOffsetInfo[] blobAssetRefOffsets = null;
            int bufferCapacity   = -1;
            var memoryOrdering   = CalculateMemoryOrdering(type);
            var stableTypeHash   = CalculateStableTypeHash(type);
            var maxChunkCapacity = int.MaxValue;

            var maxCapacityAttribute = type.GetCustomAttribute <MaximumChunkCapacityAttribute>();

            if (maxCapacityAttribute != null)
            {
                maxChunkCapacity = maxCapacityAttribute.Capacity;
            }

            int elementSize      = 0;
            int alignmentInBytes = 0;

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (type.IsInterface)
            {
                throw new ArgumentException($"{type} is an interface. It must be a concrete type.");
            }
#endif
            if (typeof(IComponentData).IsAssignableFrom(type))
            {
                CheckIsAllowedAsComponentData(type, nameof(IComponentData));

                category = TypeCategory.ComponentData;
                if (TypeManager.IsZeroSizeStruct(type))
                {
                    componentSize = 0;
                }
                else
                {
                    componentSize = UnsafeUtility.SizeOf(type);
                }

                typeInfo            = FastEquality.CreateTypeInfo(type);
                entityOffsets       = EntityRemapUtility.CalculateEntityOffsets(type);
                blobAssetRefOffsets = CalculatBlobAssetRefOffsets(type);

                int sizeInBytes = UnsafeUtility.SizeOf(type);
                // TODO: Implement UnsafeUtility.AlignOf(type)
                alignmentInBytes = 16;
                if (sizeInBytes < 16 && (sizeInBytes & (sizeInBytes - 1)) == 0)
                {
                    alignmentInBytes = sizeInBytes;
                }
            }
            else if (typeof(IBufferElementData).IsAssignableFrom(type))
            {
                CheckIsAllowedAsComponentData(type, nameof(IBufferElementData));

                category    = TypeCategory.BufferData;
                elementSize = UnsafeUtility.SizeOf(type);

                var capacityAttribute = (InternalBufferCapacityAttribute)type.GetCustomAttribute(typeof(InternalBufferCapacityAttribute));
                if (capacityAttribute != null)
                {
                    bufferCapacity = capacityAttribute.Capacity;
                }
                else
                {
                    bufferCapacity = 128 / elementSize; // Rather than 2*cachelinesize, to make it cross platform deterministic
                }
                componentSize       = sizeof(BufferHeader) + bufferCapacity * elementSize;
                typeInfo            = FastEquality.CreateTypeInfo(type);
                entityOffsets       = EntityRemapUtility.CalculateEntityOffsets(type);
                blobAssetRefOffsets = CalculatBlobAssetRefOffsets(type);

                int sizeInBytes = UnsafeUtility.SizeOf(type);
                // TODO: Implement UnsafeUtility.AlignOf(type)
                alignmentInBytes = 16;
                if (sizeInBytes < 16 && (sizeInBytes & (sizeInBytes - 1)) == 0)
                {
                    alignmentInBytes = sizeInBytes;
                }
            }
            else if (typeof(ISharedComponentData).IsAssignableFrom(type))
            {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                if (!type.IsValueType)
                {
                    throw new ArgumentException($"{type} is an ISharedComponentData, and thus must be a struct.");
                }
#endif
                entityOffsets = EntityRemapUtility.CalculateEntityOffsets(type);
                category      = TypeCategory.ISharedComponentData;
                typeInfo      = FastEquality.CreateTypeInfo(type);
            }
            else if (type.IsClass)
            {
                category = TypeCategory.Class;
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                if (type.FullName == "Unity.Entities.GameObjectEntity")
                {
                    throw new ArgumentException(
                              "GameObjectEntity cannot be used from EntityManager. The component is ignored when creating entities for a GameObject.");
                }
                if (UnityEngineComponentType == null)
                {
                    throw new ArgumentException(
                              $"{type} cannot be used from EntityManager. If it inherits UnityEngine.Component, you must first register TypeManager.UnityEngineComponentType or include the Unity.Entities.Hybrid assembly in your build.");
                }
                if (!UnityEngineComponentType.IsAssignableFrom(type))
                {
                    throw new ArgumentException($"{type} must inherit {UnityEngineComponentType}.");
                }
#endif
            }
            else
            {
                throw new ArgumentException($"{type} is not a valid component.");
            }

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            CheckComponentType(type);
#endif
            int typeIndex = s_Count;
            return(new TypeInfo(type, typeIndex, componentSize, category, typeInfo, entityOffsets, blobAssetRefOffsets, memoryOrdering,
                                bufferCapacity, elementSize > 0 ? elementSize : componentSize, alignmentInBytes, stableTypeHash, writeGroups, writeGroupCount, maxChunkCapacity));
        }
                public void Init()
                {
                    v1 = (float2 *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <float2>() * 100000, UnsafeUtility.AlignOf <float2>(), Allocator.Persistent);
                    for (int i = 0; i < 100000; ++i)
                    {
                        v1[i] = new float2(1.0f);
                    }

                    v2 = (float2 *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <float2>() * 100000, UnsafeUtility.AlignOf <float2>(), Allocator.Persistent);
                    for (int i = 0; i < 100000; ++i)
                    {
                        v2[i] = new float2(2.0f);
                    }

                    result = (float2 *)UnsafeUtility.Malloc(UnsafeUtility.SizeOf <float2>() * 100000, UnsafeUtility.AlignOf <float2>(), Allocator.Persistent);
                    for (int i = 0; i < 100000; ++i)
                    {
                        result[i] = new float2(1.0f);
                    }
                }