public unsafe void VirtualMemory_Allocate() { BaselibErrorState errorState = default; // Reserve 4GB var addressSpace = VirtualMemoryUtility.ReserveAddressSpace(1024ul * 1024ul, VirtualMemoryUtility.DefaultPageSizeInBytes, out errorState); { // Commit 1 page for an allocator VMRange page = new VMRange { ptr = addressSpace.ptr, log2PageSize = addressSpace.log2PageSize, pageCount = 1 }; VirtualMemoryUtility.CommitMemory(page, out errorState); // 1KB allocator var allocator = new UnsafeScratchAllocator((void *)page.ptr, 1024); var numbers0 = (int *)allocator.Allocate <int>(256); for (int i = 0; i < 256; i++) { numbers0[i] = i; } var anotherAllocator = new UnsafeScratchAllocator((void *)((IntPtr)page.ptr + 1024), 1024); var numbers1 = (int *)anotherAllocator.Allocate <int>(256); for (int i = 0; i < 256; i++) { numbers1[i] = numbers0[i]; } } VirtualMemoryUtility.FreeAddressSpace(addressSpace, out errorState); }
void ConstructTypeArray(ref UnsafeScratchAllocator unsafeScratchAllocator, ComponentType[] types, out int *outTypes, out byte *outAccessModes, out int outLength) { if (types == null || types.Length == 0) { outTypes = null; outAccessModes = null; outLength = 0; } else { outLength = types.Length; outTypes = (int *)unsafeScratchAllocator.Allocate <int>(types.Length); outAccessModes = (byte *)unsafeScratchAllocator.Allocate <byte>(types.Length); var sortedTypes = stackalloc ComponentType[types.Length]; for (var i = 0; i < types.Length; ++i) { SortingUtilities.InsertSorted(sortedTypes, i, types[i]); } for (int i = 0; i != types.Length; i++) { outTypes[i] = sortedTypes[i].TypeIndex; outAccessModes[i] = (byte)sortedTypes[i].AccessModeType; } } }
public unsafe void VirtualMemory_Decommit() { BaselibErrorState errorState = default; // Reserve 4GB var addressSpace = VirtualMemoryUtility.ReserveAddressSpace(1024ul * 1024ul, VirtualMemoryUtility.DefaultPageSizeInBytes, out errorState); { // Commit 4KB for an allocator VMRange page = new VMRange { ptr = addressSpace.ptr, log2PageSize = addressSpace.log2PageSize, pageCount = 1 }; VirtualMemoryUtility.CommitMemory(page, out errorState); var allocator = new UnsafeScratchAllocator((void *)page.ptr, 4096); var numbers0 = (int *)allocator.Allocate <int>(256); for (int i = 0; i < 256; i++) { numbers0[i] = i; } // Decommit and try to use VirtualMemoryUtility.DecommitMemory(page, out errorState); Assert.Throws <NullReferenceException>(() => numbers0[1] = 1); } VirtualMemoryUtility.FreeAddressSpace(addressSpace, out errorState); }
// Calculates the intersection of "All" queriesDesc private ComponentType *CalculateRequiredComponentsFromQuery(ref UnsafeScratchAllocator allocator, ArchetypeQuery *queries, int queryCount, out int outRequiredComponentsCount) { var maxIntersectionCount = 0; for (int queryIndex = 0; queryIndex < queryCount; ++queryIndex) { maxIntersectionCount = math.max(maxIntersectionCount, queries[queryIndex].AllCount); } var intersection = (int *)allocator.Allocate <int>(maxIntersectionCount); UnsafeUtility.MemCpy(intersection, queries[0].All, sizeof(int) * queries[0].AllCount); var intersectionCount = maxIntersectionCount; for (int i = 1; i < queryCount; ++i) { intersectionCount = IntersectSortedComponentIndexArrays(intersection, intersectionCount, queries[i].All, queries[i].AllCount, intersection); } var outRequiredComponents = (ComponentType *)allocator.Allocate <ComponentType>(intersectionCount + 1); outRequiredComponents[0] = ComponentType.ReadWrite <Entity>(); for (int i = 0; i < intersectionCount; ++i) { outRequiredComponents[i + 1] = ComponentType.FromTypeIndex(intersection[i]); } outRequiredComponentsCount = intersectionCount + 1; return(outRequiredComponents); }
public EntityQuery CreateEntityQuery(EntityComponentStore *entityComponentStore, ManagedComponentStore managedComponentStore, EntityQueryDesc[] queryDesc) { //@TODO: Support for CreateEntityQuery with queryDesc but using ComponentDataArray etc var buffer = stackalloc byte[1024]; var scratchAllocator = new UnsafeScratchAllocator(buffer, 1024); var archetypeQuery = CreateQuery(ref scratchAllocator, queryDesc); var outRequiredComponents = CalculateRequiredComponentsFromQuery(ref scratchAllocator, archetypeQuery, queryDesc.Length, out var outRequiredComponentsCount); return(CreateEntityQuery(entityComponentStore, managedComponentStore, archetypeQuery, queryDesc.Length, outRequiredComponents, outRequiredComponentsCount)); }
public EntityQuery CreateEntityQuery(EntityComponentStore *entityComponentStore, ManagedComponentStore managedComponentStore, ComponentType *inRequiredComponents, int inRequiredComponentsCount) { var buffer = stackalloc byte[1024]; var scratchAllocator = new UnsafeScratchAllocator(buffer, 1024); var archetypeQuery = CreateQuery(ref scratchAllocator, inRequiredComponents, inRequiredComponentsCount); var outRequiredComponents = (ComponentType *)scratchAllocator.Allocate <ComponentType>(inRequiredComponentsCount + 1); outRequiredComponents[0] = ComponentType.ReadWrite <Entity>(); for (int i = 0; i != inRequiredComponentsCount; i++) { SortingUtilities.InsertSorted(outRequiredComponents + 1, i, inRequiredComponents[i]); } var outRequiredComponentsCount = inRequiredComponentsCount + 1; return(CreateEntityQuery(entityComponentStore, managedComponentStore, archetypeQuery, 1, outRequiredComponents, outRequiredComponentsCount)); }
ArchetypeQuery *CreateQuery(ref UnsafeScratchAllocator unsafeScratchAllocator, ComponentType *requiredTypes, int count) { var allList = new NativeList <ComponentType>(Allocator.Temp); var noneList = new NativeList <ComponentType>(Allocator.Temp); for (int i = 0; i != count; i++) { if (requiredTypes[i].AccessModeType == ComponentType.AccessMode.Exclude) { noneList.Add(ComponentType.ReadOnly(requiredTypes[i].TypeIndex)); } else { allList.Add(requiredTypes[i]); } } // NativeList.ToArray requires GC Pinning, not supported in Tiny var allCount = allList.Length; var noneCount = noneList.Length; var allTypes = new ComponentType[allCount]; var noneTypes = new ComponentType[noneCount]; for (int i = 0; i < allCount; i++) { allTypes[i] = allList[i]; } for (int i = 0; i < noneCount; i++) { noneTypes[i] = noneList[i]; } var query = new EntityQueryDesc { All = allTypes, None = noneTypes }; allList.Dispose(); noneList.Dispose(); return(CreateQuery(ref unsafeScratchAllocator, new EntityQueryDesc[] { query })); }
public void Execute(int index) { BaselibErrorState errorState = default; VMRange allocation = new VMRange { ptr = jobAddressRangePtr + index * (int)VirtualMemoryUtility.DefaultPageSizeInBytes, log2PageSize = jobLog2PageSize, pageCount = jobPageCount }; // Commit a page from the address range VirtualMemoryUtility.CommitMemory(allocation, out errorState); jobErrorStates[index] = errorState; // 1 page of ints var allocator = new UnsafeScratchAllocator((void *)allocation.ptr, (int)VirtualMemoryUtility.DefaultPageSizeInBytes); var numbers0 = (int *)allocator.Allocate <int>((int)VirtualMemoryUtility.DefaultPageSizeInBytes / sizeof(int)); for (int i = 0; i < (int)VirtualMemoryUtility.DefaultPageSizeInBytes / sizeof(int); i++) { numbers0[i] = i; } }
public unsafe void VirtualMemory_AllocateAndFreeFromBurst() { BaselibErrorState errorState = default; // Reserve 1GB var addressSpace = VirtualMemoryUtility.ReserveAddressSpace(1024ul * 256ul, VirtualMemoryUtility.DefaultPageSizeInBytes, out errorState); { // 100 pages of ints const int allocationCount = 100; var errorStates = new NativeArray <BaselibErrorState>(allocationCount, Allocator.Persistent); { for (int i = 0; i < allocationCount; i++) { errorStates[i] = default; } var commitJob = new CommitJob { jobAddressRangePtr = addressSpace.ptr, jobLog2PageSize = addressSpace.log2PageSize, jobPageCount = 1, jobErrorStates = errorStates }; commitJob.Schedule(allocationCount, 1).Complete(); for (int i = 0; i < allocationCount; i++) { VirtualMemoryUtility.ReportWrappedBaselibError(errorStates[i]); } // for each page allocated for (int i = 0; i < allocationCount; i++) { var page = (void *)((ulong)addressSpace.ptr + (ulong)i * VirtualMemoryUtility.DefaultPageSizeInBytes); var allocator = new UnsafeScratchAllocator((void *)addressSpace.ptr, (int)VirtualMemoryUtility.DefaultPageSizeInBytes * allocationCount); var intCount = ((int)VirtualMemoryUtility.DefaultPageSizeInBytes / sizeof(int)); var numbersInPage = (int *)allocator.Allocate <int>(intCount); // for each int in the allocated page for (int j = 0; j < intCount; j++) { Assert.AreEqual(j, numbersInPage[j]); } } var decommitJob = new DecommitJob { jobAddressRangePtr = addressSpace.ptr, jobLog2PageSize = addressSpace.log2PageSize, jobPageCount = 1, jobErrorStates = errorStates }; decommitJob.Schedule(allocationCount, 1).Complete(); } errorStates.Dispose(); } VirtualMemoryUtility.FreeAddressSpace(addressSpace, out errorState); }
ArchetypeQuery *CreateQuery(ref UnsafeScratchAllocator unsafeScratchAllocator, EntityQueryDesc[] queryDesc) { var outQuery = (ArchetypeQuery *)unsafeScratchAllocator.Allocate(sizeof(ArchetypeQuery) * queryDesc.Length, UnsafeUtility.AlignOf <ArchetypeQuery>()); for (int q = 0; q != queryDesc.Length; q++) { // Validate the queryDesc has components declared in a consistent way queryDesc[q].Validate(); var typesNone = queryDesc[q].None; var typesAll = queryDesc[q].All; var typesAny = queryDesc[q].Any; // None forced to read only { for (int i = 0; i < typesNone.Length; i++) { if (typesNone[i].AccessModeType != ComponentType.AccessMode.ReadOnly) { typesNone[i] = ComponentType.ReadOnly(typesNone[i].TypeIndex); } } } var isFilterWriteGroup = (queryDesc[q].Options & EntityQueryOptions.FilterWriteGroup) != 0; if (isFilterWriteGroup) { // Each ReadOnly<type> in any or all // if has WriteGroup types, // - Recursively add to any (if not explictly mentioned) var explicitList = CreateExplicitTypeList(typesNone, typesAll, typesAny); for (int i = 0; i < typesAny.Length; i++) { IncludeDependentWriteGroups(typesAny[i], explicitList); } for (int i = 0; i < typesAll.Length; i++) { IncludeDependentWriteGroups(typesAll[i], explicitList); } // Each ReadWrite<type> in any or all // if has WriteGroup types, // Add to none (if not exist in any or all or none) var noneList = new NativeList <ComponentType>(typesNone.Length, Allocator.Temp); for (int i = 0; i < typesNone.Length; i++) { noneList.Add(typesNone[i]); } for (int i = 0; i < typesAny.Length; i++) { ExcludeWriteGroups(typesAny[i], noneList, explicitList); } for (int i = 0; i < typesAll.Length; i++) { ExcludeWriteGroups(typesAll[i], noneList, explicitList); } typesNone = new ComponentType[noneList.Length]; for (int i = 0; i < noneList.Length; i++) { typesNone[i] = noneList[i]; } noneList.Dispose(); explicitList.Dispose(); } ConstructTypeArray(ref unsafeScratchAllocator, typesNone, out outQuery[q].None, out outQuery[q].NoneAccessMode, out outQuery[q].NoneCount); ConstructTypeArray(ref unsafeScratchAllocator, typesAll, out outQuery[q].All, out outQuery[q].AllAccessMode, out outQuery[q].AllCount); ConstructTypeArray(ref unsafeScratchAllocator, typesAny, out outQuery[q].Any, out outQuery[q].AnyAccessMode, out outQuery[q].AnyCount); outQuery[q].Options = queryDesc[q].Options; } return(outQuery); }