From cee712105850ac3385cd0091a923438167433f9f Mon Sep 17 00:00:00 2001
From: TSR Berry <20988865+TSRBerry@users.noreply.github.com>
Date: Sat, 8 Apr 2023 01:22:00 +0200
Subject: Move solution and projects to src
---
.../Shader/HashTable/HashState.cs | 113 +++++++++++++++++++++
1 file changed, 113 insertions(+)
create mode 100644 src/Ryujinx.Graphics.Gpu/Shader/HashTable/HashState.cs
(limited to 'src/Ryujinx.Graphics.Gpu/Shader/HashTable/HashState.cs')
diff --git a/src/Ryujinx.Graphics.Gpu/Shader/HashTable/HashState.cs b/src/Ryujinx.Graphics.Gpu/Shader/HashTable/HashState.cs
new file mode 100644
index 00000000..584eefdc
--- /dev/null
+++ b/src/Ryujinx.Graphics.Gpu/Shader/HashTable/HashState.cs
@@ -0,0 +1,113 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Graphics.Gpu.Shader.HashTable
+{
+ ///
+ /// State of a hash calculation.
+ ///
+ struct HashState
+ {
+ // This is using a slightly modified implementation of FastHash64.
+ // Reference: https://github.com/ztanml/fast-hash/blob/master/fasthash.c
+ private const ulong M = 0x880355f21e6d1965UL;
+ private ulong _hash;
+ private int _start;
+
+ ///
+ /// One shot hash calculation for a given data.
+ ///
+ /// Data to be hashed
+ /// Hash of the given data
+ public static uint CalcHash(ReadOnlySpan data)
+ {
+ HashState state = new HashState();
+
+ state.Initialize();
+ state.Continue(data);
+ return state.Finalize(data);
+ }
+
+ ///
+ /// Initializes the hash state.
+ ///
+ public void Initialize()
+ {
+ _hash = 23;
+ }
+
+ ///
+ /// Calculates the hash of the given data.
+ ///
+ ///
+ /// The full data must be passed on .
+ /// If this is not the first time the method is called, then must start with the data passed on the last call.
+ /// If a smaller slice of the data was already hashed before, only the additional data will be hashed.
+ /// This can be used for additive hashing of data in chuncks.
+ ///
+ /// Data to be hashed
+ public void Continue(ReadOnlySpan data)
+ {
+ ulong h = _hash;
+
+ ReadOnlySpan dataAsUlong = MemoryMarshal.Cast(data.Slice(_start));
+
+ for (int i = 0; i < dataAsUlong.Length; i++)
+ {
+ ulong value = dataAsUlong[i];
+
+ h ^= Mix(value);
+ h *= M;
+ }
+
+ _hash = h;
+ _start = data.Length & ~7;
+ }
+
+ ///
+ /// Performs the hash finalization step, and returns the calculated hash.
+ ///
+ ///
+ /// The full data must be passed on .
+ /// must start with the data passed on the last call to .
+ /// No internal state is changed, so one can still continue hashing data with
+ /// after calling this method.
+ ///
+ /// Data to be hashed
+ /// Hash of all the data hashed with this
+ public uint Finalize(ReadOnlySpan data)
+ {
+ ulong h = _hash;
+
+ int remainder = data.Length & 7;
+ if (remainder != 0)
+ {
+ ulong v = 0;
+
+ for (int i = data.Length - remainder; i < data.Length; i++)
+ {
+ v |= (ulong)data[i] << ((i - remainder) * 8);
+ }
+
+ h ^= Mix(v);
+ h *= M;
+ }
+
+ h = Mix(h);
+ return (uint)(h - (h >> 32));
+ }
+
+ ///
+ /// Hash mix function.
+ ///
+ /// Hash to mix
+ /// Mixed hash
+ private static ulong Mix(ulong h)
+ {
+ h ^= h >> 23;
+ h *= 0x2127599bf4325c37UL;
+ h ^= h >> 47;
+ return h;
+ }
+ }
+}
--
cgit v1.2.3