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);
}