static public int constructor(IntPtr l) { try { Unity.Jobs.JobHandle o; o = new Unity.Jobs.JobHandle(); pushValue(l, true); pushValue(l, o); return(2); } catch (Exception e) { return(error(l, e)); } }
protected override JobHandle OnUpdate(Unity.Jobs.JobHandle inputDeps) { if (_enemy.Position.Length == 0 || _player.Positions.Length == 0) { return(inputDeps); } float3 player_pos = _player.Positions[0].Value; return(new ControlEnemy { PlayerPos = player_pos, // UnitPos = _enemy.Position[0].Value, Dt = Time.deltaTime }.Schedule(this, inputDeps)); }
public Unity.Jobs.JobHandle AllocateNodesJob <T>(T[] result, int count, System.Func <T> createNode) where T : GraphNode { if (!queue.AllReceiversBlocked) { throw new System.Exception("Trying to initialize a node when it is not safe to initialize any nodes. Must be done during a graph update. See http://arongranberg.com/astar/docs/graph-updates.php#direct"); } // Get all node indices that we are going to recycle and store them in a new buffer. // It's best to store them in a new buffer to avoid multithreading issues. var numRecycledNodeIndices = math.min(nodeIndexPool.Count, count); var recyledNodeIndices = ArrayPool <int> .Claim(numRecycledNodeIndices); nodeIndexPool.PopMany(recyledNodeIndices, numRecycledNodeIndices); // Highest node index + 1 in the new list of nodes var newNextNodeIndex = nextNodeIndex + (count - numRecycledNodeIndices); reservedPathNodeData = math.max(reservedPathNodeData, math.ceilpow2(newNextNodeIndex)); // It may be tempting to use a parallel job for this // but it seems like allocation (new) in C# uses some kind of locking. // Therefore it is not faster (it may even be slower) to try to allocate the nodes in multiple threads in parallel. lastAllocationJob = new JobAllocateNodes <T> { result = result, count = count, pathProcessor = this, recyledNodeIndices = recyledNodeIndices, numRecycledNodeIndices = numRecycledNodeIndices, startingNodeIndex = nextNodeIndex, reservedPathNodeData = reservedPathNodeData, createNode = createNode, }.ScheduleManaged(lastAllocationJob); // Mark the node indices as used nextNodeIndex = newNextNodeIndex; return(lastAllocationJob); }
unsafe public static JobHandle Schedule <T>(this T jobData, int arrayLength, int innerloopBatchCount, JobHandle dependsOn = new JobHandle()) where T : struct, IJobParallelFor { var scheduleParams = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf(ref jobData), GetReflectionData <T>(), dependsOn, ScheduleMode.Parallel); return(JobsUtility.ScheduleParallelFor(ref scheduleParams, arrayLength, innerloopBatchCount)); }
public static unsafe JobHandle ScheduleFilter <T>(this T jobData, NativeList <int> indices, int innerloopBatchCount, JobHandle dependsOn = new JobHandle()) where T : struct, IJobParallelForFilter { JobStructProduce <T> .JobDataWithFiltering fullData = new JobStructProduce <T> .JobDataWithFiltering() { data = jobData, outputIndices = indices, appendCount = -1 }; var scheduleParams = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf(ref fullData), JobStructProduce <T> .Initialize(), dependsOn, ScheduleMode.Batched); return(JobsUtility.Schedule(ref scheduleParams)); }
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 public JobHandle ScheduleBatch <T>(this T jobData, int arrayLength, int minIndicesPerJobCount, JobHandle dependsOn = new JobHandle()) where T : struct, IJobParallelForBatch { var scheduleParams = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf(ref jobData), ParallelForBatchJobStruct <T> .Initialize(), dependsOn, ScheduleMode.Parallel); return(JobsUtility.ScheduleParallelFor(ref scheduleParams, arrayLength, minIndicesPerJobCount)); }
public static unsafe JobHandle ScheduleBatch <T>(this T jobData, int arrayLength, int minIndicesPerJobCount, JobHandle dependsOn = new JobHandle()) where T : struct, IJobParallelForBatch { #if UNITY_SINGLETHREADED_JOBS jobData.Execute(0, arrayLength); DoDeallocateOnJobCompletion(jobData); return(new JobHandle()); #elif UNITY_DOTSPLAYER var jobStruct = new ParallelForBatchJobStruct <T>() { JobData = jobData, Ranges = new JobRanges() { ArrayLength = arrayLength, IndicesPerPhase = JobsUtility.GetDefaultIndicesPerPhase(arrayLength) }, }; var jobDataPtr = UnsafeUtility.Malloc(UnsafeUtility.SizeOf <ParallelForBatchJobStruct <T> >(), UnsafeUtility.AlignOf <ParallelForBatchJobStruct <T> >(), Allocator.TempJob); UnsafeUtility.CopyStructureToPtr(ref jobStruct, jobDataPtr); var scheduleParams = new JobsUtility.JobScheduleParameters(jobDataPtr, ParallelForBatchJobStruct <T> .Initialize(), dependsOn, ScheduleMode.Batched); return(JobsUtility.ScheduleParallelFor(ref scheduleParams, arrayLength, minIndicesPerJobCount)); #else var scheduleParams = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf(ref jobData), ParallelForBatchJobStruct <T> .Initialize(), dependsOn, ScheduleMode.Batched); return(JobsUtility.ScheduleParallelFor(ref scheduleParams, arrayLength, minIndicesPerJobCount)); #endif }
public static unsafe JobHandle ScheduleBatch <T>(this T jobData, int arrayLength, int minIndicesPerJobCount, JobHandle dependsOn = new JobHandle()) where T : struct, IJobParallelForBatch { #if UNITY_AVOID_REFLECTION // Protect against garbage collection if (!ParallelForBatchJobStruct <T> .ExecuteHandle.IsAllocated) { ParallelForBatchJobStruct <T> .ExecuteDelegate = ParallelForBatchJobStruct <T> .Execute; ParallelForBatchJobStruct <T> .ExecuteHandle = GCHandle.Alloc(ParallelForBatchJobStruct <T> .ExecuteDelegate); ParallelForBatchJobStruct <T> .ExecuteFunctionPtr = Marshal.GetFunctionPointerForDelegate(ParallelForBatchJobStruct <T> .ExecuteDelegate); } // Protect against garbage collection if (!ParallelForBatchJobStruct <T> .CleanupHandle.IsAllocated) { ParallelForBatchJobStruct <T> .CleanupDelegate = ParallelForBatchJobStruct <T> .Cleanup; ParallelForBatchJobStruct <T> .CleanupHandle = GCHandle.Alloc(ParallelForBatchJobStruct <T> .CleanupDelegate); ParallelForBatchJobStruct <T> .CleanupFunctionPtr = Marshal.GetFunctionPointerForDelegate(ParallelForBatchJobStruct <T> .CleanupDelegate); } var jobFunctionPtr = ParallelForBatchJobStruct <T> .ExecuteFunctionPtr; var completionFuncPtr = ParallelForBatchJobStruct <T> .CleanupFunctionPtr; var jobStruct = new ParallelForBatchJobStruct <T>() { JobData = jobData, Ranges = new JobRanges() { ArrayLength = arrayLength, IndicesPerPhase = JobsUtility.GetDefaultIndicesPerPhase(arrayLength) }, }; var jobDataPtr = UnsafeUtility.Malloc(UnsafeUtility.SizeOf <ParallelForBatchJobStruct <T> >(), UnsafeUtility.AlignOf <ParallelForBatchJobStruct <T> >(), Allocator.TempJob); UnsafeUtility.CopyStructureToPtr(ref jobStruct, jobDataPtr); return(JobsUtility.ScheduleJobForEach(jobFunctionPtr, completionFuncPtr, new IntPtr(jobDataPtr), arrayLength, minIndicesPerJobCount, dependsOn)); #else var scheduleParams = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf(ref jobData), ParallelForBatchJobStruct <T> .Initialize(), dependsOn, ScheduleMode.Batched); return(JobsUtility.ScheduleParallelFor(ref scheduleParams, arrayLength, minIndicesPerJobCount)); #endif }
/// <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> unsafe public static JobHandle Schedule <T, U>(this T jobData, NativeList <U> list, int innerloopBatchCount, JobHandle dependsOn = new JobHandle()) where T : struct, IJobParallelForDefer where U : struct { var scheduleParams = new JobsUtility.JobScheduleParameters(UnsafeUtility.AddressOf(ref jobData), JobStructDefer <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)); }
/// <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)); }
// Update is called once per frame void Update() { var ProjMatrix = Camera.main.projectionMatrix; var ViewMatrix = Camera.main.worldToCameraMatrix; var ViewProjMatrix = ProjMatrix * ViewMatrix; var Row3 = ViewProjMatrix.GetRow(3); var Row0 = ViewProjMatrix.GetRow(0); var Row1 = ViewProjMatrix.GetRow(1); var Row2 = ViewProjMatrix.GetRow(2); var PlaneL = NormalizePlane(Row3 + Row0); var PlaneR = NormalizePlane(Row3 - Row0); var PlaneT = NormalizePlane(Row3 - Row1); var PlaneB = NormalizePlane(Row3 + Row1); var PlaneN = NormalizePlane(Row3 + Row2); var PlaneF = NormalizePlane(Row3 - Row2); var PointNTL = PointFrom3Planes(PlaneN, PlaneT, PlaneL); var PointNTR = PointFrom3Planes(PlaneN, PlaneT, PlaneR); var PointNBL = PointFrom3Planes(PlaneN, PlaneB, PlaneL); var PointNBR = PointFrom3Planes(PlaneN, PlaneB, PlaneR); DebugDrawCross(PointNTL, RayDirFromPlanes(PlaneT, PlaneL), 0.3f); DebugDrawCross(PointNTR, RayDirFromPlanes(PlaneR, PlaneT), 0.3f); DebugDrawCross(PointNBL, RayDirFromPlanes(PlaneL, PlaneB), 0.3f); DebugDrawCross(PointNBR, RayDirFromPlanes(PlaneB, PlaneR), 0.3f); var PointFTL = PointFrom3Planes(PlaneF, PlaneT, PlaneL); var PointFTR = PointFrom3Planes(PlaneF, PlaneT, PlaneR); var PointFBL = PointFrom3Planes(PlaneF, PlaneB, PlaneL); var PointFBR = PointFrom3Planes(PlaneF, PlaneB, PlaneR); var FrustumAABBMin = Vector3.Min(Vector3.Min(Vector3.Min(PointFTL, PointFTR), Vector3.Min(PointFBL, PointFBR)), Vector3.Min(Vector3.Min(PointNTL, PointNTR), Vector3.Min(PointNBL, PointNBR))); var FrustumAABBMax = Vector3.Max(Vector3.Max(Vector3.Max(PointFTL, PointFTR), Vector3.Max(PointFBL, PointFBR)), Vector3.Max(Vector3.Max(PointNTL, PointNTR), Vector3.Max(PointNBL, PointNBR))); DebugDrawCross(PointFTL, -RayDirFromPlanes(PlaneT, PlaneL), 1.3f); DebugDrawCross(PointFTR, -RayDirFromPlanes(PlaneR, PlaneT), 1.3f); DebugDrawCross(PointFBL, -RayDirFromPlanes(PlaneL, PlaneB), 1.3f); DebugDrawCross(PointFBR, -RayDirFromPlanes(PlaneB, PlaneR), 1.3f); FrustumData.Array[0] = PlaneL; FrustumData.Array[1] = PlaneR; FrustumData.Array[2] = PlaneT; FrustumData.Array[3] = PlaneB; FrustumData.Array[4] = PlaneN; FrustumData.Array[5] = PlaneF; FrustumData.Array[6] = new Vector4(FrustumAABBMin.x, FrustumAABBMax.x, FrustumAABBMin.y, FrustumAABBMax.y); FrustumData.Array[7] = new Vector4(FrustumAABBMin.z, FrustumAABBMax.z, FrustumAABBMin.z, FrustumAABBMax.z); int NumSoAPackets = (NumMeshTranforms + 3) >> 2; NumMeshTranforms = NumSoAPackets << 2; if (PrevNumMeshTransforms != NumMeshTranforms) { Debug.Log("Re-allocate AABB data because of size change."); VisibilityMask.Reserve((NumSoAPackets + 1) >> 1); VisibilityMaskForParallel = new byte[NumSoAPackets]; BoxesMinMaxAoSoA.Reserve(NumSoAPackets * 6); Debug.Log("Native" + BoxesMinMaxAoSoANative); if (BoxesMinMaxAoSoANative.IsCreated) { BoxesMinMaxAoSoANative.Dispose(); } BoxesMinMaxAoSoANative = new NativeArray <Vector4>(BoxesMinMaxAoSoA.Array, Allocator.Persistent); MeshTransforms = new Matrix4x4[NumMeshTranforms]; RandomizeBoxes = true; } PrevNumMeshTransforms = NumMeshTranforms; if (RandomizeBoxes) { UnityEngine.Random.InitState((int)(Time.time * 1000.0f)); for (int i = 0; i < NumSoAPackets; ++i) { var c0 = RandomCenter(); var e0 = RandomExtent(); var c1 = RandomCenter(); var e1 = RandomExtent(); var c2 = RandomCenter(); var e2 = RandomExtent(); var c3 = RandomCenter(); var e3 = RandomExtent(); BoxesMinMaxAoSoA.Array[i * 6 + 0] = new Vector4(c0[0] - e0[0], c1[0] - e1[0], c2[0] - e2[0], c3[0] - e3[0]); BoxesMinMaxAoSoA.Array[i * 6 + 1] = new Vector4(c0[0] + e0[0], c1[0] + e1[0], c2[0] + e2[0], c3[0] + e3[0]); BoxesMinMaxAoSoA.Array[i * 6 + 2] = new Vector4(c0[1] - e0[1], c1[1] - e1[1], c2[1] - e2[1], c3[1] - e3[1]); BoxesMinMaxAoSoA.Array[i * 6 + 3] = new Vector4(c0[1] + e0[1], c1[1] + e1[1], c2[1] + e2[1], c3[1] + e3[1]); BoxesMinMaxAoSoA.Array[i * 6 + 4] = new Vector4(c0[2] - e0[2], c1[2] - e1[2], c2[2] - e2[2], c3[2] - e3[2]); BoxesMinMaxAoSoA.Array[i * 6 + 5] = new Vector4(c0[2] + e0[2], c1[2] + e1[2], c2[2] + e2[2], c3[2] + e3[2]); } BoxesMinMaxAoSoANative.CopyFrom(BoxesMinMaxAoSoA.Array); RandomizeBoxes = false; } if (CullingJobType == JobType.ReferenceSerialOnly || CullingJobType == JobType.NativePluginSerialOnly) { CullingJobParallel = false; } if (CullingJobType == JobType.ReferenceSerialOnly) { UnityEngine.Profiling.Profiler.BeginSample("CullBoxesAoSoA_Default"); CullBoxesAoSoA_Default( ref VisibilityMask.Array, ref BoxesMinMaxAoSoA.Array, ref FrustumData.Array, FrustumAABBMax, FrustumAABBMin, TestFrustumCorners); UnityEngine.Profiling.Profiler.EndSample(); } else if (CullingJobType == JobType.NativePluginSerialOnly) { UnityEngine.Profiling.Profiler.BeginSample("UnityNativePlugin_CountCulledBoxesAoSoA"); UnityNativePlugin_CountCulledBoxesAoSoA( VisibilityMask.Address(), BoxesMinMaxAoSoA.Address(), FrustumData.Address(), NumSoAPackets); UnityEngine.Profiling.Profiler.EndSample(); } else { if (CullingJobParallel) { UnityEngine.Profiling.Profiler.BeginSample("BeginCullBoxesAoSoA_Parallel"); if (CullingJobType == JobType.MathematicsBurstOptimized) { ParallelCullingJob = new CullingJob_Parallel(); CullingJobHandle = ParallelCullingJob.Run(ref BoxesMinMaxAoSoANative, ref FrustumData.Array, TestFrustumCorners); } else { ParallelCullingJobNoBurst = new CullingJob_ParallelNoBurst(); CullingJobHandle = ParallelCullingJobNoBurst.Run(ref BoxesMinMaxAoSoANative, ref FrustumData.Array, TestFrustumCorners); } UnityEngine.Profiling.Profiler.EndSample(); } else { UnityEngine.Profiling.Profiler.BeginSample("BeginCullBoxesAoSoA_Serial"); if (CullingJobType == JobType.MathematicsBurstOptimized) { SerialCullingJob = new CullingJob_Serial(); CullingJobHandle = SerialCullingJob.Run(ref BoxesMinMaxAoSoANative, ref FrustumData.Array, TestFrustumCorners); } else { SerialCullingJobNoBurst = new CullingJob_SerialNoBurst(); CullingJobHandle = SerialCullingJobNoBurst.Run(ref BoxesMinMaxAoSoANative, ref FrustumData.Array, TestFrustumCorners); } UnityEngine.Profiling.Profiler.EndSample(); } } }
public void Complete(Unity.Jobs.JobHandle Handle, ref byte[] VisibilityMask) { Handle.Complete(); UnityEngine.Assertions.Assert.IsTrue(Handle.IsCompleted); JobData.OnComplete(ref VisibilityMask); }