Updated Handle and Identifier that default is invalid

This commit is contained in:
2025-12-23 14:22:44 +09:00
parent aa3d9c749b
commit b8ce824292
21 changed files with 268 additions and 221 deletions

View File

@@ -6,23 +6,30 @@ public interface IKeyType;
public readonly struct Handle<T> : IEquatable<Handle<T>> public readonly struct Handle<T> : IEquatable<Handle<T>>
{ {
public readonly int id; public int ID
public readonly int generation; {
get => field - 1;
}
public int Generation
{
get => field - 1;
}
public Handle(int id, int generation) public Handle(int id, int generation)
{ {
this.id = id; ID = id + 1;
this.generation = generation; Generation = generation + 1;
} }
public static Handle<T> Invalid => new(-1, -1); public static Handle<T> Invalid => default;
public readonly bool IsValid => this != Invalid; public readonly bool IsValid => this != Invalid;
public readonly bool IsNotValid => this == Invalid; public readonly bool IsInvalid => this == Invalid;
public readonly override int GetHashCode() public readonly override int GetHashCode()
{ {
return id + (generation << 16); return ID + (Generation << 16);
} }
public readonly override bool Equals(object? obj) public readonly override bool Equals(object? obj)
@@ -32,17 +39,17 @@ public readonly struct Handle<T> : IEquatable<Handle<T>>
public override string ToString() public override string ToString()
{ {
return $"Handle<{typeof(T).Name}>({id}, {generation})"; return $"Handle<{typeof(T).Name}>({ID}, {Generation})";
} }
public readonly bool Equals(Handle<T> other) public readonly bool Equals(Handle<T> other)
{ {
return id == other.id; return ID == other.ID && Generation == other.Generation;
} }
public readonly int CompareTo(Handle<T> other) public readonly int CompareTo(Handle<T> other)
{ {
return id.CompareTo(other.id); return ID.CompareTo(other.ID);
} }
public static bool operator ==(Handle<T> a, Handle<T> b) public static bool operator ==(Handle<T> a, Handle<T> b)
@@ -58,21 +65,24 @@ public readonly struct Handle<T> : IEquatable<Handle<T>>
public readonly struct Identifier<T> : IEquatable<Identifier<T>> public readonly struct Identifier<T> : IEquatable<Identifier<T>>
{ {
public readonly int value; public int Value
{
get => field - 1;
}
public Identifier(int value) public Identifier(int value)
{ {
this.value = value; Value = value + 1;
} }
public static Identifier<T> Invalid => new(-1); public static Identifier<T> Invalid => default;
public readonly bool IsValid => this != Invalid; public readonly bool IsValid => this != Invalid;
public readonly bool IsInvalid => this == Invalid; public readonly bool IsInvalid => this == Invalid;
public readonly override int GetHashCode() public readonly override int GetHashCode()
{ {
return value; return Value;
} }
public readonly override bool Equals(object? obj) public readonly override bool Equals(object? obj)
@@ -82,17 +92,17 @@ public readonly struct Identifier<T> : IEquatable<Identifier<T>>
public override string ToString() public override string ToString()
{ {
return $"Identifier<{typeof(T).Name}>({value})"; return $"Identifier<{typeof(T).Name}>({Value})";
} }
public readonly bool Equals(Identifier<T> other) public readonly bool Equals(Identifier<T> other)
{ {
return value == other.value; return Value == other.Value;
} }
public readonly int CompareTo(Identifier<T> other) public readonly int CompareTo(Identifier<T> other)
{ {
return value.CompareTo(other.value); return Value.CompareTo(other.Value);
} }
public static bool operator ==(Identifier<T> a, Identifier<T> b) public static bool operator ==(Identifier<T> a, Identifier<T> b)
@@ -107,44 +117,48 @@ public readonly struct Identifier<T> : IEquatable<Identifier<T>>
public static bool operator <(Identifier<T> a, Identifier<T> b) public static bool operator <(Identifier<T> a, Identifier<T> b)
{ {
return a.value < b.value; return a.Value < b.Value;
} }
public static bool operator >(Identifier<T> a, Identifier<T> b) public static bool operator >(Identifier<T> a, Identifier<T> b)
{ {
return a.value > b.value; return a.Value > b.Value;
} }
public static bool operator <=(Identifier<T> a, Identifier<T> b) public static bool operator <=(Identifier<T> a, Identifier<T> b)
{ {
return a.value <= b.value; return a.Value <= b.Value;
} }
public static bool operator >=(Identifier<T> a, Identifier<T> b) public static bool operator >=(Identifier<T> a, Identifier<T> b)
{ {
return a.value >= b.value; return a.Value >= b.Value;
} }
public static implicit operator int(Identifier<T> id) => id.value; public static implicit operator int(Identifier<T> id) => id.Value;
public static implicit operator Identifier<T>(int value) => new Identifier<T>(value); public static implicit operator Identifier<T>(int value) => new Identifier<T>(value);
} }
public readonly struct Key<T> public readonly struct Key<T>
{ {
public readonly ulong value; public ulong Value
{
get;
}
public Key(ulong value) public Key(ulong value)
{ {
this.value = value; Value = value;
} }
public static Key<T> Invalid => new(0); public static Key<T> Invalid => new(0);
public bool IsValid => this != Invalid; public bool IsValid => this != Invalid;
public bool IsInvalid => this == Invalid;
public readonly override int GetHashCode() public readonly override int GetHashCode()
{ {
return value.GetHashCode(); return Value.GetHashCode();
} }
public readonly override bool Equals(object? obj) public readonly override bool Equals(object? obj)
@@ -154,12 +168,12 @@ public readonly struct Key<T>
public readonly bool Equals(Key<T> other) public readonly bool Equals(Key<T> other)
{ {
return value == other.value; return Value == other.Value;
} }
public readonly int CompareTo(Key<T> other) public readonly int CompareTo(Key<T> other)
{ {
return value.CompareTo(other.value); return Value.CompareTo(other.Value);
} }
public static bool operator ==(Key<T> a, Key<T> b) public static bool operator ==(Key<T> a, Key<T> b)

View File

@@ -129,7 +129,7 @@ internal static class ComponentRegistry
s_typeHandleToID[typeHandle] = newID; s_typeHandleToID[typeHandle] = newID;
s_nameToRuntimeID[stableName] = newID; s_nameToRuntimeID[stableName] = newID;
s_runtimeIDToType[newID.value] = typeof(T); s_runtimeIDToType[newID.Value] = typeof(T);
return newID; return newID;
} }
@@ -179,9 +179,9 @@ internal static class ComponentRegistry
var largestID = 0; var largestID = 0;
foreach (var id in componentTypeIDs) foreach (var id in componentTypeIDs)
{ {
if (id.value > largestID) if (id.Value > largestID)
{ {
largestID = id.value; largestID = id.Value;
} }
} }
@@ -192,7 +192,7 @@ internal static class ComponentRegistry
var bitSet = new SpanBitSet(bits); var bitSet = new SpanBitSet(bits);
foreach (var id in componentTypeIDs) foreach (var id in componentTypeIDs)
{ {
bitSet.SetBit(id.value); bitSet.SetBit(id.Value);
} }
return bitSet.GetHashCode(); return bitSet.GetHashCode();

View File

@@ -112,7 +112,7 @@ public readonly unsafe ref struct ChunkView
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private Archetype.ComponentMemoryLayout GetLayout(Identifier<IComponent> id) private Archetype.ComponentMemoryLayout GetLayout(Identifier<IComponent> id)
{ {
var layout = _layouts[id.value]; var layout = _layouts[id.Value];
if (layout.enableBitsOffset == -1) if (layout.enableBitsOffset == -1)
{ {
throw new InvalidOperationException($"Component {id} is not exist in the archetype."); throw new InvalidOperationException($"Component {id} is not exist in the archetype.");
@@ -502,7 +502,7 @@ public ref partial struct QueryBuilder
{ {
foreach (var id in list) foreach (var id in list)
{ {
if (id.value > max) max = id.value; if (id.Value > max) max = id.Value;
} }
} }

View File

@@ -58,7 +58,7 @@ public abstract class SystemBase : ISystem
protected void RequireQueryForUpdate(Identifier<EntityQuery> queryID) protected void RequireQueryForUpdate(Identifier<EntityQuery> queryID)
{ {
_requiredQueries ??= new List<int>(4); _requiredQueries ??= new List<int>(4);
_requiredQueries.Add(queryID.value); _requiredQueries.Add(queryID.Value);
} }
void ISystem.Initialize(ref readonly SystemAPI systemAPI) void ISystem.Initialize(ref readonly SystemAPI systemAPI)

View File

@@ -1,4 +1,3 @@
namespace Ghost.Entities; namespace Ghost.Entities;
public unsafe partial struct EntityQuery public unsafe partial struct EntityQuery
@@ -13,7 +12,7 @@ public unsafe partial struct EntityQuery
var compTypeIDs = stackalloc int[] var compTypeIDs = stackalloc int[]
{ {
comp0TypeID.value, comp0TypeID.Value,
}; };
var changedCompIDs = stackalloc int[1]; var changedCompIDs = stackalloc int[1];
@@ -99,8 +98,8 @@ public unsafe partial struct EntityQuery
var compTypeIDs = stackalloc int[] var compTypeIDs = stackalloc int[]
{ {
comp0TypeID.value, comp0TypeID.Value,
comp1TypeID.value, comp1TypeID.Value,
}; };
var changedCompIDs = stackalloc int[2]; var changedCompIDs = stackalloc int[2];
@@ -189,9 +188,9 @@ public unsafe partial struct EntityQuery
var compTypeIDs = stackalloc int[] var compTypeIDs = stackalloc int[]
{ {
comp0TypeID.value, comp0TypeID.Value,
comp1TypeID.value, comp1TypeID.Value,
comp2TypeID.value, comp2TypeID.Value,
}; };
var changedCompIDs = stackalloc int[3]; var changedCompIDs = stackalloc int[3];
@@ -283,10 +282,10 @@ public unsafe partial struct EntityQuery
var compTypeIDs = stackalloc int[] var compTypeIDs = stackalloc int[]
{ {
comp0TypeID.value, comp0TypeID.Value,
comp1TypeID.value, comp1TypeID.Value,
comp2TypeID.value, comp2TypeID.Value,
comp3TypeID.value, comp3TypeID.Value,
}; };
var changedCompIDs = stackalloc int[4]; var changedCompIDs = stackalloc int[4];
@@ -381,11 +380,11 @@ public unsafe partial struct EntityQuery
var compTypeIDs = stackalloc int[] var compTypeIDs = stackalloc int[]
{ {
comp0TypeID.value, comp0TypeID.Value,
comp1TypeID.value, comp1TypeID.Value,
comp2TypeID.value, comp2TypeID.Value,
comp3TypeID.value, comp3TypeID.Value,
comp4TypeID.value, comp4TypeID.Value,
}; };
var changedCompIDs = stackalloc int[5]; var changedCompIDs = stackalloc int[5];
@@ -483,12 +482,12 @@ public unsafe partial struct EntityQuery
var compTypeIDs = stackalloc int[] var compTypeIDs = stackalloc int[]
{ {
comp0TypeID.value, comp0TypeID.Value,
comp1TypeID.value, comp1TypeID.Value,
comp2TypeID.value, comp2TypeID.Value,
comp3TypeID.value, comp3TypeID.Value,
comp4TypeID.value, comp4TypeID.Value,
comp5TypeID.value, comp5TypeID.Value,
}; };
var changedCompIDs = stackalloc int[6]; var changedCompIDs = stackalloc int[6];
@@ -589,13 +588,13 @@ public unsafe partial struct EntityQuery
var compTypeIDs = stackalloc int[] var compTypeIDs = stackalloc int[]
{ {
comp0TypeID.value, comp0TypeID.Value,
comp1TypeID.value, comp1TypeID.Value,
comp2TypeID.value, comp2TypeID.Value,
comp3TypeID.value, comp3TypeID.Value,
comp4TypeID.value, comp4TypeID.Value,
comp5TypeID.value, comp5TypeID.Value,
comp6TypeID.value, comp6TypeID.Value,
}; };
var changedCompIDs = stackalloc int[7]; var changedCompIDs = stackalloc int[7];
@@ -699,14 +698,14 @@ public unsafe partial struct EntityQuery
var compTypeIDs = stackalloc int[] var compTypeIDs = stackalloc int[]
{ {
comp0TypeID.value, comp0TypeID.Value,
comp1TypeID.value, comp1TypeID.Value,
comp2TypeID.value, comp2TypeID.Value,
comp3TypeID.value, comp3TypeID.Value,
comp4TypeID.value, comp4TypeID.Value,
comp5TypeID.value, comp5TypeID.Value,
comp6TypeID.value, comp6TypeID.Value,
comp7TypeID.value, comp7TypeID.Value,
}; };
var changedCompIDs = stackalloc int[8]; var changedCompIDs = stackalloc int[8];
@@ -797,7 +796,7 @@ public unsafe partial struct EntityQuery
var compTypeIDs = stackalloc int[] var compTypeIDs = stackalloc int[]
{ {
comp0TypeID.value, comp0TypeID.Value,
}; };
var changedCompIDs = stackalloc int[1]; var changedCompIDs = stackalloc int[1];
@@ -884,8 +883,8 @@ public unsafe partial struct EntityQuery
var compTypeIDs = stackalloc int[] var compTypeIDs = stackalloc int[]
{ {
comp0TypeID.value, comp0TypeID.Value,
comp1TypeID.value, comp1TypeID.Value,
}; };
var changedCompIDs = stackalloc int[2]; var changedCompIDs = stackalloc int[2];
@@ -975,9 +974,9 @@ public unsafe partial struct EntityQuery
var compTypeIDs = stackalloc int[] var compTypeIDs = stackalloc int[]
{ {
comp0TypeID.value, comp0TypeID.Value,
comp1TypeID.value, comp1TypeID.Value,
comp2TypeID.value, comp2TypeID.Value,
}; };
var changedCompIDs = stackalloc int[3]; var changedCompIDs = stackalloc int[3];
@@ -1070,10 +1069,10 @@ public unsafe partial struct EntityQuery
var compTypeIDs = stackalloc int[] var compTypeIDs = stackalloc int[]
{ {
comp0TypeID.value, comp0TypeID.Value,
comp1TypeID.value, comp1TypeID.Value,
comp2TypeID.value, comp2TypeID.Value,
comp3TypeID.value, comp3TypeID.Value,
}; };
var changedCompIDs = stackalloc int[4]; var changedCompIDs = stackalloc int[4];
@@ -1169,11 +1168,11 @@ public unsafe partial struct EntityQuery
var compTypeIDs = stackalloc int[] var compTypeIDs = stackalloc int[]
{ {
comp0TypeID.value, comp0TypeID.Value,
comp1TypeID.value, comp1TypeID.Value,
comp2TypeID.value, comp2TypeID.Value,
comp3TypeID.value, comp3TypeID.Value,
comp4TypeID.value, comp4TypeID.Value,
}; };
var changedCompIDs = stackalloc int[5]; var changedCompIDs = stackalloc int[5];
@@ -1272,12 +1271,12 @@ public unsafe partial struct EntityQuery
var compTypeIDs = stackalloc int[] var compTypeIDs = stackalloc int[]
{ {
comp0TypeID.value, comp0TypeID.Value,
comp1TypeID.value, comp1TypeID.Value,
comp2TypeID.value, comp2TypeID.Value,
comp3TypeID.value, comp3TypeID.Value,
comp4TypeID.value, comp4TypeID.Value,
comp5TypeID.value, comp5TypeID.Value,
}; };
var changedCompIDs = stackalloc int[6]; var changedCompIDs = stackalloc int[6];
@@ -1379,13 +1378,13 @@ public unsafe partial struct EntityQuery
var compTypeIDs = stackalloc int[] var compTypeIDs = stackalloc int[]
{ {
comp0TypeID.value, comp0TypeID.Value,
comp1TypeID.value, comp1TypeID.Value,
comp2TypeID.value, comp2TypeID.Value,
comp3TypeID.value, comp3TypeID.Value,
comp4TypeID.value, comp4TypeID.Value,
comp5TypeID.value, comp5TypeID.Value,
comp6TypeID.value, comp6TypeID.Value,
}; };
var changedCompIDs = stackalloc int[7]; var changedCompIDs = stackalloc int[7];
@@ -1490,14 +1489,14 @@ public unsafe partial struct EntityQuery
var compTypeIDs = stackalloc int[] var compTypeIDs = stackalloc int[]
{ {
comp0TypeID.value, comp0TypeID.Value,
comp1TypeID.value, comp1TypeID.Value,
comp2TypeID.value, comp2TypeID.Value,
comp3TypeID.value, comp3TypeID.Value,
comp4TypeID.value, comp4TypeID.Value,
comp5TypeID.value, comp5TypeID.Value,
comp6TypeID.value, comp6TypeID.Value,
comp7TypeID.value, comp7TypeID.Value,
}; };
var changedCompIDs = stackalloc int[8]; var changedCompIDs = stackalloc int[8];

View File

@@ -32,7 +32,7 @@ public unsafe partial struct EntityQuery
var compTypeIDs = stackalloc int[] var compTypeIDs = stackalloc int[]
{ {
<# for (var localIndex = 0; localIndex < i; localIndex++) { #> <# for (var localIndex = 0; localIndex < i; localIndex++) { #>
comp<#= localIndex #>TypeID.value, comp<#= localIndex #>TypeID.Value,
<# } #> <# } #>
}; };

View File

@@ -21,7 +21,7 @@ public partial class World
{ {
if (s_freeWorldSlots.TryDequeue(out var index)) if (s_freeWorldSlots.TryDequeue(out var index))
{ {
s_worlds[index.value] = new World(index, entityCapacity, jobScheduler); s_worlds[index.Value] = new World(index, entityCapacity, jobScheduler);
} }
else else
{ {
@@ -29,7 +29,7 @@ public partial class World
s_worlds.Add(new World(index, entityCapacity, jobScheduler)); s_worlds.Add(new World(index, entityCapacity, jobScheduler));
} }
return s_worlds[index.value]!; return s_worlds[index.Value]!;
} }
} }
@@ -37,12 +37,12 @@ public partial class World
{ {
lock (s_worlds) lock (s_worlds)
{ {
if (id.value < 0 || id.value >= s_worlds.Count) if (id.Value < 0 || id.Value >= s_worlds.Count)
{ {
return; return;
} }
var world = s_worlds[id.value]; var world = s_worlds[id.Value];
world?.Dispose(); world?.Dispose();
} }
} }
@@ -51,12 +51,12 @@ public partial class World
internal static World GetWorldUncheck(Identifier<World> id) internal static World GetWorldUncheck(Identifier<World> id)
{ {
#if DEBUG || GHOST_EDITOR #if DEBUG || GHOST_EDITOR
if (id.value < 0 || id.value >= s_worlds.Count) if (id.Value < 0 || id.Value >= s_worlds.Count)
{ {
throw new ArgumentOutOfRangeException(nameof(id), "World ID is out of range."); throw new ArgumentOutOfRangeException(nameof(id), "World ID is out of range.");
} }
var world = s_worlds[id.value]; var world = s_worlds[id.Value];
return world is null ? throw new InvalidOperationException("World not found.") : world; return world is null ? throw new InvalidOperationException("World not found.") : world;
#else #else
return s_worlds[id.value]!; return s_worlds[id.value]!;
@@ -66,12 +66,12 @@ public partial class World
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Result<World, ErrorStatus> GetWorld(Identifier<World> id) public static Result<World, ErrorStatus> GetWorld(Identifier<World> id)
{ {
if (id.value < 0 || id.value >= s_worlds.Count) if (id.Value < 0 || id.Value >= s_worlds.Count)
{ {
return ErrorStatus.InvalidArgument; return ErrorStatus.InvalidArgument;
} }
var world = s_worlds[id.value]; var world = s_worlds[id.Value];
return world is null ? ErrorStatus.NotFound : world; return world is null ? ErrorStatus.NotFound : world;
} }
} }
@@ -175,7 +175,7 @@ public partial class World : IDisposable, IEquatable<World>
for (int i = 0; i < _entityQueries.Count; i++) for (int i = 0; i < _entityQueries.Count; i++)
{ {
ref var query = ref _entityQueries[i]; ref var query = ref _entityQueries[i];
query.AddArchetypeIfMatch(in _archetypes[arcID.value]); query.AddArchetypeIfMatch(in _archetypes[arcID.Value]);
} }
return arcID; return arcID;
@@ -195,7 +195,7 @@ public partial class World : IDisposable, IEquatable<World>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal ref Archetype GetArchetypeReference(Identifier<Archetype> id) internal ref Archetype GetArchetypeReference(Identifier<Archetype> id)
{ {
return ref _archetypes[id.value]; return ref _archetypes[id.Value];
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -205,7 +205,7 @@ public partial class World : IDisposable, IEquatable<World>
_entityQueries.Add(new EntityQuery(queryID, _id, mask)); _entityQueries.Add(new EntityQuery(queryID, _id, mask));
_querieLookup.Add(maskHash, queryID); _querieLookup.Add(maskHash, queryID);
ref var query = ref _entityQueries[queryID.value]; ref var query = ref _entityQueries[queryID.Value];
for (var i = 0; i < _archetypes.Count; i++) for (var i = 0; i < _archetypes.Count; i++)
{ {
query.AddArchetypeIfMatch(in _archetypes[i]); query.AddArchetypeIfMatch(in _archetypes[i]);
@@ -251,7 +251,7 @@ public partial class World : IDisposable, IEquatable<World>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref EntityQuery GetEntityQueryReference(Identifier<EntityQuery> id) public ref EntityQuery GetEntityQueryReference(Identifier<EntityQuery> id)
{ {
return ref _entityQueries[id.value]; return ref _entityQueries[id.Value];
} }
/// <summary> /// <summary>

View File

@@ -6,6 +6,16 @@ namespace Ghost.Graphics.Contracts;
public interface IRenderTargetStrategy public interface IRenderTargetStrategy
{ {
ViewportDesc Viewport
{
get;
}
RectDesc Scissor
{
get;
}
/// <summary> /// <summary>
/// Gets a handle to the current render target texture. /// Gets a handle to the current render target texture.
/// </summary> /// </summary>

View File

@@ -8,9 +8,22 @@ internal class SwapChainTargetStrategy : IRenderTargetStrategy
{ {
private readonly ISwapChain _swapChain; private readonly ISwapChain _swapChain;
public ViewportDesc Viewport
{
get; set;
}
public RectDesc Scissor
{
get; set;
}
public SwapChainTargetStrategy(ISwapChain swapChain) public SwapChainTargetStrategy(ISwapChain swapChain)
{ {
_swapChain = swapChain; _swapChain = swapChain;
Viewport = new ViewportDesc { Width = swapChain.Width, Height = swapChain.Height, MinDepth = 0, MaxDepth = 1 };
Scissor = new RectDesc { Right = swapChain.Width, Bottom = swapChain.Height };
} }
public Handle<Texture> GetRenderTarget() public Handle<Texture> GetRenderTarget()
@@ -38,6 +51,16 @@ internal class TextureTargetStrategy : IRenderTargetStrategy
{ {
private readonly Handle<Texture> _texture; private readonly Handle<Texture> _texture;
public ViewportDesc Viewport
{
get; set;
}
public RectDesc Scissor
{
get; set;
}
public TextureTargetStrategy(Handle<Texture> texture) public TextureTargetStrategy(Handle<Texture> texture)
{ {
_texture = texture; _texture = texture;

View File

@@ -12,21 +12,21 @@ public static class ResourceHandleExtensions
{ {
public static Handle<GPUResource> AsResource(this Handle<Texture> texture) public static Handle<GPUResource> AsResource(this Handle<Texture> texture)
{ {
return new Handle<GPUResource>(texture.id, texture.generation); return new Handle<GPUResource>(texture.ID, texture.Generation);
} }
public static Handle<GPUResource> AsResource(this Handle<GraphicsBuffer> buffer) public static Handle<GPUResource> AsResource(this Handle<GraphicsBuffer> buffer)
{ {
return new Handle<GPUResource>(buffer.id, buffer.generation); return new Handle<GPUResource>(buffer.ID, buffer.Generation);
} }
internal static Handle<Texture> AsTexture(this Handle<GPUResource> resource) internal static Handle<Texture> AsTexture(this Handle<GPUResource> resource)
{ {
return new Handle<Texture>(resource.id, resource.generation); return new Handle<Texture>(resource.ID, resource.Generation);
} }
internal static Handle<GraphicsBuffer> AsGraphicsBuffer(this Handle<GPUResource> resource) internal static Handle<GraphicsBuffer> AsGraphicsBuffer(this Handle<GPUResource> resource)
{ {
return new Handle<GraphicsBuffer>(resource.id, resource.generation); return new Handle<GraphicsBuffer>(resource.ID, resource.Generation);
} }
} }

View File

@@ -3,7 +3,6 @@ using Ghost.Core.Graphics;
using Ghost.Graphics.RHI; using Ghost.Graphics.RHI;
using Misaki.HighPerformance.LowLevel.Buffer; using Misaki.HighPerformance.LowLevel.Buffer;
using Misaki.HighPerformance.LowLevel.Collections; using Misaki.HighPerformance.LowLevel.Collections;
using System.Runtime.CompilerServices;
namespace Ghost.Graphics.Core; namespace Ghost.Graphics.Core;
@@ -41,7 +40,7 @@ public struct ShaderPass : IResourceReleasable
// TODO: Shader variant. // TODO: Shader variant.
void IResourceReleasable.ReleaseResource(IResourceDatabase database) readonly void IResourceReleasable.ReleaseResource(IResourceDatabase database)
{ {
} }
} }

View File

@@ -114,8 +114,10 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
#if DEBUG #if DEBUG
[DoesNotReturn] [DoesNotReturn]
#endif private static void RecordError(string cmdName, ErrorStatus status)
#else
private void RecordError(string cmdName, ErrorStatus status) private void RecordError(string cmdName, ErrorStatus status)
#endif
{ {
#if DEBUG #if DEBUG
throw new InvalidOperationException($"Error at {cmdName} with {status}"); throw new InvalidOperationException($"Error at {cmdName} with {status}");

View File

@@ -70,14 +70,14 @@ internal unsafe class D3D12DescriptorAllocator : IDisposable
public D3D12_CPU_DESCRIPTOR_HANDLE GetCpuHandle(Identifier<RTVDescriptor> descriptor) public D3D12_CPU_DESCRIPTOR_HANDLE GetCpuHandle(Identifier<RTVDescriptor> descriptor)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
return _rtvHeap.GetCpuHandle(descriptor.value); return _rtvHeap.GetCpuHandle(descriptor.Value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Release(Identifier<RTVDescriptor> descriptor) public void Release(Identifier<RTVDescriptor> descriptor)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
_rtvHeap.ReleaseDescriptor(descriptor.value); _rtvHeap.ReleaseDescriptor(descriptor.Value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -95,7 +95,7 @@ internal unsafe class D3D12DescriptorAllocator : IDisposable
public void MakePersistent(Identifier<RTVDescriptor> descriptor) public void MakePersistent(Identifier<RTVDescriptor> descriptor)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
_rtvHeap.CopyToPersistentHeap(descriptor.value); _rtvHeap.CopyToPersistentHeap(descriptor.Value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -155,13 +155,13 @@ internal unsafe class D3D12DescriptorAllocator : IDisposable
public D3D12_CPU_DESCRIPTOR_HANDLE GetCpuHandle(Identifier<DSVDescriptor> descriptor) public D3D12_CPU_DESCRIPTOR_HANDLE GetCpuHandle(Identifier<DSVDescriptor> descriptor)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
return _dsvHeap.GetCpuHandle(descriptor.value); return _dsvHeap.GetCpuHandle(descriptor.Value);
} }
public void Release(Identifier<DSVDescriptor> descriptor) public void Release(Identifier<DSVDescriptor> descriptor)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
_dsvHeap.ReleaseDescriptor(descriptor.value); _dsvHeap.ReleaseDescriptor(descriptor.Value);
} }
public void Release(ReadOnlySpan<Identifier<DSVDescriptor>> descriptors) public void Release(ReadOnlySpan<Identifier<DSVDescriptor>> descriptors)
@@ -178,7 +178,7 @@ internal unsafe class D3D12DescriptorAllocator : IDisposable
public void MakePersistent(Identifier<DSVDescriptor> descriptor) public void MakePersistent(Identifier<DSVDescriptor> descriptor)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
_dsvHeap.CopyToPersistentHeap(descriptor.value); _dsvHeap.CopyToPersistentHeap(descriptor.Value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -240,25 +240,25 @@ internal unsafe class D3D12DescriptorAllocator : IDisposable
public D3D12_CPU_DESCRIPTOR_HANDLE GetCpuHandle(Identifier<CbvSrvUavDescriptor> descriptor) public D3D12_CPU_DESCRIPTOR_HANDLE GetCpuHandle(Identifier<CbvSrvUavDescriptor> descriptor)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
return _cbvSrvUavHeap.GetCpuHandle(descriptor.value); return _cbvSrvUavHeap.GetCpuHandle(descriptor.Value);
} }
public D3D12_CPU_DESCRIPTOR_HANDLE GetCpuHandleShaderVisible(Identifier<CbvSrvUavDescriptor> descriptor) public D3D12_CPU_DESCRIPTOR_HANDLE GetCpuHandleShaderVisible(Identifier<CbvSrvUavDescriptor> descriptor)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
return _cbvSrvUavHeap.GetCpuHandleShaderVisible(descriptor.value); return _cbvSrvUavHeap.GetCpuHandleShaderVisible(descriptor.Value);
} }
public D3D12_GPU_DESCRIPTOR_HANDLE GetGpuHandle(Identifier<CbvSrvUavDescriptor> descriptor) public D3D12_GPU_DESCRIPTOR_HANDLE GetGpuHandle(Identifier<CbvSrvUavDescriptor> descriptor)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
return _cbvSrvUavHeap.GetGpuHandle(descriptor.value); return _cbvSrvUavHeap.GetGpuHandle(descriptor.Value);
} }
public void Release(Identifier<CbvSrvUavDescriptor> descriptor) public void Release(Identifier<CbvSrvUavDescriptor> descriptor)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
_cbvSrvUavHeap.ReleaseDescriptor(descriptor.value); _cbvSrvUavHeap.ReleaseDescriptor(descriptor.Value);
} }
public void Release(ReadOnlySpan<Identifier<CbvSrvUavDescriptor>> descriptors) public void Release(ReadOnlySpan<Identifier<CbvSrvUavDescriptor>> descriptors)
@@ -275,7 +275,7 @@ internal unsafe class D3D12DescriptorAllocator : IDisposable
public void MakePersistent(Identifier<CbvSrvUavDescriptor> descriptor) public void MakePersistent(Identifier<CbvSrvUavDescriptor> descriptor)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
_cbvSrvUavHeap.CopyToPersistentHeap(descriptor.value); _cbvSrvUavHeap.CopyToPersistentHeap(descriptor.Value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -337,25 +337,25 @@ internal unsafe class D3D12DescriptorAllocator : IDisposable
public D3D12_CPU_DESCRIPTOR_HANDLE GetCpuHandle(Identifier<SamplerDescriptor> descriptor) public D3D12_CPU_DESCRIPTOR_HANDLE GetCpuHandle(Identifier<SamplerDescriptor> descriptor)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
return _samplerHeap.GetCpuHandle(descriptor.value); return _samplerHeap.GetCpuHandle(descriptor.Value);
} }
public D3D12_CPU_DESCRIPTOR_HANDLE GetCpuHandleShaderVisible(Identifier<SamplerDescriptor> descriptor) public D3D12_CPU_DESCRIPTOR_HANDLE GetCpuHandleShaderVisible(Identifier<SamplerDescriptor> descriptor)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
return _samplerHeap.GetCpuHandleShaderVisible(descriptor.value); return _samplerHeap.GetCpuHandleShaderVisible(descriptor.Value);
} }
public D3D12_GPU_DESCRIPTOR_HANDLE GetGpuHandle(Identifier<SamplerDescriptor> descriptor) public D3D12_GPU_DESCRIPTOR_HANDLE GetGpuHandle(Identifier<SamplerDescriptor> descriptor)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
return _samplerHeap.GetGpuHandle(descriptor.value); return _samplerHeap.GetGpuHandle(descriptor.Value);
} }
public void Release(Identifier<SamplerDescriptor> descriptor) public void Release(Identifier<SamplerDescriptor> descriptor)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
_samplerHeap.ReleaseDescriptor(descriptor.value); _samplerHeap.ReleaseDescriptor(descriptor.Value);
} }
public void Release(ReadOnlySpan<Identifier<SamplerDescriptor>> descriptors) public void Release(ReadOnlySpan<Identifier<SamplerDescriptor>> descriptors)

View File

@@ -51,6 +51,7 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary
CreateDefaultRootSignature().ThrowIfFailed(); CreateDefaultRootSignature().ThrowIfFailed();
} }
// TODO: Maybe we don't need 4 root signature. We can use bindless for global, per-view, and per-object buffers as well.
private Result CreateDefaultRootSignature() private Result CreateDefaultRootSignature()
{ {
_defaultRootSignature = default; _defaultRootSignature = default;

View File

@@ -53,7 +53,7 @@ internal class D3D12Renderer : IRenderer
} }
var target = RenderTargetStrategy.GetRenderTarget(); var target = RenderTargetStrategy.GetRenderTarget();
if (target.IsNotValid) if (target.IsInvalid)
{ {
return Result.Failure("Render target is invalid."); return Result.Failure("Render target is invalid.");
} }
@@ -64,7 +64,7 @@ internal class D3D12Renderer : IRenderer
// NOTE: Temperary solution: render directly to the swap chain back buffer if available. // NOTE: Temperary solution: render directly to the swap chain back buffer if available.
// HACK: This is hard coded for testing purposes only. // HACK: This is hard coded for testing purposes only.
var error = RenderScene(target); var error = RenderScene(target, RenderTargetStrategy.Viewport, RenderTargetStrategy.Scissor);
if (error != ErrorStatus.None) if (error != ErrorStatus.None)
{ {
_commandBuffer.End(); _commandBuffer.End();
@@ -85,7 +85,7 @@ internal class D3D12Renderer : IRenderer
} }
// TODO: A proper render graph integration. // TODO: A proper render graph integration.
private ErrorStatus RenderScene(Handle<Texture> target) private ErrorStatus RenderScene(Handle<Texture> target, ViewportDesc viewport, RectDesc rect)
{ {
var clearColor = new Color128 { r = 1.0f, g = 0.0f, b = 1.0f, a = 1.0f }; var clearColor = new Color128 { r = 1.0f, g = 0.0f, b = 1.0f, a = 1.0f };
@@ -112,20 +112,9 @@ internal class D3D12Renderer : IRenderer
_pass.Initialize(ref ctx); _pass.Initialize(ref ctx);
} }
var result = _resourceDatabase.GetResourceDescription(target.AsResource());
if (result.IsFailure)
{
return result.Error;
}
// TODO: Decouple viewport and scissor from the texture size.
var texDesc = result.Value.TextureDescription;
var viewport = new ViewportDesc { Width = texDesc.Width, Height = texDesc.Height, MinDepth = 0, MaxDepth = 1 };
var scissor = new RectDesc { Right = texDesc.Width, Bottom = texDesc.Height };
_commandBuffer.BeginRenderPass(rtDesc, depthDesc, false); _commandBuffer.BeginRenderPass(rtDesc, depthDesc, false);
_commandBuffer.SetViewport(viewport); _commandBuffer.SetViewport(viewport);
_commandBuffer.SetScissorRect(scissor); _commandBuffer.SetScissorRect(rect);
// NOTE: Testing only. // NOTE: Testing only.
_pass.Execute(ref ctx); _pass.Execute(ref ctx);

View File

@@ -879,7 +879,7 @@ internal sealed unsafe partial class D3D12ResourceAllocator : IResourceAllocator
var cpuHandle = _descriptorAllocator.GetCpuHandleShaderVisible(samplerDescriptor); var cpuHandle = _descriptorAllocator.GetCpuHandleShaderVisible(samplerDescriptor);
_device.NativeDevice.Get()->CreateSampler(&samplerDesc, cpuHandle); _device.NativeDevice.Get()->CreateSampler(&samplerDesc, cpuHandle);
return _resourceDatabase.CreateSampler(in desc, samplerDescriptor.value); return _resourceDatabase.CreateSampler(in desc, samplerDescriptor.Value);
} }
public Handle<Mesh> CreateMesh(UnsafeList<Vertex> vertices, UnsafeList<uint> indices) public Handle<Mesh> CreateMesh(UnsafeList<Vertex> vertices, UnsafeList<uint> indices)

View File

@@ -6,7 +6,6 @@ using Misaki.HighPerformance.Collections;
using Misaki.HighPerformance.LowLevel; using Misaki.HighPerformance.LowLevel;
using Misaki.HighPerformance.LowLevel.Buffer; using Misaki.HighPerformance.LowLevel.Buffer;
using Misaki.HighPerformance.LowLevel.Collections; using Misaki.HighPerformance.LowLevel.Collections;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using TerraFX.Interop.DirectX; using TerraFX.Interop.DirectX;
@@ -64,7 +63,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
this.viewGroup = viewGroup; this.viewGroup = viewGroup;
this.cpuFenceValue = ~0u; this.cpuFenceValue = ~0u;
this.state = state; this.state = state;
this.desc = ResourceDesc.FromD3D12(resource->GetDesc()); this.desc = resource->GetDesc().ToResourceDesc();
} }
public uint Release(D3D12DescriptorAllocator descriptorAllocator) public uint Release(D3D12DescriptorAllocator descriptorAllocator)
@@ -102,7 +101,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
private UnsafeSlotMap<Mesh> _meshes; private UnsafeSlotMap<Mesh> _meshes;
private UnsafeSlotMap<Material> _materials; private UnsafeSlotMap<Material> _materials;
private readonly DynamicArray<Shader?> _shaders; // NOTE: We use a simple list since shader is not frequently added/removed. This can save 4 bytes for each ecs component. private readonly DynamicArray<Shader?> _shaders; // NOTE: We use a simple list since shader is not frequently added/removed. This can save 4 bytes for each ecs component.
private readonly Dictionary<ShaderPassKey, ShaderPass> _shaderPasses; // NOTE: The reason we use Dictionary here is that ShaderPassKey is a presistence identifier across multiple application sessions. // private UnsafeHashMap<ShaderPassKey, ShaderPass> _shaderPasses; // NOTE: The reason we use Dictionary here is that ShaderPassKey is a presistence identifier across multiple application sessions.
private bool _disposed; private bool _disposed;
@@ -118,7 +117,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
_meshes = new UnsafeSlotMap<Mesh>(64, Allocator.Persistent, AllocationOption.Clear); _meshes = new UnsafeSlotMap<Mesh>(64, Allocator.Persistent, AllocationOption.Clear);
_materials = new UnsafeSlotMap<Material>(16, Allocator.Persistent, AllocationOption.Clear); _materials = new UnsafeSlotMap<Material>(16, Allocator.Persistent, AllocationOption.Clear);
_shaders = new DynamicArray<Shader?>(16); _shaders = new DynamicArray<Shader?>(16);
_shaderPasses = new Dictionary<ShaderPassKey, ShaderPass>(16); // _shaderPasses = new UnsafeHashMap<ShaderPassKey, ShaderPass>(32, Allocator.Persistent);
} }
~D3D12ResourceDatabase() ~D3D12ResourceDatabase()
@@ -172,14 +171,14 @@ internal class D3D12ResourceDatabase : IResourceDatabase
public bool HasResource(Handle<GPUResource> handle) public bool HasResource(Handle<GPUResource> handle)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
return _resources.Contains(handle.id, handle.generation); return _resources.Contains(handle.ID, handle.Generation);
} }
public RefResult<ResourceRecord, ErrorStatus> GetResourceRecord(Handle<GPUResource> handle) public RefResult<ResourceRecord, ErrorStatus> GetResourceRecord(Handle<GPUResource> handle)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
ref var info = ref _resources.GetElementReferenceAt(handle.id, handle.generation, out var exist); ref var info = ref _resources.GetElementReferenceAt(handle.ID, handle.Generation, out var exist);
if (!exist) if (!exist)
{ {
return ErrorStatus.NotFound; return ErrorStatus.NotFound;
@@ -191,7 +190,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
public ref ResourceRecord GetResourceRecord(Handle<GPUResource> handle, out bool exist) public ref ResourceRecord GetResourceRecord(Handle<GPUResource> handle, out bool exist)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
return ref _resources.GetElementReferenceAt(handle.id, handle.generation, out exist); return ref _resources.GetElementReferenceAt(handle.ID, handle.Generation, out exist);
} }
public SharedPtr<ID3D12Resource> GetResource(Handle<GPUResource> handle) public SharedPtr<ID3D12Resource> GetResource(Handle<GPUResource> handle)
@@ -224,7 +223,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
ref var info = ref _resources.GetElementReferenceAt(handle.id, handle.generation, out var exist); ref var info = ref _resources.GetElementReferenceAt(handle.ID, handle.Generation, out var exist);
if (!exist || !info.Allocated) if (!exist || !info.Allocated)
{ {
throw new KeyNotFoundException($"Resource with handle {handle} not found."); throw new KeyNotFoundException($"Resource with handle {handle} not found.");
@@ -256,7 +255,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
return ErrorStatus.NotFound; return ErrorStatus.NotFound;
} }
return (uint)info.viewGroup.srv.value; return (uint)info.viewGroup.srv.Value;
} }
public string? GetResourceName(Handle<GPUResource> handle) public string? GetResourceName(Handle<GPUResource> handle)
@@ -281,7 +280,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
return; return;
} }
ref var info = ref _resources.GetElementReferenceAt(handle.id, handle.generation, out var exist); ref var info = ref _resources.GetElementReferenceAt(handle.ID, handle.Generation, out var exist);
if (!exist || !info.Allocated) if (!exist || !info.Allocated)
{ {
return; return;
@@ -293,7 +292,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
_resourceName.Remove(handle, out var name); _resourceName.Remove(handle, out var name);
#endif #endif
_resources.Remove(handle.id, handle.generation); _resources.Remove(handle.ID, handle.Generation);
} }
public Identifier<Sampler> CreateSampler(ref readonly SamplerDesc desc, int id) public Identifier<Sampler> CreateSampler(ref readonly SamplerDesc desc, int id)
@@ -328,14 +327,14 @@ internal class D3D12ResourceDatabase : IResourceDatabase
public bool HasMesh(Handle<Mesh> handle) public bool HasMesh(Handle<Mesh> handle)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
return _meshes.Contains(handle.id, handle.generation); return _meshes.Contains(handle.ID, handle.Generation);
} }
public ref Mesh GetMeshReference(Handle<Mesh> handle) public ref Mesh GetMeshReference(Handle<Mesh> handle)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
ref var mesh = ref _meshes.GetElementReferenceAt(handle.id, handle.generation, out var exist); ref var mesh = ref _meshes.GetElementReferenceAt(handle.ID, handle.Generation, out var exist);
if (!exist) if (!exist)
{ {
throw new ArgumentOutOfRangeException(nameof(handle), $"Mesh {handle} is invalid."); throw new ArgumentOutOfRangeException(nameof(handle), $"Mesh {handle} is invalid.");
@@ -348,14 +347,14 @@ internal class D3D12ResourceDatabase : IResourceDatabase
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
ref var mesh = ref _meshes.GetElementReferenceAt(handle.id, handle.generation, out var exist); ref var mesh = ref _meshes.GetElementReferenceAt(handle.ID, handle.Generation, out var exist);
if (!exist) if (!exist)
{ {
return; return;
} }
ReleaseResource(ref mesh); ReleaseResource(ref mesh);
_meshes.Remove(handle.id, handle.generation); _meshes.Remove(handle.ID, handle.Generation);
} }
public Handle<Material> AddMaterial(ref readonly Material material) public Handle<Material> AddMaterial(ref readonly Material material)
@@ -369,14 +368,14 @@ internal class D3D12ResourceDatabase : IResourceDatabase
public bool HasMaterial(Handle<Material> handle) public bool HasMaterial(Handle<Material> handle)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
return _materials.Contains(handle.id, handle.generation); return _materials.Contains(handle.ID, handle.Generation);
} }
public ref Material GetMaterialReference(Handle<Material> handle) public ref Material GetMaterialReference(Handle<Material> handle)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
ref var material = ref _materials.GetElementReferenceAt(handle.id, handle.generation, out var exist); ref var material = ref _materials.GetElementReferenceAt(handle.ID, handle.Generation, out var exist);
if (!exist) if (!exist)
{ {
throw new ArgumentOutOfRangeException(nameof(handle), $"Material handle {handle} is invalid."); throw new ArgumentOutOfRangeException(nameof(handle), $"Material handle {handle} is invalid.");
@@ -389,14 +388,14 @@ internal class D3D12ResourceDatabase : IResourceDatabase
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
ref var material = ref _materials.GetElementReferenceAt(handle.id, handle.generation, out var exist); ref var material = ref _materials.GetElementReferenceAt(handle.ID, handle.Generation, out var exist);
if (!exist) if (!exist)
{ {
return; return;
} }
ReleaseResource(ref material); ReleaseResource(ref material);
_materials.Remove(handle.id, handle.generation); _materials.Remove(handle.ID, handle.Generation);
} }
public Identifier<Shader> AddShader(Shader shader) public Identifier<Shader> AddShader(Shader shader)
@@ -411,7 +410,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
public bool HasShader(Identifier<Shader> id) public bool HasShader(Identifier<Shader> id)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
return id.value >= 0 && id.value < _shaders.Count && _shaders[id.value] != null; return id.Value >= 0 && id.Value < _shaders.Count && _shaders[id.Value] != null;
} }
public Shader GetShaderReference(Identifier<Shader> id) public Shader GetShaderReference(Identifier<Shader> id)
@@ -423,7 +422,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
throw new ArgumentOutOfRangeException(nameof(id), $"Shader id {id} is invalid."); throw new ArgumentOutOfRangeException(nameof(id), $"Shader id {id} is invalid.");
} }
var shader = _shaders[id.value]!; var shader = _shaders[id.Value]!;
return shader; return shader;
} }
@@ -436,7 +435,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
return; return;
} }
ref var shader = ref _shaders[id.value]!; ref var shader = ref _shaders[id.Value]!;
ReleaseResource(ref shader); ReleaseResource(ref shader);
} }
@@ -479,17 +478,11 @@ internal class D3D12ResourceDatabase : IResourceDatabase
ReleaseResource(ref shader); ReleaseResource(ref shader);
} }
// Same for shader pass.
foreach (var kv in _shaderPasses)
{
var pass = kv.Value;
ReleaseResource(ref pass);
}
_resources.Dispose(); _resources.Dispose();
_samplers.Dispose(); _samplers.Dispose();
_meshes.Dispose(); _meshes.Dispose();
_materials.Dispose(); _materials.Dispose();
// _shaderPasses.Dispose();
_disposed = true; _disposed = true;

View File

@@ -166,6 +166,33 @@ internal unsafe static class D3D12Utility
}; };
} }
public static ResourceDesc ToResourceDesc(this D3D12_RESOURCE_DESC desc)
{
if (desc.Dimension == D3D12_RESOURCE_DIMENSION.D3D12_RESOURCE_DIMENSION_BUFFER)
{
return ResourceDesc.Buffer(new BufferDesc
{
Size = (uint)desc.Width,
Stride = 0,
Usage = BufferUsage.None,
MemoryType = ResourceMemoryType.Default
});
}
else
{
return ResourceDesc.Texture(new TextureDesc
{
Width = (uint)desc.Width,
Height = desc.Height,
Slice = desc.DepthOrArraySize,
Format = desc.Format.ToTextureFormat(),
Dimension = desc.Dimension.ToTextureDimension(),
MipLevels = desc.MipLevels,
Usage = TextureUsage.None,
});
}
}
public static D3D12_RASTERIZER_DESC D3D12_RASTERIZER_DESC_CREATE( public static D3D12_RASTERIZER_DESC D3D12_RASTERIZER_DESC_CREATE(
D3D12_FILL_MODE fillMode, D3D12_FILL_MODE fillMode,

View File

@@ -1,17 +1,15 @@
using Ghost.Core; using Ghost.Core;
using Ghost.Core.Graphics; using Ghost.Core.Graphics;
using Ghost.Graphics.Core; using Ghost.Graphics.Core;
using Ghost.Graphics.D3D12.Utilities;
using Misaki.HighPerformance.Mathematics; using Misaki.HighPerformance.Mathematics;
using Misaki.HighPerformance.Utilities; using Misaki.HighPerformance.Utilities;
using System.IO.Hashing; using System.IO.Hashing;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using TerraFX.Interop.DirectX;
namespace Ghost.Graphics.RHI; namespace Ghost.Graphics.RHI;
public readonly struct ShaderPassKey public readonly struct ShaderPassKey : IEquatable<ShaderPassKey>
{ {
public readonly ulong value; public readonly ulong value;
@@ -31,10 +29,30 @@ public readonly struct ShaderPassKey
return value.ToString("X16"); return value.ToString("X16");
} }
public bool Equals(ShaderPassKey other)
{
return value == other.value;
}
public override int GetHashCode() public override int GetHashCode()
{ {
return value.GetHashCode(); return value.GetHashCode();
} }
public override bool Equals(object? obj)
{
return obj is ShaderPassKey key && Equals(key);
}
public static bool operator ==(ShaderPassKey left, ShaderPassKey right)
{
return left.Equals(right);
}
public static bool operator !=(ShaderPassKey left, ShaderPassKey right)
{
return !(left == right);
}
} }
public readonly struct GraphicsPipelineKey public readonly struct GraphicsPipelineKey
@@ -397,33 +415,6 @@ public struct ResourceDesc
TextureDescription = desc TextureDescription = desc
}; };
} }
internal static ResourceDesc FromD3D12(D3D12_RESOURCE_DESC desc)
{
if (desc.Dimension == D3D12_RESOURCE_DIMENSION.D3D12_RESOURCE_DIMENSION_BUFFER)
{
return Buffer(new BufferDesc
{
Size = (uint)desc.Width,
Stride = 0,
Usage = BufferUsage.None,
MemoryType = ResourceMemoryType.Default
});
}
else
{
return Texture(new TextureDesc
{
Width = (uint)desc.Width,
Height = desc.Height,
Slice = desc.DepthOrArraySize,
Format = desc.Format.ToTextureFormat(),
Dimension = desc.Dimension.ToTextureDimension(),
MipLevels = desc.MipLevels,
Usage = TextureUsage.None,
});
}
}
} }
/// <summary> /// <summary>

View File

@@ -125,7 +125,7 @@ internal class MeshRenderPass : IRenderPass
texture2 = ctx.ResourceDatabase.GetBindlessIndex(_textures[1].AsResource()).GetValueOrThrow(), texture2 = ctx.ResourceDatabase.GetBindlessIndex(_textures[1].AsResource()).GetValueOrThrow(),
texture3 = ctx.ResourceDatabase.GetBindlessIndex(_textures[2].AsResource()).GetValueOrThrow(), texture3 = ctx.ResourceDatabase.GetBindlessIndex(_textures[2].AsResource()).GetValueOrThrow(),
texture4 = ctx.ResourceDatabase.GetBindlessIndex(_textures[3].AsResource()).GetValueOrThrow(), texture4 = ctx.ResourceDatabase.GetBindlessIndex(_textures[3].AsResource()).GetValueOrThrow(),
tex_sampler = (uint)sampler.value, tex_sampler = (uint)sampler.Value,
}; };
Debug.Assert(matRef.SetPropertyCache(in matProps) == ErrorStatus.None); Debug.Assert(matRef.SetPropertyCache(in matProps) == ErrorStatus.None);

View File

@@ -2,7 +2,6 @@ using Ghost.Core;
using Ghost.Graphics.RHI; using Ghost.Graphics.RHI;
using Misaki.HighPerformance.Mathematics; using Misaki.HighPerformance.Mathematics;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Diagnostics;
namespace Ghost.Graphics; namespace Ghost.Graphics;