forked from Misaki/GhostEngine
Refactor error handling: use Error enum, update APIs
Replaces ErrorStatus with Error across all systems for consistency. Renames ResourceBarrierData fields to camelCase. Adds BindlessAccess enum and updates GetBindlessIndex API. Updates method signatures, result types, and error checks. Modernizes HLSL mesh shader syntax and fixes naming. Improves code style and updates comments for clarity.
This commit is contained in:
@@ -28,7 +28,7 @@ public readonly struct Result
|
|||||||
return new Result(false, message);
|
return new Result(false, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result Failure(ErrorStatus status)
|
public static Result Failure(Error status)
|
||||||
{
|
{
|
||||||
return new Result(false, status.ToString());
|
return new Result(false, status.ToString());
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ public readonly struct Result
|
|||||||
return Result<T>.Failure(message);
|
return Result<T>.Failure(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result<T> Failure<T>(ErrorStatus status)
|
public static Result<T> Failure<T>(Error status)
|
||||||
{
|
{
|
||||||
return Result<T>.Failure(status.ToString());
|
return Result<T>.Failure(status.ToString());
|
||||||
}
|
}
|
||||||
@@ -117,7 +117,7 @@ public readonly struct Result<T>
|
|||||||
public static implicit operator bool(Result<T> result) => result.IsSuccess;
|
public static implicit operator bool(Result<T> result) => result.IsSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ErrorStatus : byte
|
public enum Error : byte
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
NotFound,
|
NotFound,
|
||||||
@@ -249,9 +249,9 @@ public readonly ref struct RefResult<T, E>
|
|||||||
|
|
||||||
public static class ResultExtensions
|
public static class ResultExtensions
|
||||||
{
|
{
|
||||||
public static void ThrowIfFailed(this ErrorStatus result, [CallerArgumentExpression(nameof(result))] string? op = null)
|
public static void ThrowIfFailed(this Error result, [CallerArgumentExpression(nameof(result))] string? op = null)
|
||||||
{
|
{
|
||||||
if (result != ErrorStatus.None)
|
if (result != Error.None)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"{op} failed: {result}");
|
throw new InvalidOperationException($"{op} failed: {result}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,16 +31,16 @@ public static partial class AssetDatabase
|
|||||||
s_watcher.Renamed += OnAssetRenamed;
|
s_watcher.Renamed += OnAssetRenamed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Result<string, ErrorStatus> GetMetaFilePath(string assetPath)
|
private static Result<string, Error> GetMetaFilePath(string assetPath)
|
||||||
{
|
{
|
||||||
if (Directory.Exists(assetPath))
|
if (Directory.Exists(assetPath))
|
||||||
{
|
{
|
||||||
return ErrorStatus.NotFound;
|
return Error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Path.GetExtension(assetPath).Equals(".meta", StringComparison.OrdinalIgnoreCase))
|
if (Path.GetExtension(assetPath).Equals(".meta", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return ErrorStatus.InvalidState;
|
return Error.InvalidState;
|
||||||
}
|
}
|
||||||
|
|
||||||
return assetPath + ".meta";
|
return assetPath + ".meta";
|
||||||
|
|||||||
@@ -392,10 +392,10 @@ internal unsafe struct Archetype : IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public readonly ErrorStatus SetComponentData(int chunkIndex, int rowIndex, Identifier<IComponent> componentID, void* pComponent)
|
public readonly Error SetComponentData(int chunkIndex, int rowIndex, Identifier<IComponent> componentID, void* pComponent)
|
||||||
{
|
{
|
||||||
var r = GetLayout(componentID);
|
var r = GetLayout(componentID);
|
||||||
if (r.Error != ErrorStatus.None)
|
if (r.Error != Error.None)
|
||||||
{
|
{
|
||||||
return r.Error;
|
return r.Error;
|
||||||
}
|
}
|
||||||
@@ -412,14 +412,14 @@ internal unsafe struct Archetype : IDisposable
|
|||||||
var world = World.GetWorldUncheck(_worldID);
|
var world = World.GetWorldUncheck(_worldID);
|
||||||
MarkChanged(chunkIndex, componentID, world.Version);
|
MarkChanged(chunkIndex, componentID, world.Version);
|
||||||
|
|
||||||
return ErrorStatus.None;
|
return Error.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public readonly void* GetComponentData(int chunkIndex, int rowIndex, Identifier<IComponent> componentID)
|
public readonly void* GetComponentData(int chunkIndex, int rowIndex, Identifier<IComponent> componentID)
|
||||||
{
|
{
|
||||||
var r = GetLayout(componentID);
|
var r = GetLayout(componentID);
|
||||||
if (r.Error != ErrorStatus.None)
|
if (r.Error != Error.None)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -439,24 +439,24 @@ internal unsafe struct Archetype : IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public readonly Result<ComponentMemoryLayout, ErrorStatus> GetLayout(int componentID)
|
public readonly Result<ComponentMemoryLayout, Error> GetLayout(int componentID)
|
||||||
{
|
{
|
||||||
if (componentID >= _componentIDToLayoutIndex.Count)
|
if (componentID >= _componentIDToLayoutIndex.Count)
|
||||||
{
|
{
|
||||||
return ErrorStatus.InvalidArgument;
|
return Error.InvalidArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
var layoutIndex = _componentIDToLayoutIndex[componentID];
|
var layoutIndex = _componentIDToLayoutIndex[componentID];
|
||||||
if (layoutIndex == -1)
|
if (layoutIndex == -1)
|
||||||
{
|
{
|
||||||
return ErrorStatus.NotFound;
|
return Error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _layouts[layoutIndex];
|
return _layouts[layoutIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public readonly ErrorStatus MarkChanged(int chunkIndex, int componentTypeId, int globalVersion)
|
public readonly Error MarkChanged(int chunkIndex, int componentTypeId, int globalVersion)
|
||||||
{
|
{
|
||||||
var layoutResult = GetLayout(componentTypeId);
|
var layoutResult = GetLayout(componentTypeId);
|
||||||
if (layoutResult.IsFailure)
|
if (layoutResult.IsFailure)
|
||||||
@@ -467,14 +467,14 @@ internal unsafe struct Archetype : IDisposable
|
|||||||
ref var chunk = ref _chunks[chunkIndex];
|
ref var chunk = ref _chunks[chunkIndex];
|
||||||
chunk.GetVersionUnsafePtr()[layoutResult.Value.versionIndex] = globalVersion;
|
chunk.GetVersionUnsafePtr()[layoutResult.Value.versionIndex] = globalVersion;
|
||||||
|
|
||||||
return ErrorStatus.None;
|
return Error.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public readonly Result<int, ErrorStatus> GetVersion(int chunkIndex, int componentTypeId)
|
public readonly Result<int, Error> GetVersion(int chunkIndex, int componentTypeId)
|
||||||
{
|
{
|
||||||
var layoutResult = GetLayout(componentTypeId);
|
var layoutResult = GetLayout(componentTypeId);
|
||||||
if (layoutResult.Error != ErrorStatus.None)
|
if (layoutResult.Error != Error.None)
|
||||||
{
|
{
|
||||||
return layoutResult.Error;
|
return layoutResult.Error;
|
||||||
}
|
}
|
||||||
@@ -483,11 +483,11 @@ internal unsafe struct Archetype : IDisposable
|
|||||||
return chunk.GetVersionUnsafePtr()[layoutResult.Value.versionIndex];
|
return chunk.GetVersionUnsafePtr()[layoutResult.Value.versionIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
public ErrorStatus RemoveEntity(int chunkIndex, int rowIndex)
|
public Error RemoveEntity(int chunkIndex, int rowIndex)
|
||||||
{
|
{
|
||||||
if (chunkIndex < 0 || chunkIndex >= _chunks.Count)
|
if (chunkIndex < 0 || chunkIndex >= _chunks.Count)
|
||||||
{
|
{
|
||||||
return ErrorStatus.InvalidArgument;
|
return Error.InvalidArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
var world = World.GetWorldUncheck(_worldID);
|
var world = World.GetWorldUncheck(_worldID);
|
||||||
@@ -502,7 +502,7 @@ internal unsafe struct Archetype : IDisposable
|
|||||||
var pRowEntity = chunkBase + _entityIdsOffset + (sizeof(Entity) * rowIndex);
|
var pRowEntity = chunkBase + _entityIdsOffset + (sizeof(Entity) * rowIndex);
|
||||||
|
|
||||||
var result = world.EntityManager.UpdateEntityLocation(*(Entity*)pLastEntity, _id, chunkIndex, rowIndex);
|
var result = world.EntityManager.UpdateEntityLocation(*(Entity*)pLastEntity, _id, chunkIndex, rowIndex);
|
||||||
if (result != ErrorStatus.None)
|
if (result != Error.None)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -524,19 +524,19 @@ internal unsafe struct Archetype : IDisposable
|
|||||||
chunk._count--;
|
chunk._count--;
|
||||||
chunk._structuralVersion = world.Version;
|
chunk._structuralVersion = world.Version;
|
||||||
|
|
||||||
return ErrorStatus.None;
|
return Error.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ErrorStatus RemoveEntities(int chunkIndex, ReadOnlySpan<int> sortedIndicesToRemove)
|
public Error RemoveEntities(int chunkIndex, ReadOnlySpan<int> sortedIndicesToRemove)
|
||||||
{
|
{
|
||||||
if (chunkIndex < 0 || chunkIndex >= _chunks.Count)
|
if (chunkIndex < 0 || chunkIndex >= _chunks.Count)
|
||||||
{
|
{
|
||||||
return ErrorStatus.InvalidArgument;
|
return Error.InvalidArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sortedIndicesToRemove.Length == 0)
|
if (sortedIndicesToRemove.Length == 0)
|
||||||
{
|
{
|
||||||
return ErrorStatus.None;
|
return Error.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
ref var chunk = ref _chunks[chunkIndex];
|
ref var chunk = ref _chunks[chunkIndex];
|
||||||
@@ -603,7 +603,7 @@ internal unsafe struct Archetype : IDisposable
|
|||||||
// 1. Update the Map (Critical Step)
|
// 1. Update the Map (Critical Step)
|
||||||
// We tell the world: "The entity that WAS at 'candidateIndex' is now at 'holeIndex'"
|
// We tell the world: "The entity that WAS at 'candidateIndex' is now at 'holeIndex'"
|
||||||
var result = world.EntityManager.UpdateEntityLocation(*(Entity*)pFillerEntity, _id, chunkIndex, holeIndex);
|
var result = world.EntityManager.UpdateEntityLocation(*(Entity*)pFillerEntity, _id, chunkIndex, holeIndex);
|
||||||
if (result != ErrorStatus.None)
|
if (result != Error.None)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -628,7 +628,7 @@ internal unsafe struct Archetype : IDisposable
|
|||||||
chunk._count = newCount;
|
chunk._count = newCount;
|
||||||
chunk._structuralVersion = world.Version;
|
chunk._structuralVersion = world.Version;
|
||||||
|
|
||||||
return ErrorStatus.None;
|
return Error.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ internal static class ComponentRegistry
|
|||||||
size = sizeof(T),
|
size = sizeof(T),
|
||||||
alignment = (int)MemoryUtility.AlignOf<T>(),
|
alignment = (int)MemoryUtility.AlignOf<T>(),
|
||||||
isEnableable = typeof(IEnableableComponent).IsAssignableFrom(type),
|
isEnableable = typeof(IEnableableComponent).IsAssignableFrom(type),
|
||||||
// isShared = typeof(ISharedComponent).IsAssignableFrom(type),
|
//isShared = typeof(ISharedComponent).IsAssignableFrom(type),
|
||||||
};
|
};
|
||||||
|
|
||||||
s_registeredComponents.Add(info);
|
s_registeredComponents.Add(info);
|
||||||
|
|||||||
@@ -60,29 +60,29 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
Dispose();
|
Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ErrorStatus UpdateEntityLocation(Entity entity, Identifier<Archetype> newArchetypeID, int newChunkIndex, int newRowIndex)
|
internal Error UpdateEntityLocation(Entity entity, Identifier<Archetype> newArchetypeID, int newChunkIndex, int newRowIndex)
|
||||||
{
|
{
|
||||||
ref var location = ref _entityLocations.GetElementReferenceAt(entity.ID, entity.Generation, out var exist);
|
ref var location = ref _entityLocations.GetElementReferenceAt(entity.ID, entity.Generation, out var exist);
|
||||||
if (!exist)
|
if (!exist)
|
||||||
{
|
{
|
||||||
return ErrorStatus.NotFound;
|
return Error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
location.archetypeID = newArchetypeID;
|
location.archetypeID = newArchetypeID;
|
||||||
location.chunkIndex = newChunkIndex;
|
location.chunkIndex = newChunkIndex;
|
||||||
location.rowIndex = newRowIndex;
|
location.rowIndex = newRowIndex;
|
||||||
|
|
||||||
return ErrorStatus.None;
|
return Error.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Result<EntityLocation, ErrorStatus> GetEntityLocation(Entity entity)
|
internal Result<EntityLocation, Error> GetEntityLocation(Entity entity)
|
||||||
{
|
{
|
||||||
if (_entityLocations.TryGetElementAt(entity.ID, entity.Generation, out var location))
|
if (_entityLocations.TryGetElementAt(entity.ID, entity.Generation, out var location))
|
||||||
{
|
{
|
||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ErrorStatus.NotFound;
|
return Error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -240,28 +240,28 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
/// Destroy the specified entity.
|
/// Destroy the specified entity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The result status of the operation.</returns>
|
/// <returns>The result status of the operation.</returns>
|
||||||
public ErrorStatus DestroyEntity(Entity entity)
|
public Error DestroyEntity(Entity entity)
|
||||||
{
|
{
|
||||||
if (!_entityLocations.TryGetElementAt(entity.ID, entity.Generation, out var location))
|
if (!_entityLocations.TryGetElementAt(entity.ID, entity.Generation, out var location))
|
||||||
{
|
{
|
||||||
return ErrorStatus.NotFound;
|
return Error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
ref var archetype = ref _world.ComponentManager.GetArchetypeReference(location.archetypeID);
|
ref var archetype = ref _world.ComponentManager.GetArchetypeReference(location.archetypeID);
|
||||||
|
|
||||||
DestoryManagedEntityIfExists(in archetype, location);
|
DestoryManagedEntityIfExists(in archetype, location);
|
||||||
var r = archetype.RemoveEntity(location.chunkIndex, location.rowIndex);
|
var r = archetype.RemoveEntity(location.chunkIndex, location.rowIndex);
|
||||||
if (r != ErrorStatus.None)
|
if (r != Error.None)
|
||||||
{
|
{
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_entityLocations.Remove(entity.ID, entity.Generation))
|
if (!_entityLocations.Remove(entity.ID, entity.Generation))
|
||||||
{
|
{
|
||||||
return ErrorStatus.NotFound;
|
return Error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ErrorStatus.None;
|
return Error.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -383,11 +383,11 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
/// <param name="componentID">The component space ID of the singleton.</param>
|
/// <param name="componentID">The component space ID of the singleton.</param>
|
||||||
/// <param name="pComponent">Pointer to the component data.</param>
|
/// <param name="pComponent">Pointer to the component data.</param>
|
||||||
/// <returns>The result status of the operation.</returns>
|
/// <returns>The result status of the operation.</returns>
|
||||||
public ErrorStatus CreateSingleton(Identifier<IComponent> componentID, void* pComponent)
|
public Error CreateSingleton(Identifier<IComponent> componentID, void* pComponent)
|
||||||
{
|
{
|
||||||
if (pComponent == null)
|
if (pComponent == null)
|
||||||
{
|
{
|
||||||
return ErrorStatus.InvalidArgument;
|
return Error.InvalidArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if singleton already exists
|
// Check if singleton already exists
|
||||||
@@ -396,7 +396,7 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
|
|
||||||
if (arcID.IsValid)
|
if (arcID.IsValid)
|
||||||
{
|
{
|
||||||
return ErrorStatus.InvalidArgument;
|
return Error.InvalidArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
arcID = _world.ComponentManager.CreateArchetype([componentID], signatureHash);
|
arcID = _world.ComponentManager.CreateArchetype([componentID], signatureHash);
|
||||||
@@ -415,7 +415,7 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
archetype.SetEntity(chunkIndex, rowIndex, entity);
|
archetype.SetEntity(chunkIndex, rowIndex, entity);
|
||||||
archetype.SetComponentData(chunkIndex, rowIndex, componentID, pComponent);
|
archetype.SetComponentData(chunkIndex, rowIndex, componentID, pComponent);
|
||||||
|
|
||||||
return ErrorStatus.None;
|
return Error.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -424,7 +424,7 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
/// <typeparam name="T">The component space.</typeparam>
|
/// <typeparam name="T">The component space.</typeparam>
|
||||||
/// <param name="component">The component data.</param>
|
/// <param name="component">The component data.</param>
|
||||||
/// <returns>The result status of the operation.</returns>
|
/// <returns>The result status of the operation.</returns>
|
||||||
public ErrorStatus CreateSingleton<T>(T component = default)
|
public Error CreateSingleton<T>(T component = default)
|
||||||
where T : unmanaged, IComponent
|
where T : unmanaged, IComponent
|
||||||
{
|
{
|
||||||
return CreateSingleton(ComponentTypeID<T>.Value, &component);
|
return CreateSingleton(ComponentTypeID<T>.Value, &component);
|
||||||
@@ -447,7 +447,7 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
|
|
||||||
ref var archetype = ref _world.ComponentManager.GetArchetypeReference(arcID);
|
ref var archetype = ref _world.ComponentManager.GetArchetypeReference(arcID);
|
||||||
var layoutResult = archetype.GetLayout(componentID);
|
var layoutResult = archetype.GetLayout(componentID);
|
||||||
if (layoutResult.Error != ErrorStatus.None)
|
if (layoutResult.Error != Error.None)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -480,7 +480,7 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
|
|
||||||
var src = oldArch._chunks[oldChunk].GetUnsafePtr() + layout.offset + (layout.size * oldRow);
|
var src = oldArch._chunks[oldChunk].GetUnsafePtr() + layout.offset + (layout.size * oldRow);
|
||||||
var r = newArch.GetLayout(layout.componentID);
|
var r = newArch.GetLayout(layout.componentID);
|
||||||
if (r.Error != ErrorStatus.None)
|
if (r.Error != Error.None)
|
||||||
{
|
{
|
||||||
// New archetype does not have this component, skip it.
|
// New archetype does not have this component, skip it.
|
||||||
// This can happen when removing components.
|
// This can happen when removing components.
|
||||||
@@ -500,13 +500,13 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
/// <param name="componentID">The component space ID to add.</param>
|
/// <param name="componentID">The component space ID to add.</param>
|
||||||
/// <param name="pComponent">Pointer to the component data.</param>
|
/// <param name="pComponent">Pointer to the component data.</param>
|
||||||
/// <returns>The result status of the operation.</returns>
|
/// <returns>The result status of the operation.</returns>
|
||||||
public ErrorStatus AddComponent(Entity entity, Identifier<IComponent> componentID, void* pComponent)
|
public Error AddComponent(Entity entity, Identifier<IComponent> componentID, void* pComponent)
|
||||||
{
|
{
|
||||||
// Find current location
|
// Find current location
|
||||||
ref var location = ref _entityLocations.GetElementReferenceAt(entity.ID, entity.Generation, out var exist);
|
ref var location = ref _entityLocations.GetElementReferenceAt(entity.ID, entity.Generation, out var exist);
|
||||||
if (!exist)
|
if (!exist)
|
||||||
{
|
{
|
||||||
return ErrorStatus.NotFound;
|
return Error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build new archetype signature
|
// Build new archetype signature
|
||||||
@@ -516,7 +516,7 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
if (oldSignature.IsSet(componentID))
|
if (oldSignature.IsSet(componentID))
|
||||||
{
|
{
|
||||||
// Component already exists
|
// Component already exists
|
||||||
return ErrorStatus.InvalidArgument;
|
return Error.InvalidArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
var newArcID = oldArchetype.GetEdgeAdd(componentID);
|
var newArcID = oldArchetype.GetEdgeAdd(componentID);
|
||||||
@@ -572,8 +572,8 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
newArchetype.SetComponentData(newChunkIndex, newRowIndex, componentID, pComponent);
|
newArchetype.SetComponentData(newChunkIndex, newRowIndex, componentID, pComponent);
|
||||||
|
|
||||||
var r = oldArchetype.RemoveEntity(location.chunkIndex, location.rowIndex);
|
var r = oldArchetype.RemoveEntity(location.chunkIndex, location.rowIndex);
|
||||||
Debug.Assert(r == ErrorStatus.None); // We assert it because the entity should exist if the whole system is consistent.
|
Debug.Assert(r == Error.None); // We assert it because the entity should exist if the whole system is consistent.
|
||||||
if (r != ErrorStatus.None)
|
if (r != Error.None)
|
||||||
{
|
{
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -583,7 +583,7 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
location.chunkIndex = newChunkIndex;
|
location.chunkIndex = newChunkIndex;
|
||||||
location.rowIndex = newRowIndex;
|
location.rowIndex = newRowIndex;
|
||||||
|
|
||||||
return ErrorStatus.None;
|
return Error.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -593,7 +593,7 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
/// <param name="entity">The entity to add the component to.</param>
|
/// <param name="entity">The entity to add the component to.</param>
|
||||||
/// <param name="component">The component data.</param>
|
/// <param name="component">The component data.</param>
|
||||||
/// <returns>The result status of the operation.</returns>
|
/// <returns>The result status of the operation.</returns>
|
||||||
public ErrorStatus AddComponent<T>(Entity entity, T component = default)
|
public Error AddComponent<T>(Entity entity, T component = default)
|
||||||
where T : unmanaged, IComponent
|
where T : unmanaged, IComponent
|
||||||
{
|
{
|
||||||
return AddComponent(entity, ComponentTypeID<T>.Value, &component);
|
return AddComponent(entity, ComponentTypeID<T>.Value, &component);
|
||||||
@@ -605,13 +605,13 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
/// <param name="entity">The entity to remove the component from.</param>
|
/// <param name="entity">The entity to remove the component from.</param>
|
||||||
/// <param name="componentID">The component space ID to remove.</param>
|
/// <param name="componentID">The component space ID to remove.</param>
|
||||||
/// <returns>The result status of the operation.</returns>
|
/// <returns>The result status of the operation.</returns>
|
||||||
public ErrorStatus RemoveComponent(Entity entity, Identifier<IComponent> componentID)
|
public Error RemoveComponent(Entity entity, Identifier<IComponent> componentID)
|
||||||
{
|
{
|
||||||
// Find current location
|
// Find current location
|
||||||
ref var location = ref _entityLocations.GetElementReferenceAt(entity.ID, entity.Generation, out var exist);
|
ref var location = ref _entityLocations.GetElementReferenceAt(entity.ID, entity.Generation, out var exist);
|
||||||
if (!exist)
|
if (!exist)
|
||||||
{
|
{
|
||||||
return ErrorStatus.NotFound;
|
return Error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build new archetype signature
|
// Build new archetype signature
|
||||||
@@ -670,8 +670,8 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
newArchetype.SetEntity(newChunkIndex, newRowIndex, entity);
|
newArchetype.SetEntity(newChunkIndex, newRowIndex, entity);
|
||||||
|
|
||||||
var r = oldArchetype.RemoveEntity(location.chunkIndex, location.rowIndex);
|
var r = oldArchetype.RemoveEntity(location.chunkIndex, location.rowIndex);
|
||||||
Debug.Assert(r == ErrorStatus.None); // We assert it because the entity should exist if the whole system is consistent.
|
Debug.Assert(r == Error.None); // We assert it because the entity should exist if the whole system is consistent.
|
||||||
if (r != ErrorStatus.None)
|
if (r != Error.None)
|
||||||
{
|
{
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -687,7 +687,7 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
location.chunkIndex = newChunkIndex;
|
location.chunkIndex = newChunkIndex;
|
||||||
location.rowIndex = newRowIndex;
|
location.rowIndex = newRowIndex;
|
||||||
|
|
||||||
return ErrorStatus.None;
|
return Error.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -696,7 +696,7 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
/// <typeparam name="T">The component space.</typeparam>
|
/// <typeparam name="T">The component space.</typeparam>
|
||||||
/// <param name="entity">The entity to remove the component from.</param>
|
/// <param name="entity">The entity to remove the component from.</param>
|
||||||
/// <returns>The result status of the operation.</returns>
|
/// <returns>The result status of the operation.</returns>
|
||||||
public ErrorStatus RemoveComponent<T>(Entity entity)
|
public Error RemoveComponent<T>(Entity entity)
|
||||||
where T : unmanaged, IComponent
|
where T : unmanaged, IComponent
|
||||||
{
|
{
|
||||||
return RemoveComponent(entity, ComponentTypeID<T>.Value);
|
return RemoveComponent(entity, ComponentTypeID<T>.Value);
|
||||||
@@ -709,17 +709,17 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
/// <param name="componentID">The component space ID to set.</param>
|
/// <param name="componentID">The component space ID to set.</param>
|
||||||
/// <param name="pComponent">Pointer to the component data.</param>
|
/// <param name="pComponent">Pointer to the component data.</param>
|
||||||
/// <returns>The result status of the operation.</returns>
|
/// <returns>The result status of the operation.</returns>
|
||||||
public ErrorStatus SetComponent(Entity entity, Identifier<IComponent> componentID, void* pComponent)
|
public Error SetComponent(Entity entity, Identifier<IComponent> componentID, void* pComponent)
|
||||||
{
|
{
|
||||||
if (!_entityLocations.TryGetElementAt(entity.ID, entity.Generation, out var location))
|
if (!_entityLocations.TryGetElementAt(entity.ID, entity.Generation, out var location))
|
||||||
{
|
{
|
||||||
return ErrorStatus.NotFound;
|
return Error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
ref var archetype = ref _world.ComponentManager.GetArchetypeReference(location.archetypeID);
|
ref var archetype = ref _world.ComponentManager.GetArchetypeReference(location.archetypeID);
|
||||||
archetype.SetComponentData(location.chunkIndex, location.rowIndex, componentID, pComponent);
|
archetype.SetComponentData(location.chunkIndex, location.rowIndex, componentID, pComponent);
|
||||||
|
|
||||||
return ErrorStatus.None;
|
return Error.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -728,7 +728,7 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
/// <typeparam name="T">The component space.</typeparam>
|
/// <typeparam name="T">The component space.</typeparam>
|
||||||
/// <param name="entity">The entity to set the component data for.</param>
|
/// <param name="entity">The entity to set the component data for.</param>
|
||||||
/// <param name="component">The component data.</param>
|
/// <param name="component">The component data.</param>
|
||||||
public ErrorStatus SetComponent<T>(Entity entity, T component)
|
public Error SetComponent<T>(Entity entity, T component)
|
||||||
where T : unmanaged, IComponent
|
where T : unmanaged, IComponent
|
||||||
{
|
{
|
||||||
return SetComponent(entity, ComponentTypeID<T>.Value, &component);
|
return SetComponent(entity, ComponentTypeID<T>.Value, &component);
|
||||||
@@ -800,11 +800,11 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
/// <param name="componentID">The component space ID of the enableable component.</
|
/// <param name="componentID">The component space ID of the enableable component.</
|
||||||
/// <param name="enabled">True to enable the component, false to disable it.</param>
|
/// <param name="enabled">True to enable the component, false to disable it.</param>
|
||||||
/// <returns>The result status of the operation.</returns>
|
/// <returns>The result status of the operation.</returns>
|
||||||
public ErrorStatus SetEnabled(Entity entity, Identifier<IComponent> componentID, bool enabled)
|
public Error SetEnabled(Entity entity, Identifier<IComponent> componentID, bool enabled)
|
||||||
{
|
{
|
||||||
if (!_entityLocations.TryGetElementAt(entity.ID, entity.Generation, out var location))
|
if (!_entityLocations.TryGetElementAt(entity.ID, entity.Generation, out var location))
|
||||||
{
|
{
|
||||||
return ErrorStatus.NotFound;
|
return Error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
ref var archetype = ref _world.ComponentManager.GetArchetypeReference(location.archetypeID);
|
ref var archetype = ref _world.ComponentManager.GetArchetypeReference(location.archetypeID);
|
||||||
@@ -812,7 +812,7 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
var rowIndex = location.rowIndex;
|
var rowIndex = location.rowIndex;
|
||||||
|
|
||||||
var layoutResult = archetype.GetLayout(componentID);
|
var layoutResult = archetype.GetLayout(componentID);
|
||||||
if (layoutResult.Error != ErrorStatus.None)
|
if (layoutResult.Error != Error.None)
|
||||||
{
|
{
|
||||||
return layoutResult.Error;
|
return layoutResult.Error;
|
||||||
}
|
}
|
||||||
@@ -833,7 +833,7 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
maskBase[byteIndex] &= (byte)~(1 << bitIndex);
|
maskBase[byteIndex] &= (byte)~(1 << bitIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ErrorStatus.None;
|
return Error.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -843,7 +843,7 @@ public unsafe partial class EntityManager : IDisposable
|
|||||||
/// <param name="entity">The entity to set the enabled state for.</param>
|
/// <param name="entity">The entity to set the enabled state for.</param>
|
||||||
/// <param name="enabled">True to enable the component, false to disable it.</
|
/// <param name="enabled">True to enable the component, false to disable it.</
|
||||||
/// <returns>The result status of the operation.</returns>
|
/// <returns>The result status of the operation.</returns>
|
||||||
public ErrorStatus SetEnabled<T>(Entity entity, bool enabled)
|
public Error SetEnabled<T>(Entity entity, bool enabled)
|
||||||
where T : unmanaged, IEnableableComponent
|
where T : unmanaged, IEnableableComponent
|
||||||
{
|
{
|
||||||
return SetEnabled(entity, ComponentTypeID<T>.Value, enabled);
|
return SetEnabled(entity, ComponentTypeID<T>.Value, enabled);
|
||||||
|
|||||||
@@ -355,7 +355,7 @@ public unsafe partial struct EntityQuery : IDisposable
|
|||||||
{
|
{
|
||||||
// Get the EnableBitmask for this component in this chunk
|
// Get the EnableBitmask for this component in this chunk
|
||||||
var layoutResult = archetype.GetLayout(id);
|
var layoutResult = archetype.GetLayout(id);
|
||||||
if (layoutResult.Error != ErrorStatus.None
|
if (layoutResult.Error != Error.None
|
||||||
// Not enableable, always true
|
// Not enableable, always true
|
||||||
|| layoutResult.Value.enableBitsOffset == -1)
|
|| layoutResult.Value.enableBitsOffset == -1)
|
||||||
{
|
{
|
||||||
@@ -374,7 +374,7 @@ public unsafe partial struct EntityQuery : IDisposable
|
|||||||
while (it.Next(out var id))
|
while (it.Next(out var id))
|
||||||
{
|
{
|
||||||
var layoutResult = archetype.GetLayout(id);
|
var layoutResult = archetype.GetLayout(id);
|
||||||
if (layoutResult.Error != ErrorStatus.None)
|
if (layoutResult.Error != Error.None)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -395,7 +395,7 @@ public unsafe partial struct EntityQuery : IDisposable
|
|||||||
while (it.Next(out var id))
|
while (it.Next(out var id))
|
||||||
{
|
{
|
||||||
var layoutResult = archetype.GetLayout(id);
|
var layoutResult = archetype.GetLayout(id);
|
||||||
if (layoutResult.Error != ErrorStatus.None)
|
if (layoutResult.Error != Error.None)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#if false // FIX: API update in Misaki.HighPerformance.LowLevel.Collections require me to disable this for now.
|
#if false
|
||||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||||
using Misaki.HighPerformance.LowLevel.Collections;
|
using Misaki.HighPerformance.LowLevel.Collections;
|
||||||
using Misaki.HighPerformance.LowLevel.Utilities;
|
using Misaki.HighPerformance.LowLevel.Utilities;
|
||||||
|
|||||||
@@ -146,5 +146,5 @@ public interface IShaderCompiler : IDisposable
|
|||||||
{
|
{
|
||||||
Result<ShaderCompileResult> Compile(ref readonly ShaderCompilationConfig config, Allocator allocator);
|
Result<ShaderCompileResult> Compile(ref readonly ShaderCompilationConfig config, Allocator allocator);
|
||||||
Result<GraphicsCompiledResult> CompilePass(ref readonly PassDescriptor descriptor, ref readonly ShaderCompilationConfig additionalConfig, Key64<ShaderVariant> key);
|
Result<GraphicsCompiledResult> CompilePass(ref readonly PassDescriptor descriptor, ref readonly ShaderCompilationConfig additionalConfig, Key64<ShaderVariant> key);
|
||||||
Result<GraphicsCompiledResult, ErrorStatus> LoadCompiledCache(Key64<ShaderVariant> key);
|
Result<GraphicsCompiledResult, Error> LoadCompiledCache(Key64<ShaderVariant> key);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,14 +89,14 @@ internal sealed partial class DxcShaderCompiler
|
|||||||
return argsArray;
|
return argsArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Result<string, ErrorStatus> GetFinalShaderCode(string shaderPath, ReadOnlySpan<string> includes, string? injectedCode)
|
private static Result<string, Error> GetFinalShaderCode(string shaderPath, ReadOnlySpan<string> includes, string? injectedCode)
|
||||||
{
|
{
|
||||||
string shaderCode;
|
string shaderCode;
|
||||||
if (shaderPath == "hlsl_block")
|
if (shaderPath == "hlsl_block")
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(injectedCode))
|
if (string.IsNullOrEmpty(injectedCode))
|
||||||
{
|
{
|
||||||
return ErrorStatus.InvalidArgument;
|
return Error.InvalidArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
shaderCode = string.Empty;
|
shaderCode = string.Empty;
|
||||||
@@ -105,7 +105,7 @@ internal sealed partial class DxcShaderCompiler
|
|||||||
{
|
{
|
||||||
if (!File.Exists(shaderPath))
|
if (!File.Exists(shaderPath))
|
||||||
{
|
{
|
||||||
return ErrorStatus.NotFound;
|
return Error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
shaderCode = File.ReadAllText(shaderPath);
|
shaderCode = File.ReadAllText(shaderPath);
|
||||||
@@ -487,7 +487,7 @@ internal sealed unsafe partial class DxcShaderCompiler : IShaderCompiler
|
|||||||
return compiled;
|
return compiled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result<GraphicsCompiledResult, ErrorStatus> LoadCompiledCache(Key64<ShaderVariant> key)
|
public Result<GraphicsCompiledResult, Error> LoadCompiledCache(Key64<ShaderVariant> key)
|
||||||
{
|
{
|
||||||
ObjectDisposedException.ThrowIf(_disposed, this);
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||||
|
|
||||||
@@ -496,7 +496,7 @@ internal sealed unsafe partial class DxcShaderCompiler : IShaderCompiler
|
|||||||
return compiledResult;
|
return compiledResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ErrorStatus.NotFound;
|
return Error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ 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 Misaki.HighPerformance.LowLevel.Utilities;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ghost.Graphics.Core;
|
namespace Ghost.Graphics.Core;
|
||||||
|
|
||||||
@@ -66,17 +68,11 @@ public struct Material : IResourceReleasable
|
|||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
public Error SetShader(Identifier<Shader> shaderId, IResourceAllocator allocator, IResourceDatabase database)
|
||||||
private void SetDirty()
|
|
||||||
{
|
|
||||||
_isDirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ErrorStatus SetShader(Identifier<Shader> shaderId, IResourceAllocator allocator, IResourceDatabase database)
|
|
||||||
{
|
{
|
||||||
if (!shaderId.IsValid)
|
if (!shaderId.IsValid)
|
||||||
{
|
{
|
||||||
return ErrorStatus.InvalidArgument;
|
return Error.InvalidArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cBufferCache.ReleaseResource(database);
|
_cBufferCache.ReleaseResource(database);
|
||||||
@@ -125,16 +121,16 @@ public struct Material : IResourceReleasable
|
|||||||
_cBufferCache = new CBufferCache(buffer, shader.CBufferSize);
|
_cBufferCache = new CBufferCache(buffer, shader.CBufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ErrorStatus.None;
|
return Error.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public readonly unsafe Result<T, ErrorStatus> GetPropertyCache<T>()
|
public readonly unsafe Result<T, Error> GetPropertyCache<T>()
|
||||||
where T : unmanaged
|
where T : unmanaged
|
||||||
{
|
{
|
||||||
if (sizeof(T) != _cBufferCache.Size)
|
if (sizeof(T) != _cBufferCache.Size)
|
||||||
{
|
{
|
||||||
return ErrorStatus.InvalidArgument;
|
return Error.InvalidArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *(T*)_cBufferCache.CpuData.GetUnsafePtr();
|
return *(T*)_cBufferCache.CpuData.GetUnsafePtr();
|
||||||
@@ -152,32 +148,45 @@ public struct Material : IResourceReleasable
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public unsafe ErrorStatus SetPropertyCache<T>(ref readonly T data)
|
public unsafe Error SetPropertyCache<T>(ref readonly T data)
|
||||||
where T : unmanaged
|
where T : unmanaged
|
||||||
{
|
{
|
||||||
if (sizeof(T) != _cBufferCache.Size)
|
if (sizeof(T) != _cBufferCache.Size)
|
||||||
{
|
{
|
||||||
return ErrorStatus.InvalidArgument;
|
return Error.InvalidArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
Unsafe.WriteUnaligned(_cBufferCache.CpuData.GetUnsafePtr(), data);
|
var dataSpan = MemoryMarshal.AsBytes(new ReadOnlySpan<T>(in data));
|
||||||
SetDirty();
|
var cacheSpan = _cBufferCache.CpuData.AsSpan();
|
||||||
|
if (cacheSpan.SequenceEqual(dataSpan))
|
||||||
|
{
|
||||||
|
return Error.None;
|
||||||
|
}
|
||||||
|
|
||||||
return ErrorStatus.None;
|
dataSpan.CopyTo(cacheSpan);
|
||||||
|
|
||||||
|
_isDirty = true;
|
||||||
|
return Error.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public unsafe ErrorStatus SetRawPropertyCache(ReadOnlySpan<byte> data)
|
public Error SetRawPropertyCache(ReadOnlySpan<byte> data)
|
||||||
{
|
{
|
||||||
if (data.Length != _cBufferCache.Size)
|
if (data.Length != _cBufferCache.Size)
|
||||||
{
|
{
|
||||||
return ErrorStatus.InvalidArgument;
|
return Error.InvalidArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
Unsafe.WriteUnaligned(_cBufferCache.CpuData.GetUnsafePtr(), data);
|
var cacheSpan = _cBufferCache.CpuData.AsSpan();
|
||||||
SetDirty();
|
if (cacheSpan.SequenceEqual(data))
|
||||||
|
{
|
||||||
|
return Error.None;
|
||||||
|
}
|
||||||
|
|
||||||
return ErrorStatus.None;
|
data.CopyTo(cacheSpan);
|
||||||
|
|
||||||
|
_isDirty = true;
|
||||||
|
return Error.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@@ -191,11 +200,11 @@ public struct Material : IResourceReleasable
|
|||||||
{
|
{
|
||||||
ref var pipelineOverride = ref _passPipelineOverride[passIndex];
|
ref var pipelineOverride = ref _passPipelineOverride[passIndex];
|
||||||
pipelineOverride.options = options;
|
pipelineOverride.options = options;
|
||||||
SetDirty();
|
_isDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ErrorStatus SetKeyword(IResourceDatabase resourceDatabase, int keywordId, bool enabled)
|
public Error SetKeyword(IResourceDatabase resourceDatabase, int keywordId, bool enabled)
|
||||||
{
|
{
|
||||||
var r = resourceDatabase.GetShaderReference(_shader);
|
var r = resourceDatabase.GetShaderReference(_shader);
|
||||||
if (r.IsFailure)
|
if (r.IsFailure)
|
||||||
@@ -207,13 +216,13 @@ public struct Material : IResourceReleasable
|
|||||||
var localIndex = shader.GetLocalKeywordIndex(keywordId);
|
var localIndex = shader.GetLocalKeywordIndex(keywordId);
|
||||||
if (localIndex == -1)
|
if (localIndex == -1)
|
||||||
{
|
{
|
||||||
return ErrorStatus.NotFound;
|
return Error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
_keywordMask.SetKeyword(localIndex, enabled);
|
_keywordMask.SetKeyword(localIndex, enabled);
|
||||||
SetDirty();
|
_isDirty = true;
|
||||||
|
|
||||||
return ErrorStatus.None;
|
return Error.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@@ -252,9 +261,9 @@ public struct Material : IResourceReleasable
|
|||||||
var barrierData = r.Value;
|
var barrierData = r.Value;
|
||||||
var desc = BarrierDesc.Buffer(
|
var desc = BarrierDesc.Buffer(
|
||||||
cbufferResource,
|
cbufferResource,
|
||||||
barrierData.Sync,
|
barrierData.sync,
|
||||||
BarrierSync.Copy,
|
BarrierSync.Copy,
|
||||||
barrierData.Access,
|
barrierData.access,
|
||||||
BarrierAccess.CopyDest);
|
BarrierAccess.CopyDest);
|
||||||
|
|
||||||
cmd.ResourceBarrier(desc);
|
cmd.ResourceBarrier(desc);
|
||||||
|
|||||||
@@ -55,23 +55,27 @@ public readonly unsafe ref struct RenderingContext
|
|||||||
}
|
}
|
||||||
|
|
||||||
var data = r.Value;
|
var data = r.Value;
|
||||||
if (data.Layout == newLayout && data.Access == newAccess && data.Sync == newSync)
|
if (data.layout == newLayout && data.access == newAccess && data.sync == newSync)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For buffers, layout is usually Undefined/Common and doesn't change, but Access/Sync do.
|
BarrierDesc desc;
|
||||||
// For textures, layout changes matter.
|
if (isTexture)
|
||||||
var desc = isTexture ?
|
{
|
||||||
BarrierDesc.Texture(
|
desc = BarrierDesc.Texture(
|
||||||
resource,
|
resource,
|
||||||
data.Sync, newSync,
|
data.sync, newSync,
|
||||||
data.Access, newAccess,
|
data.access, newAccess,
|
||||||
data.Layout, newLayout)
|
data.layout, newLayout);
|
||||||
: BarrierDesc.Buffer(
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
desc = BarrierDesc.Buffer(
|
||||||
resource,
|
resource,
|
||||||
data.Sync, newSync,
|
data.sync, newSync,
|
||||||
data.Access, newAccess);
|
data.access, newAccess);
|
||||||
|
}
|
||||||
|
|
||||||
_directCmd.ResourceBarrier(new ReadOnlySpan<BarrierDesc>(in desc));
|
_directCmd.ResourceBarrier(new ReadOnlySpan<BarrierDesc>(in desc));
|
||||||
ResourceDatabase.SetResourceBarrierData(resource, new ResourceBarrierData(newLayout, newAccess, newSync));
|
ResourceDatabase.SetResourceBarrierData(resource, new ResourceBarrierData(newLayout, newAccess, newSync));
|
||||||
@@ -188,13 +192,13 @@ public readonly unsafe ref struct RenderingContext
|
|||||||
public void UploadTexture<T>(Handle<Texture> texture, ReadOnlySpan<T> data)
|
public void UploadTexture<T>(Handle<Texture> texture, ReadOnlySpan<T> data)
|
||||||
where T : unmanaged
|
where T : unmanaged
|
||||||
{
|
{
|
||||||
var desc = ResourceDatabase.GetResourceDescription(texture.AsResource())
|
var desc = ResourceDatabase.GetResourceDescription(texture.AsResource()).GetValueOrThrow();
|
||||||
.GetValueOrThrow();
|
|
||||||
|
|
||||||
if (data.Length * sizeof(T) != desc.TextureDescription.GetTotalBytes())
|
//var size = ResourceAllocator.GetSizeInfo(desc).Size;
|
||||||
{
|
//if ((ulong)(data.Length * sizeof(T)) != ResourceAllocator.GetSizeInfo(desc).Size)
|
||||||
throw new ArgumentException("Data size does not match texture size.");
|
//{
|
||||||
}
|
// throw new ArgumentException("Data size does not match texture size.");
|
||||||
|
//}
|
||||||
|
|
||||||
desc.TextureDescription.Format.GetSurfaceInfo(desc.TextureDescription.Width, desc.TextureDescription.Height, out var rowPitch, out var slicePitch, out _);
|
desc.TextureDescription.Format.GetSurfaceInfo(desc.TextureDescription.Width, desc.TextureDescription.Height, out var rowPitch, out var slicePitch, out _);
|
||||||
|
|
||||||
@@ -209,7 +213,7 @@ public readonly unsafe ref struct RenderingContext
|
|||||||
slicePitch = slicePitch
|
slicePitch = slicePitch
|
||||||
};
|
};
|
||||||
|
|
||||||
_directCmd.UploadTexture(texture, [subresourceData]);
|
_directCmd.UploadTexture(texture, subresourceData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -186,12 +186,12 @@ public partial struct Shader : IResourceReleasable
|
|||||||
return ref _shaderPasses[index];
|
return ref _shaderPasses[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly Result<ShaderPass, ErrorStatus> TryGetPass(Identifier<ShaderPass> passID, out int passIndex)
|
public readonly Result<ShaderPass, Error> TryGetPass(Identifier<ShaderPass> passID, out int passIndex)
|
||||||
{
|
{
|
||||||
if (_passIDToLocal.TryGetValue(passID.Value, out var index))
|
if (_passIDToLocal.TryGetValue(passID.Value, out var index))
|
||||||
{
|
{
|
||||||
passIndex = -1;
|
passIndex = -1;
|
||||||
return ErrorStatus.NotFound;
|
return Error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
passIndex = index;
|
passIndex = index;
|
||||||
|
|||||||
@@ -115,9 +115,9 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
[System.Diagnostics.CodeAnalysis.DoesNotReturn]
|
[System.Diagnostics.CodeAnalysis.DoesNotReturn]
|
||||||
private static void RecordError(string cmdName, ErrorStatus status)
|
private static void RecordError(string cmdName, Error status)
|
||||||
#else
|
#else
|
||||||
private void RecordError(string cmdName, ErrorStatus status)
|
private void RecordError(string cmdName, Error status)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@@ -168,7 +168,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
_isRecording = false;
|
_isRecording = false;
|
||||||
|
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return Result.Failure($"Command buffer ended with errors at {_lastError.CommandIndex}, command '{_lastError.CommandName}': {_lastError.Status}");
|
return Result.Failure($"Command buffer ended with errors at {_lastError.CommandIndex}, command '{_lastError.CommandName}': {_lastError.Status}");
|
||||||
}
|
}
|
||||||
@@ -182,7 +182,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -198,7 +198,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -351,7 +351,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -365,12 +365,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
var handle = renderTargets[i];
|
var handle = renderTargets[i];
|
||||||
if (!handle.IsValid)
|
if (!handle.IsValid)
|
||||||
{
|
{
|
||||||
RecordError(nameof(SetRenderTargets), ErrorStatus.InvalidArgument);
|
RecordError(nameof(SetRenderTargets), Error.InvalidArgument);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var recordResult = _resourceDatabase.GetResourceRecord(handle.AsResource());
|
var recordResult = _resourceDatabase.GetResourceRecord(handle.AsResource());
|
||||||
if (recordResult.Error != ErrorStatus.None)
|
if (recordResult.Error != Error.None)
|
||||||
{
|
{
|
||||||
RecordError(nameof(SetRenderTargets), recordResult.Error);
|
RecordError(nameof(SetRenderTargets), recordResult.Error);
|
||||||
continue;
|
continue;
|
||||||
@@ -386,7 +386,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
if (pDsvHandle != null)
|
if (pDsvHandle != null)
|
||||||
{
|
{
|
||||||
var recordResult = _resourceDatabase.GetResourceRecord(depthTarget.AsResource());
|
var recordResult = _resourceDatabase.GetResourceRecord(depthTarget.AsResource());
|
||||||
if (recordResult.Error != ErrorStatus.None)
|
if (recordResult.Error != Error.None)
|
||||||
{
|
{
|
||||||
RecordError(nameof(SetRenderTargets), recordResult.Error);
|
RecordError(nameof(SetRenderTargets), recordResult.Error);
|
||||||
return;
|
return;
|
||||||
@@ -404,7 +404,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -412,7 +412,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
IncrementCommandCount();
|
IncrementCommandCount();
|
||||||
|
|
||||||
var recordResult = _resourceDatabase.GetResourceRecord(renderTarget.AsResource());
|
var recordResult = _resourceDatabase.GetResourceRecord(renderTarget.AsResource());
|
||||||
if (recordResult.Error != ErrorStatus.None)
|
if (recordResult.Error != Error.None)
|
||||||
{
|
{
|
||||||
RecordError(nameof(ClearRenderTargetView), recordResult.Error);
|
RecordError(nameof(ClearRenderTargetView), recordResult.Error);
|
||||||
return;
|
return;
|
||||||
@@ -436,7 +436,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -444,7 +444,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
IncrementCommandCount();
|
IncrementCommandCount();
|
||||||
|
|
||||||
var recordResult = _resourceDatabase.GetResourceRecord(depthStencil.AsResource());
|
var recordResult = _resourceDatabase.GetResourceRecord(depthStencil.AsResource());
|
||||||
if (recordResult.Error != ErrorStatus.None)
|
if (recordResult.Error != Error.None)
|
||||||
{
|
{
|
||||||
RecordError(nameof(ClearDepthStencilView), recordResult.Error);
|
RecordError(nameof(ClearDepthStencilView), recordResult.Error);
|
||||||
return;
|
return;
|
||||||
@@ -467,7 +467,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -480,12 +480,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
var rtDesc = rtDescs[i];
|
var rtDesc = rtDescs[i];
|
||||||
if (rtDesc.Texture.IsInvalid)
|
if (rtDesc.Texture.IsInvalid)
|
||||||
{
|
{
|
||||||
RecordError(nameof(BeginRenderPass), ErrorStatus.InvalidArgument);
|
RecordError(nameof(BeginRenderPass), Error.InvalidArgument);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var recordResult = _resourceDatabase.GetResourceRecord(rtDesc.Texture.AsResource());
|
var recordResult = _resourceDatabase.GetResourceRecord(rtDesc.Texture.AsResource());
|
||||||
if (recordResult.Error != ErrorStatus.None)
|
if (recordResult.Error != Error.None)
|
||||||
{
|
{
|
||||||
RecordError(nameof(BeginRenderPass), recordResult.Error);
|
RecordError(nameof(BeginRenderPass), recordResult.Error);
|
||||||
continue;
|
continue;
|
||||||
@@ -539,7 +539,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
if (pDsvDesc != null)
|
if (pDsvDesc != null)
|
||||||
{
|
{
|
||||||
var recordResult = _resourceDatabase.GetResourceRecord(depthDesc.Texture.AsResource());
|
var recordResult = _resourceDatabase.GetResourceRecord(depthDesc.Texture.AsResource());
|
||||||
if (recordResult.Error != ErrorStatus.None)
|
if (recordResult.Error != Error.None)
|
||||||
{
|
{
|
||||||
RecordError(nameof(BeginRenderPass), recordResult.Error);
|
RecordError(nameof(BeginRenderPass), recordResult.Error);
|
||||||
return;
|
return;
|
||||||
@@ -628,7 +628,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -643,7 +643,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -659,7 +659,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -667,7 +667,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
IncrementCommandCount();
|
IncrementCommandCount();
|
||||||
|
|
||||||
var psor = _pipelineLibrary.GetGraphicsPSO(pipelineKey);
|
var psor = _pipelineLibrary.GetGraphicsPSO(pipelineKey);
|
||||||
if (psor.Error != ErrorStatus.None)
|
if (psor.Error != Error.None)
|
||||||
{
|
{
|
||||||
RecordError(nameof(SetPipelineState), psor.Error);
|
RecordError(nameof(SetPipelineState), psor.Error);
|
||||||
return;
|
return;
|
||||||
@@ -682,7 +682,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -698,7 +698,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -706,7 +706,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
IncrementCommandCount();
|
IncrementCommandCount();
|
||||||
|
|
||||||
var recordResult = _resourceDatabase.GetResourceRecord(buffer.AsResource());
|
var recordResult = _resourceDatabase.GetResourceRecord(buffer.AsResource());
|
||||||
if (recordResult.Error != ErrorStatus.None)
|
if (recordResult.Error != Error.None)
|
||||||
{
|
{
|
||||||
RecordError(nameof(BeginRenderPass), recordResult.Error);
|
RecordError(nameof(BeginRenderPass), recordResult.Error);
|
||||||
return;
|
return;
|
||||||
@@ -728,7 +728,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -751,7 +751,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -774,7 +774,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -792,7 +792,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -807,7 +807,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -822,7 +822,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -837,7 +837,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -870,7 +870,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -890,7 +890,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -919,7 +919,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -960,7 +960,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (_lastError.Status != ErrorStatus.None)
|
if (_lastError.Status != Error.None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -971,7 +971,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
var pSrcResource = _resourceDatabase.GetResource(src.AsResource());
|
var pSrcResource = _resourceDatabase.GetResource(src.AsResource());
|
||||||
if (pSrcResource == null || pDestResource == null)
|
if (pSrcResource == null || pDestResource == null)
|
||||||
{
|
{
|
||||||
RecordError(nameof(CopyBuffer), ErrorStatus.InvalidArgument);
|
RecordError(nameof(CopyBuffer), Error.InvalidArgument);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -331,14 +331,14 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary
|
|||||||
return _pipelineCache.ContainsKey(key);
|
return _pipelineCache.ContainsKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result<SharedPtr<ID3D12PipelineState>, ErrorStatus> GetGraphicsPSO(Key128<GraphicsPipeline> key)
|
public Result<SharedPtr<ID3D12PipelineState>, Error> GetGraphicsPSO(Key128<GraphicsPipeline> key)
|
||||||
{
|
{
|
||||||
if (_pipelineCache.TryGetValue(key, out var cacheEntry))
|
if (_pipelineCache.TryGetValue(key, out var cacheEntry))
|
||||||
{
|
{
|
||||||
return cacheEntry.pso.Share();
|
return cacheEntry.pso.Share();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ErrorStatus.NotFound;
|
return Error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ internal class D3D12Renderer : IRenderer
|
|||||||
// HACK: This is hard coded for testing purposes only.
|
// HACK: This is hard coded for testing purposes only.
|
||||||
|
|
||||||
var error = RenderScene(target, RenderOutput.Viewport, RenderOutput.Scissor);
|
var error = RenderScene(target, RenderOutput.Viewport, RenderOutput.Scissor);
|
||||||
if (error != ErrorStatus.None)
|
if (error != Error.None)
|
||||||
{
|
{
|
||||||
_commandBuffer.End();
|
_commandBuffer.End();
|
||||||
return Result.Failure(error);
|
return Result.Failure(error);
|
||||||
@@ -88,7 +88,7 @@ internal class D3D12Renderer : IRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: A proper render graph integration.
|
// TODO: A proper render graph integration.
|
||||||
private ErrorStatus RenderScene(Handle<Texture> target, ViewportDesc viewport, RectDesc rect)
|
private Error RenderScene(Handle<Texture> target, ViewportDesc viewport, RectDesc rect)
|
||||||
{
|
{
|
||||||
// NOTE: Testing only.
|
// NOTE: Testing only.
|
||||||
var ctx = new RenderingContext(_graphicsEngine, _commandBuffer);
|
var ctx = new RenderingContext(_graphicsEngine, _commandBuffer);
|
||||||
@@ -116,7 +116,7 @@ internal class D3D12Renderer : IRenderer
|
|||||||
//_commandBuffer.EndRenderPass();
|
//_commandBuffer.EndRenderPass();
|
||||||
_frameIndex++;
|
_frameIndex++;
|
||||||
|
|
||||||
return ErrorStatus.None;
|
return Error.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|||||||
@@ -605,9 +605,9 @@ internal sealed unsafe partial class D3D12ResourceAllocator : IResourceAllocator
|
|||||||
|
|
||||||
var barrierData = new ResourceBarrierData
|
var barrierData = new ResourceBarrierData
|
||||||
{
|
{
|
||||||
Access = BarrierAccess.NoAccess,
|
access = BarrierAccess.NoAccess,
|
||||||
Layout = BarrierLayout.Common,
|
layout = BarrierLayout.Common,
|
||||||
Sync = BarrierSync.None
|
sync = BarrierSync.None
|
||||||
};
|
};
|
||||||
|
|
||||||
return TrackAllocation(alloc, barrierData, ResourceViewGroup.Invalid, default, name, false);
|
return TrackAllocation(alloc, barrierData, ResourceViewGroup.Invalid, default, name, false);
|
||||||
@@ -693,9 +693,9 @@ internal sealed unsafe partial class D3D12ResourceAllocator : IResourceAllocator
|
|||||||
|
|
||||||
var barrierData = new ResourceBarrierData
|
var barrierData = new ResourceBarrierData
|
||||||
{
|
{
|
||||||
Access = BarrierAccess.NoAccess,
|
access = BarrierAccess.NoAccess,
|
||||||
Layout = BarrierLayout.Common,
|
layout = BarrierLayout.Common,
|
||||||
Sync = BarrierSync.None
|
sync = BarrierSync.None
|
||||||
};
|
};
|
||||||
|
|
||||||
Handle<GPUResource> resource;
|
Handle<GPUResource> resource;
|
||||||
@@ -715,7 +715,7 @@ internal sealed unsafe partial class D3D12ResourceAllocator : IResourceAllocator
|
|||||||
{
|
{
|
||||||
ObjectDisposedException.ThrowIf(_disposed, this);
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||||
|
|
||||||
var textureDesc = desc.ToTextureDescripton();
|
var textureDesc = desc.ToTextureDescription();
|
||||||
return CreateTexture(in textureDesc, name, options);
|
return CreateTexture(in textureDesc, name, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -803,9 +803,9 @@ internal sealed unsafe partial class D3D12ResourceAllocator : IResourceAllocator
|
|||||||
|
|
||||||
var barrierData = new ResourceBarrierData
|
var barrierData = new ResourceBarrierData
|
||||||
{
|
{
|
||||||
Access = BarrierAccess.NoAccess,
|
access = BarrierAccess.NoAccess,
|
||||||
Layout = BarrierLayout.Undefined,
|
layout = BarrierLayout.Undefined,
|
||||||
Sync = BarrierSync.None
|
sync = BarrierSync.None
|
||||||
};
|
};
|
||||||
|
|
||||||
Handle<GPUResource> resource;
|
Handle<GPUResource> resource;
|
||||||
@@ -927,7 +927,7 @@ internal sealed unsafe partial class D3D12ResourceAllocator : IResourceAllocator
|
|||||||
ObjectDisposedException.ThrowIf(_disposed, this);
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||||
|
|
||||||
var material = new Material();
|
var material = new Material();
|
||||||
if (material.SetShader(shader, this, _resourceDatabase) != ErrorStatus.None)
|
if (material.SetShader(shader, this, _resourceDatabase) != Error.None)
|
||||||
{
|
{
|
||||||
return Handle<Material>.Invalid;
|
return Handle<Material>.Invalid;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,14 @@ 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.Diagnostics;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using TerraFX.Interop.DirectX;
|
using TerraFX.Interop.DirectX;
|
||||||
|
|
||||||
namespace Ghost.Graphics.D3D12;
|
namespace Ghost.Graphics.D3D12;
|
||||||
|
|
||||||
|
// TODO: Thread safety
|
||||||
internal class D3D12ResourceDatabase : IResourceDatabase
|
internal class D3D12ResourceDatabase : IResourceDatabase
|
||||||
{
|
{
|
||||||
internal unsafe record struct ResourceRecord
|
internal unsafe record struct ResourceRecord
|
||||||
@@ -38,9 +41,6 @@ internal class D3D12ResourceDatabase : IResourceDatabase
|
|||||||
public ResourceViewGroup viewGroup;
|
public ResourceViewGroup viewGroup;
|
||||||
public ResourceUnion resource;
|
public ResourceUnion resource;
|
||||||
|
|
||||||
//public BarrierLayout layout;
|
|
||||||
//public BarrierAccess access;
|
|
||||||
//public BarrierSync sync;
|
|
||||||
public ResourceBarrierData barrierData;
|
public ResourceBarrierData barrierData;
|
||||||
|
|
||||||
public uint cpuFenceValue;
|
public uint cpuFenceValue;
|
||||||
@@ -71,7 +71,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
|
|||||||
this.desc = resource->GetDesc().ToResourceDesc();
|
this.desc = resource->GetDesc().ToResourceDesc();
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint Release(D3D12DescriptorAllocator descriptorAllocator)
|
public readonly uint Release(D3D12DescriptorAllocator descriptorAllocator)
|
||||||
{
|
{
|
||||||
var refCount = 0u;
|
var refCount = 0u;
|
||||||
if (Allocated)
|
if (Allocated)
|
||||||
@@ -87,10 +87,6 @@ internal class D3D12ResourceDatabase : IResourceDatabase
|
|||||||
}
|
}
|
||||||
|
|
||||||
descriptorAllocator.Release(viewGroup);
|
descriptorAllocator.Release(viewGroup);
|
||||||
|
|
||||||
resource = default;
|
|
||||||
viewGroup = default;
|
|
||||||
|
|
||||||
return refCount;
|
return refCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,6 +134,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
|
|||||||
public unsafe Handle<GPUResource> ImportExternalResource(ID3D12Resource* pResource, ResourceBarrierData initialBarrierData, ResourceViewGroup viewGroup, string? name = null)
|
public unsafe Handle<GPUResource> ImportExternalResource(ID3D12Resource* pResource, ResourceBarrierData initialBarrierData, ResourceViewGroup viewGroup, string? name = null)
|
||||||
{
|
{
|
||||||
ObjectDisposedException.ThrowIf(_disposed, this);
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||||
|
|
||||||
if (pResource == null)
|
if (pResource == null)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@@ -196,17 +193,17 @@ internal class D3D12ResourceDatabase : IResourceDatabase
|
|||||||
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, Error> 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 Error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RefResult<ResourceRecord, ErrorStatus>.Success(ref info);
|
return RefResult<ResourceRecord, Error>.Success(ref info);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SharedPtr<ID3D12Resource> GetResource(Handle<GPUResource> handle)
|
public SharedPtr<ID3D12Resource> GetResource(Handle<GPUResource> handle)
|
||||||
@@ -220,7 +217,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
|
|||||||
return r.Value.ResourcePtr;
|
return r.Value.ResourcePtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result<ResourceBarrierData, ErrorStatus> GetResourceBarrierData(Handle<GPUResource> handle)
|
public Result<ResourceBarrierData, Error> GetResourceBarrierData(Handle<GPUResource> handle)
|
||||||
{
|
{
|
||||||
var r = GetResourceRecord(handle);
|
var r = GetResourceRecord(handle);
|
||||||
if (r.IsFailure)
|
if (r.IsFailure)
|
||||||
@@ -231,7 +228,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
|
|||||||
return r.Value.barrierData;
|
return r.Value.barrierData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ErrorStatus SetResourceBarrierData(Handle<GPUResource> handle, ResourceBarrierData data)
|
public Error SetResourceBarrierData(Handle<GPUResource> handle, ResourceBarrierData data)
|
||||||
{
|
{
|
||||||
var r = GetResourceRecord(handle);
|
var r = GetResourceRecord(handle);
|
||||||
if (r.IsFailure)
|
if (r.IsFailure)
|
||||||
@@ -240,10 +237,10 @@ internal class D3D12ResourceDatabase : IResourceDatabase
|
|||||||
}
|
}
|
||||||
|
|
||||||
r.Value.barrierData = data;
|
r.Value.barrierData = data;
|
||||||
return ErrorStatus.None;
|
return Error.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result<ResourceDesc, ErrorStatus> GetResourceDescription(Handle<GPUResource> handle)
|
public Result<ResourceDesc, Error> GetResourceDescription(Handle<GPUResource> handle)
|
||||||
{
|
{
|
||||||
var r = GetResourceRecord(handle);
|
var r = GetResourceRecord(handle);
|
||||||
if (r.IsFailure)
|
if (r.IsFailure)
|
||||||
@@ -254,7 +251,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
|
|||||||
return r.Value.desc;
|
return r.Value.desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint GetBindlessIndex(Handle<GPUResource> handle)
|
public uint GetBindlessIndex(Handle<GPUResource> handle, BindlessAccess access = BindlessAccess.ShaderResource)
|
||||||
{
|
{
|
||||||
var r = GetResourceRecord(handle);
|
var r = GetResourceRecord(handle);
|
||||||
if (r.IsFailure || !r.Value.Allocated)
|
if (r.IsFailure || !r.Value.Allocated)
|
||||||
@@ -262,7 +259,13 @@ internal class D3D12ResourceDatabase : IResourceDatabase
|
|||||||
return ~0u;
|
return ~0u;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (uint)r.Value.viewGroup.srv.Value;
|
return access switch
|
||||||
|
{
|
||||||
|
BindlessAccess.ShaderResource => (uint)r.Value.viewGroup.srv.Value,
|
||||||
|
BindlessAccess.ConstantBuffer => (uint)r.Value.viewGroup.cbv.Value,
|
||||||
|
BindlessAccess.UnorderedAccess => (uint)r.Value.viewGroup.uav.Value,
|
||||||
|
_ => ~0u,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public string? GetResourceName(Handle<GPUResource> handle)
|
public string? GetResourceName(Handle<GPUResource> handle)
|
||||||
@@ -345,15 +348,15 @@ internal class D3D12ResourceDatabase : IResourceDatabase
|
|||||||
return _meshes.Contains(handle.ID, handle.Generation);
|
return _meshes.Contains(handle.ID, handle.Generation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RefResult<Mesh, ErrorStatus> GetMeshReference(Handle<Mesh> handle)
|
public RefResult<Mesh, Error> GetMeshReference(Handle<Mesh> handle)
|
||||||
{
|
{
|
||||||
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 ErrorStatus.NotFound;
|
return Error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RefResult<Mesh, ErrorStatus>.Success(ref mesh);
|
return RefResult<Mesh, Error>.Success(ref mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReleaseMesh(Handle<Mesh> handle)
|
public void ReleaseMesh(Handle<Mesh> handle)
|
||||||
@@ -384,15 +387,15 @@ internal class D3D12ResourceDatabase : IResourceDatabase
|
|||||||
return _materials.Contains(handle.ID, handle.Generation);
|
return _materials.Contains(handle.ID, handle.Generation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RefResult<Material, ErrorStatus> GetMaterialReference(Handle<Material> handle)
|
public RefResult<Material, Error> GetMaterialReference(Handle<Material> handle)
|
||||||
{
|
{
|
||||||
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 ErrorStatus.NotFound;
|
return Error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RefResult<Material, ErrorStatus>.Success(ref material);
|
return RefResult<Material, Error>.Success(ref material);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReleaseMaterial(Handle<Material> handle)
|
public void ReleaseMaterial(Handle<Material> handle)
|
||||||
@@ -424,14 +427,14 @@ internal class D3D12ResourceDatabase : IResourceDatabase
|
|||||||
return id.Value >= 0 && id.Value < _shaders.Count;
|
return id.Value >= 0 && id.Value < _shaders.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RefResult<Shader, ErrorStatus> GetShaderReference(Identifier<Shader> id)
|
public RefResult<Shader, Error> GetShaderReference(Identifier<Shader> id)
|
||||||
{
|
{
|
||||||
if (!HasShader(id))
|
if (!HasShader(id))
|
||||||
{
|
{
|
||||||
return ErrorStatus.NotFound;
|
return Error.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RefResult<Shader, ErrorStatus>.Success(ref _shaders[id.Value]);
|
return RefResult<Shader, Error>.Success(ref _shaders[id.Value]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReleaseShader(Identifier<Shader> id)
|
public void ReleaseShader(Identifier<Shader> id)
|
||||||
@@ -449,6 +452,8 @@ internal class D3D12ResourceDatabase : IResourceDatabase
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
[DoesNotReturn]
|
||||||
|
[Conditional("DEBUG")]
|
||||||
static void ThrowMemoryLeakException(string resourceType, int count)
|
static void ThrowMemoryLeakException(string resourceType, int count)
|
||||||
{
|
{
|
||||||
throw new MemoryLeakException($"ResourceAllocator is being disposed with {count} {resourceType} still registered. Ensure all resources are released before disposing.");
|
throw new MemoryLeakException($"ResourceAllocator is being disposed with {count} {resourceType} still registered. Ensure all resources are released before disposing.");
|
||||||
|
|||||||
@@ -159,9 +159,9 @@ internal unsafe class D3D12SwapChain : ISwapChain
|
|||||||
|
|
||||||
var barrierData = new ResourceBarrierData
|
var barrierData = new ResourceBarrierData
|
||||||
{
|
{
|
||||||
Access = BarrierAccess.NoAccess,
|
access = BarrierAccess.NoAccess,
|
||||||
Layout = BarrierLayout.Present,
|
layout = BarrierLayout.Present,
|
||||||
Sync = BarrierSync.None,
|
sync = BarrierSync.None,
|
||||||
};
|
};
|
||||||
|
|
||||||
var handle = _resourceDatabase.ImportExternalResource(pBackBuffer, barrierData, view);
|
var handle = _resourceDatabase.ImportExternalResource(pBackBuffer, barrierData, view);
|
||||||
|
|||||||
@@ -601,7 +601,7 @@ public struct RenderTargetDesc
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public TextureDesc ToTextureDescripton()
|
public TextureDesc ToTextureDescription()
|
||||||
{
|
{
|
||||||
var usage = Type == RenderTargetType.Color ? TextureUsage.RenderTarget : TextureUsage.DepthStencil;
|
var usage = Type == RenderTargetType.Color ? TextureUsage.RenderTarget : TextureUsage.DepthStencil;
|
||||||
if (CreationFlags.HasFlag(RenderTargetCreationFlags.AllowUAV))
|
if (CreationFlags.HasFlag(RenderTargetCreationFlags.AllowUAV))
|
||||||
@@ -768,7 +768,7 @@ public struct CommandError
|
|||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ErrorStatus Status
|
public Error Status
|
||||||
{
|
{
|
||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,18 +13,25 @@ public interface IResourceReleasable
|
|||||||
|
|
||||||
public struct ResourceBarrierData
|
public struct ResourceBarrierData
|
||||||
{
|
{
|
||||||
public BarrierLayout Layout;
|
public BarrierLayout layout;
|
||||||
public BarrierAccess Access;
|
public BarrierAccess access;
|
||||||
public BarrierSync Sync;
|
public BarrierSync sync;
|
||||||
|
|
||||||
public ResourceBarrierData(BarrierLayout layout, BarrierAccess access, BarrierSync sync)
|
public ResourceBarrierData(BarrierLayout layout, BarrierAccess access, BarrierSync sync)
|
||||||
{
|
{
|
||||||
Layout = layout;
|
this.layout = layout;
|
||||||
Access = access;
|
this.access = access;
|
||||||
Sync = sync;
|
this.sync = sync;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum BindlessAccess
|
||||||
|
{
|
||||||
|
ShaderResource,
|
||||||
|
ConstantBuffer,
|
||||||
|
UnorderedAccess,
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Consider adding methods for resource enumeration, statistics, and bulk operations.
|
// TODO: Consider adding methods for resource enumeration, statistics, and bulk operations.
|
||||||
// TODO: Consider adding async resource loading and streaming support.
|
// TODO: Consider adding async resource loading and streaming support.
|
||||||
// TODO: Mesh, Material, Shader management could be separated into their own interfaces for better modularity because they are not bound to specific graphics API.
|
// TODO: Mesh, Material, Shader management could be separated into their own interfaces for better modularity because they are not bound to specific graphics API.
|
||||||
@@ -53,29 +60,30 @@ public interface IResourceDatabase : IDisposable
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="handle">The handle that uniquely identifies the resource.</param>
|
/// <param name="handle">The handle that uniquely identifies the resource.</param>
|
||||||
/// <returns>A ResourceBarrierData value representing the current barrier state.</returns>
|
/// <returns>A ResourceBarrierData value representing the current barrier state.</returns>
|
||||||
Result<ResourceBarrierData, ErrorStatus> GetResourceBarrierData(Handle<GPUResource> handle);
|
Result<ResourceBarrierData, Error> GetResourceBarrierData(Handle<GPUResource> handle);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the barrier data of the specified resource handle.
|
/// Sets the barrier data of the specified resource handle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="handle">The handle that identifies the resource.</param>
|
/// <param name="handle">The handle that identifies the resource.</param>
|
||||||
/// <param name="data">The new barrier data.</param>
|
/// <param name="data">The new barrier data.</param>
|
||||||
/// <returns>An ErrorStatus indicating the success or failure of the operation.</returns>
|
/// <returns>An Error indicating the success or failure of the operation.</returns>
|
||||||
ErrorStatus SetResourceBarrierData(Handle<GPUResource> handle, ResourceBarrierData data);
|
Error SetResourceBarrierData(Handle<GPUResource> handle, ResourceBarrierData data);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves the description of a GPU resource associated with the specified handle.
|
/// Retrieves the description of a GPU resource associated with the specified handle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="handle">A handle that identifies the GPU resource for which to obtain the description. Must reference a valid resource.</param>
|
/// <param name="handle">A handle that identifies the GPU resource for which to obtain the description. Must reference a valid resource.</param>
|
||||||
/// <returns>A ResourceDesc structure containing details about the specified GPU resource.</returns>
|
/// <returns>A ResourceDesc structure containing details about the specified GPU resource.</returns>
|
||||||
Result<ResourceDesc, ErrorStatus> GetResourceDescription(Handle<GPUResource> handle);
|
Result<ResourceDesc, Error> GetResourceDescription(Handle<GPUResource> handle);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves the bindless index associated with the specified GPU resource handle.
|
/// Retrieves the bindless index associated with the specified GPU resource handle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="handle">A handle to the GPU resource for which to obtain the bindless index. Must reference a valid, currently registered resource.</param>
|
/// <param name="handle">A handle to the GPU resource for which to obtain the bindless index. Must reference a valid, currently registered resource.</param>
|
||||||
|
/// <param name="access">The type of bindless access for which to obtain the index.</param>
|
||||||
/// <returns>The bindless index corresponding to the specified GPU resource handle. ~0 if the resource does not support bindless access or is not found.</returns>
|
/// <returns>The bindless index corresponding to the specified GPU resource handle. ~0 if the resource does not support bindless access or is not found.</returns>
|
||||||
uint GetBindlessIndex(Handle<GPUResource> handle);
|
uint GetBindlessIndex(Handle<GPUResource> handle, BindlessAccess access = BindlessAccess.ShaderResource);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves the name of the GPU resource associated with the specified handle.
|
/// Retrieves the name of the GPU resource associated with the specified handle.
|
||||||
@@ -135,7 +143,7 @@ public interface IResourceDatabase : IDisposable
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="handle">The handle of the mesh to retrieve. Must refer to a valid mesh; otherwise, the behavior is undefined.</param>
|
/// <param name="handle">The handle of the mesh to retrieve. Must refer to a valid mesh; otherwise, the behavior is undefined.</param>
|
||||||
/// <returns>A result containing a reference to the mesh corresponding to the specified handle, or an error status if the handle is invalid.</returns>
|
/// <returns>A result containing a reference to the mesh corresponding to the specified handle, or an error status if the handle is invalid.</returns>
|
||||||
RefResult<Mesh, ErrorStatus> GetMeshReference(Handle<Mesh> handle);
|
RefResult<Mesh, Error> GetMeshReference(Handle<Mesh> handle);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Releases the mesh resource associated with the specified handle, freeing any resources held by it. Includes both CPU and GPU resources.
|
/// Releases the mesh resource associated with the specified handle, freeing any resources held by it. Includes both CPU and GPU resources.
|
||||||
@@ -162,7 +170,7 @@ public interface IResourceDatabase : IDisposable
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="handle">The handle of the material to retrieve. Must refer to a valid material.</param>
|
/// <param name="handle">The handle of the material to retrieve. Must refer to a valid material.</param>
|
||||||
/// <returns>A result containing a reference to the material corresponding to the specified handle, or an error status if the handle is invalid.</returns>
|
/// <returns>A result containing a reference to the material corresponding to the specified handle, or an error status if the handle is invalid.</returns>
|
||||||
RefResult<Material, ErrorStatus> GetMaterialReference(Handle<Material> handle);
|
RefResult<Material, Error> GetMaterialReference(Handle<Material> handle);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Releases the material associated with the specified handle, making it available for reuse or disposal.
|
/// Releases the material associated with the specified handle, making it available for reuse or disposal.
|
||||||
@@ -189,7 +197,7 @@ public interface IResourceDatabase : IDisposable
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id">The identifier of the shader to retrieve. Must refer to a valid shader.</param>
|
/// <param name="id">The identifier of the shader to retrieve. Must refer to a valid shader.</param>
|
||||||
/// <returns>A result containing a reference to the shader corresponding to the specified identifier, or an error status if the identifier is invalid.</returns>
|
/// <returns>A result containing a reference to the shader corresponding to the specified identifier, or an error status if the identifier is invalid.</returns>
|
||||||
RefResult<Shader, ErrorStatus> GetShaderReference(Identifier<Shader> id);
|
RefResult<Shader, Error> GetShaderReference(Identifier<Shader> id);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Releases the shader associated with the specified identifier, freeing any resources allocated to it.
|
/// Releases the shader associated with the specified identifier, freeing any resources allocated to it.
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ public sealed class RenderGraph : IDisposable
|
|||||||
Blackboard = new RenderGraphBlackboard();
|
Blackboard = new RenderGraphBlackboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resets the render graph for a new frame.
|
/// Resets the render graph for a new frame.
|
||||||
/// Reuses existing allocations to minimize GC.
|
/// Reuses existing allocations to minimize GC.
|
||||||
@@ -224,7 +223,7 @@ public sealed class RenderGraph : IDisposable
|
|||||||
{
|
{
|
||||||
_compiler.Dispose();
|
_compiler.Dispose();
|
||||||
|
|
||||||
// We need to reset the whole graph to return resources to the pool
|
// HACK: Ideally, we should have a Dispose method. But for now, we just reset to release resources.
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ internal struct ResourceBarrier
|
|||||||
public override readonly string ToString()
|
public override readonly string ToString()
|
||||||
{
|
{
|
||||||
return AliasingPredecessor.IsValid
|
return AliasingPredecessor.IsValid
|
||||||
? $"[Pass {PassIndex}] Aliasing Barrier: {AliasingPredecessor.Value}->{Resource.Value} Target: {TargetState.Layout}"
|
? $"[Pass {PassIndex}] Aliasing Barrier: {AliasingPredecessor.Value}->{Resource.Value} Target: {TargetState.layout}"
|
||||||
: $"[Pass {PassIndex}] Barrier: {Resource.Value} Target: {TargetState.Layout}";
|
: $"[Pass {PassIndex}] Barrier: {Resource.Value} Target: {TargetState.layout}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,8 +88,8 @@ internal struct CompiledBarrier
|
|||||||
public override readonly string ToString()
|
public override readonly string ToString()
|
||||||
{
|
{
|
||||||
return AliasingPredecessor.IsValid
|
return AliasingPredecessor.IsValid
|
||||||
? $"[Pass {PassIndex}] Aliasing: {AliasingPredecessor.Value}->{Resource.Value} -> {TargetState.Layout}"
|
? $"[Pass {PassIndex}] Aliasing: {AliasingPredecessor.Value}->{Resource.Value} -> {TargetState.layout}"
|
||||||
: $"[Pass {PassIndex}] Transition: {Resource.Value} -> {TargetState.Layout}";
|
: $"[Pass {PassIndex}] Transition: {Resource.Value} -> {TargetState.layout}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +254,7 @@ internal static class RenderGraphBarriers
|
|||||||
if (pass.colorAccess[i].id.IsValid)
|
if (pass.colorAccess[i].id.IsValid)
|
||||||
{
|
{
|
||||||
var usage = pass.colorAccess[i].usage;
|
var usage = pass.colorAccess[i].usage;
|
||||||
var targetState = new ResourceBarrierData(usage.Layout, usage.Access, usage.Sync);
|
var targetState = new ResourceBarrierData(usage.layout, usage.access, usage.sync);
|
||||||
AddTransition(pass.colorAccess[i].id.AsResource(), targetState);
|
AddTransition(pass.colorAccess[i].id.AsResource(), targetState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -263,7 +263,7 @@ internal static class RenderGraphBarriers
|
|||||||
if (pass.depthAccess.id.IsValid)
|
if (pass.depthAccess.id.IsValid)
|
||||||
{
|
{
|
||||||
var usage = pass.depthAccess.usage;
|
var usage = pass.depthAccess.usage;
|
||||||
var targetState = new ResourceBarrierData(usage.Layout, usage.Access, usage.Sync);
|
var targetState = new ResourceBarrierData(usage.layout, usage.access, usage.sync);
|
||||||
AddTransition(pass.depthAccess.id.AsResource(), targetState);
|
AddTransition(pass.depthAccess.id.AsResource(), targetState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ internal sealed class RenderGraphContext : IRasterRenderContext, IComputeRenderC
|
|||||||
|
|
||||||
private readonly TextureFormat[] _rtvFormats;
|
private readonly TextureFormat[] _rtvFormats;
|
||||||
private TextureFormat _dsvFormat;
|
private TextureFormat _dsvFormat;
|
||||||
|
private int _rtvCount;
|
||||||
|
|
||||||
private Handle<GraphicsBuffer> _activePerMaterialData;
|
private Handle<GraphicsBuffer> _activePerMaterialData;
|
||||||
private Handle<GraphicsBuffer> _activePerMeshData;
|
private Handle<GraphicsBuffer> _activePerMeshData;
|
||||||
@@ -82,6 +83,7 @@ internal sealed class RenderGraphContext : IRasterRenderContext, IComputeRenderC
|
|||||||
}
|
}
|
||||||
|
|
||||||
_dsvFormat = dsvFormat;
|
_dsvFormat = dsvFormat;
|
||||||
|
_rtvCount = rtvFormats.Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Handle<GPUResource> GetActualResource(Identifier<RGResource> resource)
|
public Handle<GPUResource> GetActualResource(Identifier<RGResource> resource)
|
||||||
@@ -145,7 +147,7 @@ internal sealed class RenderGraphContext : IRasterRenderContext, IComputeRenderC
|
|||||||
VariantKey = shaderVariantKey,
|
VariantKey = shaderVariantKey,
|
||||||
PipelineOption = materialPipeline,
|
PipelineOption = materialPipeline,
|
||||||
|
|
||||||
RtvFormats = _rtvFormats,
|
RtvFormats = _rtvFormats.AsSpan(0, _rtvCount),
|
||||||
DsvFormat = _dsvFormat,
|
DsvFormat = _dsvFormat,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -173,22 +173,22 @@ internal sealed class RenderGraphExecutor
|
|||||||
|
|
||||||
layoutBefore = BarrierLayout.Undefined;
|
layoutBefore = BarrierLayout.Undefined;
|
||||||
accessBefore = BarrierAccess.NoAccess;
|
accessBefore = BarrierAccess.NoAccess;
|
||||||
syncBefore = predState.Sync;
|
syncBefore = predState.sync;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
layoutBefore = currentState.Layout;
|
layoutBefore = currentState.layout;
|
||||||
accessBefore = currentState.Access;
|
accessBefore = currentState.access;
|
||||||
syncBefore = currentState.Sync;
|
syncBefore = currentState.sync;
|
||||||
}
|
}
|
||||||
|
|
||||||
var target = compiledBarrier.TargetState;
|
var target = compiledBarrier.TargetState;
|
||||||
|
|
||||||
// Skip if already in target state (optimization)
|
// Skip if already in target state (optimization)
|
||||||
if (!compiledBarrier.AliasingPredecessor.IsValid &&
|
if (!compiledBarrier.AliasingPredecessor.IsValid &&
|
||||||
layoutBefore == target.Layout &&
|
layoutBefore == target.layout &&
|
||||||
accessBefore == target.Access &&
|
accessBefore == target.access &&
|
||||||
syncBefore == target.Sync)
|
syncBefore == target.sync)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -198,16 +198,16 @@ internal sealed class RenderGraphExecutor
|
|||||||
if (compiledBarrier.ResourceType == RenderGraphResourceType.Texture)
|
if (compiledBarrier.ResourceType == RenderGraphResourceType.Texture)
|
||||||
{
|
{
|
||||||
desc = BarrierDesc.Texture(resourceHandle,
|
desc = BarrierDesc.Texture(resourceHandle,
|
||||||
syncBefore, target.Sync,
|
syncBefore, target.sync,
|
||||||
accessBefore, target.Access,
|
accessBefore, target.access,
|
||||||
layoutBefore, target.Layout,
|
layoutBefore, target.layout,
|
||||||
discard: compiledBarrier.Flags.HasFlag(BarrierFlags.Discard));
|
discard: compiledBarrier.Flags.HasFlag(BarrierFlags.Discard));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
desc = BarrierDesc.Buffer(resourceHandle,
|
desc = BarrierDesc.Buffer(resourceHandle,
|
||||||
syncBefore, target.Sync,
|
syncBefore, target.sync,
|
||||||
accessBefore, target.Access);
|
accessBefore, target.access);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (barrierCount >= MaxBatch)
|
if (barrierCount >= MaxBatch)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Ghost.Core;
|
using Ghost.Core;
|
||||||
|
using Ghost.Graphics.RHI;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Ghost.Graphics.RenderGraphModule;
|
namespace Ghost.Graphics.RenderGraphModule;
|
||||||
@@ -27,7 +28,7 @@ internal abstract class RenderGraphPassBase
|
|||||||
public bool asyncCompute;
|
public bool asyncCompute;
|
||||||
|
|
||||||
public TextureAccess depthAccess;
|
public TextureAccess depthAccess;
|
||||||
public TextureAccess[] colorAccess = new TextureAccess[8];
|
public TextureAccess[] colorAccess = new TextureAccess[RHIUtility.MAX_RENDER_TARGETS];
|
||||||
public int maxColorIndex = -1;
|
public int maxColorIndex = -1;
|
||||||
|
|
||||||
public List<Identifier<RGResource>> randomAccess = new(8);
|
public List<Identifier<RGResource>> randomAccess = new(8);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ struct PixelInput
|
|||||||
float4 uv : TEXCOORD0;
|
float4 uv : TEXCOORD0;
|
||||||
};
|
};
|
||||||
|
|
||||||
[NumThreads(3, 1, 1)] // 3 threads per triangle
|
[numthreads(3, 1, 1)] // 3 threads per triangle
|
||||||
[OUTPUT_TRIANGLE_TOPOLOGY]
|
[OUTPUT_TRIANGLE_TOPOLOGY]
|
||||||
void MSMain(
|
void MSMain(
|
||||||
uint3 groupThreadID : SV_GroupThreadID,
|
uint3 groupThreadID : SV_GroupThreadID,
|
||||||
@@ -22,7 +22,6 @@ void MSMain(
|
|||||||
Vertex v = LoadVertexData(vertexId, groupID.x, perObjectData.vertexBuffer, perObjectData.indexBuffer);
|
Vertex v = LoadVertexData(vertexId, groupID.x, perObjectData.vertexBuffer, perObjectData.indexBuffer);
|
||||||
|
|
||||||
SetMeshOutputCounts(3, 1);
|
SetMeshOutputCounts(3, 1);
|
||||||
//v.position = mul(g_PerViewData.cameraMatrix, mul(g_PerObjectData.localToWorld, v.position));
|
|
||||||
|
|
||||||
// Write vertex output
|
// Write vertex output
|
||||||
outVerts[vertexId].position = v.position;
|
outVerts[vertexId].position = v.position;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ shader "Hidden/Blit"
|
|||||||
float4 uv : TEXCOORD0;
|
float4 uv : TEXCOORD0;
|
||||||
};
|
};
|
||||||
|
|
||||||
[NumThreads(4, 1, 1)]
|
[numthreads(4, 1, 1)]
|
||||||
[OUTPUT_TRIANGLE_TOPOLOGY]
|
[OUTPUT_TRIANGLE_TOPOLOGY]
|
||||||
void MSMain(
|
void MSMain(
|
||||||
uint gtid : SV_GroupThreadID,
|
uint gtid : SV_GroupThreadID,
|
||||||
|
|||||||
@@ -49,8 +49,11 @@ struct Vertex
|
|||||||
#define SAMPLE_TEXTURE2D_ARRAY(texId, sampId, uvw) SampleTextureArray(texId, sampId, uvw)
|
#define SAMPLE_TEXTURE2D_ARRAY(texId, sampId, uvw) SampleTextureArray(texId, sampId, uvw)
|
||||||
|
|
||||||
|
|
||||||
#define OUTPUT_TRIANGLE_TOPOLOGY OutputTopology("triangle")
|
#define OUTPUT_TRIANGLE_TOPOLOGY outputtopology("triangle")
|
||||||
#define OUTPUT_LINE_TOPOLOGY OutputTopology("line")
|
#define OUTPUT_LINE_TOPOLOGY outputtopology("line")
|
||||||
|
|
||||||
|
|
||||||
|
#define ZERO_INIT(T) (T)0
|
||||||
|
|
||||||
|
|
||||||
static inline float4 SampleTexture2D(uint texId, uint sampId, float2 uv)
|
static inline float4 SampleTexture2D(uint texId, uint sampId, float2 uv)
|
||||||
|
|||||||
Reference in New Issue
Block a user