Files
GhostEngine/Ghost.Shader.Concept/RenderState.cs
Misaki f988c34b3d Add high-performance material/shader system (Ghost.Shader.Concept)
Introduces a new Ghost.Shader.Concept project implementing a modern, data-oriented material and shader system with:
- Global/local keyword bitsets (fast O(1) ops, 64 bytes)
- Multi-pass shader program and per-pass render state overrides
- Thread-safe, 16-byte aligned material property blocks
- Material pooling to reduce GC pressure
- Batch renderer for efficient PSO grouping and async variant warmup
- Full demo (Program.cs) and extensive documentation (ARCHITECTURE.md, README.md, PROJECT_SUMMARY.md)
- Minor integration: new enums, doc updates, and keyword handling in existing code

No breaking changes to the existing engine; all new code is isolated. This serves as a reference implementation for high-performance, extensible material/shader architectures.
2025-12-26 19:19:30 +09:00

127 lines
4.2 KiB
C#

using System.Runtime.InteropServices;
namespace Ghost.Shader.Concept;
/// <summary>
/// Render state configuration for pipeline creation.
/// Immutable and hashable for PSO caching.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct RenderState : IEquatable<RenderState>
{
// Rasterizer State
public CullMode CullMode;
public FillMode FillMode;
public bool FrontCounterClockwise;
public float DepthBias;
public float SlopeScaledDepthBias;
// Depth-Stencil State
public bool DepthTestEnable;
public bool DepthWriteEnable;
public CompareFunction DepthCompareFunc;
public bool StencilEnable;
public byte StencilReadMask;
public byte StencilWriteMask;
// Blend State (per RT, simplified to single RT here)
public bool BlendEnable;
public BlendFactor SrcBlend;
public BlendFactor DestBlend;
public BlendOperation BlendOp;
public BlendFactor SrcBlendAlpha;
public BlendFactor DestBlendAlpha;
public BlendOperation BlendOpAlpha;
public ColorWriteMask ColorWriteMask;
// Topology
public PrimitiveTopology Topology;
public static RenderState Default => new()
{
CullMode = CullMode.Back,
FillMode = FillMode.Solid,
FrontCounterClockwise = false,
DepthTestEnable = true,
DepthWriteEnable = true,
DepthCompareFunc = CompareFunction.LessEqual,
StencilEnable = false,
StencilReadMask = 0xFF,
StencilWriteMask = 0xFF,
BlendEnable = false,
SrcBlend = BlendFactor.One,
DestBlend = BlendFactor.Zero,
BlendOp = BlendOperation.Add,
SrcBlendAlpha = BlendFactor.One,
DestBlendAlpha = BlendFactor.Zero,
BlendOpAlpha = BlendOperation.Add,
ColorWriteMask = ColorWriteMask.All,
Topology = PrimitiveTopology.TriangleList
};
public unsafe ulong ComputeHash()
{
fixed (RenderState* ptr = &this)
{
return ComputeHash64((byte*)ptr, sizeof(RenderState));
}
}
private static unsafe ulong ComputeHash64(byte* data, int length)
{
ulong hash = 0xcbf29ce484222325;
const ulong prime = 0x100000001b3;
for (int i = 0; i < length; i++)
{
hash ^= data[i];
hash *= prime;
}
return hash;
}
public bool Equals(RenderState other)
{
return CullMode == other.CullMode &&
FillMode == other.FillMode &&
FrontCounterClockwise == other.FrontCounterClockwise &&
DepthBias == other.DepthBias &&
SlopeScaledDepthBias == other.SlopeScaledDepthBias &&
DepthTestEnable == other.DepthTestEnable &&
DepthWriteEnable == other.DepthWriteEnable &&
DepthCompareFunc == other.DepthCompareFunc &&
StencilEnable == other.StencilEnable &&
StencilReadMask == other.StencilReadMask &&
StencilWriteMask == other.StencilWriteMask &&
BlendEnable == other.BlendEnable &&
SrcBlend == other.SrcBlend &&
DestBlend == other.DestBlend &&
BlendOp == other.BlendOp &&
SrcBlendAlpha == other.SrcBlendAlpha &&
DestBlendAlpha == other.DestBlendAlpha &&
BlendOpAlpha == other.BlendOpAlpha &&
ColorWriteMask == other.ColorWriteMask &&
Topology == other.Topology;
}
public override bool Equals(object? obj) => obj is RenderState other && Equals(other);
public override int GetHashCode() => (int)ComputeHash();
}
public enum CullMode : byte { None, Front, Back }
public enum FillMode : byte { Wireframe, Solid }
public enum CompareFunction : byte { Never, Less, Equal, LessEqual, Greater, NotEqual, GreaterEqual, Always }
public enum BlendFactor : byte { Zero, One, SrcColor, InvSrcColor, SrcAlpha, InvSrcAlpha, DestAlpha, InvDestAlpha, DestColor, InvDestColor }
public enum BlendOperation : byte { Add, Subtract, ReverseSubtract, Min, Max }
public enum PrimitiveTopology : byte { PointList, LineList, LineStrip, TriangleList, TriangleStrip }
[Flags]
public enum ColorWriteMask : byte
{
None = 0,
Red = 1,
Green = 2,
Blue = 4,
Alpha = 8,
All = Red | Green | Blue | Alpha
}