aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Gpu')
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Methods.cs13
-rw-r--r--Ryujinx.Graphics.Gpu/GraphicsConfig.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/Image/Texture.cs9
-rw-r--r--Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs5
-rw-r--r--Ryujinx.Graphics.Gpu/Image/TextureManager.cs12
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/Cache/CacheHelper.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/Cache/Definition/HostShaderCacheEntry.cs5
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/Cache/Definition/HostShaderCacheEntryHeader.cs28
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs3
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs7
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/TextureDescriptorCapableGpuAccessor.cs17
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();