using System.Runtime.InteropServices; namespace Ghost.Shader.Concept; /// /// Unique identifier for a shader variant based on keyword combination. /// Used as key for shader compilation cache. /// [StructLayout(LayoutKind.Sequential)] public readonly struct ShaderVariantKey : IEquatable { public readonly int ShaderProgramId; public readonly ulong KeywordHash; public ShaderVariantKey(int shaderProgramId, ulong keywordHash) { ShaderProgramId = shaderProgramId; KeywordHash = keywordHash; } public bool Equals(ShaderVariantKey other) => ShaderProgramId == other.ShaderProgramId && KeywordHash == other.KeywordHash; public override bool Equals(object? obj) => obj is ShaderVariantKey other && Equals(other); public override int GetHashCode() => HashCode.Combine(ShaderProgramId, KeywordHash); } /// /// Unique identifier for a graphics pipeline state object. /// Combines shader variant, render state, and pass information. /// [StructLayout(LayoutKind.Sequential)] public readonly struct GraphicsPipelineKey : IEquatable { public readonly ShaderVariantKey VariantKey; public readonly ulong RenderStateHash; public readonly int PassId; public GraphicsPipelineKey(ShaderVariantKey variantKey, ulong renderStateHash, int passId) { VariantKey = variantKey; RenderStateHash = renderStateHash; PassId = passId; } public bool Equals(GraphicsPipelineKey other) => VariantKey.Equals(other.VariantKey) && RenderStateHash == other.RenderStateHash && PassId == other.PassId; public override bool Equals(object? obj) => obj is GraphicsPipelineKey other && Equals(other); public override int GetHashCode() => HashCode.Combine(VariantKey, RenderStateHash, PassId); } /// /// Mock interface for shader compiler (assumed to exist) /// public interface IShaderCompiler { /// Compiles a shader variant for the given keyword set IntPtr CompileVariant(ShaderVariantKey key, in KeywordSet keywords); } /// /// Mock interface for pipeline library (assumed to exist) /// public interface IPipelineLibrary { /// Gets or creates a PSO for the given pipeline key IntPtr GetOrCreatePipeline(in GraphicsPipelineKey key); }