From c20a11e6879aef34c844be3ac5fc4251b8835f5d Mon Sep 17 00:00:00 2001 From: gdkchan Date: Fri, 12 Oct 2018 18:41:40 -0300 Subject: [PATCH] Add support for half float attributes and fix texture pitch alignment --- Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs | 35 +++++++++++++++++++--- Ryujinx.Graphics/Texture/ImageUtils.cs | 6 +++- Ryujinx.Graphics/Texture/TextureFactory.cs | 9 +++++- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs index daac27560c..041fedb9cb 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs @@ -25,6 +25,19 @@ namespace Ryujinx.Graphics.Gal.OpenGL { GalVertexAttribSize._11_11_10, 3 } }; + private static Dictionary FloatAttribTypes = + new Dictionary() + { + { GalVertexAttribSize._32_32_32_32, VertexAttribPointerType.Float }, + { GalVertexAttribSize._32_32_32, VertexAttribPointerType.Float }, + { GalVertexAttribSize._16_16_16_16, VertexAttribPointerType.HalfFloat }, + { GalVertexAttribSize._32_32, VertexAttribPointerType.Float }, + { GalVertexAttribSize._16_16_16, VertexAttribPointerType.HalfFloat }, + { GalVertexAttribSize._16_16, VertexAttribPointerType.HalfFloat }, + { GalVertexAttribSize._32, VertexAttribPointerType.Float }, + { GalVertexAttribSize._16, VertexAttribPointerType.HalfFloat } + }; + private static Dictionary SignedAttribTypes = new Dictionary() { @@ -371,21 +384,25 @@ namespace Ryujinx.Graphics.Gal.OpenGL if (Attrib.Type == GalVertexAttribType.Float) { - Type = VertexAttribPointerType.Float; + Type = GetType(FloatAttribTypes, Attrib); } else { if (Unsigned) { - Type = UnsignedAttribTypes[Attrib.Size]; + Type = GetType(UnsignedAttribTypes, Attrib); } else { - Type = SignedAttribTypes[Attrib.Size]; + Type = GetType(SignedAttribTypes, Attrib); } } - int Size = AttribElements[Attrib.Size]; + if (!AttribElements.TryGetValue(Attrib.Size, out int Size)) + { + throw new InvalidOperationException("Invalid attribute size \"" + Attrib.Size + "\"!"); + } + int Offset = Attrib.Offset; if (Binding.Stride != 0) @@ -425,6 +442,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL } } + private static VertexAttribPointerType GetType(Dictionary Dict, GalVertexAttrib Attrib) + { + if (!Dict.TryGetValue(Attrib.Size, out VertexAttribPointerType Type)) + { + throw new NotImplementedException("Unsupported size \"" + Attrib.Size + "\" on type \"" + Attrib.Type + "\"!"); + } + + return Type; + } + private unsafe static void SetConstAttrib(GalVertexAttrib Attrib) { if (Attrib.Size == GalVertexAttribSize._10_10_10_2 || diff --git a/Ryujinx.Graphics/Texture/ImageUtils.cs b/Ryujinx.Graphics/Texture/ImageUtils.cs index 18a179fbfa..1b043245ef 100644 --- a/Ryujinx.Graphics/Texture/ImageUtils.cs +++ b/Ryujinx.Graphics/Texture/ImageUtils.cs @@ -289,7 +289,11 @@ namespace Ryujinx.Graphics.Texture { ImageDescriptor Desc = GetImageDescriptor(Format); - return Desc.BytesPerPixel * DivRoundUp(Width, Desc.BlockWidth); + int Pitch = Desc.BytesPerPixel * DivRoundUp(Width, Desc.BlockWidth); + + Pitch = (Pitch + 0x1f) & ~0x1f; + + return Pitch; } public static int GetBlockWidth(GalImageFormat Format) diff --git a/Ryujinx.Graphics/Texture/TextureFactory.cs b/Ryujinx.Graphics/Texture/TextureFactory.cs index 766c53da46..c0c53b06ef 100644 --- a/Ryujinx.Graphics/Texture/TextureFactory.cs +++ b/Ryujinx.Graphics/Texture/TextureFactory.cs @@ -40,7 +40,7 @@ namespace Ryujinx.Graphics.Texture int Width = (Tic[4] & 0xffff) + 1; int Height = (Tic[5] & 0xffff) + 1; - return new GalImage( + GalImage Image = new GalImage( Width, Height, TileWidth, @@ -51,6 +51,13 @@ namespace Ryujinx.Graphics.Texture YSource, ZSource, WSource); + + if (Layout == GalMemoryLayout.Pitch) + { + Image.Pitch = (Tic[3] & 0xffff) << 5; + } + + return Image; } public static GalTextureSampler MakeSampler(NvGpu Gpu, NvGpuVmm Vmm, long TscPosition)