SpecInfo.cs 2.8 KB

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