예제 #1
0
        public ComponentJobSafetyManager()
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            m_TempSafety = AtomicSafetyHandle.Create();
#endif


            m_ReadJobFences = (JobHandle *)UnsafeUtility.Malloc(sizeof(JobHandle) * kMaxReadJobHandles * kMaxTypes, 16,
                                                                Allocator.Persistent);
            UnsafeUtility.MemClear(m_ReadJobFences, sizeof(JobHandle) * kMaxReadJobHandles * kMaxTypes);

            m_ComponentSafetyHandles =
                (ComponentSafetyHandle *)UnsafeUtility.Malloc(sizeof(ComponentSafetyHandle) * kMaxTypes, 16,
                                                              Allocator.Persistent);
            UnsafeUtility.MemClear(m_ComponentSafetyHandles, sizeof(ComponentSafetyHandle) * kMaxTypes);

            m_JobDependencyCombineBufferCount = 4 * 1024;
            m_JobDependencyCombineBuffer      = (JobHandle *)UnsafeUtility.Malloc(
                sizeof(ComponentSafetyHandle) * m_JobDependencyCombineBufferCount, 16, Allocator.Persistent);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            CreateComponentSafetyHandles(kMaxTypes);
#endif

            m_HasCleanHandles = true;
        }
예제 #2
0
        public ComponentJobSafetyManager()
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            m_TempSafety = AtomicSafetyHandle.Create();
#endif


            m_ReadJobFences = (JobHandle *)UnsafeUtility.Malloc(sizeof(JobHandle) * kMaxReadJobHandles * kMaxTypes, 16,
                                                                Allocator.Persistent);
            UnsafeUtility.MemClear(m_ReadJobFences, sizeof(JobHandle) * kMaxReadJobHandles * kMaxTypes);

            m_ComponentSafetyHandles =
                (ComponentSafetyHandle *)UnsafeUtility.Malloc(sizeof(ComponentSafetyHandle) * kMaxTypes, 16,
                                                              Allocator.Persistent);
            UnsafeUtility.MemClear(m_ComponentSafetyHandles, sizeof(ComponentSafetyHandle) * kMaxTypes);

            m_JobDependencyCombineBufferCount = 4 * 1024;
            m_JobDependencyCombineBuffer      = (JobHandle *)UnsafeUtility.Malloc(
                sizeof(ComponentSafetyHandle) * m_JobDependencyCombineBufferCount, 16, Allocator.Persistent);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            for (var i = 0; i != kMaxTypes; i++)
            {
                m_ComponentSafetyHandles[i].SafetyHandle = AtomicSafetyHandle.Create();
                AtomicSafetyHandle.SetAllowSecondaryVersionWriting(m_ComponentSafetyHandles[i].SafetyHandle, false);
            }
#endif

            m_HasCleanHandles = true;
        }
예제 #3
0
        void CheckJobDependencies(int type, bool isReading, JobHandle dependency)
        {
            var h = m_SafetyManager.GetSafetyHandle(type, true);

            unsafe
            {
                if (!isReading)
                {
                    var        readerCount = AtomicSafetyHandle.GetReaderArray(h, 0, IntPtr.Zero);
                    JobHandle *readers     = stackalloc JobHandle[readerCount];
                    AtomicSafetyHandle.GetReaderArray(h, readerCount, (IntPtr)readers);

                    for (var i = 0; i < readerCount; ++i)
                    {
                        if (!JobHandle.CheckFenceIsDependencyOrDidSyncFence(readers[i], dependency))
                        {
                            throw new InvalidOperationException($"The system {GetType()} reads {TypeManager.GetType(type)} via {AtomicSafetyHandle.GetReaderName(h, i)} but that type was not returned as a job dependency. To ensure correct behavior of other systems, the job or a dependency of it must be returned from the OnUpdate method.");
                        }
                    }
                }

                var writer = AtomicSafetyHandle.GetWriter(h);
                if (!JobHandle.CheckFenceIsDependencyOrDidSyncFence(writer, dependency))
                {
                    throw new InvalidOperationException($"The system {GetType()} writes {TypeManager.GetType(type)} via {AtomicSafetyHandle.GetWriterName(h)} but that was not returned as a job dependency. To ensure correct behavior of other systems, the job or a dependency of it must be returned from the OnUpdate method.");
                }
            }
        }
예제 #4
0
        public void Dispose()
        {
            for (var i = 0; i < kMaxTypes; i++)
            {
                m_ComponentSafetyHandles[i].WriteFence.Complete();
            }

            for (var i = 0; i < kMaxTypes * kMaxReadJobHandles; i++)
            {
                m_ReadJobFences[i].Complete();
            }

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            for (var i = 0; i < kMaxTypes; i++)
            {
                var res = AtomicSafetyHandle.EnforceAllBufferJobsHaveCompletedAndRelease(m_ComponentSafetyHandles[i]
                                                                                         .SafetyHandle);
                if (res == EnforceJobResult.DidSyncRunningJobs)
                {
                    Debug.LogError(
                        "Disposing EntityManager but a job is still running against the ComponentData. It appears the job has not been registered with JobComponentSystem.AddDependency.");
                }
            }

            AtomicSafetyHandle.Release(m_TempSafety);
#endif

            UnsafeUtility.Free(m_JobDependencyCombineBuffer, Allocator.Persistent);

            UnsafeUtility.Free(m_ComponentSafetyHandles, Allocator.Persistent);
            m_ComponentSafetyHandles = null;

            UnsafeUtility.Free(m_ReadJobFences, Allocator.Persistent);
            m_ReadJobFences = null;
        }
        static bool CheckJobDependencies(ref SafetyErrorDetails details, int type, ComponentDependencyManager *dependencyManager)
        {
            var h = dependencyManager->Safety.GetSafetyHandle(type, true);

            var        readerCount = AtomicSafetyHandle.GetReaderArray(h, 0, IntPtr.Zero);
            JobHandle *readers     = stackalloc JobHandle[readerCount];

            AtomicSafetyHandle.GetReaderArray(h, readerCount, (IntPtr)readers);

            for (var i = 0; i < readerCount; ++i)
            {
                if (!dependencyManager->HasReaderOrWriterDependency(type, readers[i]))
                {
                    details.m_ProblematicTypeIndex = type;
                    details.m_ProblematicHandle    = h;
                    details.m_ReaderIndex          = i;
                    return(true);
                }
            }

            if (!dependencyManager->HasReaderOrWriterDependency(type, AtomicSafetyHandle.GetWriter(h)))
            {
                details.m_ProblematicTypeIndex = type;
                details.m_ProblematicHandle    = h;
                details.m_ReaderIndex          = -1;
                return(true);
            }

            return(false);
        }
        public void OnCreate()
        {
            m_TypeArrayIndices = (ushort *)UnsafeUtility.Malloc(sizeof(ushort) * kMaxTypes, 16, Allocator.Persistent);
            UnsafeUtility.MemSet(m_TypeArrayIndices, 0xFF, sizeof(ushort) * kMaxTypes);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            m_TempSafety = AtomicSafetyHandle.Create();
#endif
            m_ReadJobFences = (JobHandle *)UnsafeUtility.Malloc(sizeof(JobHandle) * kMaxReadJobHandles * kMaxTypes, 16,
                                                                Allocator.Persistent);
            UnsafeUtility.MemClear(m_ReadJobFences, sizeof(JobHandle) * kMaxReadJobHandles * kMaxTypes);

            m_ComponentSafetyHandles =
                (ComponentSafetyHandle *)UnsafeUtility.Malloc(sizeof(ComponentSafetyHandle) * kMaxTypes, 16,
                                                              Allocator.Persistent);
            UnsafeUtility.MemClear(m_ComponentSafetyHandles, sizeof(ComponentSafetyHandle) * kMaxTypes);

            m_JobDependencyCombineBufferCount = 4 * 1024;
            m_JobDependencyCombineBuffer      = (JobHandle *)UnsafeUtility.Malloc(
                sizeof(ComponentSafetyHandle) * m_JobDependencyCombineBufferCount, 16, Allocator.Persistent);

            m_TypeCount     = 0;
            IsInTransaction = false;
            IsInForEachDisallowStructuralChange = 0;
            m_ExclusiveTransactionDependency    = default(JobHandle);
        }
        public void Dispose()
        {
            for (var i = 0; i < m_DependencyHandlesCount; i++)
            {
                m_DependencyHandles[i].WriteFence.Complete();
            }

            for (var i = 0; i < m_DependencyHandlesCount * kMaxReadJobHandles; i++)
            {
                m_ReadJobFences[i].Complete();
            }

            Memory.Unmanaged.Free(m_JobDependencyCombineBuffer, Allocator.Persistent);

            Memory.Unmanaged.Free(m_TypeArrayIndices, Allocator.Persistent);
            Memory.Unmanaged.Free(m_DependencyHandles, Allocator.Persistent);
            m_DependencyHandles = null;

            Memory.Unmanaged.Free(m_ReadJobFences, Allocator.Persistent);
            m_ReadJobFences = null;

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            Safety.Dispose();
#endif
        }
예제 #8
0
        public void OnCreate(WorldUnmanaged world)
        {
            m_World            = world;
            m_TypeArrayIndices = (ushort *)Memory.Unmanaged.Allocate(sizeof(ushort) * kMaxTypes, 16, Allocator.Persistent);
            UnsafeUtility.MemSet(m_TypeArrayIndices, 0xFF, sizeof(ushort) * kMaxTypes);

            m_ReadJobFences = (JobHandle *)Memory.Unmanaged.Allocate(sizeof(JobHandle) * kMaxReadJobHandles * kMaxTypes, 16, Allocator.Persistent);
            UnsafeUtility.MemClear(m_ReadJobFences, sizeof(JobHandle) * kMaxReadJobHandles * kMaxTypes);

            m_DependencyHandles = (DependencyHandle *)Memory.Unmanaged.Allocate(sizeof(DependencyHandle) * kMaxTypes, 16, Allocator.Persistent);
            UnsafeUtility.MemClear(m_DependencyHandles, sizeof(DependencyHandle) * kMaxTypes);

            m_JobDependencyCombineBufferCount = 4 * 1024;
            m_JobDependencyCombineBuffer      = (JobHandle *)Memory.Unmanaged.Allocate(sizeof(DependencyHandle) * m_JobDependencyCombineBufferCount, 16, Allocator.Persistent);

            m_DependencyHandlesCount            = 0;
            _IsInTransaction                    = false;
            IsInForEachDisallowStructuralChange = 0;
            m_ExclusiveTransactionDependency    = default;

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            Safety.OnCreate();
#endif
            m_Marker = new ProfilerMarker("CompleteAllJobs");
        }
예제 #9
0
        private unsafe string CheckJobDependencies(int type)
        {
            AtomicSafetyHandle safetyHandle = this.m_SafetyManager.GetSafetyHandle(type, true);
            int        maxCount             = AtomicSafetyHandle.GetReaderArray(safetyHandle, 0, IntPtr.Zero);
            JobHandle *handlePtr            = (JobHandle *)stackalloc byte[(((IntPtr)maxCount) * sizeof(JobHandle))];

            AtomicSafetyHandle.GetReaderArray(safetyHandle, maxCount, (IntPtr)handlePtr);
            int index = 0;

            while (true)
            {
                string str;
                if (index < maxCount)
                {
                    if (this.m_SafetyManager.HasReaderOrWriterDependency(type, handlePtr[index]))
                    {
                        index++;
                        continue;
                    }
                    str = $"The system {base.GetType()} reads {TypeManager.GetType(type)} via {AtomicSafetyHandle.GetReaderName(safetyHandle, index)} but that type was not returned as a job dependency. To ensure correct behavior of other systems, the job or a dependency of it must be returned from the OnUpdate method.";
                }
                else if (!this.m_SafetyManager.HasReaderOrWriterDependency(type, AtomicSafetyHandle.GetWriter(safetyHandle)))
                {
                    str = $"The system {base.GetType()} writes {TypeManager.GetType(type)} via {AtomicSafetyHandle.GetWriterName(safetyHandle)} but that was not returned as a job dependency. To ensure correct behavior of other systems, the job or a dependency of it must be returned from the OnUpdate method.";
                }
                else
                {
                    str = null;
                }
                return(str);
            }
        }
예제 #10
0
        public void OnCreate()
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            m_TempSafety = AtomicSafetyHandle.Create();
#endif
            m_ReadJobFences = (JobHandle *)UnsafeUtility.Malloc(sizeof(JobHandle) * kMaxReadJobHandles * kMaxTypes, 16,
                                                                Allocator.Persistent);
            UnsafeUtility.MemClear(m_ReadJobFences, sizeof(JobHandle) * kMaxReadJobHandles * kMaxTypes);

            m_ComponentSafetyHandles =
                (ComponentSafetyHandle *)UnsafeUtility.Malloc(sizeof(ComponentSafetyHandle) * kMaxTypes, 16,
                                                              Allocator.Persistent);
            UnsafeUtility.MemClear(m_ComponentSafetyHandles, sizeof(ComponentSafetyHandle) * kMaxTypes);

            m_JobDependencyCombineBufferCount = 4 * 1024;
            m_JobDependencyCombineBuffer      = (JobHandle *)UnsafeUtility.Malloc(
                sizeof(ComponentSafetyHandle) * m_JobDependencyCombineBufferCount, 16, Allocator.Persistent);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            CreateComponentSafetyHandles(kMaxTypes);
#endif

            m_HasCleanHandles = true;
            IsInTransaction   = false;
            m_ExclusiveTransactionDependency = default(JobHandle);
        }
        public static JobHandle ScheduleJob(JobBucket *bucket, System.Action action, JobHandle *dependedHandles, uint dependCount)
        {
            JobHandle handle;

            System.IntPtr ptr = Marshal.GetFunctionPointerForDelegate(action);
            ScheduleJob(handle.Ptr(), bucket, (void *)ptr, dependedHandles, dependCount);
            return(handle);
        }
예제 #12
0
        public JobHandle AddDependency(int *readerTypes, int readerTypesCount, int *writerTypes, int writerTypesCount,
                                       JobHandle dependency)
        {
            #if ENABLE_UNITY_COLLECTIONS_CHECKS
            JobHandle *combinedDependencies      = null;
            int        combinedDependenciesCount = 0;
            #endif

            for (var i = 0; i != writerTypesCount; i++)
            {
                var writer = writerTypes[i];
                m_ComponentSafetyHandles[writer].WriteFence = dependency;
            }


            for (var i = 0; i != readerTypesCount; i++)
            {
                var reader = readerTypes[i];
                m_ReadJobFences[reader * kMaxReadJobHandles + m_ComponentSafetyHandles[reader].NumReadFences] =
                    dependency;
                m_ComponentSafetyHandles[reader].NumReadFences++;

                if (m_ComponentSafetyHandles[reader].NumReadFences == kMaxReadJobHandles)
                {
                    #if ENABLE_UNITY_COLLECTIONS_CHECKS
                    var combined = CombineReadDependencies(reader);
                    if (combinedDependencies == null)
                    {
                        JobHandle *temp = stackalloc JobHandle[readerTypesCount];
                        combinedDependencies = temp;
                    }

                    combinedDependencies[combinedDependenciesCount++] = combined;
                    #else
                    CombineReadDependencies(reader);
                    #endif
                }
            }

            if (readerTypesCount != 0 || writerTypesCount != 0)
            {
                m_HasCleanHandles = false;
            }

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (combinedDependencies != null)
            {
                return(Unity.Jobs.LowLevel.Unsafe.JobHandleUnsafeUtility.CombineDependencies(combinedDependencies, combinedDependenciesCount));
            }
            else
            {
                return(dependency);
            }
#else
            return(dependency);
#endif
        }
예제 #13
0
        public unsafe static void CompleteAll(ref JobHandle job0, ref JobHandle job1)
        {
            JobHandle *ptr = stackalloc JobHandle[2];

            *ptr = job0;
            ptr[1] = job1;
            JobHandle.ScheduleBatchedJobsAndCompleteAll((IntPtr)((void *)ptr), 2);
            job0 = default(JobHandle);
            job1 = default(JobHandle);
        }
예제 #14
0
        public static unsafe JobHandle CombineDependencies(JobHandle *jobs, int count)
        {
#if UNITY_SINGLETHREADED_JOBS
            return(default(JobHandle));
#else
            var fence = new JobHandle();
            JobsUtility.ScheduleMultiDependencyJob(ref fence, JobsUtility.BatchScheduler, new IntPtr(jobs), count);
            return(fence);
#endif
        }
예제 #15
0
 private void DeleteCommentComplete()
 {
     for (int i = 0; i < Length; i++)
     {
         DeleteCommentJobHandles[i].Complete();
     }
     UnsafeUtility.Free(DeleteCommentJobHandles, allocator);
     DeleteCommentJobHandles = null;
     _currentStage           = Stage.Done;
 }
예제 #16
0
        unsafe static void ScheduleNode(ref JobHandle *jobSched, JobHandle *jobDepends, Node *node, Point3 *points, int offset, int length, int depth, int depthSingleThreaded)
        {
            // pick median
            int median = length >> 1;

            // calc offsets
            var offsetL = offset;
            var offsetR = offset + median + 1;
            var lengthL = median;
            var lengthR = length - median - 1;
            var stepL   = lengthL > 0 ? 1 : 0;
            var stepR   = lengthR > 0 ? 1 + lengthL : 0;

            // make job
            var job = new BuildNodeJob()
            {
                node   = node,
                points = points,
                offset = offset,
                length = length,
                depth  = depth,
                leaf   = (depth >= depthSingleThreaded),
            };

            var jobHandle = jobSched++;

            if (jobDepends != null)
            {
                *jobHandle = job.Schedule(*jobDepends);
            }
            else
            {
                *jobHandle = job.Schedule();
            }

            if (depth == 0)
            {
                JobHandle.ScheduleBatchedJobs();
            }

            if (job.leaf)
            {
                return;
            }

            // schedule subtrees
            if (lengthL > 0)
            {
                ScheduleNode(ref jobSched, jobHandle, node + stepL, points, offsetL, lengthL, depth + 1, depthSingleThreaded);
            }
            if (lengthR > 0)
            {
                ScheduleNode(ref jobSched, jobHandle, node + stepR, points, offsetR, lengthR, depth + 1, depthSingleThreaded);
            }
        }
예제 #17
0
        unsafe public static void CompleteAll(ref JobHandle job0, ref JobHandle job1)
        {
            JobHandle *jobs = stackalloc JobHandle[2];

            jobs[0] = job0;
            jobs[1] = job1;
            ScheduleBatchedJobsAndCompleteAll(jobs, 2);

            job0 = new JobHandle();
            job1 = new JobHandle();
        }
        public unsafe int GetReaderArray(int maxCount, JobHandle *handles)
        {
            int result = 0;

            fixed(AtomicSafetyHandle *ash = &this)
            {
                result = AtomicSafetyHandle_GetReaderArray(ash, maxCount, handles);
            }

            ExceptionReporter.Check();
            return(result);
        }
예제 #19
0
        public unsafe static void CompleteAll(ref JobHandle job0, ref JobHandle job1, ref JobHandle job2)
        {
            JobHandle *ptr = stackalloc JobHandle[3];

            *ptr = job0;
            ptr[1] = job1;
            ptr[sizeof(JobHandle) * 2 / sizeof(JobHandle)] = job2;
            JobHandle.ScheduleBatchedJobsAndCompleteAll((IntPtr)((void *)ptr), 3);
            job0 = default(JobHandle);
            job1 = default(JobHandle);
            job2 = default(JobHandle);
        }
예제 #20
0
        public unsafe JobHandle Dispose(JobHandle inputDeps)
        {
            JobHandle *deps = stackalloc JobHandle[5]
            {
                bucketStartsAndCounts.Dispose(inputDeps),
                xmins.Dispose(inputDeps),
                xmaxs.Dispose(inputDeps),
                yzminmaxs.Dispose(inputDeps),
                bodies.Dispose(inputDeps)
            };

            return(Unity.Jobs.LowLevel.Unsafe.JobHandleUnsafeUtility.CombineDependencies(deps, 5));
        }
예제 #21
0
        public static unsafe JobHandle CombineDependencies(JobHandle *jobs, int count)
        {
            var fence = new JobHandle();

#if UNITY_SINGLETHREADED_JOBS
            fence.JobGroup = JobsUtility.GetFakeJobGroupId();
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            JobsUtility.DebugDidScheduleJob(ref fence, jobs, count);
#endif
#else
            JobsUtility.ScheduleMultiDependencyJob(ref fence, JobsUtility.BatchScheduler, jobs, count);
#endif
            return(fence);
        }
예제 #22
0
        public unsafe int GetReaderArray(int maxCount, JobHandle *handles)
        {
            AtomicSafetyNode *node = GetInternalNode();

            if (node == null)
            {
                return(0);
            }

            int count = node->readerCount < maxCount ? node->readerCount : maxCount;

            for (int i = 0; i < count; i++)
            {
                handles[i] = node->readers[i].fence;
            }

            return(node->readerCount);
        }
        static string CheckJobDependencies(object system, int type, ComponentDependencyManager *dependencyManager)
        {
            var h = dependencyManager->Safety.GetSafetyHandle(type, true);

            var        readerCount = AtomicSafetyHandle.GetReaderArray(h, 0, IntPtr.Zero);
            JobHandle *readers     = stackalloc JobHandle[readerCount];

            AtomicSafetyHandle.GetReaderArray(h, readerCount, (IntPtr)readers);

            for (var i = 0; i < readerCount; ++i)
            {
                if (!dependencyManager->HasReaderOrWriterDependency(type, readers[i]))
                {
                    if (IsSystemV1(system))
                    {
                        return($"The system {system.GetType()} reads {TypeManager.GetType(type)} via {AtomicSafetyHandle.GetReaderName(h, i)} but that type was not returned as a job dependency. To ensure correct behavior of other systems, the job or a dependency of it must be returned from the OnUpdate method.");
                    }
                    else
                    {
                        return($"The system {system.GetType()} reads {TypeManager.GetType(type)} via {AtomicSafetyHandle.GetReaderName(h, i)} but that type was not assigned to the Dependency property. To ensure correct behavior of other systems, the job or a dependency must be assigned to the Dependency property before returning from the OnUpdate method.");
                    }
                }
            }

            if (!dependencyManager->HasReaderOrWriterDependency(type, AtomicSafetyHandle.GetWriter(h)))
            {
                if (IsSystemV1(system))
                {
                    return($"The system {system.GetType()} writes {TypeManager.GetType(type)} via {AtomicSafetyHandle.GetWriterName(h)} but that was not returned as a job dependency. To ensure correct behavior of other systems, the job or a dependency of it must be returned from the OnUpdate method.");
                }
                else
                {
                    return($"The system {system.GetType()} writes {TypeManager.GetType(type)} via {AtomicSafetyHandle.GetWriterName(h)} but that type was not assigned to the Dependency property. To ensure correct behavior of other systems, the job or a dependency must be assigned to the Dependency property before returning from the OnUpdate method.");
                }
            }

            return(null);
        }
예제 #24
0
            private void DeleteCommentAsyncUpdate()
            {
                bool isAnyRunning = false;

                for (int i = 0; i < Length; i++)
                {
                    if (!DeleteCommentJobHandles[i].IsCompleted)
                    {
                        isAnyRunning = true;
                        continue;
                    }
                    DeleteCommentJobHandles[i].Complete();
                }
                if (isAnyRunning)
                {
                    return;
                }
                if (DeleteCommentJobHandles != null)
                {
                    UnsafeUtility.Free(DeleteCommentJobHandles, allocator);
                    DeleteCommentJobHandles = null;
                }
                _currentStage = Stage.Done;
            }
예제 #25
0
        unsafe string CheckJobDependencies(int type)
        {
            var h = m_SafetyManager.GetSafetyHandle(type, true);

            var        readerCount = AtomicSafetyHandle.GetReaderArray(h, 0, IntPtr.Zero);
            JobHandle *readers     = stackalloc JobHandle[readerCount];

            AtomicSafetyHandle.GetReaderArray(h, readerCount, (IntPtr)readers);

            for (var i = 0; i < readerCount; ++i)
            {
                if (!m_SafetyManager.HasReaderOrWriterDependency(type, readers[i]))
                {
                    return($"The system {GetType()} reads {TypeManager.GetType(type)} via {AtomicSafetyHandle.GetReaderName(h, i)} but that type was not returned as a job dependency. To ensure correct behavior of other systems, the job or a dependency of it must be returned from the OnUpdate method.");
                }
            }

            if (!m_SafetyManager.HasReaderOrWriterDependency(type, AtomicSafetyHandle.GetWriter(h)))
            {
                return($"The system {GetType()} writes {TypeManager.GetType(type)} via {AtomicSafetyHandle.GetWriterName(h)} but that was not returned as a job dependency. To ensure correct behavior of other systems, the job or a dependency of it must be returned from the OnUpdate method.");
            }

            return(null);
        }
예제 #26
0
 unsafe public static JobHandle CombineDependencies(JobHandle *jobs, int count)
 {
     return(JobHandle.CombineDependenciesInternalPtr(jobs, count));
 }
        public JobHandle AddDependency(int *readerTypes, int readerTypesCount, int *writerTypes, int writerTypesCount,
                                       JobHandle dependency)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            JobHandle *combinedDependencies      = null;
            var        combinedDependenciesCount = 0;
#endif
            if (readerTypesCount == 0 && writerTypesCount == 0)
            {
                ushort entityTypeArrayIndex = GetTypeArrayIndex(EntityTypeIndex);
                // if no dependency types are provided add read dependency to the Entity type
                // to ensure these jobs are still synced by CompleteAllJobsAndInvalidateArrays
                m_ReadJobFences[entityTypeArrayIndex * kMaxReadJobHandles +
                                m_DependencyHandles[entityTypeArrayIndex].NumReadFences] = dependency;
                m_DependencyHandles[entityTypeArrayIndex].NumReadFences++;

                if (m_DependencyHandles[entityTypeArrayIndex].NumReadFences == kMaxReadJobHandles)
                {
                    //@TODO: Check dynamically if the job debugger is enabled?
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                    return(CombineReadDependencies(entityTypeArrayIndex));
#else
                    CombineReadDependencies(entityTypeArrayIndex);
#endif
                }
                return(dependency);
            }

            for (var i = 0; i != writerTypesCount; i++)
            {
                m_DependencyHandles[GetTypeArrayIndex(writerTypes[i])].WriteFence = dependency;
            }


            for (var i = 0; i != readerTypesCount; i++)
            {
                var reader = GetTypeArrayIndex(readerTypes[i]);
                m_ReadJobFences[reader * kMaxReadJobHandles + m_DependencyHandles[reader].NumReadFences] =
                    dependency;
                m_DependencyHandles[reader].NumReadFences++;

                if (m_DependencyHandles[reader].NumReadFences == kMaxReadJobHandles)
                {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                    var combined = CombineReadDependencies(reader);
                    if (combinedDependencies == null)
                    {
                        JobHandle *temp = stackalloc JobHandle[readerTypesCount];
                        combinedDependencies = temp;
                    }

                    combinedDependencies[combinedDependenciesCount++] = combined;
#else
                    CombineReadDependencies(reader);
#endif
                }
            }

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (combinedDependencies != null)
            {
                return(JobHandleUnsafeUtility.CombineDependencies(combinedDependencies, combinedDependenciesCount));
            }
            return(dependency);
#else
            return(dependency);
#endif
        }
 [DllImport("JobSystemDLL")] private static extern void ScheduleJob(JobHandle *handle, JobBucket *bucket, void *funcPtr, JobHandle *dependedHandles, uint dependCount);
예제 #29
0
        public JobHandle AddDependency(int *readerTypes, int readerTypesCount, int *writerTypes, int writerTypesCount,
                                       JobHandle dependency)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            JobHandle *combinedDependencies      = null;
            var        combinedDependenciesCount = 0;
#endif
            m_HasCleanHandles = false;

            if (readerTypesCount == 0 && writerTypesCount == 0)
            {
                // if no dependency types are provided add read dependency to the Entity type
                // to ensure these jobs are still synced by CompleteAllJobsAndInvalidateArrays
                m_ReadJobFences[EntityTypeIndex * kMaxReadJobHandles +
                                m_ComponentSafetyHandles[EntityTypeIndex].NumReadFences] = dependency;
                m_ComponentSafetyHandles[EntityTypeIndex].NumReadFences++;

                if (m_ComponentSafetyHandles[EntityTypeIndex].NumReadFences == kMaxReadJobHandles)
                {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                    return(CombineReadDependencies(EntityTypeIndex));
#else
                    CombineReadDependencies(EntityTypeIndex);
#endif
                }
                return(dependency);
            }

            for (var i = 0; i != writerTypesCount; i++)
            {
                var writer = writerTypes[i] & TypeManager.ClearFlagsMask;
                m_ComponentSafetyHandles[writer].WriteFence = dependency;
            }


            for (var i = 0; i != readerTypesCount; i++)
            {
                var reader = readerTypes[i] & TypeManager.ClearFlagsMask;
                m_ReadJobFences[reader * kMaxReadJobHandles + m_ComponentSafetyHandles[reader].NumReadFences] =
                    dependency;
                m_ComponentSafetyHandles[reader].NumReadFences++;

                if (m_ComponentSafetyHandles[reader].NumReadFences == kMaxReadJobHandles)
                {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                    var combined = CombineReadDependencies(reader);
                    if (combinedDependencies == null)
                    {
                        JobHandle *temp = stackalloc JobHandle[readerTypesCount];
                        combinedDependencies = temp;
                    }

                    combinedDependencies[combinedDependenciesCount++] = combined;
#else
                    CombineReadDependencies(reader);
#endif
                }
            }

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (combinedDependencies != null)
            {
                return(JobHandleUnsafeUtility.CombineDependencies(combinedDependencies, combinedDependenciesCount));
            }
            return(dependency);
#else
            return(dependency);
#endif
        }
예제 #30
0
        // Schedule all the jobs for the simulation step.
        // Enqueued callbacks can choose to inject additional jobs at defined sync points.
        public unsafe void ScheduleStepJobs(SimulationStepInput input, JobHandle inputDeps)
        {
            if (input.TimeStep < 0)
            {
                throw new ArgumentOutOfRangeException();
            }
            if (input.ThreadCountHint <= 0)
            {
                throw new ArgumentOutOfRangeException();
            }
            if (input.NumSolverIterations <= 0)
            {
                throw new ArgumentOutOfRangeException();
            }

            // Dispose event streams from previous frame
            JobHandle handle = DisposeEventStreams(inputDeps);

            // Allocate storage for input velocities
            m_Storage.InputVelocityCount = input.World.NumDynamicBodies;

            m_Context = new Context
            {
                TimeStep        = input.TimeStep,
                InputVelocities = m_Storage.InputVelocities
            };

            if (input.World.NumDynamicBodies == 0)
            {
                // No need to do anything, since nothing can move
                FinalSimulationJobHandle = handle;
                FinalJobHandle           = handle;
                return;
            }

            SimulationCallbacks callbacks = input.Callbacks ?? new SimulationCallbacks();

            // Find all body pairs that overlap in the broadphase
            handle = input.World.CollisionWorld.Broadphase.ScheduleFindOverlapsJobs(
                out BlockStream dynamicVsDynamicBodyPairs, out BlockStream dynamicVsStaticBodyPairs, ref m_Context, handle);
            var postOverlapsHandle = handle;

            // Sort all overlapping and jointed body pairs into phases
            handle = m_Scheduler.ScheduleCreatePhasedDispatchPairsJob(
                ref input.World, ref dynamicVsDynamicBodyPairs, ref dynamicVsStaticBodyPairs, ref m_Context, handle);

            // Apply gravity and copy input velocities at this point (in parallel with the scheduler, but before the callbacks)
            var applyGravityAndCopyInputVelocitiesHandle = Solver.ScheduleApplyGravityAndCopyInputVelocitiesJob(
                ref input.World.DynamicsWorld, m_Storage.InputVelocities, input.TimeStep * input.Gravity, postOverlapsHandle);

            handle = JobHandle.CombineDependencies(handle, applyGravityAndCopyInputVelocitiesHandle);
            handle = callbacks.Execute(SimulationCallbacks.Phase.PostCreateDispatchPairs, this, ref input.World, handle);

            // Create contact points & joint Jacobians
            handle = NarrowPhase.ScheduleProcessBodyPairsJobs(ref input.World, input.TimeStep, input.NumSolverIterations, ref m_Context, handle);
            handle = callbacks.Execute(SimulationCallbacks.Phase.PostCreateContacts, this, ref input.World, handle);

            // Create contact Jacobians
            handle = Solver.ScheduleBuildContactJacobiansJobs(ref input.World.DynamicsWorld, input.TimeStep, math.length(input.Gravity), ref m_Context, handle);
            handle = callbacks.Execute(SimulationCallbacks.Phase.PostCreateContactJacobians, this, ref input.World, handle);

            // Solve all Jacobians
            handle = Solver.ScheduleSolveJacobiansJobs(ref input.World.DynamicsWorld, input.TimeStep, input.NumSolverIterations, ref m_Context, handle);
            handle = callbacks.Execute(SimulationCallbacks.Phase.PostSolveJacobians, this, ref input.World, handle);

            // Integrate motions
            handle = Integrator.ScheduleIntegrateJobs(ref input.World.DynamicsWorld, input.TimeStep, handle);

            // Synchronize the collision world
            if (input.SynchronizeCollisionWorld)
            {
                handle = input.World.CollisionWorld.ScheduleUpdateDynamicLayer(ref input.World, input.TimeStep, input.Gravity, input.ThreadCountHint, handle);  // TODO: timeStep = 0?
            }

            // Return the final simulation handle
            FinalSimulationJobHandle = handle;

            // Return the final handle, which includes disposing temporary arrays
            JobHandle *deps = stackalloc JobHandle[11]
            {
                FinalSimulationJobHandle,
                m_Context.DisposeOverlapPairs0,
                m_Context.DisposeOverlapPairs1,
                m_Context.DisposeBroadphasePairs0,
                m_Context.DisposeBroadphasePairs1,
                m_Context.DisposeContacts,
                m_Context.DisposeJacobians,
                m_Context.DisposeJointJacobians,
                m_Context.DisposeSolverSchedulerData,
                m_Context.DisposeProcessBodyPairs,
                m_Context.DisposePhasedDispatchPairs
            };

            FinalJobHandle = JobHandleUnsafeUtility.CombineDependencies(deps, 11);
        }