mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-07-29 14:17:11 +02:00

* dotnet format style --severity info Some changes were manually reverted. * dotnet format analyzers --serverity info Some changes have been minimally adapted. * Restore a few unused methods and variables * Silence dotnet format IDE0060 warnings * Silence dotnet format IDE0052 warnings * Address dotnet format CA1816 warnings * Address or silence dotnet format CA1069 warnings * Address or silence dotnet format CA2211 warnings * Address remaining dotnet format analyzer warnings * Address review comments * Address most dotnet format whitespace warnings * Apply dotnet format whitespace formatting A few of them have been manually reverted and the corresponding warning was silenced * Format if-blocks correctly * Run dotnet format whitespace after rebase * Run dotnet format style after rebase * Another rebase, another dotnet format run * Run dotnet format style after rebase * Run dotnet format after rebase and remove unused usings - analyzers - style - whitespace * Disable 'prefer switch expression' rule * Add comments to disabled warnings * Remove a few unused parameters * Replace MmeShadowScratch with Array256<uint> * Simplify properties and array initialization, Use const when possible, Remove trailing commas * Start working on disabled warnings * Fix and silence a few dotnet-format warnings again * Run dotnet format after rebase * Address IDE0251 warnings * Silence IDE0060 in .editorconfig * Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas" This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e. * dotnet format whitespace after rebase * First pass of dotnet format * Add unsafe dotnet format changes * Fix typos * Add trailing commas * Disable formatting for FormatTable * Address review feedback
96 lines
3.1 KiB
C#
96 lines
3.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Ryujinx.Graphics.Gpu.Shader.HashTable
|
|
{
|
|
/// <summary>
|
|
/// Smart data accessor that can cache data and hashes to avoid reading and re-hashing the same memory regions.
|
|
/// </summary>
|
|
ref struct SmartDataAccessor
|
|
{
|
|
private readonly IDataAccessor _dataAccessor;
|
|
private ReadOnlySpan<byte> _data;
|
|
private readonly SortedList<int, HashState> _cachedHashes;
|
|
|
|
/// <summary>
|
|
/// Creates a new smart data accessor.
|
|
/// </summary>
|
|
/// <param name="dataAccessor">Data accessor</param>
|
|
public SmartDataAccessor(IDataAccessor dataAccessor)
|
|
{
|
|
_dataAccessor = dataAccessor;
|
|
_data = ReadOnlySpan<byte>.Empty;
|
|
_cachedHashes = new SortedList<int, HashState>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a spans of a given size.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// The actual length of the span returned depends on the <see cref="IDataAccessor"/>
|
|
/// and might be less than requested.
|
|
/// </remarks>
|
|
/// <param name="length">Size in bytes</param>
|
|
/// <returns>Span with the requested size</returns>
|
|
public ReadOnlySpan<byte> GetSpan(int length)
|
|
{
|
|
if (_data.Length < length)
|
|
{
|
|
_data = _dataAccessor.GetSpan(0, length);
|
|
}
|
|
else if (_data.Length > length)
|
|
{
|
|
return _data[..length];
|
|
}
|
|
|
|
return _data;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a span of the requested size, and a hash of its data.
|
|
/// </summary>
|
|
/// <param name="length">Length of the span</param>
|
|
/// <param name="hash">Hash of the span data</param>
|
|
/// <returns>Span of data</returns>
|
|
public ReadOnlySpan<byte> GetSpanAndHash(int length, out uint hash)
|
|
{
|
|
ReadOnlySpan<byte> data = GetSpan(length);
|
|
hash = data.Length == length ? CalcHashCached(data) : 0;
|
|
return data;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calculates the hash for a requested span.
|
|
/// This will try to use a cached hash if the data was already accessed before, to avoid re-hashing.
|
|
/// </summary>
|
|
/// <param name="data">Data to be hashed</param>
|
|
/// <returns>Hash of the data</returns>
|
|
private readonly uint CalcHashCached(ReadOnlySpan<byte> data)
|
|
{
|
|
HashState state = default;
|
|
bool found = false;
|
|
|
|
for (int i = _cachedHashes.Count - 1; i >= 0; i--)
|
|
{
|
|
int cachedHashSize = _cachedHashes.Keys[i];
|
|
|
|
if (cachedHashSize < data.Length)
|
|
{
|
|
state = _cachedHashes.Values[i];
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
{
|
|
state = new HashState();
|
|
state.Initialize();
|
|
}
|
|
|
|
state.Continue(data);
|
|
_cachedHashes[data.Length & ~7] = state;
|
|
return state.Finalize(data);
|
|
}
|
|
}
|
|
}
|