diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-09-18 01:30:35 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-09-18 01:30:35 -0300 |
| commit | d4187aaa9d7194aa26d04aee838edbc3a38f1862 (patch) | |
| tree | 06fe725c1067b4aeca21749799b835d85e7d2787 /Ryujinx.Graphics/Gal | |
| parent | bec95cacc1061f91373a1e3a1411981af7fe2e4e (diff) | |
Allow "reinterpretation" of framebuffer/zeta formats (#418)
* (Re)Implement format reinterpretation, other changes
* Implement writeback to guest memory, some refactoring
* More refactoring, implement reinterpretation the old way again
* Clean up
* Some fixes on M2MF (old Dma engine), added partial support for P2MF, fix conditional ssy, add Z24S8 zeta format, other fixes
* nit: Formatting
* Address PR feedback
Diffstat (limited to 'Ryujinx.Graphics/Gal')
25 files changed, 428 insertions, 597 deletions
diff --git a/Ryujinx.Graphics/Gal/GalImage.cs b/Ryujinx.Graphics/Gal/GalImage.cs index dc6f02e0..92f43cc9 100644 --- a/Ryujinx.Graphics/Gal/GalImage.cs +++ b/Ryujinx.Graphics/Gal/GalImage.cs @@ -1,12 +1,17 @@ +using Ryujinx.Graphics.Texture; + namespace Ryujinx.Graphics.Gal { public struct GalImage { public int Width; public int Height; + public int TileWidth; + public int GobBlockHeight; + public int Pitch; - public GalImageFormat Format; - + public GalImageFormat Format; + public GalMemoryLayout Layout; public GalTextureSource XSource; public GalTextureSource YSource; public GalTextureSource ZSource; @@ -15,19 +20,44 @@ namespace Ryujinx.Graphics.Gal public GalImage( int Width, int Height, + int TileWidth, + int GobBlockHeight, + GalMemoryLayout Layout, GalImageFormat Format, GalTextureSource XSource = GalTextureSource.Red, GalTextureSource YSource = GalTextureSource.Green, GalTextureSource ZSource = GalTextureSource.Blue, GalTextureSource WSource = GalTextureSource.Alpha) { - this.Width = Width; - this.Height = Height; - this.Format = Format; - this.XSource = XSource; - this.YSource = YSource; - this.ZSource = ZSource; - this.WSource = WSource; + this.Width = Width; + this.Height = Height; + this.TileWidth = TileWidth; + this.GobBlockHeight = GobBlockHeight; + this.Layout = Layout; + this.Format = Format; + this.XSource = XSource; + this.YSource = YSource; + this.ZSource = ZSource; + this.WSource = WSource; + + Pitch = ImageUtils.GetPitch(Format, Width); + } + + public bool SizeMatches(GalImage Image) + { + if (ImageUtils.GetBytesPerPixel(Format) != + ImageUtils.GetBytesPerPixel(Image.Format)) + { + return false; + } + + if (ImageUtils.GetAlignedWidth(this) != + ImageUtils.GetAlignedWidth(Image)) + { + return false; + } + + return Height == Image.Height; } } }
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalMemoryLayout.cs b/Ryujinx.Graphics/Gal/GalMemoryLayout.cs new file mode 100644 index 00000000..73fabf8c --- /dev/null +++ b/Ryujinx.Graphics/Gal/GalMemoryLayout.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.Graphics.Gal +{ + public enum GalMemoryLayout + { + BlockLinear = 0, + Pitch = 1 + } +}
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalPipelineState.cs b/Ryujinx.Graphics/Gal/GalPipelineState.cs index 7c669514..6ee6c93e 100644 --- a/Ryujinx.Graphics/Gal/GalPipelineState.cs +++ b/Ryujinx.Graphics/Gal/GalPipelineState.cs @@ -21,6 +21,8 @@ public GalVertexBinding[] VertexBindings; + public bool FramebufferSrgb; + public float FlipX; public float FlipY; diff --git a/Ryujinx.Graphics/Gal/GalFrameBufferFormat.cs b/Ryujinx.Graphics/Gal/GalSurfaceFormat.cs index 08bd622b..08bd622b 100644 --- a/Ryujinx.Graphics/Gal/GalFrameBufferFormat.cs +++ b/Ryujinx.Graphics/Gal/GalSurfaceFormat.cs diff --git a/Ryujinx.Graphics/Gal/GalTextureFormat.cs b/Ryujinx.Graphics/Gal/GalTextureFormat.cs index e8658595..5ad76943 100644 --- a/Ryujinx.Graphics/Gal/GalTextureFormat.cs +++ b/Ryujinx.Graphics/Gal/GalTextureFormat.cs @@ -7,6 +7,7 @@ namespace Ryujinx.Graphics.Gal R32G32 = 0x4, A8B8G8R8 = 0x8, A2B10G10R10 = 0x9, + R16G16 = 0xc, R32 = 0xf, BC6H_SF16 = 0x10, BC6H_UF16 = 0x11, diff --git a/Ryujinx.Graphics/Gal/IGalRasterizer.cs b/Ryujinx.Graphics/Gal/IGalRasterizer.cs index a20b6f53..1ee630e2 100644 --- a/Ryujinx.Graphics/Gal/IGalRasterizer.cs +++ b/Ryujinx.Graphics/Gal/IGalRasterizer.cs @@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.Gal void SetIndexArray(int Size, GalIndexFormat Format); - void DrawArrays(int First, int PrimCount, GalPrimitiveType PrimType); + void DrawArrays(int First, int Count, GalPrimitiveType PrimType); void DrawElements(long IboKey, int First, int VertexBase, GalPrimitiveType PrimType); } diff --git a/Ryujinx.Graphics/Gal/IGalRenderTarget.cs b/Ryujinx.Graphics/Gal/IGalRenderTarget.cs index c44434ef..6c9166f2 100644 --- a/Ryujinx.Graphics/Gal/IGalRenderTarget.cs +++ b/Ryujinx.Graphics/Gal/IGalRenderTarget.cs @@ -1,23 +1,17 @@ -using System; - namespace Ryujinx.Graphics.Gal { public interface IGalRenderTarget { - void BindColor(long Key, int Attachment); + void BindColor(long Key, int Attachment, GalImage Image); void UnbindColor(int Attachment); - void BindZeta(long Key); + void BindZeta(long Key, GalImage Image); void UnbindZeta(); - void BindTexture(long Key, int Index); - void Set(long Key); - void Set(byte[] Data, int Width, int Height); - void SetMap(int[] Map); void SetTransform(bool FlipX, bool FlipY, int Top, int Left, int Right, int Bottom); @@ -40,12 +34,8 @@ namespace Ryujinx.Graphics.Gal int DstX1, int DstY1); - void GetBufferData(long Key, Action<byte[]> Callback); + void Reinterpret(long Key, GalImage NewImage); - void SetBufferData( - long Key, - int Width, - int Height, - byte[] Buffer); + byte[] GetData(long Key); } }
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/IGalTexture.cs b/Ryujinx.Graphics/Gal/IGalTexture.cs index 292f59ef..aeecdf1a 100644 --- a/Ryujinx.Graphics/Gal/IGalTexture.cs +++ b/Ryujinx.Graphics/Gal/IGalTexture.cs @@ -5,13 +5,13 @@ namespace Ryujinx.Graphics.Gal void LockCache(); void UnlockCache(); - void Create(long Key, byte[] Data, GalImage Image); + void Create(long Key, int Size, GalImage Image); - void CreateFb(long Key, long Size, GalImage Image); + void Create(long Key, byte[] Data, GalImage Image); - bool TryGetCachedTexture(long Key, long DataSize, out GalImage Image); + bool TryGetImage(long Key, out GalImage Image); - void Bind(long Key, int Index); + void Bind(long Key, int Index, GalImage Image); void SetSampler(GalTextureSampler Sampler); } diff --git a/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs b/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs index dda82538..8db0b8a8 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs @@ -1,14 +1,9 @@ -using OpenTK.Graphics.OpenGL; -using Ryujinx.Graphics.Texture; -using System; +using Ryujinx.Graphics.Texture; namespace Ryujinx.Graphics.Gal.OpenGL { class ImageHandler { - private static int CopyBuffer = 0; - private static int CopyBufferSize = 0; - public GalImage Image { get; private set; } public int Width => Image.Width; @@ -16,144 +11,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL public GalImageFormat Format => Image.Format; - public PixelInternalFormat InternalFormat { get; private set; } - public PixelFormat PixelFormat { get; private set; } - public PixelType PixelType { get; private set; } - public int Handle { get; private set; } - private bool Initialized; - - public ImageHandler() - { - Handle = GL.GenTexture(); - } + public bool HasColor => ImageUtils.HasColor(Image.Format); + public bool HasDepth => ImageUtils.HasDepth(Image.Format); + public bool HasStencil => ImageUtils.HasStencil(Image.Format); public ImageHandler(int Handle, GalImage Image) { this.Handle = Handle; - - this.Image = Image; - } - - public void EnsureSetup(GalImage NewImage) - { - if (Width == NewImage.Width && - Height == NewImage.Height && - Format == NewImage.Format && - Initialized) - { - return; - } - - PixelInternalFormat InternalFmt; - PixelFormat PixelFormat; - PixelType PixelType; - - if (ImageUtils.IsCompressed(NewImage.Format)) - { - InternalFmt = (PixelInternalFormat)OGLEnumConverter.GetCompressedImageFormat(NewImage.Format); - - PixelFormat = default(PixelFormat); - PixelType = default(PixelType); - } - else - { - (InternalFmt, PixelFormat, PixelType) = OGLEnumConverter.GetImageFormat(NewImage.Format); - } - - GL.BindTexture(TextureTarget.Texture2D, Handle); - - if (Initialized) - { - if (CopyBuffer == 0) - { - CopyBuffer = GL.GenBuffer(); - } - - int CurrentSize = Math.Max(ImageUtils.GetSize(NewImage), - ImageUtils.GetSize(Image)); - - GL.BindBuffer(BufferTarget.PixelPackBuffer, CopyBuffer); - GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyBuffer); - - if (CopyBufferSize < CurrentSize) - { - CopyBufferSize = CurrentSize; - - GL.BufferData(BufferTarget.PixelPackBuffer, CurrentSize, IntPtr.Zero, BufferUsageHint.StreamCopy); - } - - if (ImageUtils.IsCompressed(Image.Format)) - { - GL.GetCompressedTexImage(TextureTarget.Texture2D, 0, IntPtr.Zero); - } - else - { - GL.GetTexImage(TextureTarget.Texture2D, 0, this.PixelFormat, this.PixelType, IntPtr.Zero); - } - - GL.DeleteTexture(Handle); - - Handle = GL.GenTexture(); - - GL.BindTexture(TextureTarget.Texture2D, Handle); - } - - const int MinFilter = (int)TextureMinFilter.Linear; - const int MagFilter = (int)TextureMagFilter.Linear; - - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, MinFilter); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, MagFilter); - - const int Level = 0; - const int Border = 0; - - if (ImageUtils.IsCompressed(NewImage.Format)) - { - Console.WriteLine("Hit"); - - GL.CompressedTexImage2D( - TextureTarget.Texture2D, - Level, - (InternalFormat)InternalFmt, - NewImage.Width, - NewImage.Height, - Border, - ImageUtils.GetSize(NewImage), - IntPtr.Zero); - } - else - { - GL.TexImage2D( - TextureTarget.Texture2D, - Level, - InternalFmt, - NewImage.Width, - NewImage.Height, - Border, - PixelFormat, - PixelType, - IntPtr.Zero); - } - - if (Initialized) - { - GL.BindBuffer(BufferTarget.PixelPackBuffer, 0); - GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0); - } - - Image = NewImage; - - this.InternalFormat = InternalFmt; - this.PixelFormat = PixelFormat; - this.PixelType = PixelType; - - Initialized = true; + this.Image = Image; } - - public bool HasColor => ImageUtils.HasColor(Image.Format); - public bool HasDepth => ImageUtils.HasDepth(Image.Format); - public bool HasStencil => ImageUtils.HasStencil(Image.Format); } } diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLCachedResource.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLCachedResource.cs index 01ebf982..839915ea 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLCachedResource.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLCachedResource.cs @@ -22,9 +22,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL public CacheBucket(T Value, long DataSize, LinkedListNode<long> Node) { - this.Value = Value; - this.DataSize = DataSize; - this.Node = Node; + this.Value = Value; + this.DataSize = DataSize; + this.Node = Node; Timestamp = Environment.TickCount; } diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs index 876c7b99..fac3875e 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs @@ -149,8 +149,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL case GalImageFormat.R32 | GalImageFormat.Sfloat: return (PixelInternalFormat.R32f, PixelFormat.Red, PixelType.Float); case GalImageFormat.R32 | GalImageFormat.Sint: return (PixelInternalFormat.R32i, PixelFormat.Red, PixelType.Int); case GalImageFormat.R32 | GalImageFormat.Uint: return (PixelInternalFormat.R32ui, PixelFormat.Red, PixelType.UnsignedInt); - case GalImageFormat.A1R5G5B5 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort5551); - case GalImageFormat.B5G6R5 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba, PixelFormat.Rgb, PixelType.UnsignedShort565); + case GalImageFormat.A1R5G5B5 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort1555Reversed); + case GalImageFormat.B5G6R5 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba, PixelFormat.Rgb, PixelType.UnsignedShort565Reversed); case GalImageFormat.R16G16 | GalImageFormat.Sfloat: return (PixelInternalFormat.Rg16f, PixelFormat.Rg, PixelType.HalfFloat); case GalImageFormat.R16G16 | GalImageFormat.Sint: return (PixelInternalFormat.Rg16i, PixelFormat.RgInteger, PixelType.Short); case GalImageFormat.R16G16 | GalImageFormat.Snorm: return (PixelInternalFormat.Rg16Snorm, PixelFormat.Rg, PixelType.Byte); diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs index 051b1050..cf856a15 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs @@ -126,6 +126,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL BindVertexLayout(New); + if (New.FramebufferSrgb != Old.FramebufferSrgb) + { + Enable(EnableCap.FramebufferSrgb, New.FramebufferSrgb); + } + if (New.FlipX != Old.FlipX || New.FlipY != Old.FlipY || New.Instance != Old.Instance) { Shader.SetExtraData(New.FlipX, New.FlipY, New.Instance); @@ -337,6 +342,12 @@ namespace Ryujinx.Graphics.Gal.OpenGL foreach (GalVertexAttrib Attrib in Binding.Attribs) { + //Skip uninitialized attributes. + if (Attrib.Size == 0) + { + continue; + } + GL.EnableVertexAttribArray(Attrib.Index); GL.BindBuffer(BufferTarget.ArrayBuffer, VboHandle); diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs index 45106692..ebfba63d 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs @@ -113,14 +113,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL IndexBuffer.ElemSizeLog2 = (int)Format; } - public void DrawArrays(int First, int PrimCount, GalPrimitiveType PrimType) + public void DrawArrays(int First, int Count, GalPrimitiveType PrimType) { - if (PrimCount == 0) + if (Count == 0) { return; } - GL.DrawArrays(OGLEnumConverter.GetPrimitiveType(PrimType), First, PrimCount); + GL.DrawArrays(OGLEnumConverter.GetPrimitiveType(PrimType), First, Count); } public void DrawElements(long IboKey, int First, int VertexBase, GalPrimitiveType PrimType) diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs index 99bfa350..7dde32d8 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs @@ -15,9 +15,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL public Rect(int X, int Y, int Width, int Height) { - this.X = X; - this.Y = Y; - this.Width = Width; + this.X = X; + this.Y = Y; + this.Width = Width; this.Height = Height; } } @@ -29,7 +29,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL private OGLTexture Texture; - private ImageHandler RawTex; private ImageHandler ReadTex; private Rect Viewport; @@ -64,13 +63,13 @@ namespace Ryujinx.Graphics.Gal.OpenGL this.Texture = Texture; } - public void BindColor(long Key, int Attachment) + public void BindColor(long Key, int Attachment, GalImage Image) { - if (Texture.TryGetImage(Key, out ImageHandler Tex)) + if (Texture.TryGetImageHandler(Key, out ImageHandler CachedImage)) { EnsureFrameBuffer(); - Attach(ref ColorAttachments[Attachment], Tex.Handle, FramebufferAttachment.ColorAttachment0 + Attachment); + Attach(ref ColorAttachments[Attachment], CachedImage.Handle, FramebufferAttachment.ColorAttachment0 + Attachment); } else { @@ -84,40 +83,39 @@ namespace Ryujinx.Graphics.Gal.OpenGL Attach(ref ColorAttachments[Attachment], 0, FramebufferAttachment.ColorAttachment0 + Attachment); } - - public void BindZeta(long Key) + + public void BindZeta(long Key, GalImage Image) { - if (Texture.TryGetImage(Key, out ImageHandler Tex)) + if (Texture.TryGetImageHandler(Key, out ImageHandler CachedImage)) { EnsureFrameBuffer(); - if (Tex.HasDepth && Tex.HasStencil) + if (CachedImage.HasDepth && CachedImage.HasStencil) { - if (DepthAttachment != Tex.Handle || - StencilAttachment != Tex.Handle) + if (DepthAttachment != CachedImage.Handle || + StencilAttachment != CachedImage.Handle) { GL.FramebufferTexture( FramebufferTarget.DrawFramebuffer, FramebufferAttachment.DepthStencilAttachment, - Tex.Handle, + CachedImage.Handle, 0); - DepthAttachment = Tex.Handle; - - StencilAttachment = Tex.Handle; + DepthAttachment = CachedImage.Handle; + StencilAttachment = CachedImage.Handle; } } - else if (Tex.HasDepth) + else if (CachedImage.HasDepth) { - Attach(ref DepthAttachment, Tex.Handle, FramebufferAttachment.DepthAttachment); + Attach(ref DepthAttachment, CachedImage.Handle, FramebufferAttachment.DepthAttachment); Attach(ref StencilAttachment, 0, FramebufferAttachment.StencilAttachment); } - else if (Tex.HasStencil) + else if (CachedImage.HasStencil) { Attach(ref DepthAttachment, 0, FramebufferAttachment.DepthAttachment); - Attach(ref StencilAttachment, Tex.Handle, FramebufferAttachment.StencilAttachment); + Attach(ref StencilAttachment, CachedImage.Handle, FramebufferAttachment.StencilAttachment); } else { @@ -130,57 +128,40 @@ namespace Ryujinx.Graphics.Gal.OpenGL } } - public void UnbindZeta() + private void Attach(ref int OldHandle, int NewHandle, FramebufferAttachment FbAttachment) { - EnsureFrameBuffer(); - - if (DepthAttachment != 0 || - StencilAttachment != 0) + if (OldHandle != NewHandle) { GL.FramebufferTexture( FramebufferTarget.DrawFramebuffer, - FramebufferAttachment.DepthStencilAttachment, - 0, + FbAttachment, + NewHandle, 0); - DepthAttachment = 0; - - StencilAttachment = 0; + OldHandle = NewHandle; } } - public void BindTexture(long Key, int Index) + public void UnbindZeta() { - if (Texture.TryGetImage(Key, out ImageHandler Tex)) + EnsureFrameBuffer(); + + if (DepthAttachment != 0 || StencilAttachment != 0) { - GL.ActiveTexture(TextureUnit.Texture0 + Index); + GL.FramebufferTexture( + FramebufferTarget.DrawFramebuffer, + FramebufferAttachment.DepthStencilAttachment, + 0, + 0); - GL.BindTexture(TextureTarget.Texture2D, Tex.Handle); + DepthAttachment = 0; + StencilAttachment = 0; } } public void Set(long Key) { - if (Texture.TryGetImage(Key, out ImageHandler Tex)) - { - ReadTex = Tex; - } - } - - public void Set(byte[] Data, int Width, int Height) - { - if (RawTex == null) - { - RawTex = new ImageHandler(); - } - - RawTex.EnsureSetup(new GalImage(Width, Height, RawFormat)); - - GL.BindTexture(TextureTarget.Texture2D, RawTex.Handle); - - GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, Width, Height, RawTex.PixelFormat, RawTex.PixelType, Data); - - ReadTex = RawTex; + Texture.TryGetImageHandler(Key, out ReadTex); } public void SetMap(int[] Map) @@ -280,13 +261,15 @@ namespace Ryujinx.Graphics.Gal.OpenGL int DstY0 = FlipY ? DstPaddingY : Window.Height - DstPaddingY; int DstY1 = FlipY ? Window.Height - DstPaddingY : DstPaddingY; - if (SrcFb == 0) SrcFb = GL.GenFramebuffer(); - - GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, 0); - GL.Viewport(0, 0, Window.Width, Window.Height); + if (SrcFb == 0) + { + SrcFb = GL.GenFramebuffer(); + } + GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, SrcFb); + GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, 0); GL.FramebufferTexture(FramebufferTarget.ReadFramebuffer, FramebufferAttachment.ColorAttachment0, ReadTex.Handle, 0); @@ -298,7 +281,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL GL.BlitFramebuffer( SrcX0, SrcY0, SrcX1, SrcY1, DstX0, DstY0, DstX1, DstY1, - ClearBufferMask.ColorBufferBit, BlitFramebufferFilter.Linear); + ClearBufferMask.ColorBufferBit, + BlitFramebufferFilter.Linear); EnsureFrameBuffer(); } @@ -315,183 +299,145 @@ namespace Ryujinx.Graphics.Gal.OpenGL int DstX1, int DstY1) { - if (Texture.TryGetImage(SrcKey, out ImageHandler SrcTex) && - Texture.TryGetImage(DstKey, out ImageHandler DstTex)) + if (Texture.TryGetImageHandler(SrcKey, out ImageHandler SrcTex) && + Texture.TryGetImageHandler(DstKey, out ImageHandler DstTex)) { - if (SrcTex.HasColor != DstTex.HasColor || - SrcTex.HasDepth != DstTex.HasDepth || + if (SrcTex.HasColor != DstTex.HasColor || + SrcTex.HasDepth != DstTex.HasDepth || SrcTex.HasStencil != DstTex.HasStencil) { throw new NotImplementedException(); } - if (SrcTex.HasColor) + if (SrcFb == 0) { - CopyTextures( - SrcX0, SrcY0, SrcX1, SrcY1, - DstX0, DstY0, DstX1, DstY1, - SrcTex.Handle, - DstTex.Handle, - FramebufferAttachment.ColorAttachment0, - ClearBufferMask.ColorBufferBit, - true); + SrcFb = GL.GenFramebuffer(); } - else if (SrcTex.HasDepth && SrcTex.HasStencil) - { - CopyTextures( - SrcX0, SrcY0, SrcX1, SrcY1, - DstX0, DstY0, DstX1, DstY1, - SrcTex.Handle, - DstTex.Handle, - FramebufferAttachment.DepthStencilAttachment, - ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit, - false); - } - else if (SrcTex.HasDepth) - { - CopyTextures( - SrcX0, SrcY0, SrcX1, SrcY1, - DstX0, DstY0, DstX1, DstY1, - SrcTex.Handle, - DstTex.Handle, - FramebufferAttachment.DepthAttachment, - ClearBufferMask.DepthBufferBit, - false); - } - else if (SrcTex.HasStencil) + + if (DstFb == 0) { - CopyTextures( - SrcX0, SrcY0, SrcX1, SrcY1, - DstX0, DstY0, DstX1, DstY1, - SrcTex.Handle, - DstTex.Handle, - FramebufferAttachment.StencilAttachment, - ClearBufferMask.StencilBufferBit, - false); + DstFb = GL.GenFramebuffer(); } - else + + GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, SrcFb); + GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, DstFb); + + FramebufferAttachment Attachment = GetAttachment(SrcTex); + + GL.FramebufferTexture(FramebufferTarget.ReadFramebuffer, Attachment, SrcTex.Handle, 0); + GL.FramebufferTexture(FramebufferTarget.DrawFramebuffer, Attachment, DstTex.Handle, 0); + + BlitFramebufferFilter Filter = BlitFramebufferFilter.Nearest; + + if (SrcTex.HasColor) { - throw new InvalidOperationException(); + GL.DrawBuffer(DrawBufferMode.ColorAttachment0); + + Filter = BlitFramebufferFilter.Linear; } - } - } - public void GetBufferData(long Key, Action<byte[]> Callback) - { - if (Texture.TryGetImage(Key, out ImageHandler Tex)) - { - byte[] Data = new byte[ImageUtils.GetSize(Tex.Image)]; + ClearBufferMask Mask = GetClearMask(SrcTex); - GL.BindTexture(TextureTarget.Texture2D, Tex.Handle); + GL.Clear(Mask); - GL.GetTexImage( - TextureTarget.Texture2D, - 0, - Tex.PixelFormat, - Tex.PixelType, - Data); + GL.BlitFramebuffer(SrcX0, SrcY0, SrcX1, SrcY1, DstX0, DstY0, DstX1, DstY1, Mask, Filter); - Callback(Data); + EnsureFrameBuffer(); } } - public void SetBufferData( - long Key, - int Width, - int Height, - byte[] Buffer) + public void Reinterpret(long Key, GalImage NewImage) { - if (Texture.TryGetImage(Key, out ImageHandler Tex)) + if (!Texture.TryGetImage(Key, out GalImage OldImage)) { - GL.BindTexture(TextureTarget.Texture2D, Tex.Handle); - - const int Level = 0; - const int Border = 0; - - GL.TexImage2D( - TextureTarget.Texture2D, - Level, - Tex.InternalFormat, - Width, - Height, - Border, - Tex.PixelFormat, - Tex.PixelType, - Buffer); + return; } - } - private void EnsureFrameBuffer() - { - if (DummyFrameBuffer == 0) + if (NewImage.Format == OldImage.Format) { - DummyFrameBuffer = GL.GenFramebuffer(); + return; } - GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, DummyFrameBuffer); + byte[] Data = GetData(Key); + + GL.PixelStore(PixelStoreParameter.UnpackRowLength, OldImage.Width); + + Texture.Create(Key, Data, NewImage); + + GL.PixelStore(PixelStoreParameter.UnpackRowLength, 0); } - private void Attach(ref int OldHandle, int NewHandle, FramebufferAttachment FbAttachment) + public byte[] GetData(long Key) { - if (OldHandle != NewHandle) + if (!Texture.TryGetImageHandler(Key, out ImageHandler CachedImage)) { - GL.FramebufferTexture( - FramebufferTarget.DrawFramebuffer, - FbAttachment, - NewHandle, - 0); - - OldHandle = NewHandle; + return null; } - } - private void CopyTextures( - int SrcX0, - int SrcY0, - int SrcX1, - int SrcY1, - int DstX0, - int DstY0, - int DstX1, - int DstY1, - int SrcTexture, - int DstTexture, - FramebufferAttachment Attachment, - ClearBufferMask Mask, - bool Color) - { - if (SrcFb == 0) SrcFb = GL.GenFramebuffer(); - if (DstFb == 0) DstFb = GL.GenFramebuffer(); + if (SrcFb == 0) + { + SrcFb = GL.GenFramebuffer(); + } GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, SrcFb); - GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, DstFb); - GL.FramebufferTexture( - FramebufferTarget.ReadFramebuffer, - Attachment, - SrcTexture, - 0); + FramebufferAttachment Attachment = GetAttachment(CachedImage); + + GL.FramebufferTexture(FramebufferTarget.ReadFramebuffer, Attachment, CachedImage.Handle, 0); + + int Size = ImageUtils.GetSize(CachedImage.Image); + + byte[] Data = new byte[Size]; - GL.FramebufferTexture( - FramebufferTarget.DrawFramebuffer, - Attachment, - DstTexture, - 0); + int Width = CachedImage.Width; + int Height = CachedImage.Height; - if (Color) + (_, PixelFormat Format, PixelType Type) = OGLEnumConverter.GetImageFormat(CachedImage.Format); + + GL.ReadPixels(0, 0, Width, Height, Format, Type, Data); + + return Data; + } + + private static FramebufferAttachment GetAttachment(ImageHandler CachedImage) + { + if (CachedImage.HasColor) { - GL.DrawBuffer(DrawBufferMode.ColorAttachment0); + return FramebufferAttachment.ColorAttachment0; + } + else if (CachedImage.HasDepth && CachedImage.HasStencil) + { + return FramebufferAttachment.DepthStencilAttachment; + } + else if (CachedImage.HasDepth) + { + return FramebufferAttachment.DepthAttachment; + } + else if (CachedImage.HasStencil) + { + return FramebufferAttachment.StencilAttachment; + } + else + { + throw new InvalidOperationException(); } + } - GL.Clear(Mask); + private static ClearBufferMask GetClearMask(ImageHandler CachedImage) + { + return (CachedImage.HasColor ? ClearBufferMask.ColorBufferBit : 0) | + (CachedImage.HasDepth ? ClearBufferMask.DepthBufferBit : 0) | + (CachedImage.HasStencil ? ClearBufferMask.StencilBufferBit : 0); + } - GL.BlitFramebuffer( - SrcX0, SrcY0, SrcX1, SrcY1, - DstX0, DstY0, DstX1, DstY1, - Mask, - Color ? BlitFramebufferFilter.Linear : BlitFramebufferFilter.Nearest); + private void EnsureFrameBuffer() + { + if (DummyFrameBuffer == 0) + { + DummyFrameBuffer = GL.GenFramebuffer(); + } - EnsureFrameBuffer(); + GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, DummyFrameBuffer); } } }
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs index 7e1c0e53..3347afbd 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs @@ -28,17 +28,65 @@ namespace Ryujinx.Graphics.Gal.OpenGL GL.DeleteTexture(CachedImage.Handle); } - public void Create(long Key, byte[] Data, GalImage Image) + public void Create(long Key, int Size, GalImage Image) { int Handle = GL.GenTexture(); - TextureCache.AddOrUpdate(Key, new ImageHandler(Handle, Image), (uint)Data.Length); + GL.BindTexture(TextureTarget.Texture2D, Handle); + + const int Level = 0; //TODO: Support mipmap textures. + const int Border = 0; + + TextureCache.AddOrUpdate(Key, new ImageHandler(Handle, Image), (uint)Size); + + GalImageFormat TypeLess = Image.Format & GalImageFormat.FormatMask; + + bool IsASTC = TypeLess >= GalImageFormat.ASTC_BEGIN && TypeLess <= GalImageFormat.ASTC_END; + + if (ImageUtils.IsCompressed(Image.Format) && !IsASTC) + { + InternalFormat InternalFmt = OGLEnumConverter.GetCompressedImageFormat(Image.Format); + + GL.CompressedTexImage2D( + TextureTarget.Texture2D, + Level, + InternalFmt, + Image.Width, + Image.Height, + Border, + Size, + IntPtr.Zero); + } + else + { + (PixelInternalFormat InternalFmt, + PixelFormat Format, + PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format); + + GL.TexImage2D( + TextureTarget.Texture2D, + Level, + InternalFmt, + Image.Width, + Image.Height, + Border, + Format, + Type, + IntPtr.Zero); + } + } + + public void Create(long Key, byte[] Data, GalImage Image) + { + int Handle = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, Handle); const int Level = 0; //TODO: Support mipmap textures. const int Border = 0; + TextureCache.AddOrUpdate(Key, new ImageHandler(Handle, Image), (uint)Data.Length); + GalImageFormat TypeLess = Image.Format & GalImageFormat.FormatMask; bool IsASTC = TypeLess >= GalImageFormat.ASTC_BEGIN && TypeLess <= GalImageFormat.ASTC_END; @@ -62,8 +110,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL //TODO: Use KHR_texture_compression_astc_hdr when available if (IsASTC) { - int TextureBlockWidth = GetAstcBlockWidth(Image.Format); - int TextureBlockHeight = GetAstcBlockHeight(Image.Format); + int TextureBlockWidth = ImageUtils.GetBlockWidth(Image.Format); + int TextureBlockHeight = ImageUtils.GetBlockHeight(Image.Format); Data = ASTCDecoder.DecodeToRGBA8888( Data, @@ -85,12 +133,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL Image.Format = GalImageFormat.R8G8 | (Image.Format & GalImageFormat.TypeMask); } - (PixelInternalFormat InternalFormat, PixelFormat Format, PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format); + (PixelInternalFormat InternalFmt, + PixelFormat Format, + PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format); GL.TexImage2D( TextureTarget.Texture2D, Level, - InternalFormat, + InternalFmt, Image.Width, Image.Height, Border, @@ -98,112 +148,51 @@ namespace Ryujinx.Graphics.Gal.OpenGL Type, Data); } - - int SwizzleR = (int)OGLEnumConverter.GetTextureSwizzle(Image.XSource); - int SwizzleG = (int)OGLEnumConverter.GetTextureSwizzle(Image.YSource); - int SwizzleB = (int)OGLEnumConverter.GetTextureSwizzle(Image.ZSource); - int SwizzleA = (int)OGLEnumConverter.GetTextureSwizzle(Image.WSource); - - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleR, SwizzleR); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleG, SwizzleG); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleB, SwizzleB); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleA, SwizzleA); } - public void CreateFb(long Key, long Size, GalImage Image) + public bool TryGetImage(long Key, out GalImage Image) { - if (!TryGetImage(Key, out ImageHandler CachedImage)) + if (TextureCache.TryGetValue(Key, out ImageHandler CachedImage)) { - CachedImage = new ImageHandler(); - - TextureCache.AddOrUpdate(Key, CachedImage, Size); - } + Image = CachedImage.Image; - CachedImage.EnsureSetup(Image); - } - - public bool TryGetImage(long Key, out ImageHandler CachedImage) - { - if (TextureCache.TryGetValue(Key, out CachedImage)) - { return true; } - CachedImage = null; + Image = default(GalImage); return false; } - private static int GetAstcBlockWidth(GalImageFormat Format) + public bool TryGetImageHandler(long Key, out ImageHandler CachedImage) { - switch (Format) - { - case GalImageFormat.ASTC_4x4 | GalImageFormat.Unorm: return 4; - case GalImageFormat.ASTC_5x5 | GalImageFormat.Unorm: return 5; - case GalImageFormat.ASTC_6x6 | GalImageFormat.Unorm: return 6; - case GalImageFormat.ASTC_8x8 | GalImageFormat.Unorm: return 8; - case GalImageFormat.ASTC_10x10 | GalImageFormat.Unorm: return 10; - case GalImageFormat.ASTC_12x12 | GalImageFormat.Unorm: return 12; - case GalImageFormat.ASTC_5x4 | GalImageFormat.Unorm: return 5; - case GalImageFormat.ASTC_6x5 | GalImageFormat.Unorm: return 6; - case GalImageFormat.ASTC_8x6 | GalImageFormat.Unorm: return 8; - case GalImageFormat.ASTC_10x8 | GalImageFormat.Unorm: return 10; - case GalImageFormat.ASTC_12x10 | GalImageFormat.Unorm: return 12; - case GalImageFormat.ASTC_8x5 | GalImageFormat.Unorm: return 8; - case GalImageFormat.ASTC_10x5 | GalImageFormat.Unorm: return 10; - case GalImageFormat.ASTC_10x6 | GalImageFormat.Unorm: return 10; - } - - throw new ArgumentException(nameof(Format)); - } - - private static int GetAstcBlockHeight(GalImageFormat Format) - { - switch (Format) - { - case GalImageFormat.ASTC_4x4 | GalImageFormat.Unorm: return 4; - case GalImageFormat.ASTC_5x5 | GalImageFormat.Unorm: return 5; - case GalImageFormat.ASTC_6x6 | GalImageFormat.Unorm: return 6; - case GalImageFormat.ASTC_8x8 | GalImageFormat.Unorm: return 8; - case GalImageFormat.ASTC_10x10 | GalImageFormat.Unorm: return 10; - case GalImageFormat.ASTC_12x12 | GalImageFormat.Unorm: return 12; - case GalImageFormat.ASTC_5x4 | GalImageFormat.Unorm: return 4; - case GalImageFormat.ASTC_6x5 | GalImageFormat.Unorm: return 5; - case GalImageFormat.ASTC_8x6 | GalImageFormat.Unorm: return 6; - case GalImageFormat.ASTC_10x8 | GalImageFormat.Unorm: return 8; - case GalImageFormat.ASTC_12x10 | GalImageFormat.Unorm: return 10; - case GalImageFormat.ASTC_8x5 | GalImageFormat.Unorm: return 5; - case GalImageFormat.ASTC_10x5 | GalImageFormat.Unorm: return 5; - case GalImageFormat.ASTC_10x6 | GalImageFormat.Unorm: return 6; - } - - throw new ArgumentException(nameof(Format)); - } - - public bool TryGetCachedTexture(long Key, long DataSize, out GalImage Image) - { - if (TextureCache.TryGetSize(Key, out long Size) && Size == DataSize) + if (TextureCache.TryGetValue(Key, out CachedImage)) { - if (TextureCache.TryGetValue(Key, out ImageHandler CachedImage)) - { - Image = CachedImage.Image; - - return true; - } + return true; } - Image = default(GalImage); + CachedImage = null; return false; } - public void Bind(long Key, int Index) + public void Bind(long Key, int Index, GalImage Image) { if (TextureCache.TryGetValue(Key, out ImageHandler CachedImage)) { GL.ActiveTexture(TextureUnit.Texture0 + Index); GL.BindTexture(TextureTarget.Texture2D, CachedImage.Handle); + + int[] SwizzleRgba = new int[] + { + (int)OGLEnumConverter.GetTextureSwizzle(Image.XSource), + (int)OGLEnumConverter.GetTextureSwizzle(Image.YSource), + (int)OGLEnumConverter.GetTextureSwizzle(Image.ZSource), + (int)OGLEnumConverter.GetTextureSwizzle(Image.WSource) + }; + + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleRgba, SwizzleRgba); } } diff --git a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs index ac34400e..60fe91c2 100644 --- a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs +++ b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs @@ -641,6 +641,7 @@ namespace Ryujinx.Graphics.Gal.Shader default: SB.AppendLine(Identation + GetSrcExpr(Op, true) + ";"); + break; } } diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs index c2ee474b..0a3c0da9 100644 --- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs +++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeAlu.cs @@ -6,32 +6,32 @@ namespace Ryujinx.Graphics.Gal.Shader { static partial class ShaderDecode { - public static void Bfe_C(ShaderIrBlock Block, long OpCode, long Position) + public static void Bfe_C(ShaderIrBlock Block, long OpCode, int Position) { EmitBfe(Block, OpCode, ShaderOper.CR); } - public static void Bfe_I(ShaderIrBlock Block, long OpCode, long Position) + public static void Bfe_I(ShaderIrBlock Block, long OpCode, int Position) { EmitBfe(Block, OpCode, ShaderOper.Imm); } - public static void Bfe_R(ShaderIrBlock Block, long OpCode, long Position) + public static void Bfe_R(ShaderIrBlock Block, long OpCode, int Position) { EmitBfe(Block, OpCode, ShaderOper.RR); } - public static void Fadd_C(ShaderIrBlock Block, long OpCode, long Position) + public static void Fadd_C(ShaderIrBlock Block, long OpCode, int Position) { EmitFadd(Block, OpCode, ShaderOper.CR); } - public static void Fadd_I(ShaderIrBlock Block, long OpCode, long Position) + public static void Fadd_I(ShaderIrBlock Block, long OpCode, int Position) { EmitFadd(Block, OpCode, ShaderOper.Immf); } - public static void Fadd_I32(ShaderIrBlock Block, long OpCode, long Position) + public static void Fadd_I32(ShaderIrBlock Block, long OpCode, int Position) { ShaderIrNode OperA = OpCode.Gpr8(); ShaderIrNode OperB = OpCode.Immf32_20(); @@ -49,47 +49,47 @@ namespace Ryujinx.Graphics.Gal.Shader Block.AddNode(OpCode.PredNode(new ShaderIrAsg(OpCode.Gpr0(), Op))); } - public static void Fadd_R(ShaderIrBlock Block, long OpCode, long Position) + public static void Fadd_R(ShaderIrBlock Block, long OpCode, int Position) { EmitFadd(Block, OpCode, ShaderOper.RR); } - public static void Ffma_CR(ShaderIrBlock Block, long OpCode, long Position) + public static void Ffma_CR(ShaderIrBlock Block, long OpCode, int Position) { EmitFfma(Block, OpCode, ShaderOper.CR); } - public static void Ffma_I(ShaderIrBlock Block, long OpCode, long Position) + public static void Ffma_I(ShaderIrBlock Block, long OpCode, int Position) { EmitFfma(Block, OpCode, ShaderOper.Immf); } - public static void Ffma_RC(ShaderIrBlock Block, long OpCode, long Position) + public static void Ffma_RC(ShaderIrBlock Block, long OpCode, int Position) { EmitFfma(Block, OpCode, ShaderOper.RC); } - public static void Ffma_RR(ShaderIrBlock Block, long OpCode, long Position) + public static void Ffma_RR(ShaderIrBlock Block, long OpCode, int Position) { EmitFfma(Block, OpCode, ShaderOper.RR); } - public static void Fmnmx_C(ShaderIrBlock Block, long OpCode, long Position) + public static void Fmnmx_C(ShaderIrBlock Block, long OpCode, int Position) { EmitFmnmx(Block, OpCode, ShaderOper.CR); } - public static void Fmnmx_I(ShaderIrBlock Block, long OpCode, long Position) + public static void Fmnmx_I(ShaderIrBlock Block, long OpCode, int Position) { EmitFmnmx(Block, OpCode, ShaderOper.Immf); } - public static void Fmnmx_R(ShaderIrBlock Block, long OpCode, long Position) + public static void Fmnmx_R(ShaderIrBlock Block, long OpCode, int Position) { EmitFmnmx(Block, OpCode, ShaderOper.RR); } - public static void Fmul_I32(ShaderIrBlock Block, long OpCode, long Position) + public static void Fmul_I32(ShaderIrBlock Block, long OpCode, int Position) { ShaderIrNode OperA = OpCode.Gpr8(); ShaderIrNode OperB = OpCode.Immf32_20(); @@ -99,62 +99,62 @@ namespace Ryujinx.Graphics.Gal.Shader Block.AddNode(OpCode.PredNode(new ShaderIrAsg(OpCode.Gpr0(), Op))); } - public static void Fmul_C(ShaderIrBlock Block, long OpCode, long Position) + public static void Fmul_C(ShaderIrBlock Block, long OpCode, int Position) { EmitFmul(Block, OpCode, ShaderOper.CR); } - public static void Fmul_I(ShaderIrBlock Block, long OpCode, long Position) + public static void Fmul_I(ShaderIrBlock Block, long OpCode, int Position) { EmitFmul(Block, OpCode, ShaderOper.Immf); } - public static void Fmul_R(ShaderIrBlock Block, long OpCode, long Position) + public static void Fmul_R(ShaderIrBlock Block, long OpCode, int Position) { EmitFmul(Block, OpCode, ShaderOper.RR); } - public static void Fset_C(ShaderIrBlock Block, long OpCode, long Position) + public static void Fset_C(ShaderIrBlock Block, long OpCode, int Position) { EmitFset(Block, OpCode, ShaderOper.CR); } - public static void Fset_I(ShaderIrBlock Block, long OpCode, long Position) + public static void Fset_I(ShaderIrBlock Block, long OpCode, int Position) { EmitFset(Block, OpCode, ShaderOper.Immf); } - public static void Fset_R(ShaderIrBlock Block, long OpCode, long Position) + public static void Fset_R(ShaderIrBlock Block, long OpCode, int Position) { EmitFset(Block, OpCode, ShaderOper.RR); } - public static void Fsetp_C(ShaderIrBlock Block, long OpCode, long Position) + public static void Fsetp_C(ShaderIrBlock Block, long OpCode, int Position) { EmitFsetp(Block, OpCode, ShaderOper.CR); } - public static void Fsetp_I(ShaderIrBlock Block, long OpCode, long Position) + public static void Fsetp_I(ShaderIrBlock Block, long OpCode, int Position) { EmitFsetp(Block, OpCode, ShaderOper.Immf); } - public static void Fsetp_R(ShaderIrBlock Block, long OpCode, long Position) + public static void Fsetp_R(ShaderIrBlock Block, long OpCode, int Position) { EmitFsetp(Block, OpCode, ShaderOper.RR); } - public static void Iadd_C(ShaderIrBlock Block, long OpCode, long Position) + public static void Iadd_C(ShaderIrBlock Block, long OpCode, int Position) { EmitIadd(Block, OpCode, ShaderOper.CR); } - public static void Iadd_I(ShaderIrBlock Block, long OpCode, long Position) + public static void Iadd_I(ShaderIrBlock Block, long OpCode, int Position) { EmitIadd(Block, OpCode, ShaderOper.Imm); } - public static void Iadd_I32(ShaderIrBlock Block, long OpCode, long Position) + public static void Iadd_I32(ShaderIrBlock Block, long OpCode, int Position) { ShaderIrNode OperA = OpCode.Gpr8(); ShaderIrNode OperB = OpCode.Imm32_20(); @@ -168,42 +168,42 @@ namespace Ryujinx.Graphics.Gal.Shader Block.AddNode(OpCode.PredNode(new ShaderIrAsg(OpCode.Gpr0(), Op))); } - public static void Iadd_R(ShaderIrBlock Block, long OpCode, long Position) + public static void Iadd_R(ShaderIrBlock Block, long OpCode, int Position) { EmitIadd(Block, OpCode, ShaderOper.RR); } - public static void Iadd3_C(ShaderIrBlock Block, long OpCode, long Position) + public static void Iadd3_C(ShaderIrBlock Block, long OpCode, int Position) { EmitIadd3(Block, OpCode, ShaderOper.CR); } - public static void Iadd3_I(ShaderIrBlock Block, long OpCode, long Position) + public static void Iadd3_I(ShaderIrBlock Block, long OpCode, int Position) { EmitIadd3(Block, OpCode, ShaderOper.Imm); } - public static void Iadd3_R(ShaderIrBlock Block, long OpCode, long Position) + public static void Iadd3_R(ShaderIrBlock Block, long OpCode, int Position) { EmitIadd3(Block, OpCode, ShaderOper.RR); } - public static void Imnmx_C(ShaderIrBlock Block, long OpCode, long Position) + public static void Imnmx_C(ShaderIrBlock Block, long OpCode, int Position) { EmitImnmx(Block, OpCode, ShaderOper.CR); } - public static void Imnmx_I(ShaderIrBlock Block, long OpCode, long Position) + public static void Imnmx_I(ShaderIrBlock Block, long OpCode, int Position) { EmitImnmx(Block, OpCode, ShaderOper.Imm); } - public static void Imnmx_R(ShaderIrBlock Block, long OpCode, long Position) + public static void Imnmx_R(ShaderIrBlock Block, long OpCode, int Position) { EmitImnmx(Block, OpCode, ShaderOper.RR); } - public static void Ipa(ShaderIrBlock Block, long OpCode, long Position) + public static void Ipa(ShaderIrBlock Block, long OpCode, int Position) { ShaderIrNode OperA = OpCode.Abuf28(); ShaderIrNode OperB = OpCode.Gpr20(); @@ -217,52 +217,52 @@ namespace Ryujinx.Graphics.Gal.Shader Block.AddNode(OpCode.PredNode(new ShaderIrAsg(OpCode.Gpr0(), Op))); } - public static void Iscadd_C(ShaderIrBlock Block, long OpCode, long Position) + public static void Iscadd_C(ShaderIrBlock Block, long OpCode, int Position) { EmitIscadd(Block, OpCode, ShaderOper.CR); } - public static void Iscadd_I(ShaderIrBlock Block, long OpCode, long Position) + public static void Iscadd_I(ShaderIrBlock Block, long OpCode, int Position) { EmitIscadd(Block, OpCode, ShaderOper.Imm); } - public static void Iscadd_R(ShaderIrBlock Block, long OpCode, long Position) + public static void Iscadd_R(ShaderIrBlock Block, long OpCode, int Position) { EmitIscadd(Block, OpCode, ShaderOper.RR); } - public static void Iset_C(ShaderIrBlock Block, long OpCode, long Position) + public static void Iset_C(ShaderIrBlock Block, long OpCode, int Position) { EmitIset(Block, OpCode, ShaderOper.CR); } - public static void Iset_I(ShaderIrBlock Block, long OpCode, long Position) + public static void Iset_I(ShaderIrBlock Block, long OpCode, int Position) { EmitIset(Block, OpCode, ShaderOper.Imm); } - public static void Iset_R(ShaderIrBlock Block, long OpCode, long Position) + public static void Iset_R(ShaderIrBlock Block, long OpCode, int Position) { EmitIset(Block, OpCode, ShaderOper.RR); } - public static void Isetp_C(ShaderIrBlock Block, long OpCode, long Position) + public static void Isetp_C(ShaderIrBlock Block, long OpCode, int Position) { EmitIsetp(Block, OpCode, ShaderOper.CR); } - public static void Isetp_I(ShaderIrBlock Block, long OpCode, long Position) + public static void Isetp_I(ShaderIrBlock Block, long OpCode, int Position) { EmitIsetp(Block, OpCode, ShaderOper.Imm); } - public static void Isetp_R(ShaderIrBlock Block, long OpCode, long Position) + public static void Isetp_R(ShaderIrBlock Block, long OpCode, int Position) { EmitIsetp(Block, OpCode, ShaderOper.RR); } - public static void Lop_I32(ShaderIrBlock Block, long OpCode, long Position) + public static void Lop_I32(ShaderIrBlock Block, long OpCode, int Position) { int SubOp = OpCode.Read(53, 3); @@ -296,22 +296,22 @@ namespace Ryujinx.Graphics.Gal.Shader } } - public static void Lop_C(ShaderIrBlock Block, long OpCode, long Position) + public static void Lop_C(ShaderIrBlock Block, long OpCode, int Position) { EmitLop(Block, OpCode, ShaderOper.CR); } - public static void Lop_I(ShaderIrBlock Block, long OpCode, long Position) + public static void Lop_I(ShaderIrBlock Block, long OpCode, int Position) { EmitLop(Block, OpCode, ShaderOper.Imm); } - public static void Lop_R(ShaderIrBlock Block, long OpCode, long Position) + public static void Lop_R(ShaderIrBlock Block, long OpCode, int Position) { EmitLop(Block, OpCode, ShaderOper.RR); } - public static void Mufu(ShaderIrBlock Block, long OpCode, long Position) + public static void Mufu(ShaderIrBlock Block, long OpCode, int Position) { int SubOp = OpCode.Read(20, 0xf); @@ -340,7 +340,7 @@ namespace Ryujinx.Graphics.Gal.Shader Block.AddNode(OpCode.PredNode(new ShaderIrAsg(OpCode.Gpr0(), Op))); } - public static void Psetp(ShaderIrBlock Block, long OpCode, long Position) + public static void Psetp(ShaderIrBlock Block, long OpCode, int Position) { bool NegA = OpCode.Read(15); bool NegB = OpCode.Read(32); @@ -394,47 +394,47 @@ namespace Ryujinx.Graphics.Gal.Shader Block.AddNode(OpCode.PredNode(new ShaderIrAsg(P0Node, Op))); } - public static void Rro_C(ShaderIrBlock Block, long OpCode, long Position) + public static void Rro_C(ShaderIrBlock Block, long OpCode, int Position) { EmitRro(Block, OpCode, ShaderOper.CR); } - public static void Rro_I(ShaderIrBlock Block, long OpCode, long Position) + public static void Rro_I(ShaderIrBlock Block, long OpCode, int Position) { EmitRro(Block, OpCode, ShaderOper.Immf); } - public static void Rro_R(ShaderIrBlock Block, long OpCode, long Position) + public static void Rro_R(ShaderIrBlock Block, long OpCode, int Position) { EmitRro(Block, OpCode, ShaderOper.RR); } - public static void Shl_C(ShaderIrBlock Block, long OpCode, long Position) + public static void Shl_C(ShaderIrBlock Block, long OpCode, int Position) { EmitAluBinary(Block, OpCode, ShaderOper.CR, ShaderIrInst.Lsl); } - public static void Shl_I(ShaderIrBlock Block, long OpCode, long Position) + public static void Shl_I(ShaderIrBlock Block, long OpCode, int Position) { EmitAluBinary(Block, OpCode, ShaderOper.Imm, ShaderIrInst.Lsl); } - public static void Shl_R(ShaderIrBlock Block, long OpCode, long Position) + public static void Shl_R(ShaderIrBlock Block, long OpCode, int Position) { EmitAluBinary(Block, OpCode, ShaderOper.RR, ShaderIrInst.Lsl); } - public static void Shr_C(ShaderIrBlock Block, long OpCode, long Position) + public static void Shr_C(ShaderIrBlock Block, long OpCode, int Position) { EmitAluBinary(Block, OpCode, ShaderOper.CR, GetShrInst(OpCode)); } - public static void Shr_I(ShaderIrBlock Block, long OpCode, long Position) + public static void Shr_I(ShaderIrBlock Block, long OpCode, int Position) { EmitAluBinary(Block, OpCode, ShaderOper.Imm, GetShrInst(OpCode)); } - public static void Shr_R(ShaderIrBlock Block, long OpCode, long Position) + public static void Shr_R(ShaderIrBlock Block, long OpCode, int Position) { EmitAluBinary(Block, OpCode, ShaderOper.RR, GetShrInst(OpCode)); } @@ -446,7 +446,7 @@ namespace Ryujinx.Graphics.Gal.Shader return Signed ? ShaderIrInst.Asr : ShaderIrInst.Lsr; } - public static void Vmad(ShaderIrBlock Block, long OpCode, long Position) + public static void Vmad(ShaderIrBlock Block, long OpCode, int Position) { ShaderIrNode OperA = OpCode.Gpr8(); @@ -481,22 +481,22 @@ namespace Ryujinx.Graphics.Gal.Shader Block.AddNode(OpCode.PredNode(new ShaderIrAsg(OpCode.Gpr0(), Final))); } - public static void Xmad_CR(ShaderIrBlock Block, long OpCode, long Position) + public static void Xmad_CR(ShaderIrBlock Block, long OpCode, int Position) { EmitXmad(Block, OpCode, ShaderOper.CR); } - public static void Xmad_I(ShaderIrBlock Block, long OpCode, long Position) + public static void Xmad_I(ShaderIrBlock Block, long OpCode, int Position) { EmitXmad(Block, OpCode, ShaderOper.Imm); } - public static void Xmad_RC(ShaderIrBlock Block, long OpCode, long Position) + public static void Xmad_RC(ShaderIrBlock Block, long OpCode, int Position) { EmitXmad(Block, OpCode, ShaderOper.RC); } - public static void Xmad_RR(ShaderIrBlock Block, long OpCode, long Position) + public static void Xmad_RR(ShaderIrBlock Block, long OpCode, int Position) { EmitXmad(Block, OpCode, ShaderOper.RR); } diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeFlow.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeFlow.cs index dfd10e00..bc2539bd 100644 --- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeFlow.cs +++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeFlow.cs @@ -1,12 +1,10 @@ using System; -using static Ryujinx.Graphics.Gal.Shader.ShaderDecodeHelper; - namespace Ryujinx.Graphics.Gal.Shader { static partial class ShaderDecode { - public static void Bra(ShaderIrBlock Block, long OpCode, long Position) + public static void Bra(ShaderIrBlock Block, long OpCode, int Position) { if ((OpCode & 0x20) != 0) { @@ -15,14 +13,12 @@ namespace Ryujinx.Graphics.Gal.Shader throw new NotImplementedException(); } - int Target = OpCode.Branch(); - - ShaderIrOperImm Imm = new ShaderIrOperImm(Target); + ShaderIrOperImm Imm = new ShaderIrOperImm(Position + OpCode.Branch()); Block.AddNode(OpCode.PredNode(new ShaderIrOp(ShaderIrInst.Bra, Imm))); } - public static void Exit(ShaderIrBlock Block, long OpCode, long Position) + public static void Exit(ShaderIrBlock Block, long OpCode, int Position) { int CCode = (int)OpCode & 0x1f; @@ -31,15 +27,14 @@ namespace Ryujinx.Graphics.Gal.Shader { Block.AddNode(OpCode.PredNode(new ShaderIrOp(ShaderIrInst.Exit))); } - } - public static void Kil(ShaderIrBlock Block, long OpCode, long Position) + public static void Kil(ShaderIrBlock Block, long OpCode, int Position) { Block.AddNode(OpCode.PredNode(new ShaderIrOp(ShaderIrInst.Kil))); } - public static void Ssy(ShaderIrBlock Block, long OpCode, long Position) + public static void Ssy(ShaderIrBlock Block, long OpCode, int Position) { if ((OpCode & 0x20) != 0) { @@ -48,19 +43,14 @@ namespace Ryujinx.Graphics.Gal.Shader throw new NotImplementedException(); } - int Offset = OpCode.Branch(); - - int Target = (int)(Position + Offset); - - ShaderIrOperImm Imm = new ShaderIrOperImm(Target); + ShaderIrOperImm Imm = new ShaderIrOperImm(Position + OpCode.Branch()); Block.AddNode(new ShaderIrOp(ShaderIrInst.Ssy, Imm)); } - public static void Sync(ShaderIrBlock Block, long OpCode, long Position) + public static void Sync(ShaderIrBlock Block, long OpCode, int Position) { //TODO: Implement Sync condition codes - Block.AddNode(OpCode.PredNode(new ShaderIrOp(ShaderIrInst.Sync))); } } diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecode.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeFunc.cs index 73625f65..73248aa0 100644 --- a/Ryujinx.Graphics/Gal/Shader/ShaderDecode.cs +++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeFunc.cs @@ -1,4 +1,4 @@ namespace Ryujinx.Graphics.Gal.Shader { - delegate void ShaderDecodeFunc(ShaderIrBlock Block, long OpCode, long Position); + delegate void ShaderDecodeFunc(ShaderIrBlock Block, long OpCode, int Position); }
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs index 010f06aa..ebacd53a 100644 --- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs +++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeHelper.cs @@ -1,5 +1,3 @@ -using System; - namespace Ryujinx.Graphics.Gal.Shader { static class ShaderDecodeHelper diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs index 508a0205..cd655995 100644 --- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs +++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMem.cs @@ -31,7 +31,7 @@ namespace Ryujinx.Graphics.Gal.Shader { RGB_, RG_A, R_BA, _GBA, RGBA, ____, ____, ____ } }; - public static void Ld_A(ShaderIrBlock Block, long OpCode, long Position) + public static void Ld_A(ShaderIrBlock Block, long OpCode, int Position) { ShaderIrNode[] Opers = OpCode.Abuf20(); @@ -50,7 +50,7 @@ namespace Ryujinx.Graphics.Gal.Shader } } - public static void Ld_C(ShaderIrBlock Block, long OpCode, long Position) + public static void Ld_C(ShaderIrBlock Block, long OpCode, int Position) { int CbufPos = OpCode.Read(22, 0x3fff); int CbufIndex = OpCode.Read(36, 0x1f); @@ -97,7 +97,7 @@ namespace Ryujinx.Graphics.Gal.Shader } } - public static void St_A(ShaderIrBlock Block, long OpCode, long Position) + public static void St_A(ShaderIrBlock Block, long OpCode, int Position) { ShaderIrNode[] Opers = OpCode.Abuf20(); @@ -113,7 +113,7 @@ namespace Ryujinx.Graphics.Gal.Shader } } - public static void Texq(ShaderIrBlock Block, long OpCode, long Position) + public static void Texq(ShaderIrBlock Block, long OpCode, int Position) { ShaderIrNode OperD = OpCode.Gpr0(); ShaderIrNode OperA = OpCode.Gpr8(); @@ -132,12 +132,12 @@ namespace Ryujinx.Graphics.Gal.Shader Block.AddNode(OpCode.PredNode(new ShaderIrAsg(OperA, Op1))); //Is this right? } - public static void Tex(ShaderIrBlock Block, long OpCode, long Position) + public static void Tex(ShaderIrBlock Block, long OpCode, int Position) { EmitTex(Block, OpCode, GprHandle: false); } - public static void Tex_B(ShaderIrBlock Block, long OpCode, long Position) + public static void Tex_B(ShaderIrBlock Block, long OpCode, int Position) { EmitTex(Block, OpCode, GprHandle: true); } @@ -202,12 +202,12 @@ namespace Ryujinx.Graphics.Gal.Shader } } - public static void Texs(ShaderIrBlock Block, long OpCode, long Position) + public static void Texs(ShaderIrBlock Block, long OpCode, int Position) { EmitTexs(Block, OpCode, ShaderIrInst.Texs); } - public static void Tlds(ShaderIrBlock Block, long OpCode, long Position) + public static void Tlds(ShaderIrBlock Block, long OpCode, int Position) { EmitTexs(Block, OpCode, ShaderIrInst.Txlf); } diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs index add39402..cd602db7 100644 --- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs +++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeMove.cs @@ -25,67 +25,67 @@ namespace Ryujinx.Graphics.Gal.Shader F64 = 3 } - public static void F2f_C(ShaderIrBlock Block, long OpCode, long Position) + public static void F2f_C(ShaderIrBlock Block, long OpCode, int Position) { EmitF2f(Block, OpCode, ShaderOper.CR); } - public static void F2f_I(ShaderIrBlock Block, long OpCode, long Position) + public static void F2f_I(ShaderIrBlock Block, long OpCode, int Position) { EmitF2f(Block, OpCode, ShaderOper.Immf); } - public static void F2f_R(ShaderIrBlock Block, long OpCode, long Position) + public static void F2f_R(ShaderIrBlock Block, long OpCode, int Position) { EmitF2f(Block, OpCode, ShaderOper.RR); } - public static void F2i_C(ShaderIrBlock Block, long OpCode, long Position) + public static void F2i_C(ShaderIrBlock Block, long OpCode, int Position) { EmitF2i(Block, OpCode, ShaderOper.CR); } - public static void F2i_I(ShaderIrBlock Block, long OpCode, long Position) + public static void F2i_I(ShaderIrBlock Block, long OpCode, int Position) { EmitF2i(Block, OpCode, ShaderOper.Immf); } - public static void F2i_R(ShaderIrBlock Block, long OpCode, long Position) + public static void F2i_R(ShaderIrBlock Block, long OpCode, int Position) { EmitF2i(Block, OpCode, ShaderOper.RR); } - public static void I2f_C(ShaderIrBlock Block, long OpCode, long Position) + public static void I2f_C(ShaderIrBlock Block, long OpCode, int Position) { EmitI2f(Block, OpCode, ShaderOper.CR); } - public static void I2f_I(ShaderIrBlock Block, long OpCode, long Position) + public static void I2f_I(ShaderIrBlock Block, long OpCode, int Position) { EmitI2f(Block, OpCode, ShaderOper.Imm); } - public static void I2f_R(ShaderIrBlock Block, long OpCode, long Position) + public static void I2f_R(ShaderIrBlock Block, long OpCode, int Position) { EmitI2f(Block, OpCode, ShaderOper.RR); } - public static void I2i_C(ShaderIrBlock Block, long OpCode, long Position) + public static void I2i_C(ShaderIrBlock Block, long OpCode, int Position) { EmitI2i(Block, OpCode, ShaderOper.CR); } - public static void I2i_I(ShaderIrBlock Block, long OpCode, long Position) + public static void I2i_I(ShaderIrBlock Block, long OpCode, int Position) { EmitI2i(Block, OpCode, ShaderOper.Imm); } - public static void I2i_R(ShaderIrBlock Block, long OpCode, long Position) + public static void I2i_R(ShaderIrBlock Block, long OpCode, int Position) { EmitI2i(Block, OpCode, ShaderOper.RR); } - public static void Isberd(ShaderIrBlock Block, long OpCode, long Position) + public static void Isberd(ShaderIrBlock Block, long OpCode, int Position) { //This instruction seems to be used to translate from an address to a vertex index in a GS //Stub it as such @@ -95,50 +95,50 @@ namespace Ryujinx.Graphics.Gal.Shader Block.AddNode(OpCode.PredNode(new ShaderIrAsg(OpCode.Gpr0(), OpCode.Gpr8()))); } - public static void Mov_C(ShaderIrBlock Block, long OpCode, long Position) + public static void Mov_C(ShaderIrBlock Block, long OpCode, int Position) { ShaderIrOperCbuf Cbuf = OpCode.Cbuf34(); Block.AddNode(OpCode.PredNode(new ShaderIrAsg(OpCode.Gpr0(), Cbuf))); } - public static void Mov_I(ShaderIrBlock Block, long OpCode, long Position) + public static void Mov_I(ShaderIrBlock Block, long OpCode, int Position) { ShaderIrOperImm Imm = OpCode.Imm19_20(); Block.AddNode(OpCode.PredNode(new ShaderIrAsg(OpCode.Gpr0(), Imm))); } - public static void Mov_I32(ShaderIrBlock Block, long OpCode, long Position) + public static void Mov_I32(ShaderIrBlock Block, long OpCode, int Position) { ShaderIrOperImm Imm = OpCode.Imm32_20(); Block.AddNode(OpCode.PredNode(new ShaderIrAsg(OpCode.Gpr0(), Imm))); } - public static void Mov_R(ShaderIrBlock Block, long OpCode, long Position) + public static void Mov_R(ShaderIrBlock Block, long OpCode, int Position) { ShaderIrOperGpr Gpr = OpCode.Gpr20(); Block.AddNode(OpCode.PredNode(new ShaderIrAsg(OpCode.Gpr0(), Gpr))); } - public static void Sel_C(ShaderIrBlock Block, long OpCode, long Position) + public static void Sel_C(ShaderIrBlock Block, long OpCode, int Position) { EmitSel(Block, OpCode, ShaderOper.CR); } - public static void Sel_I(ShaderIrBlock Block, long OpCode, long Position) + public static void Sel_I(ShaderIrBlock Block, long OpCode, int Position) { EmitSel(Block, OpCode, ShaderOper.Imm); } - public static void Sel_R(ShaderIrBlock Block, long OpCode, long Position) + public static void Sel_R(ShaderIrBlock Block, long OpCode, int Position) { EmitSel(Block, OpCode, ShaderOper.RR); } - public static void Mov_S(ShaderIrBlock Block, long OpCode, long Position) + public static void Mov_S(ShaderIrBlock Block, long OpCode, int Position) { Block.AddNode(new ShaderIrCmnt("Stubbed.")); diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeSpecial.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeSpecial.cs index c3e42654..35abdb76 100644 --- a/Ryujinx.Graphics/Gal/Shader/ShaderDecodeSpecial.cs +++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecodeSpecial.cs @@ -1,10 +1,8 @@ -using static Ryujinx.Graphics.Gal.Shader.ShaderDecodeHelper; - -namespace Ryujinx.Graphics.Gal.Shader +namespace Ryujinx.Graphics.Gal.Shader { static partial class ShaderDecode { - public static void Out_R(ShaderIrBlock Block, long OpCode, long Position) + public static void Out_R(ShaderIrBlock Block, long OpCode, int Position) { //TODO: Those registers have to be used for something ShaderIrOperGpr Gpr0 = OpCode.Gpr0(); diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecoder.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecoder.cs index 81d8f312..ac6ae8d5 100644 --- a/Ryujinx.Graphics/Gal/Shader/ShaderDecoder.cs +++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecoder.cs @@ -10,12 +10,14 @@ namespace Ryujinx.Graphics.Gal.Shader public static ShaderIrBlock[] Decode(IGalMemory Memory, long Start) { - Dictionary<long, ShaderIrBlock> Visited = new Dictionary<long, ShaderIrBlock>(); - Dictionary<long, ShaderIrBlock> VisitedEnd = new Dictionary<long, ShaderIrBlock>(); + Dictionary<int, ShaderIrBlock> Visited = new Dictionary<int, ShaderIrBlock>(); + Dictionary<int, ShaderIrBlock> VisitedEnd = new Dictionary<int, ShaderIrBlock>(); Queue<ShaderIrBlock> Blocks = new Queue<ShaderIrBlock>(); - ShaderIrBlock Enqueue(long Position, ShaderIrBlock Source = null) + long Beginning = Start + HeaderSize; + + ShaderIrBlock Enqueue(int Position, ShaderIrBlock Source = null) { if (!Visited.TryGetValue(Position, out ShaderIrBlock Output)) { @@ -34,13 +36,13 @@ namespace Ryujinx.Graphics.Gal.Shader return Output; } - ShaderIrBlock Entry = Enqueue(Start + HeaderSize); + ShaderIrBlock Entry = Enqueue(0); while (Blocks.Count > 0) { ShaderIrBlock Current = Blocks.Dequeue(); - FillBlock(Memory, Current, Start + HeaderSize); + FillBlock(Memory, Current, Beginning); //Set child blocks. "Branch" is the block the branch instruction //points to (when taken), "Next" is the block at the next address, @@ -54,20 +56,18 @@ namespace Ryujinx.Graphics.Gal.Shader if (InnerOp?.Inst == ShaderIrInst.Bra) { - int Offset = ((ShaderIrOperImm)InnerOp.OperandA).Value; - - long Target = Current.EndPosition + Offset; + int Target = ((ShaderIrOperImm)InnerOp.OperandA).Value; Current.Branch = Enqueue(Target, Current); } foreach (ShaderIrNode Node in Current.Nodes) { - if (Node is ShaderIrOp CurrOp && CurrOp.Inst == ShaderIrInst.Ssy) - { - int Offset = ((ShaderIrOperImm)CurrOp.OperandA).Value; + InnerOp = GetInnermostOp(Node); - long Target = Offset; + if (InnerOp is ShaderIrOp CurrOp && CurrOp.Inst == ShaderIrInst.Ssy) + { + int Target = ((ShaderIrOperImm)CurrOp.OperandA).Value; Current.Branch = Enqueue(Target, Current); } @@ -112,15 +112,15 @@ namespace Ryujinx.Graphics.Gal.Shader while (Visited.Count > 0) { - ulong FirstPos = ulong.MaxValue; + uint FirstPos = uint.MaxValue; foreach (ShaderIrBlock Block in Visited.Values) { - if (FirstPos > (ulong)Block.Position) - FirstPos = (ulong)Block.Position; + if (FirstPos > (uint)Block.Position) + FirstPos = (uint)Block.Position; } - ShaderIrBlock Current = Visited[(long)FirstPos]; + ShaderIrBlock Current = Visited[(int)FirstPos]; do { @@ -138,20 +138,20 @@ namespace Ryujinx.Graphics.Gal.Shader private static void FillBlock(IGalMemory Memory, ShaderIrBlock Block, long Beginning) { - long Position = Block.Position; + int Position = Block.Position; do { //Ignore scheduling instructions, which are written every 32 bytes. - if (((Position - Beginning) & 0x1f) == 0) + if ((Position & 0x1f) == 0) { Position += 8; continue; } - uint Word0 = (uint)Memory.ReadInt32(Position + 0); - uint Word1 = (uint)Memory.ReadInt32(Position + 4); + uint Word0 = (uint)Memory.ReadInt32(Position + Beginning + 0); + uint Word1 = (uint)Memory.ReadInt32(Position + Beginning + 4); Position += 8; @@ -161,7 +161,7 @@ namespace Ryujinx.Graphics.Gal.Shader if (AddDbgComments) { - string DbgOpCode = $"0x{(Position - Beginning - 8):x16}: 0x{OpCode:x16} "; + string DbgOpCode = $"0x{(Position - 8):x16}: 0x{OpCode:x16} "; DbgOpCode += (Decode?.Method.Name ?? "???"); @@ -169,7 +169,7 @@ namespace Ryujinx.Graphics.Gal.Shader { int Offset = ((int)(OpCode >> 20) << 8) >> 8; - long Target = Position + Offset - Beginning; + long Target = Position + Offset; DbgOpCode += " (0x" + Target.ToString("x16") + ")"; } diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderIrBlock.cs b/Ryujinx.Graphics/Gal/Shader/ShaderIrBlock.cs index 50e563b8..782f9626 100644 --- a/Ryujinx.Graphics/Gal/Shader/ShaderIrBlock.cs +++ b/Ryujinx.Graphics/Gal/Shader/ShaderIrBlock.cs @@ -4,8 +4,8 @@ namespace Ryujinx.Graphics.Gal.Shader { class ShaderIrBlock { - public long Position { get; set; } - public long EndPosition { get; set; } + public int Position { get; set; } + public int EndPosition { get; set; } public ShaderIrBlock Next { get; set; } public ShaderIrBlock Branch { get; set; } @@ -14,7 +14,7 @@ namespace Ryujinx.Graphics.Gal.Shader public List<ShaderIrNode> Nodes { get; private set; } - public ShaderIrBlock(long Position) + public ShaderIrBlock(int Position) { this.Position = Position; |
