feat(shader): refactor and enhance shader pipeline
Refactored the shader compilation pipeline to introduce modularity, improve performance, and enhance maintainability. Key changes include: - Added `ShaderCompilationConfig`, `CompilerOptimizeLevel`, and `ShaderStage` enums. - Replaced `SM` property with `ShaderModel` in shader models. - Introduced `ShaderLibrary` for in-memory and disk-based shader caching. - Refactored `DSLShaderCompiler` and `AntlrShaderCompiler` for better hashing and error handling. - Centralized shader compilation logic in `ShaderCompilerUtility`. - Removed legacy shader compilation logic from `IShaderCompiler`. - Updated `RenderGraph`, `ResourceManager`, and `Material` to integrate with the new caching system. - Improved memory management with `NativeMemoryManager<T>`. BREAKING CHANGE: Removed legacy shader compilation methods and replaced them with a new caching and compilation system.
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
using Ghost.Core.Utilities;
|
||||
using System.IO.Hashing;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ghost.Core.Graphics;
|
||||
|
||||
public enum ShaderModel
|
||||
{
|
||||
Invalid,
|
||||
SM_6_6,
|
||||
SM_6_7,
|
||||
SM_6_8
|
||||
@@ -20,6 +24,18 @@ public struct ShaderCode
|
||||
public string entryPoint;
|
||||
|
||||
public readonly bool IsCreated => !string.IsNullOrEmpty(code) && !string.IsNullOrEmpty(entryPoint);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public readonly ulong GetHashCode64()
|
||||
{
|
||||
return Hash.Combine64(XxHash64.HashToUInt64(MemoryMarshal.AsBytes(code.AsSpan())), XxHash64.HashToUInt64(MemoryMarshal.AsBytes(entryPoint.AsSpan())));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override readonly int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(code, entryPoint);
|
||||
}
|
||||
}
|
||||
|
||||
public struct KeywordsGroup
|
||||
@@ -53,7 +69,6 @@ public class GraphicsShaderDescriptor
|
||||
|
||||
public class ComputeShaderDescriptor
|
||||
{
|
||||
public required ulong identifier;
|
||||
public required string name = string.Empty;
|
||||
public required uint propertyBufferSize;
|
||||
public required ShaderModel shaderModel;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Misaki.HighPerformance.LowLevel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ghost.Core;
|
||||
|
||||
@@ -260,6 +261,64 @@ public readonly ref struct RefResult<T, E>
|
||||
public static implicit operator bool(RefResult<T, E> result) => result.IsSuccess;
|
||||
}
|
||||
|
||||
[AsyncMethodBuilder(typeof(AsyncValueTaskMethodBuilder))]
|
||||
public readonly struct ResultTask
|
||||
{
|
||||
private readonly ValueTask<Result> _task;
|
||||
|
||||
public ResultTask(ValueTask<Result> task)
|
||||
{
|
||||
_task = task;
|
||||
}
|
||||
|
||||
public ValueTaskAwaiter<Result> GetAwaiter() => _task.GetAwaiter();
|
||||
|
||||
public ValueTask<Result> AsValueTask() => _task;
|
||||
public Task<Result> AsTask() => _task.AsTask();
|
||||
|
||||
public static implicit operator ResultTask(ValueTask<Result> task) => new ResultTask(task);
|
||||
public static implicit operator ValueTask<Result>(ResultTask resultTask) => resultTask._task;
|
||||
}
|
||||
|
||||
[AsyncMethodBuilder(typeof(AsyncValueTaskMethodBuilder))]
|
||||
public readonly struct ResultTask<T>
|
||||
{
|
||||
private readonly ValueTask<Result<T>> _task;
|
||||
|
||||
public ResultTask(ValueTask<Result<T>> task)
|
||||
{
|
||||
_task = task;
|
||||
}
|
||||
|
||||
public ValueTaskAwaiter<Result<T>> GetAwaiter() => _task.GetAwaiter();
|
||||
|
||||
public ValueTask<Result<T>> AsValueTask() => _task;
|
||||
public Task<Result<T>> AsTask() => _task.AsTask();
|
||||
|
||||
public static implicit operator ResultTask<T>(ValueTask<Result<T>> task) => new ResultTask<T>(task);
|
||||
public static implicit operator ValueTask<Result<T>>(ResultTask<T> resultTask) => resultTask._task;
|
||||
}
|
||||
|
||||
[AsyncMethodBuilder(typeof(AsyncValueTaskMethodBuilder))]
|
||||
public readonly struct ResultTask<T, E>
|
||||
where E : struct, Enum
|
||||
{
|
||||
private readonly ValueTask<Result<T, E>> _task;
|
||||
|
||||
public ResultTask(ValueTask<Result<T, E>> task)
|
||||
{
|
||||
_task = task;
|
||||
}
|
||||
|
||||
public ValueTaskAwaiter<Result<T, E>> GetAwaiter() => _task.GetAwaiter();
|
||||
|
||||
public ValueTask<Result<T, E>> AsValueTask() => _task;
|
||||
public Task<Result<T, E>> AsTask() => _task.AsTask();
|
||||
|
||||
public static implicit operator ResultTask<T, E>(ValueTask<Result<T, E>> task) => new ResultTask<T, E>(task);
|
||||
public static implicit operator ValueTask<Result<T, E>>(ResultTask<T, E> resultTask) => resultTask._task;
|
||||
}
|
||||
|
||||
public static class ResultExtensions
|
||||
{
|
||||
extension(Error error)
|
||||
|
||||
46
src/Runtime/Ghost.Core/Utilities/NativeMemoryManager.cs
Normal file
46
src/Runtime/Ghost.Core/Utilities/NativeMemoryManager.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using Misaki.HighPerformance.LowLevel.Collections.Contracts;
|
||||
using System.Buffers;
|
||||
|
||||
namespace Ghost.Core.Utilities;
|
||||
|
||||
public unsafe class NativeMemoryManager<T> : MemoryManager<T>
|
||||
where T : unmanaged
|
||||
{
|
||||
private readonly T* _pointer;
|
||||
private readonly int _length;
|
||||
|
||||
public NativeMemoryManager(T* pointer, int length)
|
||||
{
|
||||
_pointer = pointer;
|
||||
_length = length;
|
||||
}
|
||||
|
||||
public static NativeMemoryManager<T> FromUnsafeCollection<C>(ref readonly C collection)
|
||||
where C : unmanaged, IUnsafeCollection<T>
|
||||
{
|
||||
if (!collection.IsCreated)
|
||||
{
|
||||
throw new InvalidOperationException("The collection is not created.");
|
||||
}
|
||||
|
||||
return new NativeMemoryManager<T>((T*)collection.GetUnsafePtr(), collection.Count);
|
||||
}
|
||||
|
||||
public override Span<T> GetSpan()
|
||||
{
|
||||
return new Span<T>(_pointer, _length);
|
||||
}
|
||||
|
||||
public override MemoryHandle Pin(int elementIndex = 0)
|
||||
{
|
||||
return new MemoryHandle(_pointer + elementIndex);
|
||||
}
|
||||
|
||||
public override void Unpin()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user