Пример #1
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();
            }
        }
Пример #2
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="programIndex">Index of the program in the cache</param>
        /// <param name="streams">Output streams to use</param>
        private void WriteHostCode(GpuContext context, ReadOnlySpan <byte> hostCode, int programIndex, DiskCacheOutputStreams streams = null)
        {
            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);
            }

            if (programIndex == -1)
            {
                tocFileStream.Seek(0, SeekOrigin.End);
            }
            else
            {
                tocFileStream.Seek(Unsafe.SizeOf <TocHeader>() + (programIndex * Unsafe.SizeOf <OffsetAndSize>()), SeekOrigin.Begin);
            }

            dataFileStream.Seek(0, SeekOrigin.End);

            BinarySerializer tocWriter = new BinarySerializer(tocFileStream);

            OffsetAndSize offsetAndSize = new OffsetAndSize();

            offsetAndSize.Offset = (ulong)dataFileStream.Position;
            offsetAndSize.Size   = (uint)hostCode.Length;
            tocWriter.Write(ref offsetAndSize);

            BinarySerializer.WriteCompressed(dataFileStream, hostCode, DiskCacheCommon.GetCompressionAlgorithm());

            if (streams == null)
            {
                tocFileStream.Dispose();
                dataFileStream.Dispose();
            }
        }
Пример #3
0
        /// <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);

            if (tocFileStream.Length == 0)
            {
                TocHeader header = new TocHeader();
                CreateToc(tocFileStream, ref header, TocsMagic, CodeGenVersion);
            }

            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);

                WriteShaderProgramInfo(ref dataWriter, shader.Info);
            }

            program.SpecializationState.Write(ref dataWriter);
            dataWriter.EndCompression();

            if (streams == null)
            {
                tocFileStream.Dispose();
                dataFileStream.Dispose();
            }

            if (hostCode.IsEmpty)
            {
                return;
            }

            WriteHostCode(context, hostCode, -1, streams);
        }