Exemple #1
0
        /// <summary>
        /// Write the guest GpuAccessor informations to the given stream.
        /// </summary>
        /// <param name="stream">The stream to write the guest GpuAcessor</param>
        /// <param name="shaderContext">The shader tranlator context in use</param>
        /// <returns>The guest gpu accessor header</returns>
        private static GuestGpuAccessorHeader WriteGuestGpuAccessorCache(Stream stream, TranslatorContext shaderContext)
        {
            BinaryWriter writer = new BinaryWriter(stream);

            GuestGpuAccessorHeader header = CreateGuestGpuAccessorCache(shaderContext.GpuAccessor);

            // If we have a full gpu accessor, cache textures descriptors
            if (shaderContext.GpuAccessor is GpuAccessor gpuAccessor)
            {
                HashSet <int> textureHandlesInUse = shaderContext.TextureHandlesForCache;

                header.TextureDescriptorCount = textureHandlesInUse.Count;

                foreach (int textureHandle in textureHandlesInUse)
                {
                    GuestTextureDescriptor textureDescriptor = ((Image.TextureDescriptor)gpuAccessor.GetTextureDescriptor(textureHandle)).ToCache();

                    textureDescriptor.Handle = (uint)textureHandle;

                    writer.WriteStruct(textureDescriptor);
                }
            }

            return(header);
        }
Exemple #2
0
        /// <summary>
        /// Create guest shader cache entries from the runtime contexts.
        /// </summary>
        /// <param name="memoryManager">The GPU memory manager in use</param>
        /// <param name="shaderContexts">The runtime contexts</param>
        /// <returns>Guest shader cahe entries from the runtime contexts</returns>
        public static GuestShaderCacheEntry[] CreateShaderCacheEntries(MemoryManager memoryManager, ReadOnlySpan <TranslatorContext> shaderContexts)
        {
            int startIndex = shaderContexts.Length > 1 ? 1 : 0;

            GuestShaderCacheEntry[] entries = new GuestShaderCacheEntry[shaderContexts.Length - startIndex];

            for (int i = startIndex; i < shaderContexts.Length; i++)
            {
                TranslatorContext context = shaderContexts[i];

                if (context == null)
                {
                    continue;
                }

                TranslatorContext translatorContext2 = i == 1 ? shaderContexts[0] : null;

                int sizeA = translatorContext2 != null ? translatorContext2.Size : 0;

                byte[] code = new byte[context.Size + sizeA];

                memoryManager.GetSpan(context.Address, context.Size).CopyTo(code);

                if (translatorContext2 != null)
                {
                    memoryManager.GetSpan(translatorContext2.Address, sizeA).CopyTo(code.AsSpan().Slice(context.Size, sizeA));
                }

                GuestGpuAccessorHeader gpuAccessorHeader = CreateGuestGpuAccessorCache(context.GpuAccessor);

                if (context.GpuAccessor is GpuAccessor)
                {
                    gpuAccessorHeader.TextureDescriptorCount = context.TextureHandlesForCache.Count;
                }

                GuestShaderCacheEntryHeader header = new GuestShaderCacheEntryHeader(context.Stage, context.Size, sizeA, gpuAccessorHeader);

                GuestShaderCacheEntry entry = new GuestShaderCacheEntry(header, code);

                if (context.GpuAccessor is GpuAccessor gpuAccessor)
                {
                    foreach (int textureHandle in context.TextureHandlesForCache)
                    {
                        GuestTextureDescriptor textureDescriptor = ((Image.TextureDescriptor)gpuAccessor.GetTextureDescriptor(textureHandle, -1)).ToCache();

                        textureDescriptor.Handle = (uint)textureHandle;

                        entry.TextureDescriptors.Add(textureHandle, textureDescriptor);
                    }
                }

                entries[i - startIndex] = entry;
            }

            return(entries);
        }
        /// <summary>
        /// Create the equivalent of this TextureDescriptor for the shader cache.
        /// </summary>
        /// <returns>The equivalent of this TextureDescriptor for the shader cache.</returns>
        public GuestTextureDescriptor ToCache()
        {
            GuestTextureDescriptor result = new GuestTextureDescriptor
            {
                Handle = uint.MaxValue,
                Format = UnpackFormat(),
                Target = UnpackTextureTarget(),
                IsSrgb = UnpackSrgb(),
                IsTextureCoordNormalized = UnpackTextureCoordNormalized(),
            };

            return(result);
        }
        /// <summary>
        /// Create the equivalent of this TextureDescriptor for the shader cache.
        /// </summary>
        /// <returns>The equivalent of this TextureDescriptor for the shader cache.</returns>
        public GuestTextureDescriptor ToCache()
        {
            GuestTextureDescriptor result = new GuestTextureDescriptor
            {
                Handle     = uint.MaxValue,
                Descriptor = this
            };

            // Clear the virtual address
            result.Descriptor.Word0  = 0;
            result.Descriptor.Word2 &= 0xFFFF0000;

            return(result);
        }
Exemple #5
0
        /// <summary>
        /// Create guest shader cache entries from the runtime contexts.
        /// </summary>
        /// <param name="channel">The GPU channel in use</param>
        /// <param name="shaderContexts">The runtime contexts</param>
        /// <returns>Guest shader cahe entries from the runtime contexts</returns>
        public static GuestShaderCacheEntry[] CreateShaderCacheEntries(GpuChannel channel, ReadOnlySpan <TranslatorContext> shaderContexts)
        {
            MemoryManager memoryManager = channel.MemoryManager;

            int startIndex = shaderContexts.Length > 1 ? 1 : 0;

            GuestShaderCacheEntry[] entries = new GuestShaderCacheEntry[shaderContexts.Length - startIndex];

            for (int i = startIndex; i < shaderContexts.Length; i++)
            {
                TranslatorContext context = shaderContexts[i];

                if (context == null)
                {
                    continue;
                }

                GpuAccessor gpuAccessor = context.GpuAccessor as GpuAccessor;

                ulong cb1DataAddress;
                int   cb1DataSize = gpuAccessor?.Cb1DataSize ?? 0;

                if (context.Stage == ShaderStage.Compute)
                {
                    cb1DataAddress = channel.BufferManager.GetComputeUniformBufferAddress(1);
                }
                else
                {
                    int stageIndex = context.Stage switch
                    {
                        ShaderStage.TessellationControl => 1,
                        ShaderStage.TessellationEvaluation => 2,
                        ShaderStage.Geometry => 3,
                        ShaderStage.Fragment => 4,
                        _ => 0
                    };

                    cb1DataAddress = channel.BufferManager.GetGraphicsUniformBufferAddress(stageIndex, 1);
                }

                int size = context.Size;

                TranslatorContext translatorContext2 = i == 1 ? shaderContexts[0] : null;

                int sizeA = translatorContext2 != null ? translatorContext2.Size : 0;

                byte[] code = new byte[size + cb1DataSize + sizeA];

                memoryManager.GetSpan(context.Address, size).CopyTo(code);

                if (cb1DataAddress != 0 && cb1DataSize != 0)
                {
                    memoryManager.Physical.GetSpan(cb1DataAddress, cb1DataSize).CopyTo(code.AsSpan(size, cb1DataSize));
                }

                if (translatorContext2 != null)
                {
                    memoryManager.GetSpan(translatorContext2.Address, sizeA).CopyTo(code.AsSpan(size + cb1DataSize, sizeA));
                }

                GuestGpuAccessorHeader gpuAccessorHeader = CreateGuestGpuAccessorCache(context.GpuAccessor);

                if (gpuAccessor != null)
                {
                    gpuAccessorHeader.TextureDescriptorCount = context.TextureHandlesForCache.Count;
                }

                GuestShaderCacheEntryHeader header = new GuestShaderCacheEntryHeader(
                    context.Stage,
                    size + cb1DataSize,
                    sizeA,
                    cb1DataSize,
                    gpuAccessorHeader);

                GuestShaderCacheEntry entry = new GuestShaderCacheEntry(header, code);

                if (gpuAccessor != null)
                {
                    foreach (int textureHandle in context.TextureHandlesForCache)
                    {
                        GuestTextureDescriptor textureDescriptor = ((Image.TextureDescriptor)gpuAccessor.GetTextureDescriptor(textureHandle, -1)).ToCache();

                        textureDescriptor.Handle = (uint)textureHandle;

                        entry.TextureDescriptors.Add(textureHandle, textureDescriptor);
                    }
                }

                entries[i - startIndex] = entry;
            }

            return(entries);
        }