Optimize I/O of ShPk for ResourceTree generation

This commit is contained in:
Exter-N 2024-08-03 17:46:29 +02:00
parent 5323add662
commit c01aa000fb
2 changed files with 17 additions and 8 deletions

View file

@ -230,8 +230,8 @@ internal unsafe partial record ResolveContext(
node.Children.Add(shpkNode);
}
var shpkFile = Global.WithUiData && shpkNode != null ? Global.TreeBuildCache.ReadShaderPackage(shpkNode.FullPath) : null;
var shpk = Global.WithUiData && shpkNode != null ? (ShaderPackage*)shpkNode.ObjectAddress : null;
var shpkNames = Global.WithUiData && shpkNode != null ? Global.TreeBuildCache.ReadShaderPackageNames(shpkNode.FullPath) : null;
var shpk = Global.WithUiData && shpkNode != null ? (ShaderPackage*)shpkNode.ObjectAddress : null;
var alreadyProcessedSamplerIds = new HashSet<uint>();
for (var i = 0; i < resource->TextureCount; i++)
@ -255,7 +255,12 @@ internal unsafe partial record ResolveContext(
alreadyProcessedSamplerIds.Add(samplerId.Value);
var samplerCrc = GetSamplerCrcById(shpk, samplerId.Value);
if (samplerCrc.HasValue)
name = shpkFile?.GetSamplerById(samplerCrc.Value)?.Name ?? $"Texture 0x{samplerCrc.Value:X8}";
{
if (shpkNames != null && shpkNames.TryGetValue(samplerCrc.Value, out var samplerName))
name = samplerName.Value;
else
name = $"Texture 0x{samplerCrc.Value:X8}";
}
}
}

View file

@ -1,8 +1,11 @@
using System.IO.MemoryMappedFiles;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Plugin.Services;
using Penumbra.GameData.Actors;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Files;
using Penumbra.GameData.Files.ShaderStructs;
using Penumbra.GameData.Files.Utility;
using Penumbra.GameData.Interop;
using Penumbra.GameData.Structs;
using Penumbra.String.Classes;
@ -11,7 +14,7 @@ namespace Penumbra.Interop.ResourceTree;
internal readonly struct TreeBuildCache(ObjectManager objects, IDataManager dataManager, ActorManager actors)
{
private readonly Dictionary<FullPath, ShpkFile?> _shaderPackages = [];
private readonly Dictionary<FullPath, IReadOnlyDictionary<uint, Name>?> _shaderPackageNames = [];
public unsafe bool IsLocalPlayerRelated(ICharacter character)
{
@ -68,10 +71,10 @@ internal readonly struct TreeBuildCache(ObjectManager objects, IDataManager data
}
/// <summary> Try to read a shpk file from the given path and cache it on success. </summary>
public ShpkFile? ReadShaderPackage(FullPath path)
=> ReadFile(dataManager, path, _shaderPackages, bytes => new ShpkFile(bytes));
public IReadOnlyDictionary<uint, Name>? ReadShaderPackageNames(FullPath path)
=> ReadFile(dataManager, path, _shaderPackageNames, bytes => ShpkFile.FastExtractNames(bytes.Span));
private static T? ReadFile<T>(IDataManager dataManager, FullPath path, Dictionary<FullPath, T?> cache, Func<byte[], T> parseFile)
private static T? ReadFile<T>(IDataManager dataManager, FullPath path, Dictionary<FullPath, T?> cache, Func<ReadOnlyMemory<byte>, T> parseFile)
where T : class
{
if (path.FullName.Length == 0)
@ -86,7 +89,8 @@ internal readonly struct TreeBuildCache(ObjectManager objects, IDataManager data
{
if (path.IsRooted)
{
parsed = parseFile(File.ReadAllBytes(pathStr));
using var mmFile = MmioMemoryManager.CreateFromFile(pathStr, access: MemoryMappedFileAccess.Read);
parsed = parseFile(mmFile.Memory);
}
else
{