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:
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user