PipelineUid.cs
1 using Ryujinx.Common.Memory; 2 using Silk.NET.Vulkan; 3 using System; 4 using System.Runtime.CompilerServices; 5 using System.Runtime.InteropServices; 6 using System.Runtime.Intrinsics; 7 8 namespace Ryujinx.Graphics.Vulkan 9 { 10 struct PipelineUid : IRefEquatable<PipelineUid> 11 { 12 public ulong Id0; 13 public ulong Id1; 14 public ulong Id2; 15 public ulong Id3; 16 17 public ulong Id4; 18 public ulong Id5; 19 public ulong Id6; 20 21 public ulong Id7; 22 public ulong Id8; 23 24 private readonly uint VertexAttributeDescriptionsCount => (byte)((Id5 >> 38) & 0xFF); 25 private readonly uint VertexBindingDescriptionsCount => (byte)((Id5 >> 46) & 0xFF); 26 private readonly uint ColorBlendAttachmentStateCount => (byte)((Id6 >> 8) & 0xFF); 27 private readonly bool HasDepthStencil => ((Id6 >> 63) & 0x1) != 0UL; 28 29 public Array32<VertexInputAttributeDescription> VertexAttributeDescriptions; 30 public Array33<VertexInputBindingDescription> VertexBindingDescriptions; 31 public Array8<PipelineColorBlendAttachmentState> ColorBlendAttachmentState; 32 public Array9<Format> AttachmentFormats; 33 public uint AttachmentIntegerFormatMask; 34 public bool LogicOpsAllowed; 35 36 public readonly override bool Equals(object obj) 37 { 38 return obj is PipelineUid other && Equals(other); 39 } 40 41 public bool Equals(ref PipelineUid other) 42 { 43 if (!Unsafe.As<ulong, Vector256<byte>>(ref Id0).Equals(Unsafe.As<ulong, Vector256<byte>>(ref other.Id0)) || 44 !Unsafe.As<ulong, Vector256<byte>>(ref Id4).Equals(Unsafe.As<ulong, Vector256<byte>>(ref other.Id4)) || 45 !Unsafe.As<ulong, Vector128<byte>>(ref Id7).Equals(Unsafe.As<ulong, Vector128<byte>>(ref other.Id7))) 46 { 47 return false; 48 } 49 50 if (!SequenceEqual<VertexInputAttributeDescription>(VertexAttributeDescriptions.AsSpan(), other.VertexAttributeDescriptions.AsSpan(), VertexAttributeDescriptionsCount)) 51 { 52 return false; 53 } 54 55 if (!SequenceEqual<VertexInputBindingDescription>(VertexBindingDescriptions.AsSpan(), other.VertexBindingDescriptions.AsSpan(), VertexBindingDescriptionsCount)) 56 { 57 return false; 58 } 59 60 if (!SequenceEqual<PipelineColorBlendAttachmentState>(ColorBlendAttachmentState.AsSpan(), other.ColorBlendAttachmentState.AsSpan(), ColorBlendAttachmentStateCount)) 61 { 62 return false; 63 } 64 65 if (!SequenceEqual<Format>(AttachmentFormats.AsSpan(), other.AttachmentFormats.AsSpan(), ColorBlendAttachmentStateCount + (HasDepthStencil ? 1u : 0u))) 66 { 67 return false; 68 } 69 70 return true; 71 } 72 73 private static bool SequenceEqual<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, uint count) where T : unmanaged 74 { 75 return MemoryMarshal.Cast<T, byte>(x[..(int)count]).SequenceEqual(MemoryMarshal.Cast<T, byte>(y[..(int)count])); 76 } 77 78 public override int GetHashCode() 79 { 80 ulong hash64 = Id0 * 23 ^ 81 Id1 * 23 ^ 82 Id2 * 23 ^ 83 Id3 * 23 ^ 84 Id4 * 23 ^ 85 Id5 * 23 ^ 86 Id6 * 23 ^ 87 Id7 * 23 ^ 88 Id8 * 23; 89 90 for (int i = 0; i < (int)VertexAttributeDescriptionsCount; i++) 91 { 92 hash64 ^= VertexAttributeDescriptions[i].Binding * 23; 93 hash64 ^= (uint)VertexAttributeDescriptions[i].Format * 23; 94 hash64 ^= VertexAttributeDescriptions[i].Location * 23; 95 hash64 ^= VertexAttributeDescriptions[i].Offset * 23; 96 } 97 98 for (int i = 0; i < (int)VertexBindingDescriptionsCount; i++) 99 { 100 hash64 ^= VertexBindingDescriptions[i].Binding * 23; 101 hash64 ^= (uint)VertexBindingDescriptions[i].InputRate * 23; 102 hash64 ^= VertexBindingDescriptions[i].Stride * 23; 103 } 104 105 for (int i = 0; i < (int)ColorBlendAttachmentStateCount; i++) 106 { 107 hash64 ^= ColorBlendAttachmentState[i].BlendEnable * 23; 108 hash64 ^= (uint)ColorBlendAttachmentState[i].SrcColorBlendFactor * 23; 109 hash64 ^= (uint)ColorBlendAttachmentState[i].DstColorBlendFactor * 23; 110 hash64 ^= (uint)ColorBlendAttachmentState[i].ColorBlendOp * 23; 111 hash64 ^= (uint)ColorBlendAttachmentState[i].SrcAlphaBlendFactor * 23; 112 hash64 ^= (uint)ColorBlendAttachmentState[i].DstAlphaBlendFactor * 23; 113 hash64 ^= (uint)ColorBlendAttachmentState[i].AlphaBlendOp * 23; 114 hash64 ^= (uint)ColorBlendAttachmentState[i].ColorWriteMask * 23; 115 } 116 117 for (int i = 0; i < (int)ColorBlendAttachmentStateCount; i++) 118 { 119 hash64 ^= (uint)AttachmentFormats[i] * 23; 120 } 121 122 return (int)hash64 ^ ((int)(hash64 >> 32) * 17); 123 } 124 } 125 }