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);
    }
Ejemplo n.º 10
0
        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);
        }