/// <summary>
        /// Schedule the job for execution on worker threads.
        /// list.Length is used as the iteration count.
        /// Note that it is required to embed the list on the job struct as well.
        /// </summary>
        /// <param name="jobData">The job and data to schedule.</param>
        /// <param name="list">list.Length is used as the iteration count.</param>
        /// <param name="innerloopBatchCount">Granularity in which workstealing is performed. A value of 32, means the job queue will steal 32 iterations and then perform them in an efficient inner loop.</param>
        /// <param name="dependsOn">Dependencies are used to ensure that a job executes on workerthreads after the dependency has completed execution. Making sure that two jobs reading or writing to same data do not run in parallel.</param>
        /// <returns>JobHandle The handle identifying the scheduled job. Can be used as a dependency for a later job or ensure completion on the main thread.</returns>
        public static unsafe JobHandle Schedule <T, U>(this T jobData, NativeList <U> list, int innerloopBatchCount,
                                                       JobHandle dependsOn = new JobHandle())
            where T : struct, IJobParallelForDefer
            where U : struct
        {
            void *atomicSafetyHandlePtr = null;

            // Calculate the deferred atomic safety handle before constructing JobScheduleParameters so
            // DOTS Runtime can validate the deferred list statically similar to the reflection based
            // validation in Big Unity.
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            var safety = NativeListUnsafeUtility.GetAtomicSafetyHandle(ref list);
            atomicSafetyHandlePtr = UnsafeUtility.AddressOf(ref safety);
#endif

            var scheduleParams = new JobsUtility.JobScheduleParameters(
                UnsafeUtility.AddressOf(ref jobData),
                JobParallelForDeferProducer <T> .Initialize(), dependsOn,
#if UNITY_2020_2_OR_NEWER
                ScheduleMode.Parallel
#else
                ScheduleMode.Batched
#endif
                );

            return(JobsUtility.ScheduleParallelForDeferArraySize(ref scheduleParams, innerloopBatchCount,
                                                                 NativeListUnsafeUtility.GetInternalListDataPtrUnchecked(ref list), atomicSafetyHandlePtr));
        }
Example #2
0
        static unsafe JobHandle Schedule(void *fullData, NativeArray <byte> prefilterData, int unfilteredLength, int innerloopBatchCount,
                                         bool isParallelFor, bool isFiltered, ref JobForEachCache cache, void *deferredCountData, JobHandle dependsOn, ScheduleMode mode)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            try
            {
#endif
            if (isParallelFor)
            {
                var scheduleParams = new JobsUtility.JobScheduleParameters(fullData, cache.JobReflectionDataParallelFor, dependsOn, mode);
                if (isFiltered)
                {
                    return(JobsUtility.ScheduleParallelForDeferArraySize(ref scheduleParams, innerloopBatchCount, deferredCountData, null));
                }
                else
                {
                    return(JobsUtility.ScheduleParallelFor(ref scheduleParams, unfilteredLength, innerloopBatchCount));
                }
            }
            else
            {
                var scheduleParams = new JobsUtility.JobScheduleParameters(fullData, cache.JobReflectionData, dependsOn, mode);
                return(JobsUtility.Schedule(ref scheduleParams));
            }
#if ENABLE_UNITY_COLLECTIONS_CHECKS
        }

        catch (InvalidOperationException e)
        {
            prefilterData.Dispose();
            throw e;
        }
#endif
        }
Example #3
0
        unsafe public static JobHandle ScheduleBatch <T>(this T jobData, ParticleSystem ps, int innerLoopBatchCount, JobHandle dependsOn = new JobHandle()) where T : struct, IJobParticleSystemParallelForBatch
        {
            var scheduleParams = CreateScheduleParams(ref jobData, ps, dependsOn, ParticleSystemParallelForBatchJobStruct <T> .Initialize());
            var handle         = JobsUtility.ScheduleParallelForDeferArraySize(ref scheduleParams, innerLoopBatchCount, ps.GetManagedJobData(), null);

            ps.SetManagedJobHandle(handle);
            return(handle);
        }
        unsafe public static JobHandle Schedule <T>(this T jobData, ParticleSystem ps, int minIndicesPerJobCount, JobHandle dependsOn = new JobHandle()) where T : struct, IJobParticleSystemParallelFor
        {
            var scheduleParams = ParticleSystemJobUtility.CreateScheduleParams(ref jobData, ps, dependsOn, IJobParticleSystemParallelForExtensions.GetReflectionData <T>());
            var handle         = JobsUtility.ScheduleParallelForDeferArraySize(ref scheduleParams, minIndicesPerJobCount, ps.GetManagedJobData(), null);

            ps.SetManagedJobHandle(handle);
            return(handle);
        }
        public static JobHandle ScheduleBatch <T>(this T jobData, ParticleSystem ps, int innerLoopBatchCount, JobHandle dependsOn = default(JobHandle)) where T : struct, IJobParticleSystemParallelForBatch
        {
            JobsUtility.JobScheduleParameters jobScheduleParameters = IParticleSystemJobExtensions.CreateScheduleParams <T>(ref jobData, ps, dependsOn, ParticleSystemParallelForBatchJobStruct <T> .Initialize());
            JobHandle jobHandle = JobsUtility.ScheduleParallelForDeferArraySize(ref jobScheduleParameters, innerLoopBatchCount, ps.GetManagedJobData(), null);

            ps.SetManagedJobHandle(jobHandle);
            return(jobHandle);
        }
        /// <summary>
        /// Schedule the job for execution on worker threads.
        /// forEachCount is a pointer to the number of iterations, when dependsOn has completed.
        /// This API is unsafe, it is recommended to use the NativeList based Schedule method instead.
        /// </summary>
        /// <param name="jobData"></param>
        /// <param name="forEachCount"></param>
        /// <param name="innerloopBatchCount"></param>
        /// <param name="dependsOn"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        unsafe public static JobHandle Schedule <T>(this T jobData, int *forEachCount, int innerloopBatchCount, JobHandle dependsOn = new JobHandle())
            where T : struct, IJobParallelForDefer
        {
            var scheduleParams = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf(ref jobData), JobStructDefer <T> .Initialize(), dependsOn, ScheduleMode.Batched);
            var forEachListPtr = (byte *)forEachCount - sizeof(void *);

            return(JobsUtility.ScheduleParallelForDeferArraySize(ref scheduleParams, innerloopBatchCount, forEachListPtr, null));
        }
Example #7
0
        internal static unsafe JobHandle ScheduleInternal <T>(ref T jobData, EntityQuery query, JobHandle dependsOn, ScheduleMode mode)
            where T : struct, IJobChunk
        {
            ComponentChunkIterator iterator = query.GetComponentChunkIterator();

            var unfilteredChunkCount = query.CalculateChunkCountWithoutFiltering();

            var prefilterHandle = ComponentChunkIterator.PreparePrefilteredChunkLists(unfilteredChunkCount,
                                                                                      iterator.m_MatchingArchetypeList, iterator.m_Filter, dependsOn, mode, out var prefilterData,
                                                                                      out var deferredCountData);

            JobChunkData <T> fullData = new JobChunkData <T>
            {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                // All IJobChunk jobs have a EntityManager safety handle to ensure that BeforeStructuralChange throws an error if
                // jobs without any other safety handles are still running (haven't been synced).
                safety = new EntitySafetyHandle {
                    m_Safety = query.SafetyManager->GetEntityManagerSafetyHandle()
                },
#endif
                Data          = jobData,
                PrefilterData = prefilterData,
            };

            var scheduleParams = new JobsUtility.JobScheduleParameters(
                UnsafeUtility.AddressOf(ref fullData),
                JobChunk_Process <T> .Initialize(),
                prefilterHandle,
                mode);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            try
            {
#endif
            if (mode == ScheduleMode.Batched)
            {
                return(JobsUtility.ScheduleParallelForDeferArraySize(ref scheduleParams, 1, deferredCountData, null));
            }
            else
            {
                var count = unfilteredChunkCount;
                return(JobsUtility.ScheduleParallelFor(ref scheduleParams, count, 1));
            }
#if ENABLE_UNITY_COLLECTIONS_CHECKS
        }

        catch (InvalidOperationException e)
        {
            prefilterData.Dispose();
            throw e;
        }
#endif
        }
        unsafe public static JobHandle Schedule <T, U>(this T jobData, NativeList <U> list, int innerloopBatchCount, JobHandle dependsOn = new JobHandle())
            where T : struct, IJobParallelFor
            where U : struct
        {
            var   scheduleParams        = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf(ref jobData), ParallelForJobStruct <T> .Initialize(), dependsOn, ScheduleMode.Batched);
            void *atomicSafetyHandlePtr = null;

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            var safety = NativeListUnsafeUtility.GetAtomicSafetyHandle(ref list);
            atomicSafetyHandlePtr = UnsafeUtility.AddressOf(ref safety);
#endif
            return(JobsUtility.ScheduleParallelForDeferArraySize(ref scheduleParams, innerloopBatchCount, NativeListUnsafeUtility.GetInternalListDataPtrUnchecked(ref list), atomicSafetyHandlePtr));
        }
Example #9
0
        /// <summary>
        /// Schedule the job for execution on worker threads.
        /// list.Length is used as the iteration count.
        /// Note that it is required to embed the list on the job struct as well.
        /// </summary>
        /// <param name="jobData">The job and data to schedule.</param>
        /// <param name="list">list.Length is used as the iteration count.</param>
        /// <param name="innerloopBatchCount">Granularity in which workstealing is performed. A value of 32, means the job queue will steal 32 iterations and then perform them in an efficient inner loop.</param>
        /// <param name="dependsOn">Dependencies are used to ensure that a job executes on workerthreads after the dependency has completed execution. Making sure that two jobs reading or writing to same data do not run in parallel.</param>
        /// <returns>JobHandle The handle identifying the scheduled job. Can be used as a dependency for a later job or ensure completion on the main thread.</returns>
        public static unsafe JobHandle Schedule <T, U>(this T jobData, NativeList <U> list, int innerloopBatchCount, JobHandle dependsOn = new JobHandle())
            where T : struct, IJobParallelForDefer
            where U : struct
        {
            void *atomicSafetyHandlePtr = null;

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            var safety = NativeListUnsafeUtility.GetAtomicSafetyHandle(ref list);
            atomicSafetyHandlePtr = UnsafeUtility.AddressOf(ref safety);
#endif

#if UNITY_AVOID_REFLECTION
            var listPtr        = (UnsafeList *)NativeListUnsafeUtility.GetInternalListDataPtrUnchecked(ref list);
            var arrayLengthPtr = &listPtr->Length;

            return(Schedule(ref jobData, new IntPtr(arrayLengthPtr), innerloopBatchCount, dependsOn));
#else
            var scheduleParams = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf(ref jobData), JobStructDefer <T> .Initialize(), dependsOn, ScheduleMode.Batched);
            return(JobsUtility.ScheduleParallelForDeferArraySize(ref scheduleParams, innerloopBatchCount, NativeListUnsafeUtility.GetInternalListDataPtrUnchecked(ref list), atomicSafetyHandlePtr));
#endif
        }