SpecInfo.cs 2.9 KB

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