namespace Ghost.Graphics.Data; internal readonly struct TextureInfo { public required string Name { get; init; } public uint RegisterSlot { get; init; } public uint RootParameterIndex { get; init; } } internal readonly struct PropertyInfo { public required string Name { get; init; } public uint CBufferIndex { get; init; } public uint ByteOffset { get; init; } public uint Size { get; init; } } internal readonly struct CBufferInfo { public required string Name { get; init; } public uint Size { get; init; } public uint RegisterSlot { get; init; } } /// /// Bindless shader implementation using SM 6.6 with ResourceDescriptorHeap /// and D3D12_ROOT_SIGNATURE_FLAG_CBV_SRV_UAV_HEAP_DIRECTLY_INDEXED /// Enhanced to support both bindless and regular texture binding for hybrid materials /// public unsafe class Shader : IDisposable { private readonly string _source; private readonly List _constantBuffers = new(); private readonly List _properties = new(); private readonly List _regularTextures = new(); // Add regular texture support private readonly Dictionary _propertyNameToIdMap = new(); private bool _disposed; internal string Source => _source; internal List ConstantBuffers => _constantBuffers; internal List Properties => _properties; internal List RegularTextures => _regularTextures; internal Dictionary PropertyNameToIdMap => _propertyNameToIdMap; internal Shader(string shaderCode) { _source = shaderCode; } /// /// Gets a unique, stable ID for a shader property. /// /// The name of the property (e.g., "_Color"). /// The integer ID of the property, or -1 if not found. public int GetPropertyId(string propertyName) { return _propertyNameToIdMap.TryGetValue(propertyName, out var id) ? id : -1; } public void Dispose() { if (_disposed) { return; } _constantBuffers.Clear(); _properties.Clear(); _propertyNameToIdMap.Clear(); _regularTextures.Clear(); GC.SuppressFinalize(this); _disposed = true; } }