diff options
Diffstat (limited to 'Ryujinx.Graphics.Gpu')
12 files changed, 72 insertions, 33 deletions
diff --git a/Ryujinx.Graphics.Gpu/Engine/Methods.cs b/Ryujinx.Graphics.Gpu/Engine/Methods.cs index 033311b2..ae9bdb0d 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Methods.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Methods.cs @@ -39,6 +39,7 @@ namespace Ryujinx.Graphics.Gpu.Engine private bool _isAnyVbInstanced; private bool _vsUsesInstanceId; + private byte _vsClipDistancesWritten; private bool _forceShaderUpdate; @@ -993,7 +994,15 @@ namespace Ryujinx.Graphics.Gpu.Engine ShaderBundle gs = ShaderCache.GetGraphicsShader(state, addresses); - _vsUsesInstanceId = gs.Shaders[0]?.Info.UsesInstanceId ?? false; + byte oldVsClipDistancesWritten = _vsClipDistancesWritten; + + _vsUsesInstanceId = gs.Shaders[0]?.Info.UsesInstanceId ?? false; + _vsClipDistancesWritten = gs.Shaders[0]?.Info.ClipDistancesWritten ?? 0; + + if (oldVsClipDistancesWritten != _vsClipDistancesWritten) + { + UpdateUserClipState(state); + } int storageBufferBindingsCount = 0; int uniformBufferBindingsCount = 0; @@ -1098,7 +1107,7 @@ namespace Ryujinx.Graphics.Gpu.Engine /// <param name="state">Current GPU state</param> private void UpdateUserClipState(GpuState state) { - int clipMask = state.Get<int>(MethodOffset.ClipDistanceEnable); + int clipMask = state.Get<int>(MethodOffset.ClipDistanceEnable) & _vsClipDistancesWritten; for (int i = 0; i < Constants.TotalClipDistances; ++i) { diff --git a/Ryujinx.Graphics.Gpu/GraphicsConfig.cs b/Ryujinx.Graphics.Gpu/GraphicsConfig.cs index af980e77..7ef102e2 100644 --- a/Ryujinx.Graphics.Gpu/GraphicsConfig.cs +++ b/Ryujinx.Graphics.Gpu/GraphicsConfig.cs @@ -13,7 +13,7 @@ namespace Ryujinx.Graphics.Gpu /// <summary> /// Max Anisotropy. Values range from 0 - 16. Set to -1 to let the game decide. /// </summary> - public static float MaxAnisotropy; + public static float MaxAnisotropy = -1; /// <summary> /// Base directory used to write shader code dumps. diff --git a/Ryujinx.Graphics.Gpu/Image/Texture.cs b/Ryujinx.Graphics.Gpu/Image/Texture.cs index 6d2510f1..4d7e31c5 100644 --- a/Ryujinx.Graphics.Gpu/Image/Texture.cs +++ b/Ryujinx.Graphics.Gpu/Image/Texture.cs @@ -1014,6 +1014,15 @@ namespace Ryujinx.Graphics.Gpu.Image result = TextureCompatibility.PropagateViewCompatibility(result, TextureCompatibility.ViewTargetCompatible(Info, info)); result = TextureCompatibility.PropagateViewCompatibility(result, TextureCompatibility.ViewSubImagesInBounds(Info, info, firstLayer, firstLevel)); + if (result == TextureViewCompatibility.Full && Info.FormatInfo.Format != info.FormatInfo.Format && !_context.Capabilities.SupportsMismatchingViewFormat) + { + // AMD and Intel have a bug where the view format is always ignored; + // they use the parent format instead. + // Create a copy dependency to avoid this issue. + + result = TextureViewCompatibility.CopyOnly; + } + return (Info.SamplesInX == info.SamplesInX && Info.SamplesInY == info.SamplesInY) ? result : TextureViewCompatibility.Incompatible; } diff --git a/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs index 7fea7ebe..ae610a76 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs @@ -398,10 +398,11 @@ namespace Ryujinx.Graphics.Gpu.Image /// <param name="state">The current GPU state</param> /// <param name="stageIndex">The stage number where the texture is bound</param> /// <param name="handle">The texture handle</param> + /// <param name="cbufSlot">The texture handle's constant buffer slot</param> /// <returns>The texture descriptor for the specified texture</returns> - public TextureDescriptor GetTextureDescriptor(GpuState state, int stageIndex, int handle) + public TextureDescriptor GetTextureDescriptor(GpuState state, int stageIndex, int handle, int cbufSlot) { - int packedId = ReadPackedId(stageIndex, handle, state.Get<int>(MethodOffset.TextureBufferIndex)); + int packedId = ReadPackedId(stageIndex, handle, cbufSlot < 0 ? state.Get<int>(MethodOffset.TextureBufferIndex) : cbufSlot); int textureId = UnpackTextureId(packedId); var poolState = state.Get<PoolState>(MethodOffset.TexturePoolState); diff --git a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs index 17bb553f..e08e55ee 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureManager.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureManager.cs @@ -340,10 +340,11 @@ namespace Ryujinx.Graphics.Gpu.Image /// </summary> /// <param name="state">Current GPU state</param> /// <param name="handle">Shader "fake" handle of the texture</param> + /// <param name="cbufSlot">Shader constant buffer slot of the texture</param> /// <returns>The texture descriptor</returns> - public TextureDescriptor GetComputeTextureDescriptor(GpuState state, int handle) + public TextureDescriptor GetComputeTextureDescriptor(GpuState state, int handle, int cbufSlot) { - return _cpBindingsManager.GetTextureDescriptor(state, 0, handle); + return _cpBindingsManager.GetTextureDescriptor(state, 0, handle, cbufSlot); } /// <summary> @@ -352,10 +353,11 @@ namespace Ryujinx.Graphics.Gpu.Image /// <param name="state">Current GPU state</param> /// <param name="stageIndex">Index of the shader stage where the texture is bound</param> /// <param name="handle">Shader "fake" handle of the texture</param> + /// <param name="cbufSlot">Shader constant buffer slot of the texture</param> /// <returns>The texture descriptor</returns> - public TextureDescriptor GetGraphicsTextureDescriptor(GpuState state, int stageIndex, int handle) + public TextureDescriptor GetGraphicsTextureDescriptor(GpuState state, int stageIndex, int handle, int cbufSlot) { - return _gpBindingsManager.GetTextureDescriptor(state, stageIndex, handle); + return _gpBindingsManager.GetTextureDescriptor(state, stageIndex, handle, cbufSlot); } /// <summary> @@ -1297,4 +1299,4 @@ namespace Ryujinx.Graphics.Gpu.Image } } } -}
\ No newline at end of file +} diff --git a/Ryujinx.Graphics.Gpu/Shader/Cache/CacheHelper.cs b/Ryujinx.Graphics.Gpu/Shader/Cache/CacheHelper.cs index 1ec4ab74..f6caddef 100644 --- a/Ryujinx.Graphics.Gpu/Shader/Cache/CacheHelper.cs +++ b/Ryujinx.Graphics.Gpu/Shader/Cache/CacheHelper.cs @@ -417,7 +417,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.Cache { foreach (int textureHandle in context.TextureHandlesForCache) { - GuestTextureDescriptor textureDescriptor = ((Image.TextureDescriptor)gpuAccessor.GetTextureDescriptor(textureHandle)).ToCache(); + GuestTextureDescriptor textureDescriptor = ((Image.TextureDescriptor)gpuAccessor.GetTextureDescriptor(textureHandle, -1)).ToCache(); textureDescriptor.Handle = (uint)textureHandle; diff --git a/Ryujinx.Graphics.Gpu/Shader/Cache/Definition/HostShaderCacheEntry.cs b/Ryujinx.Graphics.Gpu/Shader/Cache/Definition/HostShaderCacheEntry.cs index f592919f..b538e2de 100644 --- a/Ryujinx.Graphics.Gpu/Shader/Cache/Definition/HostShaderCacheEntry.cs +++ b/Ryujinx.Graphics.Gpu/Shader/Cache/Definition/HostShaderCacheEntry.cs @@ -75,7 +75,8 @@ namespace Ryujinx.Graphics.Gpu.Shader.Cache.Definition programInfo.SBuffers.Count, programInfo.Textures.Count, programInfo.Images.Count, - programInfo.UsesInstanceId); + programInfo.UsesInstanceId, + programInfo.ClipDistancesWritten); CBuffers = programInfo.CBuffers.ToArray(); SBuffers = programInfo.SBuffers.ToArray(); Textures = programInfo.Textures.ToArray(); @@ -88,7 +89,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.Cache.Definition /// <returns>A new <see cref="ShaderProgramInfo"/> from this instance</returns> internal ShaderProgramInfo ToShaderProgramInfo() { - return new ShaderProgramInfo(CBuffers, SBuffers, Textures, Images, Header.UsesInstanceId); + return new ShaderProgramInfo(CBuffers, SBuffers, Textures, Images, Header.UsesInstanceId, Header.ClipDistancesWritten); } /// <summary> diff --git a/Ryujinx.Graphics.Gpu/Shader/Cache/Definition/HostShaderCacheEntryHeader.cs b/Ryujinx.Graphics.Gpu/Shader/Cache/Definition/HostShaderCacheEntryHeader.cs index 9b1af8fb..7f27124f 100644 --- a/Ryujinx.Graphics.Gpu/Shader/Cache/Definition/HostShaderCacheEntryHeader.cs +++ b/Ryujinx.Graphics.Gpu/Shader/Cache/Definition/HostShaderCacheEntryHeader.cs @@ -42,9 +42,14 @@ namespace Ryujinx.Graphics.Gpu.Shader.Cache.Definition public bool InUse; /// <summary> + /// Mask of clip distances that are written to on the shader. + /// </summary> + public byte ClipDistancesWritten; + + /// <summary> /// Reserved / unused. /// </summary> - public short Reserved; + public byte Reserved; /// <summary> /// Create a new host shader cache entry header. @@ -54,14 +59,21 @@ namespace Ryujinx.Graphics.Gpu.Shader.Cache.Definition /// <param name="texturesCount">Count of texture descriptors</param> /// <param name="imagesCount">Count of image descriptors</param> /// <param name="usesInstanceId">Set to true if the shader uses instance id</param> - public HostShaderCacheEntryHeader(int cBuffersCount, int sBuffersCount, int texturesCount, int imagesCount, bool usesInstanceId) : this() + public HostShaderCacheEntryHeader( + int cBuffersCount, + int sBuffersCount, + int texturesCount, + int imagesCount, + bool usesInstanceId, + byte clipDistancesWritten) : this() { - CBuffersCount = cBuffersCount; - SBuffersCount = sBuffersCount; - TexturesCount = texturesCount; - ImagesCount = imagesCount; - UsesInstanceId = usesInstanceId; - InUse = true; + CBuffersCount = cBuffersCount; + SBuffersCount = sBuffersCount; + TexturesCount = texturesCount; + ImagesCount = imagesCount; + UsesInstanceId = usesInstanceId; + ClipDistancesWritten = clipDistancesWritten; + InUse = true; } } } diff --git a/Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs b/Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs index f714d97b..a7bd4edb 100644 --- a/Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs +++ b/Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs @@ -140,8 +140,9 @@ namespace Ryujinx.Graphics.Gpu.Shader /// Gets the texture descriptor for a given texture on the pool. /// </summary> /// <param name="handle">Index of the texture (this is the word offset of the handle in the constant buffer)</param> + /// <param name="cbufSlot">Constant buffer slot for the texture handle</param> /// <returns>Texture descriptor</returns> - public override Image.ITextureDescriptor GetTextureDescriptor(int handle) + public override Image.ITextureDescriptor GetTextureDescriptor(int handle, int cbufSlot) { if (!_textureDescriptors.TryGetValue(handle, out GuestTextureDescriptor textureDescriptor)) { diff --git a/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs b/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs index c0ad481e..f5373bd6 100644 --- a/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs +++ b/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs @@ -184,16 +184,17 @@ namespace Ryujinx.Graphics.Gpu.Shader /// Gets the texture descriptor for a given texture on the pool. /// </summary> /// <param name="handle">Index of the texture (this is the word offset of the handle in the constant buffer)</param> + /// <param name="cbufSlot">Constant buffer slot for the texture handle</param> /// <returns>Texture descriptor</returns> - public override Image.ITextureDescriptor GetTextureDescriptor(int handle) + public override Image.ITextureDescriptor GetTextureDescriptor(int handle, int cbufSlot) { if (_compute) { - return _context.Methods.TextureManager.GetComputeTextureDescriptor(_state, handle); + return _context.Methods.TextureManager.GetComputeTextureDescriptor(_state, handle, cbufSlot); } else { - return _context.Methods.TextureManager.GetGraphicsTextureDescriptor(_state, _stageIndex, handle); + return _context.Methods.TextureManager.GetGraphicsTextureDescriptor(_state, _stageIndex, handle, cbufSlot); } } diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs index bfd46c82..f6dcf052 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs @@ -36,7 +36,7 @@ namespace Ryujinx.Graphics.Gpu.Shader /// <summary> /// Version of the codegen (to be changed when codegen or guest format change). /// </summary> - private const ulong ShaderCodeGenVersion = 2200; + private const ulong ShaderCodeGenVersion = 2261; // Progress reporting helpers private volatile int _shaderCount; diff --git a/Ryujinx.Graphics.Gpu/Shader/TextureDescriptorCapableGpuAccessor.cs b/Ryujinx.Graphics.Gpu/Shader/TextureDescriptorCapableGpuAccessor.cs index dc0e392b..904a0fd4 100644 --- a/Ryujinx.Graphics.Gpu/Shader/TextureDescriptorCapableGpuAccessor.cs +++ b/Ryujinx.Graphics.Gpu/Shader/TextureDescriptorCapableGpuAccessor.cs @@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Gpu.Shader { public abstract T MemoryRead<T>(ulong address) where T : unmanaged; - public abstract ITextureDescriptor GetTextureDescriptor(int handle); + public abstract ITextureDescriptor GetTextureDescriptor(int handle, int cbufSlot); /// <summary> /// Queries texture format information, for shaders using image load or store. @@ -18,10 +18,11 @@ namespace Ryujinx.Graphics.Gpu.Shader /// If the format of the texture is a compressed, depth or unsupported format, then a default value is returned. /// </remarks> /// <param name="handle">Texture handle</param> + /// <param name="cbufSlot">Constant buffer slot for the texture handle</param> /// <returns>Color format of the non-compressed texture</returns> - public TextureFormat QueryTextureFormat(int handle) + public TextureFormat QueryTextureFormat(int handle, int cbufSlot = -1) { - var descriptor = GetTextureDescriptor(handle); + var descriptor = GetTextureDescriptor(handle, cbufSlot); if (!FormatTable.TryGetTextureFormat(descriptor.UnpackFormat(), descriptor.UnpackSrgb(), out FormatInfo formatInfo)) { @@ -78,20 +79,22 @@ namespace Ryujinx.Graphics.Gpu.Shader /// Queries texture target information. /// </summary> /// <param name="handle">Texture handle</param> + /// <param name="cbufSlot">Constant buffer slot for the texture handle</param> /// <returns>True if the texture is a buffer texture, false otherwise</returns> - public bool QueryIsTextureBuffer(int handle) + public bool QueryIsTextureBuffer(int handle, int cbufSlot = -1) { - return GetTextureDescriptor(handle).UnpackTextureTarget() == TextureTarget.TextureBuffer; + return GetTextureDescriptor(handle, cbufSlot).UnpackTextureTarget() == TextureTarget.TextureBuffer; } /// <summary> /// Queries texture target information. /// </summary> /// <param name="handle">Texture handle</param> + /// <param name="cbufSlot">Constant buffer slot for the texture handle</param> /// <returns>True if the texture is a rectangle texture, false otherwise</returns> - public bool QueryIsTextureRectangle(int handle) + public bool QueryIsTextureRectangle(int handle, int cbufSlot = -1) { - var descriptor = GetTextureDescriptor(handle); + var descriptor = GetTextureDescriptor(handle, cbufSlot); TextureTarget target = descriptor.UnpackTextureTarget(); |
