aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
diff options
context:
space:
mode:
authorTSR Berry <20988865+TSRBerry@users.noreply.github.com>2023-04-08 01:22:00 +0200
committerMary <thog@protonmail.com>2023-04-27 23:51:14 +0200
commitcee712105850ac3385cd0091a923438167433f9f (patch)
tree4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
parentcd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff)
Move solution and projects to src
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs')
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs839
1 files changed, 0 insertions, 839 deletions
diff --git a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
deleted file mode 100644
index b182f299..00000000
--- a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
+++ /dev/null
@@ -1,839 +0,0 @@
-using Ryujinx.Graphics.GAL;
-using Ryujinx.Graphics.Shader;
-using Ryujinx.Graphics.Shader.Translation;
-using System;
-using System.IO;
-using System.Numerics;
-using System.Runtime.CompilerServices;
-
-namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
-{
- /// <summary>
- /// On-disk shader cache storage for host code.
- /// </summary>
- class DiskCacheHostStorage
- {
- private const uint TocsMagic = (byte)'T' | ((byte)'O' << 8) | ((byte)'C' << 16) | ((byte)'S' << 24);
- private const uint TochMagic = (byte)'T' | ((byte)'O' << 8) | ((byte)'C' << 16) | ((byte)'H' << 24);
- private const uint ShdiMagic = (byte)'S' | ((byte)'H' << 8) | ((byte)'D' << 16) | ((byte)'I' << 24);
- private const uint BufdMagic = (byte)'B' | ((byte)'U' << 8) | ((byte)'F' << 16) | ((byte)'D' << 24);
- private const uint TexdMagic = (byte)'T' | ((byte)'E' << 8) | ((byte)'X' << 16) | ((byte)'D' << 24);
-
- private const ushort FileFormatVersionMajor = 1;
- private const ushort FileFormatVersionMinor = 2;
- private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
- private const uint CodeGenVersion = 4735;
-
- private const string SharedTocFileName = "shared.toc";
- private const string SharedDataFileName = "shared.data";
-
- private readonly string _basePath;
-
- public bool CacheEnabled => !string.IsNullOrEmpty(_basePath);
-
- /// <summary>
- /// TOC (Table of contents) file header.
- /// </summary>
- private struct TocHeader
- {
- /// <summary>
- /// Magic value, for validation and identification.
- /// </summary>
- public uint Magic;
-
- /// <summary>
- /// File format version.
- /// </summary>
- public uint FormatVersion;
-
- /// <summary>
- /// Generated shader code version.
- /// </summary>
- public uint CodeGenVersion;
-
- /// <summary>
- /// Header padding.
- /// </summary>
- public uint Padding;
-
- /// <summary>
- /// Timestamp of when the file was first created.
- /// </summary>
- public ulong Timestamp;
-
- /// <summary>
- /// Reserved space, to be used in the future. Write as zero.
- /// </summary>
- public ulong Reserved;
- }
-
- /// <summary>
- /// Offset and size pair.
- /// </summary>
- private struct OffsetAndSize
- {
- /// <summary>
- /// Offset.
- /// </summary>
- public ulong Offset;
-
- /// <summary>
- /// Size of uncompressed data.
- /// </summary>
- public uint UncompressedSize;
-
- /// <summary>
- /// Size of compressed data.
- /// </summary>
- public uint CompressedSize;
- }
-
- /// <summary>
- /// Per-stage data entry.
- /// </summary>
- private struct DataEntryPerStage
- {
- /// <summary>
- /// Index of the guest code on the guest code cache TOC file.
- /// </summary>
- public int GuestCodeIndex;
- }
-
- /// <summary>
- /// Per-program data entry.
- /// </summary>
- private struct DataEntry
- {
- /// <summary>
- /// Bit mask where each bit set is a used shader stage. Should be zero for compute shaders.
- /// </summary>
- public uint StagesBitMask;
- }
-
- /// <summary>
- /// Per-stage shader information, returned by the translator.
- /// </summary>
- private struct DataShaderInfo
- {
- /// <summary>
- /// Total constant buffers used.
- /// </summary>
- public ushort CBuffersCount;
-
- /// <summary>
- /// Total storage buffers used.
- /// </summary>
- public ushort SBuffersCount;
-
- /// <summary>
- /// Total textures used.
- /// </summary>
- public ushort TexturesCount;
-
- /// <summary>
- /// Total images used.
- /// </summary>
- public ushort ImagesCount;
-
- /// <summary>
- /// Shader stage.
- /// </summary>
- public ShaderStage Stage;
-
- /// <summary>
- /// Indicates if the shader accesses the Instance ID built-in variable.
- /// </summary>
- public bool UsesInstanceId;
-
- /// <summary>
- /// Indicates if the shader modifies the Layer built-in variable.
- /// </summary>
- public bool UsesRtLayer;
-
- /// <summary>
- /// Bit mask with the clip distances written on the vertex stage.
- /// </summary>
- public byte ClipDistancesWritten;
-
- /// <summary>
- /// Bit mask of the render target components written by the fragment stage.
- /// </summary>
- public int FragmentOutputMap;
-
- /// <summary>
- /// Indicates if the vertex shader accesses draw parameters.
- /// </summary>
- public bool UsesDrawParameters;
- }
-
- private readonly DiskCacheGuestStorage _guestStorage;
-
- /// <summary>
- /// Creates a disk cache host storage.
- /// </summary>
- /// <param name="basePath">Base path of the shader cache</param>
- public DiskCacheHostStorage(string basePath)
- {
- _basePath = basePath;
- _guestStorage = new DiskCacheGuestStorage(basePath);
-
- if (CacheEnabled)
- {
- Directory.CreateDirectory(basePath);
- }
- }
-
- /// <summary>
- /// Gets the total of host programs on the cache.
- /// </summary>
- /// <returns>Host programs count</returns>
- public int GetProgramCount()
- {
- string tocFilePath = Path.Combine(_basePath, SharedTocFileName);
-
- if (!File.Exists(tocFilePath))
- {
- return 0;
- }
-
- return Math.Max((int)((new FileInfo(tocFilePath).Length - Unsafe.SizeOf<TocHeader>()) / sizeof(ulong)), 0);
- }
-
- /// <summary>
- /// Guest the name of the host program cache file, with extension.
- /// </summary>
- /// <param name="context">GPU context</param>
- /// <returns>Name of the file, without extension</returns>
- private static string GetHostFileName(GpuContext context)
- {
- string apiName = context.Capabilities.Api.ToString().ToLowerInvariant();
- string vendorName = RemoveInvalidCharacters(context.Capabilities.VendorName.ToLowerInvariant());
- return $"{apiName}_{vendorName}";
- }
-
- /// <summary>
- /// Removes invalid path characters and spaces from a file name.
- /// </summary>
- /// <param name="fileName">File name</param>
- /// <returns>Filtered file name</returns>
- private static string RemoveInvalidCharacters(string fileName)
- {
- int indexOfSpace = fileName.IndexOf(' ');
- if (indexOfSpace >= 0)
- {
- fileName = fileName.Substring(0, indexOfSpace);
- }
-
- return string.Concat(fileName.Split(Path.GetInvalidFileNameChars(), StringSplitOptions.RemoveEmptyEntries));
- }
-
- /// <summary>
- /// Gets the name of the TOC host file.
- /// </summary>
- /// <param name="context">GPU context</param>
- /// <returns>File name</returns>
- private static string GetHostTocFileName(GpuContext context)
- {
- return GetHostFileName(context) + ".toc";
- }
-
- /// <summary>
- /// Gets the name of the data host file.
- /// </summary>
- /// <param name="context">GPU context</param>
- /// <returns>File name</returns>
- private static string GetHostDataFileName(GpuContext context)
- {
- return GetHostFileName(context) + ".data";
- }
-
- /// <summary>
- /// Checks if a disk cache exists for the current application.
- /// </summary>
- /// <returns>True if a disk cache exists, false otherwise</returns>
- public bool CacheExists()
- {
- string tocFilePath = Path.Combine(_basePath, SharedTocFileName);
- string dataFilePath = Path.Combine(_basePath, SharedDataFileName);
-
- if (!File.Exists(tocFilePath) || !File.Exists(dataFilePath) || !_guestStorage.TocFileExists() || !_guestStorage.DataFileExists())
- {
- return false;
- }
-
- return true;
- }
-
- /// <summary>
- /// Loads all shaders from the cache.
- /// </summary>
- /// <param name="context">GPU context</param>
- /// <param name="loader">Parallel disk cache loader</param>
- public void LoadShaders(GpuContext context, ParallelDiskCacheLoader loader)
- {
- if (!CacheExists())
- {
- return;
- }
-
- Stream hostTocFileStream = null;
- Stream hostDataFileStream = null;
-
- try
- {
- using var tocFileStream = DiskCacheCommon.OpenFile(_basePath, SharedTocFileName, writable: false);
- using var dataFileStream = DiskCacheCommon.OpenFile(_basePath, SharedDataFileName, writable: false);
-
- using var guestTocFileStream = _guestStorage.OpenTocFileStream();
- using var guestDataFileStream = _guestStorage.OpenDataFileStream();
-
- BinarySerializer tocReader = new BinarySerializer(tocFileStream);
- BinarySerializer dataReader = new BinarySerializer(dataFileStream);
-
- TocHeader header = new TocHeader();
-
- if (!tocReader.TryRead(ref header) || header.Magic != TocsMagic)
- {
- throw new DiskCacheLoadException(DiskCacheLoadResult.FileCorruptedGeneric);
- }
-
- if (header.FormatVersion != FileFormatVersionPacked)
- {
- throw new DiskCacheLoadException(DiskCacheLoadResult.IncompatibleVersion);
- }
-
- bool loadHostCache = header.CodeGenVersion == CodeGenVersion;
-
- int programIndex = 0;
-
- DataEntry entry = new DataEntry();
-
- while (tocFileStream.Position < tocFileStream.Length && loader.Active)
- {
- ulong dataOffset = 0;
- tocReader.Read(ref dataOffset);
-
- if ((ulong)dataOffset >= (ulong)dataFileStream.Length)
- {
- throw new DiskCacheLoadException(DiskCacheLoadResult.FileCorruptedGeneric);
- }
-
- dataFileStream.Seek((long)dataOffset, SeekOrigin.Begin);
-
- dataReader.BeginCompression();
- dataReader.Read(ref entry);
- uint stagesBitMask = entry.StagesBitMask;
-
- if ((stagesBitMask & ~0x3fu) != 0)
- {
- throw new DiskCacheLoadException(DiskCacheLoadResult.FileCorruptedGeneric);
- }
-
- bool isCompute = stagesBitMask == 0;
- if (isCompute)
- {
- stagesBitMask = 1;
- }
-
- GuestCodeAndCbData?[] guestShaders = new GuestCodeAndCbData?[isCompute ? 1 : Constants.ShaderStages + 1];
-
- DataEntryPerStage stageEntry = new DataEntryPerStage();
-
- while (stagesBitMask != 0)
- {
- int stageIndex = BitOperations.TrailingZeroCount(stagesBitMask);
-
- dataReader.Read(ref stageEntry);
-
- guestShaders[stageIndex] = _guestStorage.LoadShader(
- guestTocFileStream,
- guestDataFileStream,
- stageEntry.GuestCodeIndex);
-
- stagesBitMask &= ~(1u << stageIndex);
- }
-
- ShaderSpecializationState specState = ShaderSpecializationState.Read(ref dataReader);
- dataReader.EndCompression();
-
- if (loadHostCache)
- {
- (byte[] hostCode, CachedShaderStage[] shaders) = ReadHostCode(
- context,
- ref hostTocFileStream,
- ref hostDataFileStream,
- guestShaders,
- programIndex,
- header.Timestamp);
-
- if (hostCode != null)
- {
- bool hasFragmentShader = shaders.Length > 5 && shaders[5] != null;
- int fragmentOutputMap = hasFragmentShader ? shaders[5].Info.FragmentOutputMap : -1;
-
- ShaderInfo shaderInfo = specState.PipelineState.HasValue
- ? new ShaderInfo(fragmentOutputMap, specState.PipelineState.Value, fromCache: true)
- : new ShaderInfo(fragmentOutputMap, fromCache: true);
-
- IProgram hostProgram;
-
- if (context.Capabilities.Api == TargetApi.Vulkan)
- {
- ShaderSource[] shaderSources = ShaderBinarySerializer.Unpack(shaders, hostCode);
-
- hostProgram = context.Renderer.CreateProgram(shaderSources, shaderInfo);
- }
- else
- {
- hostProgram = context.Renderer.LoadProgramBinary(hostCode, hasFragmentShader, shaderInfo);
- }
-
- CachedShaderProgram program = new CachedShaderProgram(hostProgram, specState, shaders);
-
- loader.QueueHostProgram(program, hostCode, programIndex, isCompute);
- }
- else
- {
- loadHostCache = false;
- }
- }
-
- if (!loadHostCache)
- {
- loader.QueueGuestProgram(guestShaders, specState, programIndex, isCompute);
- }
-
- loader.CheckCompilation();
- programIndex++;
- }
- }
- finally
- {
- _guestStorage.ClearMemoryCache();
-
- hostTocFileStream?.Dispose();
- hostDataFileStream?.Dispose();
- }
- }
-
- /// <summary>
- /// Reads the host code for a given shader, if existent.
- /// </summary>
- /// <param name="context">GPU context</param>
- /// <param name="tocFileStream">Host TOC file stream, intialized if needed</param>
- /// <param name="dataFileStream">Host data file stream, initialized if needed</param>
- /// <param name="guestShaders">Guest shader code for each active stage</param>
- /// <param name="programIndex">Index of the program on the cache</param>
- /// <param name="expectedTimestamp">Timestamp of the shared cache file. The host file must be newer than it</param>
- /// <returns>Host binary code, or null if not found</returns>
- private (byte[], CachedShaderStage[]) ReadHostCode(
- GpuContext context,
- ref Stream tocFileStream,
- ref Stream dataFileStream,
- GuestCodeAndCbData?[] guestShaders,
- int programIndex,
- ulong expectedTimestamp)
- {
- if (tocFileStream == null && dataFileStream == null)
- {
- string tocFilePath = Path.Combine(_basePath, GetHostTocFileName(context));
- string dataFilePath = Path.Combine(_basePath, GetHostDataFileName(context));
-
- if (!File.Exists(tocFilePath) || !File.Exists(dataFilePath))
- {
- return (null, null);
- }
-
- tocFileStream = DiskCacheCommon.OpenFile(_basePath, GetHostTocFileName(context), writable: false);
- dataFileStream = DiskCacheCommon.OpenFile(_basePath, GetHostDataFileName(context), writable: false);
-
- BinarySerializer tempTocReader = new BinarySerializer(tocFileStream);
-
- TocHeader header = new TocHeader();
-
- tempTocReader.Read(ref header);
-
- if (header.Timestamp < expectedTimestamp)
- {
- return (null, null);
- }
- }
-
- int offset = Unsafe.SizeOf<TocHeader>() + programIndex * Unsafe.SizeOf<OffsetAndSize>();
- if (offset + Unsafe.SizeOf<OffsetAndSize>() > tocFileStream.Length)
- {
- return (null, null);
- }
-
- if ((ulong)offset >= (ulong)dataFileStream.Length)
- {
- throw new DiskCacheLoadException(DiskCacheLoadResult.FileCorruptedGeneric);
- }
-
- tocFileStream.Seek(offset, SeekOrigin.Begin);
-
- BinarySerializer tocReader = new BinarySerializer(tocFileStream);
-
- OffsetAndSize offsetAndSize = new OffsetAndSize();
- tocReader.Read(ref offsetAndSize);
-
- if (offsetAndSize.Offset >= (ulong)dataFileStream.Length)
- {
- throw new DiskCacheLoadException(DiskCacheLoadResult.FileCorruptedGeneric);
- }
-
- dataFileStream.Seek((long)offsetAndSize.Offset, SeekOrigin.Begin);
-
- byte[] hostCode = new byte[offsetAndSize.UncompressedSize];
-
- BinarySerializer.ReadCompressed(dataFileStream, hostCode);
-
- CachedShaderStage[] shaders = new CachedShaderStage[guestShaders.Length];
- BinarySerializer dataReader = new BinarySerializer(dataFileStream);
-
- dataFileStream.Seek((long)(offsetAndSize.Offset + offsetAndSize.CompressedSize), SeekOrigin.Begin);
-
- dataReader.BeginCompression();
-
- for (int index = 0; index < guestShaders.Length; index++)
- {
- if (!guestShaders[index].HasValue)
- {
- continue;
- }
-
- GuestCodeAndCbData guestShader = guestShaders[index].Value;
- ShaderProgramInfo info = index != 0 || guestShaders.Length == 1 ? ReadShaderProgramInfo(ref dataReader) : null;
-
- shaders[index] = new CachedShaderStage(info, guestShader.Code, guestShader.Cb1Data);
- }
-
- dataReader.EndCompression();
-
- return (hostCode, shaders);
- }
-
- /// <summary>
- /// Gets output streams for the disk cache, for faster batch writing.
- /// </summary>
- /// <param name="context">The GPU context, used to determine the host disk cache</param>
- /// <returns>A collection of disk cache output streams</returns>
- public DiskCacheOutputStreams GetOutputStreams(GpuContext context)
- {
- var tocFileStream = DiskCacheCommon.OpenFile(_basePath, SharedTocFileName, writable: true);
- var dataFileStream = DiskCacheCommon.OpenFile(_basePath, SharedDataFileName, writable: true);
-
- var hostTocFileStream = DiskCacheCommon.OpenFile(_basePath, GetHostTocFileName(context), writable: true);
- var hostDataFileStream = DiskCacheCommon.OpenFile(_basePath, GetHostDataFileName(context), writable: true);
-
- return new DiskCacheOutputStreams(tocFileStream, dataFileStream, hostTocFileStream, hostDataFileStream);
- }
-
- /// <summary>
- /// Adds a shader to the cache.
- /// </summary>
- /// <param name="context">GPU context</param>
- /// <param name="program">Cached program</param>
- /// <param name="hostCode">Optional host binary code</param>
- /// <param name="streams">Output streams to use</param>
- public void AddShader(GpuContext context, CachedShaderProgram program, ReadOnlySpan<byte> hostCode, DiskCacheOutputStreams streams = null)
- {
- uint stagesBitMask = 0;
-
- for (int index = 0; index < program.Shaders.Length; index++)
- {
- var shader = program.Shaders[index];
- if (shader == null || (shader.Info != null && shader.Info.Stage == ShaderStage.Compute))
- {
- continue;
- }
-
- stagesBitMask |= 1u << index;
- }
-
- var tocFileStream = streams != null ? streams.TocFileStream : DiskCacheCommon.OpenFile(_basePath, SharedTocFileName, writable: true);
- var dataFileStream = streams != null ? streams.DataFileStream : DiskCacheCommon.OpenFile(_basePath, SharedDataFileName, writable: true);
-
- ulong timestamp = (ulong)DateTime.UtcNow.Subtract(DateTime.UnixEpoch).TotalSeconds;
-
- if (tocFileStream.Length == 0)
- {
- TocHeader header = new TocHeader();
- CreateToc(tocFileStream, ref header, TocsMagic, CodeGenVersion, timestamp);
- }
-
- tocFileStream.Seek(0, SeekOrigin.End);
- dataFileStream.Seek(0, SeekOrigin.End);
-
- BinarySerializer tocWriter = new BinarySerializer(tocFileStream);
- BinarySerializer dataWriter = new BinarySerializer(dataFileStream);
-
- ulong dataOffset = (ulong)dataFileStream.Position;
- tocWriter.Write(ref dataOffset);
-
- DataEntry entry = new DataEntry();
-
- entry.StagesBitMask = stagesBitMask;
-
- dataWriter.BeginCompression(DiskCacheCommon.GetCompressionAlgorithm());
- dataWriter.Write(ref entry);
-
- DataEntryPerStage stageEntry = new DataEntryPerStage();
-
- for (int index = 0; index < program.Shaders.Length; index++)
- {
- var shader = program.Shaders[index];
- if (shader == null)
- {
- continue;
- }
-
- stageEntry.GuestCodeIndex = _guestStorage.AddShader(shader.Code, shader.Cb1Data);
-
- dataWriter.Write(ref stageEntry);
- }
-
- program.SpecializationState.Write(ref dataWriter);
- dataWriter.EndCompression();
-
- if (streams == null)
- {
- tocFileStream.Dispose();
- dataFileStream.Dispose();
- }
-
- if (hostCode.IsEmpty)
- {
- return;
- }
-
- WriteHostCode(context, hostCode, program.Shaders, streams, timestamp);
- }
-
- /// <summary>
- /// Clears all content from the guest cache files.
- /// </summary>
- public void ClearGuestCache()
- {
- _guestStorage.ClearCache();
- }
-
- /// <summary>
- /// Clears all content from the shared cache files.
- /// </summary>
- /// <param name="context">GPU context</param>
- public void ClearSharedCache()
- {
- using var tocFileStream = DiskCacheCommon.OpenFile(_basePath, SharedTocFileName, writable: true);
- using var dataFileStream = DiskCacheCommon.OpenFile(_basePath, SharedDataFileName, writable: true);
-
- tocFileStream.SetLength(0);
- dataFileStream.SetLength(0);
- }
-
- /// <summary>
- /// Deletes all content from the host cache files.
- /// </summary>
- /// <param name="context">GPU context</param>
- public void ClearHostCache(GpuContext context)
- {
- using var tocFileStream = DiskCacheCommon.OpenFile(_basePath, GetHostTocFileName(context), writable: true);
- using var dataFileStream = DiskCacheCommon.OpenFile(_basePath, GetHostDataFileName(context), writable: true);
-
- tocFileStream.SetLength(0);
- dataFileStream.SetLength(0);
- }
-
- /// <summary>
- /// Writes the host binary code on the host cache.
- /// </summary>
- /// <param name="context">GPU context</param>
- /// <param name="hostCode">Host binary code</param>
- /// <param name="shaders">Shader stages to be added to the host cache</param>
- /// <param name="streams">Output streams to use</param>
- /// <param name="timestamp">File creation timestamp</param>
- private void WriteHostCode(
- GpuContext context,
- ReadOnlySpan<byte> hostCode,
- CachedShaderStage[] shaders,
- DiskCacheOutputStreams streams,
- ulong timestamp)
- {
- var tocFileStream = streams != null ? streams.HostTocFileStream : DiskCacheCommon.OpenFile(_basePath, GetHostTocFileName(context), writable: true);
- var dataFileStream = streams != null ? streams.HostDataFileStream : DiskCacheCommon.OpenFile(_basePath, GetHostDataFileName(context), writable: true);
-
- if (tocFileStream.Length == 0)
- {
- TocHeader header = new TocHeader();
- CreateToc(tocFileStream, ref header, TochMagic, 0, timestamp);
- }
-
- tocFileStream.Seek(0, SeekOrigin.End);
- dataFileStream.Seek(0, SeekOrigin.End);
-
- BinarySerializer tocWriter = new BinarySerializer(tocFileStream);
- BinarySerializer dataWriter = new BinarySerializer(dataFileStream);
-
- OffsetAndSize offsetAndSize = new OffsetAndSize();
- offsetAndSize.Offset = (ulong)dataFileStream.Position;
- offsetAndSize.UncompressedSize = (uint)hostCode.Length;
-
- long dataStartPosition = dataFileStream.Position;
-
- BinarySerializer.WriteCompressed(dataFileStream, hostCode, DiskCacheCommon.GetCompressionAlgorithm());
-
- offsetAndSize.CompressedSize = (uint)(dataFileStream.Position - dataStartPosition);
-
- tocWriter.Write(ref offsetAndSize);
-
- dataWriter.BeginCompression(DiskCacheCommon.GetCompressionAlgorithm());
-
- for (int index = 0; index < shaders.Length; index++)
- {
- if (shaders[index] != null)
- {
- WriteShaderProgramInfo(ref dataWriter, shaders[index].Info);
- }
- }
-
- dataWriter.EndCompression();
-
- if (streams == null)
- {
- tocFileStream.Dispose();
- dataFileStream.Dispose();
- }
- }
-
- /// <summary>
- /// Creates a TOC file for the host or shared cache.
- /// </summary>
- /// <param name="tocFileStream">TOC file stream</param>
- /// <param name="header">Set to the TOC file header</param>
- /// <param name="magic">Magic value to be written</param>
- /// <param name="codegenVersion">Shader codegen version, only valid for the host file</param>
- /// <param name="timestamp">File creation timestamp</param>
- private void CreateToc(Stream tocFileStream, ref TocHeader header, uint magic, uint codegenVersion, ulong timestamp)
- {
- BinarySerializer writer = new BinarySerializer(tocFileStream);
-
- header.Magic = magic;
- header.FormatVersion = FileFormatVersionPacked;
- header.CodeGenVersion = codegenVersion;
- header.Padding = 0;
- header.Reserved = 0;
- header.Timestamp = timestamp;
-
- if (tocFileStream.Length > 0)
- {
- tocFileStream.Seek(0, SeekOrigin.Begin);
- tocFileStream.SetLength(0);
- }
-
- writer.Write(ref header);
- }
-
- /// <summary>
- /// Reads the shader program info from the cache.
- /// </summary>
- /// <param name="dataReader">Cache data reader</param>
- /// <returns>Shader program info</returns>
- private static ShaderProgramInfo ReadShaderProgramInfo(ref BinarySerializer dataReader)
- {
- DataShaderInfo dataInfo = new DataShaderInfo();
-
- dataReader.ReadWithMagicAndSize(ref dataInfo, ShdiMagic);
-
- BufferDescriptor[] cBuffers = new BufferDescriptor[dataInfo.CBuffersCount];
- BufferDescriptor[] sBuffers = new BufferDescriptor[dataInfo.SBuffersCount];
- TextureDescriptor[] textures = new TextureDescriptor[dataInfo.TexturesCount];
- TextureDescriptor[] images = new TextureDescriptor[dataInfo.ImagesCount];
-
- for (int index = 0; index < dataInfo.CBuffersCount; index++)
- {
- dataReader.ReadWithMagicAndSize(ref cBuffers[index], BufdMagic);
- }
-
- for (int index = 0; index < dataInfo.SBuffersCount; index++)
- {
- dataReader.ReadWithMagicAndSize(ref sBuffers[index], BufdMagic);
- }
-
- for (int index = 0; index < dataInfo.TexturesCount; index++)
- {
- dataReader.ReadWithMagicAndSize(ref textures[index], TexdMagic);
- }
-
- for (int index = 0; index < dataInfo.ImagesCount; index++)
- {
- dataReader.ReadWithMagicAndSize(ref images[index], TexdMagic);
- }
-
- return new ShaderProgramInfo(
- cBuffers,
- sBuffers,
- textures,
- images,
- ShaderIdentification.None,
- 0,
- dataInfo.Stage,
- dataInfo.UsesInstanceId,
- dataInfo.UsesDrawParameters,
- dataInfo.UsesRtLayer,
- dataInfo.ClipDistancesWritten,
- dataInfo.FragmentOutputMap);
- }
-
- /// <summary>
- /// Writes the shader program info into the cache.
- /// </summary>
- /// <param name="dataWriter">Cache data writer</param>
- /// <param name="info">Program info</param>
- private static void WriteShaderProgramInfo(ref BinarySerializer dataWriter, ShaderProgramInfo info)
- {
- if (info == null)
- {
- return;
- }
-
- DataShaderInfo dataInfo = new DataShaderInfo();
-
- dataInfo.CBuffersCount = (ushort)info.CBuffers.Count;
- dataInfo.SBuffersCount = (ushort)info.SBuffers.Count;
- dataInfo.TexturesCount = (ushort)info.Textures.Count;
- dataInfo.ImagesCount = (ushort)info.Images.Count;
- dataInfo.Stage = info.Stage;
- dataInfo.UsesInstanceId = info.UsesInstanceId;
- dataInfo.UsesDrawParameters = info.UsesDrawParameters;
- dataInfo.UsesRtLayer = info.UsesRtLayer;
- dataInfo.ClipDistancesWritten = info.ClipDistancesWritten;
- dataInfo.FragmentOutputMap = info.FragmentOutputMap;
-
- dataWriter.WriteWithMagicAndSize(ref dataInfo, ShdiMagic);
-
- for (int index = 0; index < info.CBuffers.Count; index++)
- {
- var entry = info.CBuffers[index];
- dataWriter.WriteWithMagicAndSize(ref entry, BufdMagic);
- }
-
- for (int index = 0; index < info.SBuffers.Count; index++)
- {
- var entry = info.SBuffers[index];
- dataWriter.WriteWithMagicAndSize(ref entry, BufdMagic);
- }
-
- for (int index = 0; index < info.Textures.Count; index++)
- {
- var entry = info.Textures[index];
- dataWriter.WriteWithMagicAndSize(ref entry, TexdMagic);
- }
-
- for (int index = 0; index < info.Images.Count; index++)
- {
- var entry = info.Images[index];
- dataWriter.WriteWithMagicAndSize(ref entry, TexdMagic);
- }
- }
- }
-}