SpecInfo.cs
1 using Silk.NET.Vulkan; 2 using System; 3 4 namespace Ryujinx.Graphics.Vulkan 5 { 6 public enum SpecConstType 7 { 8 Bool32, 9 Int16, 10 Int32, 11 Int64, 12 Float16, 13 Float32, 14 Float64, 15 } 16 17 sealed class SpecDescription 18 { 19 public readonly SpecializationInfo Info; 20 public readonly SpecializationMapEntry[] Map; 21 22 // For mapping a simple packed struct or single entry 23 public SpecDescription(params (uint Id, SpecConstType Type)[] description) 24 { 25 int count = description.Length; 26 Map = new SpecializationMapEntry[count]; 27 28 uint structSize = 0; 29 30 for (int i = 0; i < Map.Length; ++i) 31 { 32 var typeSize = SizeOf(description[i].Type); 33 Map[i] = new SpecializationMapEntry(description[i].Id, structSize, typeSize); 34 structSize += typeSize; 35 } 36 37 Info = new SpecializationInfo 38 { 39 DataSize = structSize, 40 MapEntryCount = (uint)count, 41 }; 42 } 43 44 // For advanced mapping with overlapping or staggered fields 45 public SpecDescription(SpecializationMapEntry[] map) 46 { 47 Map = map; 48 49 uint structSize = 0; 50 for (int i = 0; i < map.Length; ++i) 51 { 52 structSize = Math.Max(structSize, map[i].Offset + (uint)map[i].Size); 53 } 54 55 Info = new SpecializationInfo 56 { 57 DataSize = structSize, 58 MapEntryCount = (uint)map.Length, 59 }; 60 } 61 62 private static uint SizeOf(SpecConstType type) => type switch 63 { 64 SpecConstType.Int16 or SpecConstType.Float16 => 2, 65 SpecConstType.Bool32 or SpecConstType.Int32 or SpecConstType.Float32 => 4, 66 SpecConstType.Int64 or SpecConstType.Float64 => 8, 67 _ => throw new ArgumentOutOfRangeException(nameof(type)), 68 }; 69 70 private SpecDescription() 71 { 72 Info = new(); 73 } 74 75 public static readonly SpecDescription Empty = new(); 76 } 77 78 readonly struct SpecData : IRefEquatable<SpecData> 79 { 80 private readonly byte[] _data; 81 private readonly int _hash; 82 83 public int Length => _data.Length; 84 public ReadOnlySpan<byte> Span => _data.AsSpan(); 85 public override int GetHashCode() => _hash; 86 87 public SpecData(ReadOnlySpan<byte> data) 88 { 89 _data = new byte[data.Length]; 90 data.CopyTo(_data); 91 92 var hc = new HashCode(); 93 hc.AddBytes(data); 94 _hash = hc.ToHashCode(); 95 } 96 97 public override bool Equals(object obj) => obj is SpecData other && Equals(other); 98 public bool Equals(ref SpecData other) => _data.AsSpan().SequenceEqual(other._data); 99 } 100 }