Refactor GPU resource management and rendering pipeline

- Introduced `Handle<T>` and `Identifier<T>` for lightweight, strongly-typed resource identifiers.
- Replaced `BitSet` with `UnsafeBitSet` for improved performance and memory safety.
- Refactored `Mesh` and `Material` into `MeshClass` and `MaterialClass` for better GPU resource handling.
- Added `D3D12ResourceDatabase` to centralize GPU resource tracking and lifecycle management.
- Updated `D3D12ShaderCompiler` to load shaders from disk and dynamically populate constant buffers and textures.
- Enhanced `ICommandBuffer` with new upload operations for buffers and textures.
- Refactored `Vertex` struct for simplified memory layout and better performance.
- Updated `MeshBuilder` and rendering logic to align with new resource and shader structures.
- Added `BindlessDescriptor` support to `TextureHandle` and `BufferHandle`.
- Removed unused classes and performed general cleanup.
- Updated unit tests and demos to reflect the new architecture.
This commit is contained in:
2025-09-19 23:20:15 +09:00
parent 6a504cefc8
commit a39f377533
39 changed files with 1669 additions and 826 deletions

View File

@@ -472,7 +472,7 @@ internal struct ComponentStorage : IDisposable
private int _currentCapacity = 16;
private IComponentPool?[] _componentPools = new IComponentPool[16];
private BitSet?[] _componentEntityMasks = new BitSet[16];
private UnsafeBitSet?[] _componentEntityMasks = new UnsafeBitSet?[16];
private readonly Dictionary<TypeHandle, int> _typeIDMap = new(16);
private readonly Dictionary<int, TypeHandle> _typeHandleMap = new(16);
@@ -487,7 +487,7 @@ internal struct ComponentStorage : IDisposable
}
internal readonly IReadOnlyList<IComponentPool?> ComponentPools => _componentPools;
internal readonly IReadOnlyList<BitSet?> ComponentEntityMasks => _componentEntityMasks;
internal readonly IReadOnlyList<UnsafeBitSet?> ComponentEntityMasks => _componentEntityMasks;
internal readonly ScriptComponentPool ScriptComponentPool => _scriptComponentPool;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -621,7 +621,7 @@ internal struct ComponentStorage : IDisposable
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly bool TryGetMask(TypeHandle typeHandle, [NotNullWhen(true)] out BitSet? bitSet)
public readonly bool TryGetMask(TypeHandle typeHandle, [NotNullWhen(true)] out UnsafeBitSet? bitSet)
{
if (!_typeIDMap.TryGetValue(typeHandle, out var id)
|| id >= _currentCapacity)
@@ -631,17 +631,17 @@ internal struct ComponentStorage : IDisposable
}
bitSet = _componentEntityMasks[id];
return bitSet != null;
return bitSet.HasValue;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly bool TryGetMask<T>([NotNullWhen(true)] out BitSet? bitSet)
public readonly bool TryGetMask<T>([NotNullWhen(true)] out UnsafeBitSet? bitSet)
where T : unmanaged, IComponentData
{
return TryGetMask(TypeHandle.Get<T>(), out bitSet);
}
public BitSet GetOrCreateMask<T>()
public UnsafeBitSet GetOrCreateMask<T>()
where T : unmanaged, IComponentData
{
var typeHandle = TypeHandle.Get<T>();
@@ -658,12 +658,12 @@ internal struct ComponentStorage : IDisposable
}
ref var set = ref _componentEntityMasks[id];
set ??= new BitSet();
set ??= new UnsafeBitSet();
return set;
return set.Value;
}
public BitSet GetOrCreateMask(Type type)
public UnsafeBitSet GetOrCreateMask(Type type)
{
var typeHandle = TypeHandle.Get(type);
if (!_typeIDMap.TryGetValue(typeHandle, out var id))
@@ -679,9 +679,9 @@ internal struct ComponentStorage : IDisposable
}
ref var set = ref _componentEntityMasks[id];
set ??= new BitSet();
set ??= new UnsafeBitSet();
return set;
return set.Value;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -704,7 +704,11 @@ internal struct ComponentStorage : IDisposable
pool?.Dispose();
}
Array.Clear(_componentPools);
foreach (var bitSet in _componentEntityMasks)
{
bitSet?.Dispose();
}
_scriptComponentPool.Dispose();
}
}

View File

@@ -186,7 +186,7 @@ public readonly struct EntityManager : IDisposable
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly bool HasComponent(Entity entity, TypeHandle typeHandle)
{
return _world.ComponentStorage.TryGetMask(typeHandle, out var bitSet) && bitSet.IsSet(entity.ID);
return _world.ComponentStorage.TryGetMask(typeHandle, out var bitSet) && bitSet.Value.IsSet(entity.ID);
}
/// <summary>

View File

@@ -25,25 +25,20 @@ internal struct QueryFilter()
internal List<TypeHandle> _absent = new(6);
internal List<TypeHandle> _disabled = new(6);
public readonly BitSet ComputeFilterBitMask(World world)
public readonly UnsafeBitSet ComputeFilterBitMask(World world)
{
BitSet? allMask = null;
BitSet? anyMask = null;
BitSet? absentMask = null;
var hasAll = false;
var hasAny = false;
var hasAbsent = false;
UnsafeBitSet? allMask = null;
UnsafeBitSet? anyMask = null;
UnsafeBitSet? absentMask = null;
foreach (var typeHandle in _all)
{
var mask = world.ComponentStorage.GetOrCreateMask(typeHandle);
if (!hasAll)
if (!allMask.HasValue)
{
allMask = new BitSet(mask.Length);
allMask.SetAll();
hasAll = true;
allMask = new UnsafeBitSet(mask.Length);
allMask.Value.SetAll();
}
allMask &= mask;
@@ -53,10 +48,9 @@ internal struct QueryFilter()
{
var mask = world.ComponentStorage.GetOrCreateMask(typeHandle);
if (!hasAny)
if (!anyMask.HasValue)
{
anyMask = new BitSet(mask.Length);
hasAny = true;
anyMask = new UnsafeBitSet(mask.Length);
}
anyMask |= mask;
@@ -66,31 +60,30 @@ internal struct QueryFilter()
{
var mask = world.ComponentStorage.GetOrCreateMask(typeHandle);
if (!hasAbsent)
if (!absentMask.HasValue)
{
absentMask = new BitSet(mask.Length);
hasAbsent = true;
absentMask = new UnsafeBitSet(mask.Length);
}
absentMask |= mask;
}
var result = new BitSet(world.EntityManager.EntityCount);
var result = new UnsafeBitSet(world.EntityManager.EntityCount);
result.SetAll();
if (hasAll)
if (allMask.HasValue)
{
result &= allMask!;
result &= allMask.Value;
}
if (hasAny)
if (anyMask.HasValue)
{
result &= anyMask!;
result &= anyMask.Value;
}
if (hasAbsent)
if (absentMask.HasValue)
{
result &= ~absentMask!;
result &= ~absentMask.Value;
}
return result;

View File

@@ -42,7 +42,7 @@ public struct QueryEnumerable<T0>
private int _index;
private readonly int _count;
private BitSet _filterMask;
private UnsafeBitSet _filterMask;
public QueryItem<T0> Current
{
@@ -213,7 +213,7 @@ public struct QueryEnumerable<T0, T1>
private int _index;
private readonly int _count;
private BitSet _filterMask;
private UnsafeBitSet _filterMask;
public QueryItem<T0, T1> Current
{
@@ -389,7 +389,7 @@ public struct QueryEnumerable<T0, T1, T2>
private int _index;
private readonly int _count;
private BitSet _filterMask;
private UnsafeBitSet _filterMask;
public QueryItem<T0, T1, T2> Current
{
@@ -570,7 +570,7 @@ public struct QueryEnumerable<T0, T1, T2, T3>
private int _index;
private readonly int _count;
private BitSet _filterMask;
private UnsafeBitSet _filterMask;
public QueryItem<T0, T1, T2, T3> Current
{
@@ -756,7 +756,7 @@ public struct QueryEnumerable<T0, T1, T2, T3, T4>
private int _index;
private readonly int _count;
private BitSet _filterMask;
private UnsafeBitSet _filterMask;
public QueryItem<T0, T1, T2, T3, T4> Current
{
@@ -947,7 +947,7 @@ public struct QueryEnumerable<T0, T1, T2, T3, T4, T5>
private int _index;
private readonly int _count;
private BitSet _filterMask;
private UnsafeBitSet _filterMask;
public QueryItem<T0, T1, T2, T3, T4, T5> Current
{
@@ -1143,7 +1143,7 @@ public struct QueryEnumerable<T0, T1, T2, T3, T4, T5, T6>
private int _index;
private readonly int _count;
private BitSet _filterMask;
private UnsafeBitSet _filterMask;
public QueryItem<T0, T1, T2, T3, T4, T5, T6> Current
{
@@ -1344,7 +1344,7 @@ public struct QueryEnumerable<T0, T1, T2, T3, T4, T5, T6, T7>
private int _index;
private readonly int _count;
private BitSet _filterMask;
private UnsafeBitSet _filterMask;
public QueryItem<T0, T1, T2, T3, T4, T5, T6, T7> Current
{

View File

@@ -66,7 +66,7 @@ public struct QueryEnumerable<<#= generics #>>
private int _index;
private readonly int _count;
private BitSet _filterMask;
private UnsafeBitSet _filterMask;
public QueryItem<<#= generics #>> Current
{