/// <summary> /// 現在のエンティティを二倍にする /// </summary> unsafe void DoubleEntities() { // 2倍のエンティティ配列を確保して、前半分に既存のエンティティ情報をメモリコピー var doubleEntities = new NativeArray <Entity>(this.entities.Length * 2, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); UnsafeUtility.MemCpy(doubleEntities.GetUnsafePtr(), this.entities.GetUnsafePtr(), UnsafeUtility.SizeOf(typeof(Entity)) * this.entities.Length); // 後ろ半分のエンティティ配列をオフセットを与えてノー確保で別名として作成 var newEntities = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <Entity>( (Entity *)doubleEntities.GetUnsafePtr() + entities.Length, entities.Length, Allocator.None); // Editorで実行する際に安全に読み書きを行うためのおまじない #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref newEntities, NativeArrayUnsafeUtility.GetAtomicSafetyHandle(doubleEntities)); #endif // 後ろ半分のエンティティ配列にエンティティを作成して詰める var manager = World.Active.EntityManager; manager.Instantiate(this.prefabEntity, newEntities); // エンティティの初期位置を前半分のエンティティと同じにする var entityIndex = 0; foreach (var entity in this.entities) { manager.SetComponentData(newEntities[entityIndex++], manager.GetComponentData <Translation>(entity)); } // 新しいエンティティ配列を保持 this.entities.Dispose(); this.entities = doubleEntities; }
public static unsafe void Copy <T>(NativeSpan src, int srcIndex, NativeArray <T> dst, int dstIndex, int length) where T : struct { #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.CheckWriteAndThrow(NativeArrayUnsafeUtility.GetAtomicSafetyHandle(dst)); #endif if (length < 0) { throw new ArgumentOutOfRangeException(nameof(length), "length must be equal or greater than zero."); } if (srcIndex < 0 || srcIndex > src.Length || srcIndex == src.Length && src.Length > 0) { throw new ArgumentOutOfRangeException(nameof(srcIndex), "srcIndex is outside the range of valid indexes for the source NativeArray2."); } if (dstIndex < 0 || dstIndex > dst.Length || dstIndex == dst.Length && dst.Length > 0) { throw new ArgumentOutOfRangeException(nameof(dstIndex), "dstIndex is outside the range of valid indexes for the destination NativeArray2."); } if (srcIndex + length > src.Length) { throw new ArgumentException("length is greater than the number of elements from srcIndex to the end of the source NativeArray2.", nameof(length)); } if (dstIndex + length > dst.Length) { throw new ArgumentException("length is greater than the number of elements from dstIndex to the end of the destination NativeArray2.", nameof(length)); } UnsafeUtility.MemCpy((void *)((IntPtr)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(dst) + (dstIndex * UnsafeUtility.SizeOf <T>())), (void *)((IntPtr)src.m_Buffer + (srcIndex * UnsafeUtility.SizeOf <T>())), (long)(length * UnsafeUtility.SizeOf <T>())); }
internal unsafe static void CalculateBounds(this SpriteSkin spriteSkin) { Debug.Assert(spriteSkin.isValid); var sprite = spriteSkin.sprite; var deformVertexData = new NativeArray <byte>(sprite.GetVertexStreamSize() * sprite.GetVertexCount(), Allocator.Temp, NativeArrayOptions.UninitializedMemory); void *dataPtr = NativeArrayUnsafeUtility.GetUnsafePtr(deformVertexData); var deformedPosSlice = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <Vector3>(dataPtr, sprite.GetVertexStreamSize(), sprite.GetVertexCount()); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeSliceUnsafeUtility.SetAtomicSafetyHandle(ref deformedPosSlice, NativeArrayUnsafeUtility.GetAtomicSafetyHandle(deformVertexData)); #endif var rootBone = spriteSkin.rootBone; spriteSkin.Bake(ref deformVertexData); var bounds = new Bounds(); if (deformVertexData.Length > 0) { bounds.min = rootBone.InverseTransformPoint(deformedPosSlice[0]); bounds.max = bounds.min; } foreach (var v in deformedPosSlice) { bounds.Encapsulate(rootBone.InverseTransformPoint(v)); } bounds.extents = Vector3.Scale(bounds.extents, new Vector3(1.25f, 1.25f, 1f)); spriteSkin.bounds = bounds; }
public unsafe static void MoveFromByteArray <T>(ref byte[] src, ref NativeArray <T> dst) where T : struct { #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.CheckReadAndThrow(NativeArrayUnsafeUtility.GetAtomicSafetyHandle(dst)); if (src == null) { throw new System.ArgumentNullException(nameof(src)); } #endif // var size = UnsafeUtility.SizeOf<T>(); // if (src.Length != (size * dst.Length)) // { // dst.Dispose(); // dst = new NativeArray<T>(src.Length / size, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); //#if ENABLE_UNITY_COLLECTIONS_CHECKS // AtomicSafetyHandle.CheckReadAndThrow(NativeArrayUnsafeUtility.GetAtomicSafetyHandle(dst)); //#endif // } var dstAddr = (byte *)dst.GetUnsafeReadOnlyPtr(); fixed(byte *srcAddr = src) { UnsafeUtility.MemCpy(&dstAddr[0], &srcAddr[0], src.Length); } }
private void InitializeEntities(EntityManager manager) { if (count == 0) { return; } var entities = new NativeArray <Entity>((int)count, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); try { entities[0] = manager.CreateEntity(ComponentType.Create <Position>(), ComponentType.Create <MeshInstanceRenderer>(), ComponentType.Create <StartTime>(), ComponentType.Create <Velocity>(), ComponentType.Create <DanceMove>(), ComponentType.Create <DanceSystem.Tag>()); manager.SetSharedComponentData(entities[0], meshInstanceRenderer); manager.SetComponentData(entities[0], new StartTime { Value = Time.timeSinceLevelLoad }); unsafe { var rest = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <Entity>(((Entity * )NativeArrayUnsafeUtility.GetUnsafePtr(entities)) + 1, entities.Length - 1, Allocator.Temp); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref rest, NativeArrayUnsafeUtility.GetAtomicSafetyHandle(entities)); #endif manager.Instantiate(entities[0], rest); } var rand = new Unity.Mathematics.Random((uint)DateTime.Now.Ticks); for (int i = 0; i < entities.Length; i++) { InitializeEntity(ref rand, manager, entities[i]); } } finally { entities.Dispose(); } }
public static void FreeJsDataAndArray(NativeArray <byte> array, IntPtr dataPointer) { #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.Release(NativeArrayUnsafeUtility.GetAtomicSafetyHandle(array)); #endif UnsafeUtility.Free((void *)dataPointer, Allocator.Invalid); }
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); }
/// <summary> /// Indices into source NativeArray sorted by value /// </summary> /// <returns>Index NativeArray where each element refers to alement ini source NativeArray</returns> public unsafe NativeArray <int> GetSortedIndices() { int *rawIndices = ((int *)m_Buffer.GetUnsafeReadOnlyPtr()) + (m_SortedBuffer * m_Source.Length); var arr = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <int>(rawIndices, m_Source.Length, Allocator.Invalid); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref arr, NativeArrayUnsafeUtility.GetAtomicSafetyHandle(m_Buffer)); #endif return(arr); }
/// <summary> /// Construct a new 2D Native Array with the given row and column count, and given allocator. /// </summary> /// <param name="columnCount"></param> /// <param name="rowCount"></param> /// <param name="allocator"></param> public NativeArray2D(int columnCount, int rowCount, Allocator allocator, NativeArrayOptions options = NativeArrayOptions.ClearMemory) { m_data = new NativeArray <T>(columnCount * rowCount, allocator, options); #if ENABLE_UNITY_COLLECTIONS_CHECKS m_safety = NativeArrayUnsafeUtility.GetAtomicSafetyHandle(m_data); #endif m_columns = columnCount; m_rows = rowCount; }
public static void Copy <T>(NativeSpan src, NativeArray <T> dst) where T : struct { #if ENABLE_UNITY_COLLECTIONS_CHECKS AtomicSafetyHandle.CheckWriteAndThrow(NativeArrayUnsafeUtility.GetAtomicSafetyHandle(dst)); #endif if (src.Length != dst.Length) { throw new ArgumentException("source and destination length must be the same"); } Copy(src, 0, dst, 0, src.Length); }
//@TODO: Make part of NativeArray API unsafe static NativeArray <U> ReinterpretCast <T, U>(NativeArray <T> array) where T : struct where U : struct { Assert.AreEqual(UnsafeUtility.SizeOf <T>(), UnsafeUtility.SizeOf <U>()); var castedArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <U>((byte *)array.GetUnsafePtr(), array.Length, Allocator.Invalid); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref castedArray, NativeArrayUnsafeUtility.GetAtomicSafetyHandle(array)); #endif return(castedArray); }
public static DeferredBlittableArray Create <T>(NativeList <T> list) where T : struct { var deferred = list.AsDeferredJobArray(); DeferredBlittableArray ret; ret.m_Ptr = NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(deferred); #if ENABLE_UNITY_COLLECTIONS_CHECKS ret.m_Safety = NativeArrayUnsafeUtility.GetAtomicSafetyHandle(deferred); #endif return(ret); }
public DataStreamReader(NativeArray <byte> array) { #if ENABLE_UNITY_COLLECTIONS_CHECKS m_Safety = NativeArrayUnsafeUtility.GetAtomicSafetyHandle(array); #endif m_bufferPtr = (byte *)array.GetUnsafeReadOnlyPtr(); m_Length = array.Length; m_Context = default; uint test = 1; unsafe { byte *test_b = (byte *)&test; m_IsLittleEndian = test_b[0] == 1 ? 1 : 0; } }
public static unsafe DataStreamReader AsDataStreamReader <T>(this DynamicBuffer <T> self) where T : struct, IBufferElementData { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (UnsafeUtility.SizeOf <T>() != 1) { throw new System.InvalidOperationException("Can only convert DynamicBuffers of size 1 to DataStreamWriters"); } #endif var na = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <byte>(self.GetUnsafePtr(), self.Length, Allocator.Invalid); #if ENABLE_UNITY_COLLECTIONS_CHECKS var safety = NativeArrayUnsafeUtility.GetAtomicSafetyHandle(self.AsNativeArray()); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref na, safety); #endif return(new DataStreamReader(na)); }
static NativeArray <ulong2> GetULong2View(NativeArray <byte> data) { unsafe { var ptr = (ulong2 *)data.GetUnsafeReadOnlyPtr(); var blocks = data.Length >> 4; var r = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <ulong2>(ptr, blocks, Allocator.None); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref r, NativeArrayUnsafeUtility.GetAtomicSafetyHandle(data)); #endif return(r); } }
public static AsyncRequestNativeArrayData CreateAndCheckAccess <T>(NativeArray <T> array) where T : struct { var nativeArrayData = new AsyncRequestNativeArrayData(); nativeArrayData.nativeArrayBuffer = array.GetUnsafePtr(); nativeArrayData.lengthInBytes = array.Length * UnsafeUtility.SizeOf <T>(); var handle = NativeArrayUnsafeUtility.GetAtomicSafetyHandle(array); var versionPtr = (int *)handle.versionNode; if (handle.version != ((*versionPtr) & AtomicSafetyHandle.WriteCheck)) { AtomicSafetyHandle.CheckWriteAndThrowNoEarlyOut(handle); } nativeArrayData.safetyHandle = handle; return(nativeArrayData); }
/// <summary> /// Array of indiices into source NativeArray which share the same source value /// </summary> /// <param name="index">Index of shared value</param> /// <returns></returns> public unsafe NativeArray <int> GetSharedValueIndicesBySharedIndex(int index) { int sharedValueIndexCountOffset = 2 * m_Source.Length; int sharedValueIndexCount = m_Buffer[sharedValueIndexCountOffset + index]; int sharedValueStartIndicesOffset = 3 * m_Source.Length; int sharedValueStartIndex = m_Buffer[sharedValueStartIndicesOffset + index]; int sortedValueOffset = m_SortedBuffer * m_Source.Length; int *rawIndices = ((int *)m_Buffer.GetUnsafeReadOnlyPtr()) + (sortedValueOffset + sharedValueStartIndex); var arr = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <int>(rawIndices, sharedValueIndexCount, Allocator.Invalid); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref arr, NativeArrayUnsafeUtility.GetAtomicSafetyHandle(m_Buffer)); #endif return(arr); }
/// <summary> /// Construct a 2D Native Array from a given C# managed 2D array with the given allocator. /// </summary> /// <param name="array"></param> /// <param name="allocator"></param> public unsafe NativeArray2D(T[,] array, Allocator allocator) { m_data = new NativeArray <T>(array.GetLength(0) * array.GetLength(1), allocator); fixed(void *arrayPtr = &array[0, 0]) { UnsafeUtility.MemCpy(m_data.GetUnsafePtr(), arrayPtr, m_data.Length * sizeof(T)); } #if ENABLE_UNITY_COLLECTIONS_CHECKS m_safety = NativeArrayUnsafeUtility.GetAtomicSafetyHandle(m_data); #endif m_columns = array.GetLength(0); m_rows = array.GetLength(1); }
public unsafe static AsyncRequestNativeArrayData CreateAndCheckAccess <T>(NativeArray <T> array) where T : struct { AsyncRequestNativeArrayData result = default(AsyncRequestNativeArrayData); result.nativeArrayBuffer = array.GetUnsafePtr <T>(); result.lengthInBytes = (long)array.Length * (long)UnsafeUtility.SizeOf <T>(); AtomicSafetyHandle atomicSafetyHandle = NativeArrayUnsafeUtility.GetAtomicSafetyHandle <T>(array); int *ptr = (int *)((void *)atomicSafetyHandle.versionNode); bool flag = atomicSafetyHandle.version != (*ptr & -6); if (flag) { AtomicSafetyHandle.CheckWriteAndThrowNoEarlyOut(atomicSafetyHandle); } result.safetyHandle = atomicSafetyHandle; return(result); }
/// <summary> /// Returns an array of FieldInfos for the passed in Type, if that type was had field information generated via /// the [GenerateComponentFieldInfo] attribute. See that attribute for more details on usage. /// This function can be called recursively using Types from the returned NativeArray's FieldInfo element's FieldType property. /// </summary> /// <param name="type"></param> /// <returns>NativeArray of FieldInfo</returns> public static NativeArray <FieldInfo> GetFieldInfos(Type type) { if (!s_TypeToFieldInfosMap.TryGetValue(type, out var lookup)) { throw new ArgumentException($"'{type}' is not a Component type or a nested field type of a component. We only generate FieldInfo for Components and their fields if the component was registered using [GenerateComponentFieldInfo]."); } var array = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <FieldInfo>((FieldInfo *)s_FieldInfos.GetUnsafeReadOnlyPtr() + lookup.Index, lookup.Count, Allocator.None); #if ENABLE_UNITY_COLLECTIONS_CHECKS // This handle isn't correct but collections makes this way more difficult than this needs to be // and we know s_TypeInfos has the same lifetime and readonly requirement as the fieldinfos var handle = NativeArrayUnsafeUtility.GetAtomicSafetyHandle(s_TypeInfos); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref array, handle); #endif return(array); }
internal unsafe static void CalculateBounds(this SpriteSkin spriteSkin) { Debug.Assert(spriteSkin.isValid); var sprite = spriteSkin.sprite; var deformVertexData = new NativeArray <byte>(sprite.GetVertexStreamSize() * sprite.GetVertexCount(), Allocator.Temp, NativeArrayOptions.UninitializedMemory); void *dataPtr = NativeArrayUnsafeUtility.GetUnsafePtr(deformVertexData); var deformedPosSlice = NativeSliceUnsafeUtility.ConvertExistingDataToNativeSlice <Vector3>(dataPtr, sprite.GetVertexStreamSize(), sprite.GetVertexCount()); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeSliceUnsafeUtility.SetAtomicSafetyHandle(ref deformedPosSlice, NativeArrayUnsafeUtility.GetAtomicSafetyHandle(deformVertexData)); #endif spriteSkin.Bake(ref deformVertexData); UpdateBounds(spriteSkin, deformVertexData); deformVertexData.Dispose(); }
internal NativeArray <byte> GetTypeMask(int typeIndex) { var view = GetMaskView(typeIndex); unsafe { var result = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <byte> ( view.Ptr, view.LengthInBytes, Allocator.None ); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref result, NativeArrayUnsafeUtility.GetAtomicSafetyHandle(MaskBuffer)); #endif return(result); } }
public static AsyncRequestNativeArrayData CreateAndCheckAccess <T>(NativeArray <T> array) where T : struct { if (array.m_AllocatorLabel == Allocator.Temp || array.m_AllocatorLabel == Allocator.TempJob) { throw new ArgumentException("AsyncGPUReadback cannot use Temp memory as input since the result may only become available at an unspecified point in the future."); } var nativeArrayData = new AsyncRequestNativeArrayData(); nativeArrayData.nativeArrayBuffer = array.GetUnsafePtr(); nativeArrayData.lengthInBytes = (long)array.Length * UnsafeUtility.SizeOf <T>(); var handle = NativeArrayUnsafeUtility.GetAtomicSafetyHandle(array); var versionPtr = (int *)handle.versionNode; if (handle.version != ((*versionPtr) & AtomicSafetyHandle.WriteCheck)) { AtomicSafetyHandle.CheckWriteAndThrowNoEarlyOut(handle); } nativeArrayData.safetyHandle = handle; return(nativeArrayData); }
// Creates an alias to the same array, but the caller cannot Dispose it. unsafe NativeArray <T> GetUndisposable <T>(NativeArray <T> disposable) where T : struct { if (!disposable.IsCreated) { return(default(NativeArray <T>)); } var array = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>( disposable.GetUnsafePtr(), disposable.Length, Allocator.None); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle( ref array, NativeArrayUnsafeUtility.GetAtomicSafetyHandle(disposable)); #endif return(array); }
/// <summary> /// Reinterpret a native array as being of another type, aliasing its contents via type punning. /// </summary> /// <param name="array">The array to alias</param> /// <typeparam name="T">Source type of array elements</typeparam> /// <typeparam name="U">Target type of array elements</typeparam> /// <returns>The same array, with a different type of element</returns> public static NativeArray <U> Reinterpret <T, U>(this NativeArray <T> array) where U : struct where T : struct { var tSize = UnsafeUtility.SizeOf <T>(); var uSize = UnsafeUtility.SizeOf <U>(); var byteLen = ((long)array.Length) * tSize; var uLen = byteLen / uSize; CheckReinterpretSize <T, U>(ref array); var ptr = NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(array); var result = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <U>(ptr, (int)uLen, Allocator.None); #if ENABLE_UNITY_COLLECTIONS_CHECKS var handle = NativeArrayUnsafeUtility.GetAtomicSafetyHandle(array); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref result, handle); #endif return(result); }
private static void Initialize(out DataStreamWriter self, NativeArray <byte> data) { self.m_SendHandleData = IntPtr.Zero; self.m_Data.capacity = data.Length; self.m_Data.length = 0; self.m_Data.buffer = (byte *)data.GetUnsafePtr(); self.m_Data.bitBuffer = 0; self.m_Data.bitIndex = 0; self.m_Data.failedWrites = 0; #if ENABLE_UNITY_COLLECTIONS_CHECKS self.m_Safety = NativeArrayUnsafeUtility.GetAtomicSafetyHandle(data); #endif uint test = 1; unsafe { byte *test_b = (byte *)&test; self.m_IsLittleEndian = test_b[0] == 1 ? 1 : 0; } }
/// <summary> /// Reinterpret a native array as being of another type, aliasing its contents via type punning. /// </summary> /// <param name="array">The array to alias</param> /// <typeparam name="T">Source type of array elements</typeparam> /// <typeparam name="U">Target type of array elements</typeparam> /// <returns>The same array, with a different type of element</returns> public static NativeArray <U> Reinterpret <T, U>(this NativeArray <T> array) where U : struct where T : struct { var tSize = UnsafeUtility.SizeOf <T>(); var uSize = UnsafeUtility.SizeOf <U>(); var byteLen = ((long)array.Length) * tSize; var uLen = byteLen / uSize; #if ENABLE_UNITY_COLLECTIONS_CHECKS if (uLen * uSize != byteLen) { throw new InvalidOperationException($"Types {typeof(T)} (array length {array.Length}) and {typeof(U)} cannot be aliased due to size constraints. The size of the types and lengths involved must line up."); } #endif var ptr = NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(array); var result = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <U>(ptr, (int)uLen, Allocator.None); #if ENABLE_UNITY_COLLECTIONS_CHECKS var handle = NativeArrayUnsafeUtility.GetAtomicSafetyHandle(array); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref result, handle); #endif return(result); }
private unsafe static void InvokeOnPerformCulling(BatchRendererGroup group, ref BatchRendererCullingOutput context, ref LODParameters lodParameters) { NativeArray <Plane> nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <Plane>((void *)context.cullingPlanes, context.cullingPlanesCount, Allocator.Invalid); NativeArray <BatchVisibility> nativeArray2 = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <BatchVisibility>((void *)context.batchVisibility, context.batchVisibilityCount, Allocator.Invalid); NativeArray <int> nativeArray3 = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <int>((void *)context.visibleIndices, context.visibleIndicesCount, Allocator.Invalid); NativeArray <int> nativeArray4 = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <int>((void *)context.visibleIndicesY, context.visibleIndicesCount, Allocator.Invalid); NativeArrayUnsafeUtility.SetAtomicSafetyHandle <Plane>(ref nativeArray, AtomicSafetyHandle.Create()); NativeArrayUnsafeUtility.SetAtomicSafetyHandle <BatchVisibility>(ref nativeArray2, AtomicSafetyHandle.Create()); NativeArrayUnsafeUtility.SetAtomicSafetyHandle <int>(ref nativeArray3, AtomicSafetyHandle.Create()); NativeArrayUnsafeUtility.SetAtomicSafetyHandle <int>(ref nativeArray4, AtomicSafetyHandle.Create()); try { context.cullingJobsFence = group.m_PerformCulling(group, new BatchCullingContext(nativeArray, nativeArray2, nativeArray3, nativeArray4, lodParameters, context.cullingMatrix, context.nearPlane)); } finally { JobHandle.ScheduleBatchedJobs(); AtomicSafetyHandle.Release(NativeArrayUnsafeUtility.GetAtomicSafetyHandle <Plane>(nativeArray)); AtomicSafetyHandle.Release(NativeArrayUnsafeUtility.GetAtomicSafetyHandle <BatchVisibility>(nativeArray2)); AtomicSafetyHandle.Release(NativeArrayUnsafeUtility.GetAtomicSafetyHandle <int>(nativeArray3)); AtomicSafetyHandle.Release(NativeArrayUnsafeUtility.GetAtomicSafetyHandle <int>(nativeArray4)); } }
unsafe static void InvokeOnPerformCulling(BatchRendererGroup group, ref BatchRendererCullingOutput context, ref LODParameters lodParameters) { NativeArray <Plane> cullingPlanes = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <Plane>(context.cullingPlanes, context.cullingPlanesCount, Allocator.Invalid); NativeArray <BatchVisibility> batchVisibility = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <BatchVisibility>(context.batchVisibility, context.batchVisibilityCount, Allocator.Invalid); NativeArray <int> visibleIndices = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <int>(context.visibleIndices, context.visibleIndicesCount, Allocator.Invalid); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref cullingPlanes, AtomicSafetyHandle.Create()); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref batchVisibility, AtomicSafetyHandle.Create()); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref visibleIndices, AtomicSafetyHandle.Create()); try { context.cullingJobsFence = group.m_PerformCulling(group, new BatchCullingContext(cullingPlanes, batchVisibility, visibleIndices, lodParameters)); } finally { JobHandle.ScheduleBatchedJobs(); //@TODO: Check that the no jobs using the buffers have been scheduled that are not returned here... AtomicSafetyHandle.Release(NativeArrayUnsafeUtility.GetAtomicSafetyHandle(cullingPlanes)); AtomicSafetyHandle.Release(NativeArrayUnsafeUtility.GetAtomicSafetyHandle(batchVisibility)); AtomicSafetyHandle.Release(NativeArrayUnsafeUtility.GetAtomicSafetyHandle(visibleIndices)); } }
private void SharedValueIndicesSetSafetyHandle(ref NativeArray <int> arr) { NativeArrayUnsafeUtility.SetAtomicSafetyHandle <int>(ref arr, NativeArrayUnsafeUtility.GetAtomicSafetyHandle <int>(this.m_Buffer)); }