コード例 #1
0
ファイル: ShaderCache.cs プロジェクト: Xpl0itR/Ryujinx
        /// <summary>
        /// Gets a compute shader from the cache.
        /// </summary>
        /// <remarks>
        /// This automatically translates, compiles and adds the code to the cache if not present.
        /// </remarks>
        /// <param name="channel">GPU channel</param>
        /// <param name="poolState">Texture pool state</param>
        /// <param name="computeState">Compute engine state</param>
        /// <param name="gpuVa">GPU virtual address of the binary shader code</param>
        /// <returns>Compiled compute shader code</returns>
        public CachedShaderProgram GetComputeShader(
            GpuChannel channel,
            GpuChannelPoolState poolState,
            GpuChannelComputeState computeState,
            ulong gpuVa)
        {
            if (_cpPrograms.TryGetValue(gpuVa, out var cpShader) && IsShaderEqual(channel, poolState, cpShader, gpuVa))
            {
                return(cpShader);
            }

            if (_computeShaderCache.TryFind(channel, poolState, gpuVa, out cpShader, out byte[] cachedGuestCode))
コード例 #2
0
        /// <summary>
        /// Tries to find a cached program.
        /// </summary>
        /// <param name="channel">GPU channel</param>
        /// <param name="poolState">Texture pool state</param>
        /// <param name="gpuVa">GPU virtual address of the compute shader</param>
        /// <param name="program">Cached host program for the given state, if found</param>
        /// <param name="cachedGuestCode">Cached guest code, if any found</param>
        /// <returns>True if a cached host program was found, false otherwise</returns>
        public bool TryFind(
            GpuChannel channel,
            GpuChannelPoolState poolState,
            ulong gpuVa,
            out CachedShaderProgram program,
            out byte[] cachedGuestCode)
        {
            program = null;
            ShaderCodeAccessor codeAccessor = new ShaderCodeAccessor(channel.MemoryManager, gpuVa);
            bool hasSpecList = _cache.TryFindItem(codeAccessor, out var specList, out cachedGuestCode);

            return(hasSpecList && specList.TryFindForCompute(channel, poolState, out program));
        }
コード例 #3
0
        /// <summary>
        /// Tries to find an existing compute program on the cache.
        /// </summary>
        /// <param name="channel">GPU channel</param>
        /// <param name="poolState">Texture pool state</param>
        /// <param name="program">Cached program, if found</param>
        /// <returns>True if a compatible program is found, false otherwise</returns>
        public bool TryFindForCompute(GpuChannel channel, GpuChannelPoolState poolState, out CachedShaderProgram program)
        {
            foreach (var entry in _entries)
            {
                if (entry.SpecializationState.MatchesCompute(channel, poolState, true))
                {
                    program = entry;
                    return(true);
                }
            }

            program = default;
            return(false);
        }
コード例 #4
0
        /// <summary>
        /// Checks if the recorded state matches the current GPU 3D engine state.
        /// </summary>
        /// <param name="channel">GPU channel</param>
        /// <param name="poolState">Texture pool state</param>
        /// <param name="graphicsState">Graphics state</param>
        /// <param name="checkTextures">Indicates whether texture descriptors should be checked</param>
        /// <returns>True if the state matches, false otherwise</returns>
        public bool MatchesGraphics(GpuChannel channel, GpuChannelPoolState poolState, GpuChannelGraphicsState graphicsState, bool checkTextures)
        {
            if (graphicsState.ViewportTransformDisable != GraphicsState.ViewportTransformDisable)
            {
                return(false);
            }

            bool thisA2cDitherEnable  = GraphicsState.AlphaToCoverageEnable && GraphicsState.AlphaToCoverageDitherEnable;
            bool otherA2cDitherEnable = graphicsState.AlphaToCoverageEnable && graphicsState.AlphaToCoverageDitherEnable;

            if (otherA2cDitherEnable != thisA2cDitherEnable)
            {
                return(false);
            }

            return(Matches(channel, poolState, checkTextures, isCompute: false));
        }
コード例 #5
0
        /// <summary>
        /// Checks if the recorded state matches the current GPU 3D engine state.
        /// </summary>
        /// <param name="channel">GPU channel</param>
        /// <param name="poolState">Texture pool state</param>
        /// <param name="graphicsState">Graphics state</param>
        /// <param name="checkTextures">Indicates whether texture descriptors should be checked</param>
        /// <returns>True if the state matches, false otherwise</returns>
        public bool MatchesGraphics(GpuChannel channel, GpuChannelPoolState poolState, GpuChannelGraphicsState graphicsState, bool checkTextures)
        {
            if (graphicsState.ViewportTransformDisable != GraphicsState.ViewportTransformDisable)
            {
                return(false);
            }

            bool thisA2cDitherEnable  = GraphicsState.AlphaToCoverageEnable && GraphicsState.AlphaToCoverageDitherEnable;
            bool otherA2cDitherEnable = graphicsState.AlphaToCoverageEnable && graphicsState.AlphaToCoverageDitherEnable;

            if (otherA2cDitherEnable != thisA2cDitherEnable)
            {
                return(false);
            }

            if (graphicsState.DepthMode != GraphicsState.DepthMode)
            {
                return(false);
            }

            if (graphicsState.AlphaTestEnable != GraphicsState.AlphaTestEnable)
            {
                return(false);
            }

            if (graphicsState.AlphaTestEnable &&
                (graphicsState.AlphaTestCompare != GraphicsState.AlphaTestCompare ||
                 graphicsState.AlphaTestReference != GraphicsState.AlphaTestReference))
            {
                return(false);
            }

            if (!graphicsState.AttributeTypes.AsSpan().SequenceEqual(GraphicsState.AttributeTypes.AsSpan()))
            {
                return(false);
            }

            return(Matches(channel, poolState, checkTextures, isCompute: false));
        }
コード例 #6
0
 /// <summary>
 /// Checks if the recorded state matches the current GPU compute engine state.
 /// </summary>
 /// <param name="channel">GPU channel</param>
 /// <param name="poolState">Texture pool state</param>
 /// <param name="checkTextures">Indicates whether texture descriptors should be checked</param>
 /// <returns>True if the state matches, false otherwise</returns>
 public bool MatchesCompute(GpuChannel channel, GpuChannelPoolState poolState, bool checkTextures)
 {
     return(Matches(channel, poolState, checkTextures, isCompute: true));
 }
コード例 #7
0
        /// <summary>
        /// Checks if the recorded state matches the current GPU state.
        /// </summary>
        /// <param name="channel">GPU channel</param>
        /// <param name="poolState">Texture pool state</param>
        /// <param name="isCompute">Indicates whenever the check is requested by the 3D or compute engine</param>
        /// <returns>True if the state matches, false otherwise</returns>
        private bool Matches(GpuChannel channel, GpuChannelPoolState poolState, bool isCompute)
        {
            int constantBufferUsePerStageMask = _constantBufferUsePerStage;

            while (constantBufferUsePerStageMask != 0)
            {
                int index = BitOperations.TrailingZeroCount(constantBufferUsePerStageMask);

                uint useMask = isCompute
                    ? channel.BufferManager.GetComputeUniformBufferUseMask()
                    : channel.BufferManager.GetGraphicsUniformBufferUseMask(index);

                if (ConstantBufferUse[index] != useMask)
                {
                    return(false);
                }

                constantBufferUsePerStageMask &= ~(1 << index);
            }

            foreach (var kv in _textureSpecialization)
            {
                TextureKey textureKey = kv.Key;

                (int textureBufferIndex, int samplerBufferIndex) = TextureHandle.UnpackSlots(textureKey.CbufSlot, poolState.TextureBufferIndex);

                ulong textureCbAddress;
                ulong samplerCbAddress;

                if (isCompute)
                {
                    textureCbAddress = channel.BufferManager.GetComputeUniformBufferAddress(textureBufferIndex);
                    samplerCbAddress = channel.BufferManager.GetComputeUniformBufferAddress(samplerBufferIndex);
                }
                else
                {
                    textureCbAddress = channel.BufferManager.GetGraphicsUniformBufferAddress(textureKey.StageIndex, textureBufferIndex);
                    samplerCbAddress = channel.BufferManager.GetGraphicsUniformBufferAddress(textureKey.StageIndex, samplerBufferIndex);
                }

                if (!channel.MemoryManager.Physical.IsMapped(textureCbAddress) || !channel.MemoryManager.Physical.IsMapped(samplerCbAddress))
                {
                    continue;
                }

                Image.TextureDescriptor descriptor;

                if (isCompute)
                {
                    descriptor = channel.TextureManager.GetComputeTextureDescriptor(
                        poolState.TexturePoolGpuVa,
                        poolState.TextureBufferIndex,
                        poolState.TexturePoolMaximumId,
                        textureKey.Handle,
                        textureKey.CbufSlot);
                }
                else
                {
                    descriptor = channel.TextureManager.GetGraphicsTextureDescriptor(
                        poolState.TexturePoolGpuVa,
                        poolState.TextureBufferIndex,
                        poolState.TexturePoolMaximumId,
                        textureKey.StageIndex,
                        textureKey.Handle,
                        textureKey.CbufSlot);
                }

                Box <TextureSpecializationState> specializationState = kv.Value;

                if (specializationState.Value.QueriedFlags.HasFlag(QueriedTextureStateFlags.CoordNormalized) &&
                    specializationState.Value.CoordNormalized != descriptor.UnpackTextureCoordNormalized())
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #8
0
 /// <summary>
 /// Checks if the recorded state matches the current GPU compute engine state.
 /// </summary>
 /// <param name="channel">GPU channel</param>
 /// <param name="poolState">Texture pool state</param>
 /// <returns>True if the state matches, false otherwise</returns>
 public bool MatchesCompute(GpuChannel channel, GpuChannelPoolState poolState)
 {
     return(Matches(channel, poolState, isCompute: true));
 }
コード例 #9
0
 /// <summary>
 /// Checks if the recorded state matches the current GPU 3D engine state.
 /// </summary>
 /// <param name="channel">GPU channel</param>
 /// <param name="poolState">Texture pool state</param>
 /// <returns>True if the state matches, false otherwise</returns>
 public bool MatchesGraphics(GpuChannel channel, GpuChannelPoolState poolState)
 {
     return(Matches(channel, poolState, isCompute: false));
 }