diff --git a/Ryujinx.Graphics.Gpu/Image/ITextureDescriptor.cs b/Ryujinx.Graphics.Gpu/Image/ITextureDescriptor.cs new file mode 100644 index 00000000..378de44b --- /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 74fb9887..76d97bf8 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureDescriptor.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureDescriptor.cs @@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.Gpu.Image /// /// Maxwell texture descriptor, as stored on the GPU texture pool memory region. /// - 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 301fc87b..1db758fc 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureTarget.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureTarget.cs @@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.Gpu.Image /// /// Texture target. /// - 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 d241eb01..0c4eba2a 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 /// /// Version of the guest cache shader (to increment when guest cache structure change). /// - private const ulong GuestCacheVersion = 1; + private const ulong GuestCacheVersion = 1717; /// /// 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 7c73ef7b..9491496d 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 { /// - /// Mostly identical to TextureDescriptor from but we don't store the address of the texture and store its handle instead. + /// Contains part of TextureDescriptor from used for shader codegen. /// - [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 5f1458fa..02136982 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 _data; private readonly GuestGpuAccessorHeader _header; - private readonly Dictionary _textureDescriptors; + private readonly Dictionary _textureDescriptors; /// /// 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(); + _textureDescriptors = new Dictionary(); foreach (KeyValuePair 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 /// /// Index of the texture (this is the word offset of the handle in the constant buffer) /// Texture descriptor - 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 b3f1b3a8..2783714b 100644 --- a/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs +++ b/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs @@ -185,7 +185,7 @@ namespace Ryujinx.Graphics.Gpu.Shader /// /// Index of the texture (this is the word offset of the handle in the constant buffer) /// Texture descriptor - 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 ac5aedbe..b469aab5 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 _cpProgramsDiskCache; /// - /// Version of the codegen (to be incremented when codegen changes). + /// Version of the codegen (to be changed when codegen or guest format change). /// - private const ulong ShaderCodeGenVersion = 1; + private const ulong ShaderCodeGenVersion = 1717; /// /// 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 7901fe59..dc0e392b 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(ulong address) where T : unmanaged; - public abstract Image.TextureDescriptor GetTextureDescriptor(int handle); + public abstract ITextureDescriptor GetTextureDescriptor(int handle); /// /// Queries texture format information, for shaders using image load or store.