feat(graphics): refactor pipeline keying and allocators

Major refactor of graphics pipeline keying, shader cache, and resource allocation.
Replaced most Allocator usage with AllocationHandle, modernized logger usage,
and unified pipeline state keys. Updated MeshUtility to use AllocationHandle.FreeList.
Added new shader pipeline architecture docs and improved error handling throughout.

BREAKING CHANGE: Pipeline keying and resource allocation APIs have changed.
This commit is contained in:
2026-04-13 23:07:52 +09:00
parent c66fda5332
commit 817b32b8d9
69 changed files with 1436 additions and 2095 deletions

View File

@@ -124,8 +124,8 @@ internal unsafe struct Chunk : IDisposable
public Chunk(int bufferSize, int capacity, int componentCount, uint globalVersion)
{
_data = new UnsafeArray<byte>(bufferSize, Allocator.Persistent, AllocationOption.Clear);
_versions = new UnsafeArray<uint>(componentCount, Allocator.Persistent);
_data = new UnsafeArray<byte>(bufferSize, AllocationHandle.Persistent, AllocationOption.Clear);
_versions = new UnsafeArray<uint>(componentCount, AllocationHandle.Persistent);
_capacity = capacity;
_count = 0;
@@ -200,13 +200,13 @@ internal unsafe struct Archetype : IDisposable
_id = id;
_worldID = worldID;
_chunks = new UnsafeList<Chunk>(4, Allocator.Persistent);
_edgesAdd = new UnsafeList<Edge>(4, Allocator.Persistent);
_edgesRemove = new UnsafeList<Edge>(4, Allocator.Persistent);
_chunks = new UnsafeList<Chunk>(4, AllocationHandle.Persistent);
_edgesAdd = new UnsafeList<Edge>(4, AllocationHandle.Persistent);
_edgesRemove = new UnsafeList<Edge>(4, AllocationHandle.Persistent);
if (componentIds.IsEmpty)
{
_signature = new UnsafeBitSet(1, Allocator.Persistent, AllocationOption.Clear);
_signature = new UnsafeBitSet(1, AllocationHandle.Persistent, AllocationOption.Clear);
_hash = 0;
_signature.ClearAll();
@@ -224,7 +224,7 @@ internal unsafe struct Archetype : IDisposable
}
}
_signature = new UnsafeBitSet(highestComponentID + 1, Allocator.Persistent, AllocationOption.Clear);
_signature = new UnsafeBitSet(highestComponentID + 1, AllocationHandle.Persistent, AllocationOption.Clear);
_hash = _signature.GetHashCode();
CalculateLayout(componentIds);
@@ -268,8 +268,8 @@ internal unsafe struct Archetype : IDisposable
_maxComponentID = maxComponentID;
_entityCapacity = Chunk.CHUNK_BUFFER_SIZE / bytesPerEntity;
_layouts = new UnsafeArray<ComponentMemoryLayout>(components.Length, Allocator.Persistent);
_componentIDToLayoutIndex = new UnsafeArray<int>(_maxComponentID + 1, Allocator.Persistent);
_layouts = new UnsafeArray<ComponentMemoryLayout>(components.Length, AllocationHandle.Persistent);
_componentIDToLayoutIndex = new UnsafeArray<int>(_maxComponentID + 1, AllocationHandle.Persistent);
_componentIDToLayoutIndex.AsSpan().Fill(-1);

View File

@@ -168,11 +168,11 @@ public partial class ComponentManager : IDisposable
{
_world = world;
_archetypes = new UnsafeList<Archetype>(16, Allocator.Persistent);
_entityQueries = new UnsafeList<EntityQuery>(16, Allocator.Persistent);
_archetypes = new UnsafeList<Archetype>(16, AllocationHandle.Persistent);
_entityQueries = new UnsafeList<EntityQuery>(16, AllocationHandle.Persistent);
_archetypeLookup = new UnsafeHashMap<int, Identifier<Archetype>>(16, Allocator.Persistent);
_querieLookup = new UnsafeHashMap<int, Identifier<EntityQuery>>(16, Allocator.Persistent);
_archetypeLookup = new UnsafeHashMap<int, Identifier<Archetype>>(16, AllocationHandle.Persistent);
_querieLookup = new UnsafeHashMap<int, Identifier<EntityQuery>>(16, AllocationHandle.Persistent);
// Create the empty archetype
CreateArchetype(ReadOnlySpan<Identifier<IComponent>>.Empty, 0);
@@ -297,11 +297,6 @@ public struct ComponentSet : IDisposable, IEquatable<ComponentSet>
_hashCode = -1;
}
public ComponentSet(Allocator allocator, params ReadOnlySpan<Identifier<IComponent>> components)
: this(AllocationManager.GetAllocationHandle(allocator), components)
{
}
public readonly bool Equals(ComponentSet other)
{
return _hashCode == other._hashCode;

View File

@@ -25,7 +25,7 @@ public unsafe class EntityCommandBuffer : IDisposable
public EntityCommandBuffer(EntityManager entityManager)
{
_entityManager = entityManager;
_buffer = new UnsafeList<byte>(4096, Allocator.Persistent);
_buffer = new UnsafeList<byte>(4096, AllocationHandle.Persistent);
}
~EntityCommandBuffer()

View File

@@ -50,7 +50,7 @@ public unsafe partial class EntityManager : IDisposable
internal EntityManager(World world, int initialCapacity)
{
_world = world;
_entityLocations = new UnsafeSlotMap<EntityLocation>(initialCapacity, Allocator.Persistent, AllocationOption.Clear);
_entityLocations = new UnsafeSlotMap<EntityLocation>(initialCapacity, AllocationHandle.Persistent, AllocationOption.Clear);
_scriptComponents = new SlotMap<List<ScriptComponent>>(initialCapacity / 2);
// _storages = new IManagedComponentStorage[16];
}
@@ -638,7 +638,7 @@ public unsafe partial class EntityManager : IDisposable
newArchetype.SetComponentData(newChunkIndex, newRowIndex, componentID, pComponent);
var r = oldArchetype.RemoveEntity(location.chunkIndex, location.rowIndex);
Debug.Assert(r == Error.None); // We assert it because the entity should exist if the whole system is consistent.
Logger.DebugAssert(r == Error.None); // We assert it because the entity should exist if the whole system is consistent.
if (r != Error.None)
{
return r;
@@ -742,7 +742,7 @@ public unsafe partial class EntityManager : IDisposable
newArchetype.SetEntity(newChunkIndex, newRowIndex, entity);
var r = oldArchetype.RemoveEntity(location.chunkIndex, location.rowIndex);
Debug.Assert(r == Error.None); // We assert it because the entity should exist if the whole system is consistent.
Logger.DebugAssert(r == Error.None); // We assert it because the entity should exist if the whole system is consistent.
if (r != Error.None)
{
return r;

View File

@@ -345,7 +345,7 @@ public unsafe partial struct EntityQuery : IDisposable
_id = id;
_worldID = worldID;
_mask = mask;
_matchingArchetypes = new UnsafeList<Identifier<Archetype>>(8, Allocator.Persistent);
_matchingArchetypes = new UnsafeList<Identifier<Archetype>>(8, AllocationHandle.Persistent);
}
// TODO: Fetching layout every time is not optimal. Cache them?
@@ -642,7 +642,7 @@ public ref partial struct QueryBuilder : IDisposable
public Identifier<EntityQuery> Build(World world, bool dispose = true)
{
BuildQueryMask(AllocationManager.GetAllocationHandle(Allocator.Persistent), out var mask);
BuildQueryMask(AllocationHandle.Persistent, out var mask);
var maskHash = mask.GetHashCode();
var queryID = world.ComponentManager.GetEntityQueryIDByMaskHash(maskHash);

View File

@@ -56,7 +56,7 @@ internal sealed unsafe class SharedComponentStore : IDisposable
public SharedComponentStore(int initialCapacity = 16)
{
_perType = new UnsafeHashMap<int, TypeStore>(initialCapacity, Allocator.Persistent);
_perType = new UnsafeHashMap<int, TypeStore>(initialCapacity, AllocationHandle.Persistent);
}
~SharedComponentStore()
@@ -203,9 +203,9 @@ internal sealed unsafe class SharedComponentStore : IDisposable
var store = new TypeStore
{
typeSize = typeSize,
data = new UnsafeList<byte>(typeSize * 16, Allocator.Persistent),
infos = new UnsafeList<EntryInfo>(16, Allocator.Persistent),
hashLookup = new UnsafeHashMap<long, int>(16, Allocator.Persistent),
data = new UnsafeList<byte>(typeSize * 16, AllocationHandle.Persistent),
infos = new UnsafeList<EntryInfo>(16, AllocationHandle.Persistent),
hashLookup = new UnsafeHashMap<long, int>(16, AllocationHandle.Persistent),
freeListHead = 0,
versionCounter = 0
};
@@ -217,7 +217,7 @@ internal sealed unsafe class SharedComponentStore : IDisposable
_perType.Add(componentTypeId, store);
existing = ref _perType.GetValueRef(componentTypeId, out exist);
Debug.Assert(exist);
Logger.DebugAssert(exist);
return ref existing;
}

View File

@@ -61,7 +61,7 @@ public abstract class SystemBase : ISystem
{
if (!_requiredQueries.IsCreated)
{
_requiredQueries = new UnsafeList<int>(4, Misaki.HighPerformance.LowLevel.Buffer.Allocator.Persistent);
_requiredQueries = new UnsafeList<int>(4, Misaki.HighPerformance.LowLevel.Buffer.AllocationHandle.Persistent);
}
_requiredQueries.Add(queryID.Value);