diff --git a/Ryujinx.Graphics.Gpu/Image/ITextureDescriptor.cs b/Ryujinx.Graphics.Gpu/Image/ITextureDescriptor.cs new file mode 100644 index 0000000000..378de44b6b --- /dev/null +++ b/Ryujinx.Graphics.Gpu/Image/ITextureDescriptor.cs @@ -0,0 +1,10 @@ +namespace Ryujinx.Graphics.Gpu.Image +{ + interface ITextureDescriptor + { + public uint UnpackFormat(); + public TextureTarget UnpackTextureTarget(); + public bool UnpackSrgb(); + public bool UnpackTextureCoordNormalized(); + } +} diff --git a/Ryujinx.Graphics.Gpu/Image/TextureDescriptor.cs b/Ryujinx.Graphics.Gpu/Image/TextureDescriptor.cs index 74fb988740..76d97bf8c9 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureDescriptor.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureDescriptor.cs @@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.Gpu.Image /// <summary> /// Maxwell texture descriptor, as stored on the GPU texture pool memory region. /// </summary> - struct TextureDescriptor + struct TextureDescriptor : ITextureDescriptor { #pragma warning disable CS0649 public uint Word0; @@ -239,12 +239,12 @@ namespace Ryujinx.Graphics.Gpu.Image GuestTextureDescriptor result = new GuestTextureDescriptor { Handle = uint.MaxValue, - Descriptor = this - }; + Format = UnpackFormat(), + Target = UnpackTextureTarget(), + IsSrgb = UnpackSrgb(), + IsTextureCoordNormalized = UnpackTextureCoordNormalized(), - // Clear the virtual address - result.Descriptor.Word0 = 0; - result.Descriptor.Word2 &= 0xFFFF0000; + }; return result; } diff --git a/Ryujinx.Graphics.Gpu/Image/TextureTarget.cs b/Ryujinx.Graphics.Gpu/Image/TextureTarget.cs index 301fc87b2b..1db758fcd2 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureTarget.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureTarget.cs @@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.Gpu.Image /// <summary> /// Texture target. /// </summary> - enum TextureTarget + enum TextureTarget : byte { Texture1D, Texture2D, diff --git a/Ryujinx.Graphics.Gpu/Shader/Cache/CacheManager.cs b/Ryujinx.Graphics.Gpu/Shader/Cache/CacheManager.cs index d241eb010a..0c4eba2a8c 100644 --- a/Ryujinx.Graphics.Gpu/Shader/Cache/CacheManager.cs +++ b/Ryujinx.Graphics.Gpu/Shader/Cache/CacheManager.cs @@ -29,7 +29,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.Cache /// <summary> /// Version of the guest cache shader (to increment when guest cache structure change). /// </summary> - private const ulong GuestCacheVersion = 1; + private const ulong GuestCacheVersion = 1717; /// <summary> /// Create a new cache manager instance diff --git a/Ryujinx.Graphics.Gpu/Shader/Cache/Definition/GuestTextureDescriptor.cs b/Ryujinx.Graphics.Gpu/Shader/Cache/Definition/GuestTextureDescriptor.cs index 7c73ef7bcf..9491496d63 100644 --- a/Ryujinx.Graphics.Gpu/Shader/Cache/Definition/GuestTextureDescriptor.cs +++ b/Ryujinx.Graphics.Gpu/Shader/Cache/Definition/GuestTextureDescriptor.cs @@ -4,12 +4,38 @@ using System.Runtime.InteropServices; namespace Ryujinx.Graphics.Gpu.Shader.Cache.Definition { /// <summary> - /// Mostly identical to TextureDescriptor from <see cref="Image"/> but we don't store the address of the texture and store its handle instead. + /// Contains part of TextureDescriptor from <see cref="Image"/> used for shader codegen. /// </summary> - [StructLayout(LayoutKind.Sequential, Size = 0x20, Pack = 1)] - struct GuestTextureDescriptor + [StructLayout(LayoutKind.Sequential, Size = 0xC, Pack = 1)] + struct GuestTextureDescriptor : ITextureDescriptor { public uint Handle; - internal TextureDescriptor Descriptor; + public uint Format; + public TextureTarget Target; + [MarshalAs(UnmanagedType.I1)] + public bool IsSrgb; + [MarshalAs(UnmanagedType.I1)] + public bool IsTextureCoordNormalized; + public byte Reserved; + + public uint UnpackFormat() + { + return Format; + } + + public bool UnpackSrgb() + { + return IsSrgb; + } + + public bool UnpackTextureCoordNormalized() + { + return IsTextureCoordNormalized; + } + + public TextureTarget UnpackTextureTarget() + { + return Target; + } } } diff --git a/Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs b/Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs index 5f1458fa01..021369821b 100644 --- a/Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs +++ b/Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs @@ -12,7 +12,7 @@ namespace Ryujinx.Graphics.Gpu.Shader private readonly GpuContext _context; private readonly ReadOnlyMemory<byte> _data; private readonly GuestGpuAccessorHeader _header; - private readonly Dictionary<int, Image.TextureDescriptor> _textureDescriptors; + private readonly Dictionary<int, GuestTextureDescriptor> _textureDescriptors; /// <summary> /// Creates a new instance of the cached GPU state accessor for shader translation. @@ -26,11 +26,11 @@ namespace Ryujinx.Graphics.Gpu.Shader _context = context; _data = data; _header = header; - _textureDescriptors = new Dictionary<int, Image.TextureDescriptor>(); + _textureDescriptors = new Dictionary<int, GuestTextureDescriptor>(); foreach (KeyValuePair<int, GuestTextureDescriptor> guestTextureDescriptor in guestTextureDescriptors) { - _textureDescriptors.Add(guestTextureDescriptor.Key, guestTextureDescriptor.Value.Descriptor); + _textureDescriptors.Add(guestTextureDescriptor.Key, guestTextureDescriptor.Value); } } @@ -141,9 +141,9 @@ namespace Ryujinx.Graphics.Gpu.Shader /// </summary> /// <param name="handle">Index of the texture (this is the word offset of the handle in the constant buffer)</param> /// <returns>Texture descriptor</returns> - public override Image.TextureDescriptor GetTextureDescriptor(int handle) + public override Image.ITextureDescriptor GetTextureDescriptor(int handle) { - if (!_textureDescriptors.TryGetValue(handle, out Image.TextureDescriptor textureDescriptor)) + if (!_textureDescriptors.TryGetValue(handle, out GuestTextureDescriptor textureDescriptor)) { throw new ArgumentException(); } diff --git a/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs b/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs index b3f1b3a86b..2783714b3a 100644 --- a/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs +++ b/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs @@ -185,7 +185,7 @@ namespace Ryujinx.Graphics.Gpu.Shader /// </summary> /// <param name="handle">Index of the texture (this is the word offset of the handle in the constant buffer)</param> /// <returns>Texture descriptor</returns> - public override Image.TextureDescriptor GetTextureDescriptor(int handle) + public override Image.ITextureDescriptor GetTextureDescriptor(int handle) { if (_compute) { diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs index ac5aedbeb3..b469aab52b 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs @@ -35,9 +35,9 @@ namespace Ryujinx.Graphics.Gpu.Shader private Dictionary<Hash128, ShaderBundle> _cpProgramsDiskCache; /// <summary> - /// Version of the codegen (to be incremented when codegen changes). + /// Version of the codegen (to be changed when codegen or guest format change). /// </summary> - private const ulong ShaderCodeGenVersion = 1; + private const ulong ShaderCodeGenVersion = 1717; /// <summary> /// Creates a new instance of the shader cache. @@ -888,7 +888,7 @@ namespace Ryujinx.Graphics.Gpu.Shader foreach (int textureHandle in textureHandlesInUse) { - GuestTextureDescriptor textureDescriptor = gpuAccessor.GetTextureDescriptor(textureHandle).ToCache(); + GuestTextureDescriptor textureDescriptor = ((Image.TextureDescriptor)gpuAccessor.GetTextureDescriptor(textureHandle)).ToCache(); textureDescriptor.Handle = (uint)textureHandle; diff --git a/Ryujinx.Graphics.Gpu/Shader/TextureDescriptorCapableGpuAccessor.cs b/Ryujinx.Graphics.Gpu/Shader/TextureDescriptorCapableGpuAccessor.cs index 7901fe5937..dc0e392bc7 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 Image.TextureDescriptor GetTextureDescriptor(int handle); + public abstract ITextureDescriptor GetTextureDescriptor(int handle); /// <summary> /// Queries texture format information, for shaders using image load or store.