From 0fe651cc2fccc1562741f78e0e8fa8130b0e8283 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 5 Aug 2018 18:01:15 -0300 Subject: [PATCH 01/13] Add multiple color outputs for fragment shaders --- Ryujinx.Graphics/Gal/Shader/GlslDecl.cs | 6 +++++- Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs b/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs index ccc59e0489..74404ced50 100644 --- a/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs +++ b/Ryujinx.Graphics/Gal/Shader/GlslDecl.cs @@ -16,6 +16,7 @@ namespace Ryujinx.Graphics.Gal.Shader public const int VertexIdAttr = 0x2fc; public const int FaceAttr = 0x3fc; + public const int MaxFrameBufferAttachments = 8; public const int MaxUboSize = 1024; public const int GlPositionVec4Index = 7; @@ -99,7 +100,10 @@ namespace Ryujinx.Graphics.Gal.Shader if (ShaderType == GalShaderType.Fragment) { - m_Gprs.Add(0, new ShaderDeclInfo(FragmentOutputName, 0, false, 0, 4)); + for (int Index = 0; Index < MaxFrameBufferAttachments; Index++) + { + m_Gprs.Add(Index * 4, new ShaderDeclInfo(FragmentOutputName + Index, Index * 4, false, 0, 4)); + } } foreach (ShaderIrBlock Block in Blocks) diff --git a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs index 7f1cfabc8c..08d3f64cdd 100644 --- a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs +++ b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs @@ -352,9 +352,9 @@ namespace Ryujinx.Graphics.Gal.Shader { Name = CustomType + " " + DeclInfo.Name + Suffix + ";"; } - else if (DeclInfo.Name == GlslDecl.FragmentOutputName) + else if (DeclInfo.Name.Contains(GlslDecl.FragmentOutputName)) { - Name = "layout (location = 0) out vec4 " + DeclInfo.Name + Suffix + ";" + Environment.NewLine; + Name = "layout (location = " + DeclInfo.Index / 4 + ") out vec4 " + DeclInfo.Name + Suffix + ";" + Environment.NewLine; } else { @@ -876,7 +876,7 @@ namespace Ryujinx.Graphics.Gal.Shader private string GetNameWithSwizzle(IReadOnlyDictionary Dict, int Index) { - int VecIndex = Index >> 2; + int VecIndex = Index & ~3; if (Dict.TryGetValue(VecIndex, out ShaderDeclInfo DeclInfo)) { From a11293b793553cd6be9e06d5f080f60f63e549be Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 5 Aug 2018 20:13:44 -0300 Subject: [PATCH 02/13] Add registers and gal enums --- Ryujinx.Graphics/Gal/GalFrameBufferFormat.cs | 68 ++++++++++++++++++++ Ryujinx.Graphics/Gal/GalZetaFormat.cs | 16 +++++ Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs | 7 ++ 3 files changed, 91 insertions(+) create mode 100644 Ryujinx.Graphics/Gal/GalFrameBufferFormat.cs create mode 100644 Ryujinx.Graphics/Gal/GalZetaFormat.cs diff --git a/Ryujinx.Graphics/Gal/GalFrameBufferFormat.cs b/Ryujinx.Graphics/Gal/GalFrameBufferFormat.cs new file mode 100644 index 0000000000..90e6b1e7e4 --- /dev/null +++ b/Ryujinx.Graphics/Gal/GalFrameBufferFormat.cs @@ -0,0 +1,68 @@ +namespace Ryujinx.Graphics.Gal +{ + public enum GalFrameBufferFormat + { + Bitmap = 0x1c, + Unknown1D = 0x1d, + RGBA32Float = 0xc0, + RGBA32Sint = 0xc1, + RGBA32Uint = 0xc2, + RGBX32Float = 0xc3, + RGBX32Sint = 0xc4, + RGBX32Uint = 0xc5, + RGBA16Unorm = 0xc6, + RGBA16Snorm = 0xc7, + RGBA16Sint = 0xc8, + RGBA16Uint = 0xc9, + RGBA16Float = 0xca, + RG32Float = 0xcb, + RG32Sint = 0xcc, + RG32Uint = 0xcd, + RGBX16Float = 0xce, + BGRA8Unorm = 0x0cf, + BGRA8Srgb = 0xd0, + RGB10A2Unorm = 0xd1, + RGB10A2Uint = 0xd2, + RGBA8Unorm = 0xd5, + RGBA8Srgb = 0xd6, + RGBA8Snorm = 0xd7, + RGBA8Sint = 0xd8, + RGBA8Uint = 0xd9, + RG16Unorm = 0xda, + RG16Snorm = 0xdb, + RG16Sint = 0xdc, + RG16Uint = 0xdd, + RG16Float = 0xde, + BGR10A2Unorm = 0xdf, + R11G11B10Float = 0xe0, + R32Sint = 0xe3, + R32Uint = 0xe4, + R32Float = 0xe5, + BGRX8Unorm = 0xe6, + BGRX8Srgb = 0xe7, + B5G6R5Unorm = 0xe8, + BGR5A1Unorm = 0xe9, + RG8Unorm = 0xea, + RG8Snorm = 0xeb, + RG8Sint = 0xec, + RG8Uint = 0xed, + R16Unorm = 0xee, + R16Snorm = 0xef, + R16Sint = 0xf0, + R16Uint = 0xf1, + R16Float = 0xf2, + R8Unorm = 0xf3, + R8Snorm = 0xf4, + R8Sint = 0xf5, + R8Uint = 0xf6, + A8Unorm = 0xf7, + BGR5X1Unorm = 0xf8, + RGBX8Unorm = 0xf9, + RGBX8Srgb = 0xfa, + BGR5X1UnormUnknownFB = 0xfb, + BGR5X1UnormUnknownFC = 0xfc, + BGRX8UnormUnknownFD = 0xfd, + BGRX8UnormUnknownFE = 0xfe, + Y32UintUnknownFF = 0xff + } +} \ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalZetaFormat.cs b/Ryujinx.Graphics/Gal/GalZetaFormat.cs new file mode 100644 index 0000000000..759e312170 --- /dev/null +++ b/Ryujinx.Graphics/Gal/GalZetaFormat.cs @@ -0,0 +1,16 @@ +namespace Ryujinx.Graphics.Gal +{ + public enum GalZetaFormat + { + Z32Float = 0x0a, + Z16Unorm = 0x13, + S8Z24Unorm = 0x14, + Z24X8Unorm = 0x15, + Z24S8Unorm = 0x16, + Z24C8Unorm = 0x18, + Z32S8X24Float = 0x19, + Z24X8S8C8X16Unorm = 0x1d, + Z32X8C8X16Float = 0x1e, + Z32S8C8X16Float = 0x1f + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs index 39a5ee8cfb..b14a96deb3 100644 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs @@ -22,7 +22,14 @@ namespace Ryujinx.HLE.Gpu.Engines StencilBackFuncRef = 0x3d5, StencilBackMask = 0x3d6, StencilBackFuncMask = 0x3d7, + ZetaAddress = 0x3f8, + ZetaFormat = 0x3fa, + ZetaBlockDimensions = 0x3fb, + ZetaLayerStride = 0x3fc, VertexAttribNFormat = 0x458, + ZetaHoriz = 0x48a, + ZetaVert = 0x48b, + ZetaArrayMode = 0x48c, DepthTestEnable = 0x4b3, IBlendEnable = 0x4b9, DepthTestFunction = 0x4c3, From b723bd5e4a452abc1d417ed3d8381ac742f6c8d9 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 5 Aug 2018 20:30:25 -0300 Subject: [PATCH 03/13] Use textures for framebuffers and split color and zeta framebuffers --- Ryujinx.Graphics/Gal/GalFrameBufferFormat.cs | 2 +- Ryujinx.Graphics/Gal/IGalFrameBuffer.cs | 13 +- Ryujinx.Graphics/Gal/IGalRasterizer.cs | 1 + Ryujinx.Graphics/Gal/OpenGL/OGLBlend.cs | 48 ++ .../Gal/OpenGL/OGLEnumConverter.cs | 69 +++ Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs | 579 ++++++++++++------ Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs | 15 +- Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs | 4 - Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs | 43 +- Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs | 1 + 10 files changed, 557 insertions(+), 218 deletions(-) create mode 100644 Ryujinx.Graphics/Gal/OpenGL/OGLBlend.cs diff --git a/Ryujinx.Graphics/Gal/GalFrameBufferFormat.cs b/Ryujinx.Graphics/Gal/GalFrameBufferFormat.cs index 90e6b1e7e4..670c51b265 100644 --- a/Ryujinx.Graphics/Gal/GalFrameBufferFormat.cs +++ b/Ryujinx.Graphics/Gal/GalFrameBufferFormat.cs @@ -19,7 +19,7 @@ RG32Sint = 0xcc, RG32Uint = 0xcd, RGBX16Float = 0xce, - BGRA8Unorm = 0x0cf, + BGRA8Unorm = 0xcf, BGRA8Srgb = 0xd0, RGB10A2Unorm = 0xd1, RGB10A2Uint = 0xd2, diff --git a/Ryujinx.Graphics/Gal/IGalFrameBuffer.cs b/Ryujinx.Graphics/Gal/IGalFrameBuffer.cs index c0287ef8be..91608ffa77 100644 --- a/Ryujinx.Graphics/Gal/IGalFrameBuffer.cs +++ b/Ryujinx.Graphics/Gal/IGalFrameBuffer.cs @@ -4,9 +4,17 @@ namespace Ryujinx.Graphics.Gal { public interface IGalFrameBuffer { - void Create(long Key, int Width, int Height); + void CreateColor(long Key, int Width, int Height, GalFrameBufferFormat Format); - void Bind(long Key); + void BindColor(long Key, int Attachment); + + void UnbindColor(int Attachment); + + void CreateZeta(long Key, int Width, int Height, GalZetaFormat Format); + + void BindZeta(long Key); + + void UnbindZeta(); void BindTexture(long Key, int Index); @@ -40,7 +48,6 @@ namespace Ryujinx.Graphics.Gal long Key, int Width, int Height, - GalTextureFormat Format, byte[] Buffer); } } \ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/IGalRasterizer.cs b/Ryujinx.Graphics/Gal/IGalRasterizer.cs index 89e50b1f1b..a20b6f5322 100644 --- a/Ryujinx.Graphics/Gal/IGalRasterizer.cs +++ b/Ryujinx.Graphics/Gal/IGalRasterizer.cs @@ -9,6 +9,7 @@ namespace Ryujinx.Graphics.Gal void ClearBuffers( GalClearBufferFlags Flags, + int Attachment, float Red, float Green, float Blue, float Alpha, float Depth, int Stencil); diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLBlend.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLBlend.cs new file mode 100644 index 0000000000..6e41c85a28 --- /dev/null +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLBlend.cs @@ -0,0 +1,48 @@ +using OpenTK.Graphics.OpenGL; + +namespace Ryujinx.Graphics.Gal.OpenGL +{ + public class OGLBlend : IGalBlend + { + public void Enable() + { + GL.Enable(EnableCap.Blend); + } + + public void Disable() + { + GL.Disable(EnableCap.Blend); + } + + public void Set( + GalBlendEquation Equation, + GalBlendFactor FuncSrc, + GalBlendFactor FuncDst) + { + GL.BlendEquation(OGLEnumConverter.GetBlendEquation(Equation)); + + GL.BlendFunc( + OGLEnumConverter.GetBlendFactor(FuncSrc), + OGLEnumConverter.GetBlendFactor(FuncDst)); + } + + public void SetSeparate( + GalBlendEquation EquationRgb, + GalBlendEquation EquationAlpha, + GalBlendFactor FuncSrcRgb, + GalBlendFactor FuncDstRgb, + GalBlendFactor FuncSrcAlpha, + GalBlendFactor FuncDstAlpha) + { + GL.BlendEquationSeparate( + OGLEnumConverter.GetBlendEquation(EquationRgb), + OGLEnumConverter.GetBlendEquation(EquationAlpha)); + + GL.BlendFuncSeparate( + (BlendingFactorSrc)OGLEnumConverter.GetBlendFactor(FuncSrcRgb), + (BlendingFactorDest)OGLEnumConverter.GetBlendFactor(FuncDstRgb), + (BlendingFactorSrc)OGLEnumConverter.GetBlendFactor(FuncSrcAlpha), + (BlendingFactorDest)OGLEnumConverter.GetBlendFactor(FuncDstAlpha)); + } + } +} \ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs index 3c42e5d387..28665026e5 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs @@ -125,6 +125,75 @@ namespace Ryujinx.Graphics.Gal.OpenGL throw new ArgumentException(nameof(Type)); } + public static PixelInternalFormat GetFrameBufferInternalFormat(GalFrameBufferFormat Format) + { + switch (Format) + { + //Sometimes it's not set, use a safe format + case 0: return PixelInternalFormat.Rgba8; + + case GalFrameBufferFormat.RGBA32Float: return PixelInternalFormat.Rgba32f; + case GalFrameBufferFormat.RGBA32Sint: return PixelInternalFormat.Rgba32i; + case GalFrameBufferFormat.RGBA32Uint: return PixelInternalFormat.Rgba32ui; + case GalFrameBufferFormat.RGBA16Unorm: return PixelInternalFormat.Rgba16; + case GalFrameBufferFormat.RGBA16Snorm: return PixelInternalFormat.Rgba16Snorm; + case GalFrameBufferFormat.RGBA16Sint: return PixelInternalFormat.Rgba16i; + case GalFrameBufferFormat.RGBA16Uint: return PixelInternalFormat.Rgba16ui; + case GalFrameBufferFormat.RGBA16Float: return PixelInternalFormat.Rgba16f; + case GalFrameBufferFormat.RG32Float: return PixelInternalFormat.Rg32f; + case GalFrameBufferFormat.RG32Sint: return PixelInternalFormat.Rg32i; + case GalFrameBufferFormat.RG32Uint: return PixelInternalFormat.Rg32ui; + case GalFrameBufferFormat.RGB10A2Unorm: return PixelInternalFormat.Rgb10A2; + case GalFrameBufferFormat.RGB10A2Uint: return PixelInternalFormat.Rgb10A2ui; + case GalFrameBufferFormat.RGBA8Unorm: return PixelInternalFormat.Rgba8; + case GalFrameBufferFormat.RGBA8Srgb: return PixelInternalFormat.Srgb8; + case GalFrameBufferFormat.RG16Snorm: return PixelInternalFormat.Rg16Snorm; + case GalFrameBufferFormat.R11G11B10Float: return PixelInternalFormat.R11fG11fB10f; + case GalFrameBufferFormat.R32Float: return PixelInternalFormat.R32f; + case GalFrameBufferFormat.R16Float: return PixelInternalFormat.R16f; + case GalFrameBufferFormat.R8Unorm: return PixelInternalFormat.R8; + case GalFrameBufferFormat.R8Snorm: return PixelInternalFormat.R8Snorm; + case GalFrameBufferFormat.R8Sint: return PixelInternalFormat.R8i; + case GalFrameBufferFormat.R8Uint: return PixelInternalFormat.R8ui; + } + + throw new NotImplementedException(Format.ToString()); + } + + public static (PixelFormat Format, PixelType Type) GetFrameBufferFormat(GalFrameBufferFormat Format) + { + switch (Format) + { + case 0: return (PixelFormat.Rgba, PixelType.UnsignedByte); + + case GalFrameBufferFormat.RGBA32Float: return (PixelFormat.Rgba, PixelType.Float); + case GalFrameBufferFormat.RGBA32Sint: return (PixelFormat.Rgba, PixelType.Int); + case GalFrameBufferFormat.RGBA32Uint: return (PixelFormat.Rgba, PixelType.UnsignedInt); + case GalFrameBufferFormat.RGBA16Unorm: return (PixelFormat.Rgba, PixelType.UnsignedShort); + case GalFrameBufferFormat.RGBA16Snorm: return (PixelFormat.Rgba, PixelType.Short); + case GalFrameBufferFormat.RGBA16Sint: return (PixelFormat.Rgba, PixelType.Short); + case GalFrameBufferFormat.RGBA16Uint: return (PixelFormat.Rgba, PixelType.UnsignedShort); + case GalFrameBufferFormat.RGBA16Float: return (PixelFormat.Rgba, PixelType.HalfFloat); + case GalFrameBufferFormat.RG32Float: return (PixelFormat.Rg, PixelType.Float); + case GalFrameBufferFormat.RG32Sint: return (PixelFormat.Rg, PixelType.Int); + case GalFrameBufferFormat.RG32Uint: return (PixelFormat.Rg, PixelType.UnsignedInt); + case GalFrameBufferFormat.RGB10A2Unorm: return (PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed); + case GalFrameBufferFormat.RGB10A2Uint: return (PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed); + case GalFrameBufferFormat.RGBA8Unorm: return (PixelFormat.Rgba, PixelType.UnsignedByte); + case GalFrameBufferFormat.RGBA8Srgb: return (PixelFormat.Rgba, PixelType.UnsignedByte); + case GalFrameBufferFormat.RG16Snorm: return (PixelFormat.Rg, PixelType.Short); + case GalFrameBufferFormat.R11G11B10Float: return (PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev); + case GalFrameBufferFormat.R32Float: return (PixelFormat.Red, PixelType.Float); + case GalFrameBufferFormat.R16Float: return (PixelFormat.Red, PixelType.HalfFloat); + case GalFrameBufferFormat.R8Unorm: return (PixelFormat.Red, PixelType.UnsignedByte); + case GalFrameBufferFormat.R8Snorm: return (PixelFormat.Red, PixelType.Byte); + case GalFrameBufferFormat.R8Sint: return (PixelFormat.Red, PixelType.Byte); + case GalFrameBufferFormat.R8Uint: return (PixelFormat.Red, PixelType.UnsignedByte); + } + + throw new NotImplementedException(Format.ToString()); + } + public static (PixelFormat, PixelType) GetTextureFormat(GalTextureFormat Format) { switch (Format) diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs index 30a3de64a0..9da9853dae 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs @@ -16,50 +16,163 @@ 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; } } - private class FrameBuffer + private class Texture { - public int Width { get; set; } - public int Height { get; set; } + public int Width { get; private set; } + public int Height { get; private set; } - public int Handle { get; private set; } - public int RbHandle { get; private set; } - public int TexHandle { get; private set; } + public PixelInternalFormat InternalFormat { get; private set; } + public PixelFormat Format { get; private set; } + public PixelType Type { get; private set; } - public FrameBuffer(int Width, int Height, bool HasRenderBuffer) + public int Handle { get; private set; } + + private bool Initialized; + + public Texture() { - this.Width = Width; - this.Height = Height; + Handle = GL.GenTexture(); + } - Handle = GL.GenFramebuffer(); - TexHandle = GL.GenTexture(); - - if (HasRenderBuffer) + public void EnsureSetup( + int Width, + int Height, + PixelInternalFormat InternalFormat, + PixelFormat Format, + PixelType Type) + { + if (!Initialized || + this.Width != Width || + this.Height != Height || + this.InternalFormat != InternalFormat) { - RbHandle = GL.GenRenderbuffer(); + int CopyBuffer = 0; + + bool ChangingFormat = Initialized && this.InternalFormat != InternalFormat; + + GL.BindTexture(TextureTarget.Texture2D, Handle); + + if (ChangingFormat) + { + CopyBuffer = GL.GenBuffer(); + + GL.BindBuffer(BufferTarget.PixelPackBuffer, CopyBuffer); + GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyBuffer); + + int MaxWidth = Math.Max(Width, this.Width); + int MaxHeight = Math.Max(Height, this.Height); + + //TODO: Dehardcode size number + GL.BufferData(BufferTarget.PixelPackBuffer, MaxWidth * MaxHeight * MaxBpp, IntPtr.Zero, BufferUsageHint.StaticCopy); + + GL.GetTexImage(TextureTarget.Texture2D, 0, this.Format, this.Type, 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; + + GL.TexImage2D( + TextureTarget.Texture2D, + Level, + InternalFormat, + Width, + Height, + Border, + Format, + Type, + IntPtr.Zero); + + if (ChangingFormat) + { + GL.BindBuffer(BufferTarget.PixelPackBuffer, 0); + GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0); + + GL.DeleteBuffer(CopyBuffer); + } + + this.Width = Width; + this.Height = Height; + this.InternalFormat = InternalFormat; + this.Format = Format; + this.Type = Type; + + Initialized = true; } } + + public void EnsureSetup(int Width, int Height, GalFrameBufferFormat Format) + { + //TODO: Convert color format + + EnsureSetup( + Width, + Height, + PixelInternalFormat.Rgba8, + PixelFormat.Rgba, + PixelType.UnsignedByte); + } + + public void EnsureSetup(int Width, int Height, GalZetaFormat Format) + { + //TODO: Convert zeta format + + EnsureSetup( + Width, + Height, + PixelInternalFormat.Depth24Stencil8, + PixelFormat.DepthStencil, + PixelType.UnsignedInt248); + } } + private static readonly DrawBuffersEnum[] DrawBuffers = new DrawBuffersEnum[] + { + DrawBuffersEnum.ColorAttachment0, + DrawBuffersEnum.ColorAttachment1, + DrawBuffersEnum.ColorAttachment2, + DrawBuffersEnum.ColorAttachment3, + DrawBuffersEnum.ColorAttachment4, + DrawBuffersEnum.ColorAttachment5, + DrawBuffersEnum.ColorAttachment6, + DrawBuffersEnum.ColorAttachment7, + }; + private const int NativeWidth = 1280; private const int NativeHeight = 720; - private Dictionary Fbs; + //TODO: Use a variable value here + private const int MaxBpp = 16; + + private const GalTextureFormat RawFormat = GalTextureFormat.A8B8G8R8; + + private Dictionary ColorTextures; + private Dictionary ZetaTextures; + + private Texture RawTex; + private Texture ReadTex; private Rect Viewport; private Rect Window; - private FrameBuffer CurrFb; - private FrameBuffer CurrReadFb; - - private FrameBuffer RawFb; - private bool FlipX; private bool FlipY; @@ -68,111 +181,137 @@ namespace Ryujinx.Graphics.Gal.OpenGL private int CropRight; private int CropBottom; + private int DummyFrameBuffer; + + private int SrcFb; + private int DstFb; + public OGLFrameBuffer() { - Fbs = new Dictionary(); + ColorTextures = new Dictionary(); + + ZetaTextures = new Dictionary(); } - public void Create(long Key, int Width, int Height) + public void CreateColor(long Key, int Width, int Height, GalFrameBufferFormat Format) { - if (Fbs.TryGetValue(Key, out FrameBuffer Fb)) + if (!ColorTextures.TryGetValue(Key, out Texture Tex)) { - if (Fb.Width != Width || - Fb.Height != Height) - { - SetupTexture(Fb.TexHandle, Width, Height); + Tex = new Texture(); - Fb.Width = Width; - Fb.Height = Height; - } - - return; + ColorTextures.Add(Key, Tex); } - Fb = new FrameBuffer(Width, Height, true); + Tex.EnsureSetup(Width, Height, Format); + } - SetupTexture(Fb.TexHandle, Width, Height); + public void BindColor(long Key, int Attachment) + { + if (ColorTextures.TryGetValue(Key, out Texture Tex)) + { + EnsureFrameBuffer(); - GL.BindFramebuffer(FramebufferTarget.Framebuffer, Fb.Handle); + GL.FramebufferTexture( + FramebufferTarget.Framebuffer, + FramebufferAttachment.ColorAttachment0 + Attachment, + Tex.Handle, + 0); + } + else + { + UnbindColor(Attachment); + } + } - GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, Fb.RbHandle); - - GL.RenderbufferStorage( - RenderbufferTarget.Renderbuffer, - RenderbufferStorage.Depth24Stencil8, - Width, - Height); - - GL.FramebufferRenderbuffer( - FramebufferTarget.Framebuffer, - FramebufferAttachment.DepthStencilAttachment, - RenderbufferTarget.Renderbuffer, - Fb.RbHandle); + public void UnbindColor(int Attachment) + { + EnsureFrameBuffer(); GL.FramebufferTexture( FramebufferTarget.Framebuffer, - FramebufferAttachment.ColorAttachment0, - Fb.TexHandle, + FramebufferAttachment.ColorAttachment0 + Attachment, + 0, 0); - - GL.DrawBuffer(DrawBufferMode.ColorAttachment0); - - Fbs.Add(Key, Fb); } - public void Bind(long Key) + public void CreateZeta(long Key, int Width, int Height, GalZetaFormat Format) { - if (Fbs.TryGetValue(Key, out FrameBuffer Fb)) + if (!ZetaTextures.TryGetValue(Key, out Texture Tex)) { - GL.BindFramebuffer(FramebufferTarget.Framebuffer, Fb.Handle); + Tex = new Texture(); - CurrFb = Fb; + ZetaTextures.Add(Key, Tex); } + + Tex.EnsureSetup(Width, Height, Format); + } + + public void BindZeta(long Key) + { + if (ZetaTextures.TryGetValue(Key, out Texture Tex)) + { + EnsureFrameBuffer(); + + GL.FramebufferTexture( + FramebufferTarget.Framebuffer, + FramebufferAttachment.DepthStencilAttachment, + Tex.Handle, + 0); + } + else + { + UnbindZeta(); + } + } + + public void UnbindZeta() + { + EnsureFrameBuffer(); + + GL.FramebufferTexture( + FramebufferTarget.Framebuffer, + FramebufferAttachment.DepthStencilAttachment, + 0, + 0); } public void BindTexture(long Key, int Index) { - if (Fbs.TryGetValue(Key, out FrameBuffer Fb)) + Texture Tex; + + if (ColorTextures.TryGetValue(Key, out Tex) || + ZetaTextures.TryGetValue(Key, out Tex)) { GL.ActiveTexture(TextureUnit.Texture0 + Index); - GL.BindTexture(TextureTarget.Texture2D, Fb.TexHandle); + GL.BindTexture(TextureTarget.Texture2D, Tex.Handle); } } public void Set(long Key) { - if (Fbs.TryGetValue(Key, out FrameBuffer Fb)) + if (ColorTextures.TryGetValue(Key, out Texture Tex)) { - CurrReadFb = Fb; + ReadTex = Tex; } } public void Set(byte[] Data, int Width, int Height) { - if (RawFb == null) + if (RawTex == null) { - CreateRawFb(Width, Height); + RawTex = new Texture(); } - if (RawFb.Width != Width || - RawFb.Height != Height) - { - SetupTexture(RawFb.TexHandle, Width, Height); + RawTex.EnsureSetup(Width, Height, PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte); - RawFb.Width = Width; - RawFb.Height = Height; - } + GL.BindTexture(TextureTarget.Texture2D, RawTex.Handle); - GL.ActiveTexture(TextureUnit.Texture0); - - GL.BindTexture(TextureTarget.Texture2D, RawFb.TexHandle); - - (PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(GalTextureFormat.A8B8G8R8); + (PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(RawFormat); GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, Width, Height, Format, Type, Data); - CurrReadFb = RawFb; + ReadTex = RawTex; } public void SetTransform(bool FlipX, bool FlipY, int Top, int Left, int Right, int Bottom) @@ -209,60 +348,71 @@ namespace Ryujinx.Graphics.Gal.OpenGL public void Render() { - if (CurrReadFb != null) + if (ReadTex == null) { - int SrcX0, SrcX1, SrcY0, SrcY1; - - if (CropLeft == 0 && CropRight == 0) - { - SrcX0 = 0; - SrcX1 = CurrReadFb.Width; - } - else - { - SrcX0 = CropLeft; - SrcX1 = CropRight; - } - - if (CropTop == 0 && CropBottom == 0) - { - SrcY0 = 0; - SrcY1 = CurrReadFb.Height; - } - else - { - SrcY0 = CropTop; - SrcY1 = CropBottom; - } - - float RatioX = MathF.Min(1f, (Window.Height * (float)NativeWidth) / ((float)NativeHeight * Window.Width)); - float RatioY = MathF.Min(1f, (Window.Width * (float)NativeHeight) / ((float)NativeWidth * Window.Height)); - - int DstWidth = (int)(Window.Width * RatioX); - int DstHeight = (int)(Window.Height * RatioY); - - int DstPaddingX = (Window.Width - DstWidth) / 2; - int DstPaddingY = (Window.Height - DstHeight) / 2; - - int DstX0 = FlipX ? Window.Width - DstPaddingX : DstPaddingX; - int DstX1 = FlipX ? DstPaddingX : Window.Width - DstPaddingX; - - int DstY0 = FlipY ? DstPaddingY : Window.Height - DstPaddingY; - int DstY1 = FlipY ? Window.Height - DstPaddingY : DstPaddingY; - - GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); - - GL.Viewport(0, 0, Window.Width, Window.Height); - - GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, CurrReadFb.Handle); - - GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); - - GL.BlitFramebuffer( - SrcX0, SrcY0, SrcX1, SrcY1, - DstX0, DstY0, DstX1, DstY1, - ClearBufferMask.ColorBufferBit, BlitFramebufferFilter.Linear); + return; } + + int SrcX0, SrcX1, SrcY0, SrcY1; + + if (CropLeft == 0 && CropRight == 0) + { + SrcX0 = 0; + SrcX1 = ReadTex.Width; + } + else + { + SrcX0 = CropLeft; + SrcX1 = CropRight; + } + + if (CropTop == 0 && CropBottom == 0) + { + SrcY0 = 0; + SrcY1 = ReadTex.Height; + } + else + { + SrcY0 = CropTop; + SrcY1 = CropBottom; + } + + float RatioX = MathF.Min(1f, (Window.Height * (float)NativeWidth) / ((float)NativeHeight * Window.Width)); + float RatioY = MathF.Min(1f, (Window.Width * (float)NativeHeight) / ((float)NativeWidth * Window.Height)); + + int DstWidth = (int)(Window.Width * RatioX); + int DstHeight = (int)(Window.Height * RatioY); + + int DstPaddingX = (Window.Width - DstWidth) / 2; + int DstPaddingY = (Window.Height - DstHeight) / 2; + + int DstX0 = FlipX ? Window.Width - DstPaddingX : DstPaddingX; + int DstX1 = FlipX ? DstPaddingX : Window.Width - DstPaddingX; + + 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); + + GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, SrcFb); + + GL.FramebufferTexture(FramebufferTarget.ReadFramebuffer, FramebufferAttachment.ColorAttachment0, ReadTex.Handle, 0); + + GL.ReadBuffer(ReadBufferMode.ColorAttachment0); + GL.DrawBuffer(DrawBufferMode.ColorAttachment0); + + GL.Clear(ClearBufferMask.ColorBufferBit); + + GL.BlitFramebuffer( + SrcX0, SrcY0, SrcX1, SrcY1, + DstX0, DstY0, DstX1, DstY1, + ClearBufferMask.ColorBufferBit, BlitFramebufferFilter.Linear); + + EnsureFrameBuffer(); } public void Copy( @@ -277,39 +427,61 @@ namespace Ryujinx.Graphics.Gal.OpenGL int DstX1, int DstY1) { - if (Fbs.TryGetValue(SrcKey, out FrameBuffer SrcFb) && - Fbs.TryGetValue(DstKey, out FrameBuffer DstFb)) + bool Found = false; + + if (ColorTextures.TryGetValue(SrcKey, out Texture SrcTex) && + ColorTextures.TryGetValue(DstKey, out Texture DstTex)) { - GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, SrcFb.Handle); - GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, DstFb.Handle); - - GL.Clear(ClearBufferMask.ColorBufferBit); - - GL.BlitFramebuffer( + CopyTextures( SrcX0, SrcY0, SrcX1, SrcY1, DstX0, DstY0, DstX1, DstY1, + SrcTex.Handle, + DstTex.Handle, + FramebufferAttachment.ColorAttachment0, ClearBufferMask.ColorBufferBit, - BlitFramebufferFilter.Linear); + true); + + Found = true; } -} + + if (ZetaTextures.TryGetValue(SrcKey, out Texture ZetaSrcTex) && + ZetaTextures.TryGetValue(DstKey, out Texture ZetaDstTex)) + { + CopyTextures( + SrcX0, SrcY0, SrcX1, SrcY1, + DstX0, DstY0, DstX1, DstY1, + ZetaSrcTex.Handle, + ZetaDstTex.Handle, + FramebufferAttachment.DepthStencilAttachment, + ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit, + false); + + Found = true; + } + + if (Found) + { + EnsureFrameBuffer(); + } + } public void GetBufferData(long Key, Action Callback) { - if (Fbs.TryGetValue(Key, out FrameBuffer Fb)) + Texture Tex; + + if (ColorTextures.TryGetValue(Key, out Tex) || + ZetaTextures.TryGetValue(Key, out Tex)) { - GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, Fb.Handle); + //Note: Change this value when framebuffer sizes are dehardcoded + byte[] Data = new byte[Tex.Width * Tex.Height * MaxBpp]; - byte[] Data = new byte[Fb.Width * Fb.Height * 4]; + GL.BindTexture(TextureTarget.Texture2D, Tex.Handle); - (PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(GalTextureFormat.A8B8G8R8); - - GL.ReadPixels( + GL.GetTexImage( + TextureTarget.Texture2D, 0, - 0, - Fb.Width, - Fb.Height, - Format, - Type, + Tex.Format, + Tex.Type, Data); Callback(Data); @@ -320,83 +492,88 @@ namespace Ryujinx.Graphics.Gal.OpenGL long Key, int Width, int Height, - GalTextureFormat Format, byte[] Buffer) { - if (Fbs.TryGetValue(Key, out FrameBuffer Fb)) + Texture Tex; + + if (ColorTextures.TryGetValue(Key, out Tex) || + ZetaTextures.TryGetValue(Key, out Tex)) { - GL.BindTexture(TextureTarget.Texture2D, Fb.TexHandle); + GL.BindTexture(TextureTarget.Texture2D, Tex.Handle); const int Level = 0; const int Border = 0; - const PixelInternalFormat InternalFmt = PixelInternalFormat.Rgba; - - (PixelFormat GlFormat, PixelType Type) = OGLEnumConverter.GetTextureFormat(Format); - GL.TexImage2D( TextureTarget.Texture2D, Level, - InternalFmt, + Tex.InternalFormat, Width, Height, Border, - GlFormat, - Type, + Tex.Format, + Tex.Type, Buffer); } } - private void CreateRawFb(int Width, int Height) + private void EnsureFrameBuffer() { - if (RawFb == null) + if (DummyFrameBuffer == 0) { - RawFb = new FrameBuffer(Width, Height, false); - - SetupTexture(RawFb.TexHandle, Width, Height); - - RawFb.Width = Width; - RawFb.Height = Height; - - GL.BindFramebuffer(FramebufferTarget.Framebuffer, RawFb.Handle); - - GL.FramebufferTexture( - FramebufferTarget.Framebuffer, - FramebufferAttachment.ColorAttachment0, - RawFb.TexHandle, - 0); - - GL.Viewport(0, 0, Width, Height); + DummyFrameBuffer = GL.GenFramebuffer(); } + + GL.BindFramebuffer(FramebufferTarget.Framebuffer, DummyFrameBuffer); + + GL.DrawBuffers(8, DrawBuffers); } - private void SetupTexture(int Handle, int Width, int Height) + 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) { - GL.BindTexture(TextureTarget.Texture2D, Handle); + if (SrcFb == 0) SrcFb = GL.GenFramebuffer(); + if (DstFb == 0) DstFb = GL.GenFramebuffer(); - const int MinFilter = (int)TextureMinFilter.Linear; - const int MagFilter = (int)TextureMagFilter.Linear; + GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, SrcFb); + GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, DstFb); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, MinFilter); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, MagFilter); + GL.FramebufferTexture( + FramebufferTarget.ReadFramebuffer, + Attachment, + SrcTexture, + 0); - (PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(GalTextureFormat.A8B8G8R8); + GL.FramebufferTexture( + FramebufferTarget.DrawFramebuffer, + Attachment, + DstTexture, + 0); - const PixelInternalFormat InternalFmt = PixelInternalFormat.Rgba; + if (Color) + { + GL.DrawBuffer(DrawBufferMode.ColorAttachment0); + } - const int Level = 0; - const int Border = 0; + GL.Clear(Mask); - GL.TexImage2D( - TextureTarget.Texture2D, - Level, - InternalFmt, - Width, - Height, - Border, - Format, - Type, - IntPtr.Zero); + GL.BlitFramebuffer( + SrcX0, SrcY0, SrcX1, SrcY1, + DstX0, DstY0, DstX1, DstY1, + Mask, + Color ? BlitFramebufferFilter.Linear : BlitFramebufferFilter.Nearest); } } } \ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs index 0802147857..c0e4bd0f53 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs @@ -45,17 +45,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL public void ClearBuffers( GalClearBufferFlags Flags, + int Attachment, float Red, float Green, float Blue, float Alpha, float Depth, int Stencil) { - ClearBufferMask Mask = ClearBufferMask.ColorBufferBit; + //TODO: Handle attachment - GL.ColorMask( - Flags.HasFlag(GalClearBufferFlags.ColorRed), - Flags.HasFlag(GalClearBufferFlags.ColorGreen), - Flags.HasFlag(GalClearBufferFlags.ColorBlue), - Flags.HasFlag(GalClearBufferFlags.ColorAlpha)); + ClearBufferMask Mask = ClearBufferMask.ColorBufferBit; if (Flags.HasFlag(GalClearBufferFlags.Depth)) { @@ -67,6 +64,12 @@ namespace Ryujinx.Graphics.Gal.OpenGL Mask |= ClearBufferMask.StencilBufferBit; } + GL.ColorMask( + Flags.HasFlag(GalClearBufferFlags.ColorRed), + Flags.HasFlag(GalClearBufferFlags.ColorGreen), + Flags.HasFlag(GalClearBufferFlags.ColorBlue), + Flags.HasFlag(GalClearBufferFlags.ColorAlpha)); + GL.ClearColor(Red, Green, Blue, Alpha); GL.ClearDepth(Depth); diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs index d2c5f1262b..7fb5ea8af4 100644 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs @@ -154,16 +154,12 @@ namespace Ryujinx.HLE.Gpu.Engines } else if (IsDstFb) { - //Texture -> Frame Buffer copy. - const GalTextureFormat Format = GalTextureFormat.A8B8G8R8; - byte[] Buffer = TextureReader.Read(Vmm, SrcTexture()); Gpu.Renderer.FrameBuffer.SetBufferData( DstKey, DstWidth, DstHeight, - Format, Buffer); } else diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs index 6f60124458..19488e7e0a 100644 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs @@ -104,6 +104,8 @@ namespace Ryujinx.HLE.Gpu.Engines SetFrameBuffer(Vmm, 0); + SetZeta(Vmm); + long[] Keys = UploadShaders(Vmm); Gpu.Renderer.Shader.BindProgram(); @@ -152,6 +154,7 @@ namespace Ryujinx.HLE.Gpu.Engines Gpu.Renderer.Rasterizer.ClearBuffers( Flags, + FbIndex, Red, Green, Blue, Alpha, Depth, Stencil); @@ -161,13 +164,22 @@ namespace Ryujinx.HLE.Gpu.Engines { long VA = MakeInt64From2xInt32(NvGpuEngine3dReg.FrameBufferNAddress + FbIndex * 0x10); + int Format = ReadRegister(NvGpuEngine3dReg.FrameBufferNFormat + FbIndex * 0x10); + + if (VA == 0 || Format == 0) + { + Gpu.Renderer.FrameBuffer.UnbindColor(FbIndex); + + return; + } + long Key = Vmm.GetPhysicalAddress(VA); FrameBuffers.Add(Key); int Width = ReadRegister(NvGpuEngine3dReg.FrameBufferNWidth + FbIndex * 0x10); int Height = ReadRegister(NvGpuEngine3dReg.FrameBufferNHeight + FbIndex * 0x10); - + float TX = ReadRegisterFloat(NvGpuEngine3dReg.ViewportNTranslateX + FbIndex * 4); float TY = ReadRegisterFloat(NvGpuEngine3dReg.ViewportNTranslateY + FbIndex * 4); @@ -180,12 +192,37 @@ namespace Ryujinx.HLE.Gpu.Engines int VpW = (int)(TX + MathF.Abs(SX)) - VpX; int VpH = (int)(TY + MathF.Abs(SY)) - VpY; - Gpu.Renderer.FrameBuffer.Create(Key, Width, Height); - Gpu.Renderer.FrameBuffer.Bind(Key); + Gpu.Renderer.FrameBuffer.CreateColor(Key, Width, Height, (GalFrameBufferFormat)Format); + Gpu.Renderer.FrameBuffer.BindColor(Key, FbIndex); Gpu.Renderer.FrameBuffer.SetViewport(VpX, VpY, VpW, VpH); } + private void SetZeta(NvGpuVmm Vmm) + { + long ZA = MakeInt64From2xInt32(NvGpuEngine3dReg.ZetaAddress); + + int Format = ReadRegister(NvGpuEngine3dReg.ZetaFormat); + + bool ZetaEnable = (ReadRegister(NvGpuEngine3dReg.ZetaEnable) & 1) != 0; + + if (ZA == 0 || Format == 0 || !ZetaEnable) + { + Gpu.Renderer.FrameBuffer.UnbindZeta(); + + return; + } + + long Key = Vmm.GetPhysicalAddress(ZA); + + int Width = ReadRegister(NvGpuEngine3dReg.ZetaHoriz); + int Height = ReadRegister(NvGpuEngine3dReg.ZetaVert); + + Gpu.Renderer.FrameBuffer.CreateZeta(Key, Width, Height, (GalZetaFormat)Format); + + Gpu.Renderer.FrameBuffer.BindZeta(Key); + } + private long[] UploadShaders(NvGpuVmm Vmm) { long[] Keys = new long[5]; diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs index b14a96deb3..b03aef0241 100644 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3dReg.cs @@ -51,6 +51,7 @@ namespace Ryujinx.HLE.Gpu.Engines StencilFrontFuncMask = 0x4e6, StencilFrontMask = 0x4e7, VertexArrayElemBase = 0x50d, + ZetaEnable = 0x54e, TexHeaderPoolOffset = 0x55d, TexSamplerPoolOffset = 0x557, StencilTwoSideEnable = 0x565, From 65c7842d6d1188401177368f9a7571172e598a6f Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Fri, 10 Aug 2018 01:12:39 -0300 Subject: [PATCH 04/13] Abstract texture and framebuffer targets as an image --- .../Gal/{GalTexture.cs => GalImage.cs} | 16 +- Ryujinx.Graphics/Gal/GalImageFormat.cs | 44 ++++ Ryujinx.Graphics/Gal/IGalTexture.cs | 4 +- Ryujinx.Graphics/Gal/ImageFormatConverter.cs | 129 ++++++++++++ Ryujinx.Graphics/Gal/OpenGL/OGLBlend.cs | 48 ----- .../Gal/OpenGL/OGLEnumConverter.cs | 115 +++-------- Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs | 193 ++++-------------- Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs | 139 ++++++------- Ryujinx.Graphics/Gal/OpenGL/TCE.cs | 112 ++++++++++ Ryujinx.Graphics/Ryujinx.Graphics.csproj | 4 + Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs | 6 +- Ryujinx.HLE/Gpu/Texture/TextureFactory.cs | 6 +- Ryujinx.HLE/Gpu/Texture/TextureHelper.cs | 116 +++++------ 13 files changed, 484 insertions(+), 448 deletions(-) rename Ryujinx.Graphics/Gal/{GalTexture.cs => GalImage.cs} (61%) create mode 100644 Ryujinx.Graphics/Gal/GalImageFormat.cs create mode 100644 Ryujinx.Graphics/Gal/ImageFormatConverter.cs delete mode 100644 Ryujinx.Graphics/Gal/OpenGL/OGLBlend.cs create mode 100644 Ryujinx.Graphics/Gal/OpenGL/TCE.cs diff --git a/Ryujinx.Graphics/Gal/GalTexture.cs b/Ryujinx.Graphics/Gal/GalImage.cs similarity index 61% rename from Ryujinx.Graphics/Gal/GalTexture.cs rename to Ryujinx.Graphics/Gal/GalImage.cs index 2c1be65b21..dc6f02e044 100644 --- a/Ryujinx.Graphics/Gal/GalTexture.cs +++ b/Ryujinx.Graphics/Gal/GalImage.cs @@ -1,25 +1,25 @@ namespace Ryujinx.Graphics.Gal { - public struct GalTexture + public struct GalImage { public int Width; public int Height; - public GalTextureFormat Format; + public GalImageFormat Format; public GalTextureSource XSource; public GalTextureSource YSource; public GalTextureSource ZSource; public GalTextureSource WSource; - public GalTexture( + public GalImage( int Width, int Height, - GalTextureFormat Format, - GalTextureSource XSource, - GalTextureSource YSource, - GalTextureSource ZSource, - GalTextureSource WSource) + GalImageFormat Format, + GalTextureSource XSource = GalTextureSource.Red, + GalTextureSource YSource = GalTextureSource.Green, + GalTextureSource ZSource = GalTextureSource.Blue, + GalTextureSource WSource = GalTextureSource.Alpha) { this.Width = Width; this.Height = Height; diff --git a/Ryujinx.Graphics/Gal/GalImageFormat.cs b/Ryujinx.Graphics/Gal/GalImageFormat.cs new file mode 100644 index 0000000000..4de248b16b --- /dev/null +++ b/Ryujinx.Graphics/Gal/GalImageFormat.cs @@ -0,0 +1,44 @@ +namespace Ryujinx.Graphics.Gal +{ + public enum GalImageFormat + { + R32G32B32A32, + R16G16B16A16, + A8B8G8R8, + A2B10G10R10, + R32, + BC6H_SF16, + BC6H_UF16, + A1B5G5R5, + B5G6R5, + BC7U, + G8R8, + R16, + R8, + BF10GF11RF11, + BC1, + BC2, + BC3, + BC4, + BC5, + Z24S8, + ZF32, + + ConvertedBegin, + Astc2D4x4, + Astc2D5x5, + Astc2D6x6, + Astc2D8x8, + Astc2D10x10, + Astc2D12x12, + Astc2D5x4, + Astc2D6x5, + Astc2D8x6, + Astc2D10x8, + Astc2D12x10, + Astc2D8x5, + Astc2D10x5, + Astc2D10x6, + ConvertedEnd + } +} \ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/IGalTexture.cs b/Ryujinx.Graphics/Gal/IGalTexture.cs index 2ab4119904..f6caa29791 100644 --- a/Ryujinx.Graphics/Gal/IGalTexture.cs +++ b/Ryujinx.Graphics/Gal/IGalTexture.cs @@ -5,9 +5,9 @@ namespace Ryujinx.Graphics.Gal void LockCache(); void UnlockCache(); - void Create(long Key, byte[] Data, GalTexture Texture); + void Create(long Key, byte[] Data, GalImage Image); - bool TryGetCachedTexture(long Key, long DataSize, out GalTexture Texture); + bool TryGetCachedTexture(long Key, long DataSize, out GalImage Image); void Bind(long Key, int Index); diff --git a/Ryujinx.Graphics/Gal/ImageFormatConverter.cs b/Ryujinx.Graphics/Gal/ImageFormatConverter.cs new file mode 100644 index 0000000000..6e38292208 --- /dev/null +++ b/Ryujinx.Graphics/Gal/ImageFormatConverter.cs @@ -0,0 +1,129 @@ +using System; + +namespace Ryujinx.Graphics.Gal +{ + public static class ImageFormatConverter + { + public static GalImageFormat ConvertTexture(GalTextureFormat Format) + { + switch (Format) + { + case GalTextureFormat.R32G32B32A32: return GalImageFormat.R32G32B32A32; + case GalTextureFormat.R16G16B16A16: return GalImageFormat.R16G16B16A16; + case GalTextureFormat.A8B8G8R8: return GalImageFormat.A8B8G8R8; + case GalTextureFormat.A2B10G10R10: return GalImageFormat.A2B10G10R10; + case GalTextureFormat.R32: return GalImageFormat.R32; + case GalTextureFormat.BC6H_SF16: return GalImageFormat.BC6H_SF16; + case GalTextureFormat.BC6H_UF16: return GalImageFormat.BC6H_UF16; + case GalTextureFormat.A1B5G5R5: return GalImageFormat.A1B5G5R5; + case GalTextureFormat.B5G6R5: return GalImageFormat.B5G6R5; + case GalTextureFormat.BC7U: return GalImageFormat.BC7U; + case GalTextureFormat.G8R8: return GalImageFormat.G8R8; + case GalTextureFormat.R16: return GalImageFormat.R16; + case GalTextureFormat.R8: return GalImageFormat.R8; + case GalTextureFormat.BF10GF11RF11: return GalImageFormat.BF10GF11RF11; + case GalTextureFormat.BC1: return GalImageFormat.BC1; + case GalTextureFormat.BC2: return GalImageFormat.BC2; + case GalTextureFormat.BC3: return GalImageFormat.BC3; + case GalTextureFormat.BC4: return GalImageFormat.BC4; + case GalTextureFormat.BC5: return GalImageFormat.BC5; + case GalTextureFormat.Z24S8: return GalImageFormat.Z24S8; + case GalTextureFormat.ZF32: return GalImageFormat.ZF32; + case GalTextureFormat.Astc2D4x4: return GalImageFormat.Astc2D4x4; + case GalTextureFormat.Astc2D5x5: return GalImageFormat.Astc2D5x5; + case GalTextureFormat.Astc2D6x6: return GalImageFormat.Astc2D6x6; + case GalTextureFormat.Astc2D8x8: return GalImageFormat.Astc2D8x8; + case GalTextureFormat.Astc2D10x10: return GalImageFormat.Astc2D10x10; + case GalTextureFormat.Astc2D12x12: return GalImageFormat.Astc2D12x12; + case GalTextureFormat.Astc2D5x4: return GalImageFormat.Astc2D5x4; + case GalTextureFormat.Astc2D6x5: return GalImageFormat.Astc2D6x5; + case GalTextureFormat.Astc2D8x6: return GalImageFormat.Astc2D8x6; + case GalTextureFormat.Astc2D10x8: return GalImageFormat.Astc2D10x8; + case GalTextureFormat.Astc2D12x10: return GalImageFormat.Astc2D12x10; + case GalTextureFormat.Astc2D8x5: return GalImageFormat.Astc2D8x5; + case GalTextureFormat.Astc2D10x5: return GalImageFormat.Astc2D10x5; + case GalTextureFormat.Astc2D10x6: return GalImageFormat.Astc2D10x6; + } + + throw new NotImplementedException(Format.ToString()); + } + + public static GalImageFormat ConvertFrameBuffer(GalFrameBufferFormat Format) + { + //Stubbed. + return GalImageFormat.A8B8G8R8; + } + + public static GalImageFormat ConvertZeta(GalZetaFormat Format) + { + //Stubbed. + return GalImageFormat.Z24S8; + } + + public static bool HasColor(GalImageFormat Format) + { + switch (Format) + { + case GalImageFormat.R32G32B32A32: + case GalImageFormat.R16G16B16A16: + case GalImageFormat.A8B8G8R8: + case GalImageFormat.A2B10G10R10: + case GalImageFormat.R32: + case GalImageFormat.BC6H_SF16: + case GalImageFormat.BC6H_UF16: + case GalImageFormat.A1B5G5R5: + case GalImageFormat.B5G6R5: + case GalImageFormat.BC7U: + case GalImageFormat.G8R8: + case GalImageFormat.R16: + case GalImageFormat.R8: + case GalImageFormat.BF10GF11RF11: + case GalImageFormat.BC1: + case GalImageFormat.BC2: + case GalImageFormat.BC3: + case GalImageFormat.BC4: + case GalImageFormat.BC5: + case GalImageFormat.Astc2D4x4: + case GalImageFormat.Astc2D5x5: + case GalImageFormat.Astc2D6x6: + case GalImageFormat.Astc2D8x8: + case GalImageFormat.Astc2D10x10: + case GalImageFormat.Astc2D12x12: + case GalImageFormat.Astc2D5x4: + case GalImageFormat.Astc2D6x5: + case GalImageFormat.Astc2D8x6: + case GalImageFormat.Astc2D10x8: + case GalImageFormat.Astc2D12x10: + case GalImageFormat.Astc2D8x5: + case GalImageFormat.Astc2D10x5: + case GalImageFormat.Astc2D10x6: + return true; + } + + return false; + } + + public static bool HasDepth(GalImageFormat Format) + { + switch (Format) + { + case GalImageFormat.Z24S8: + case GalImageFormat.ZF32: + return true; + } + + return false; + } + + public static bool HasStencil(GalImageFormat Format) + { + switch (Format) + { + case GalImageFormat.Z24S8: + return true; + } + + return false; + } + } +} \ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLBlend.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLBlend.cs deleted file mode 100644 index 6e41c85a28..0000000000 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLBlend.cs +++ /dev/null @@ -1,48 +0,0 @@ -using OpenTK.Graphics.OpenGL; - -namespace Ryujinx.Graphics.Gal.OpenGL -{ - public class OGLBlend : IGalBlend - { - public void Enable() - { - GL.Enable(EnableCap.Blend); - } - - public void Disable() - { - GL.Disable(EnableCap.Blend); - } - - public void Set( - GalBlendEquation Equation, - GalBlendFactor FuncSrc, - GalBlendFactor FuncDst) - { - GL.BlendEquation(OGLEnumConverter.GetBlendEquation(Equation)); - - GL.BlendFunc( - OGLEnumConverter.GetBlendFactor(FuncSrc), - OGLEnumConverter.GetBlendFactor(FuncDst)); - } - - public void SetSeparate( - GalBlendEquation EquationRgb, - GalBlendEquation EquationAlpha, - GalBlendFactor FuncSrcRgb, - GalBlendFactor FuncDstRgb, - GalBlendFactor FuncSrcAlpha, - GalBlendFactor FuncDstAlpha) - { - GL.BlendEquationSeparate( - OGLEnumConverter.GetBlendEquation(EquationRgb), - OGLEnumConverter.GetBlendEquation(EquationAlpha)); - - GL.BlendFuncSeparate( - (BlendingFactorSrc)OGLEnumConverter.GetBlendFactor(FuncSrcRgb), - (BlendingFactorDest)OGLEnumConverter.GetBlendFactor(FuncDstRgb), - (BlendingFactorSrc)OGLEnumConverter.GetBlendFactor(FuncSrcAlpha), - (BlendingFactorDest)OGLEnumConverter.GetBlendFactor(FuncDstAlpha)); - } - } -} \ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs index 28665026e5..dccebb1c48 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs @@ -125,109 +125,40 @@ namespace Ryujinx.Graphics.Gal.OpenGL throw new ArgumentException(nameof(Type)); } - public static PixelInternalFormat GetFrameBufferInternalFormat(GalFrameBufferFormat Format) + public static (PixelInternalFormat, PixelFormat, PixelType) GetImageFormat(GalImageFormat Format) { switch (Format) { - //Sometimes it's not set, use a safe format - case 0: return PixelInternalFormat.Rgba8; - - case GalFrameBufferFormat.RGBA32Float: return PixelInternalFormat.Rgba32f; - case GalFrameBufferFormat.RGBA32Sint: return PixelInternalFormat.Rgba32i; - case GalFrameBufferFormat.RGBA32Uint: return PixelInternalFormat.Rgba32ui; - case GalFrameBufferFormat.RGBA16Unorm: return PixelInternalFormat.Rgba16; - case GalFrameBufferFormat.RGBA16Snorm: return PixelInternalFormat.Rgba16Snorm; - case GalFrameBufferFormat.RGBA16Sint: return PixelInternalFormat.Rgba16i; - case GalFrameBufferFormat.RGBA16Uint: return PixelInternalFormat.Rgba16ui; - case GalFrameBufferFormat.RGBA16Float: return PixelInternalFormat.Rgba16f; - case GalFrameBufferFormat.RG32Float: return PixelInternalFormat.Rg32f; - case GalFrameBufferFormat.RG32Sint: return PixelInternalFormat.Rg32i; - case GalFrameBufferFormat.RG32Uint: return PixelInternalFormat.Rg32ui; - case GalFrameBufferFormat.RGB10A2Unorm: return PixelInternalFormat.Rgb10A2; - case GalFrameBufferFormat.RGB10A2Uint: return PixelInternalFormat.Rgb10A2ui; - case GalFrameBufferFormat.RGBA8Unorm: return PixelInternalFormat.Rgba8; - case GalFrameBufferFormat.RGBA8Srgb: return PixelInternalFormat.Srgb8; - case GalFrameBufferFormat.RG16Snorm: return PixelInternalFormat.Rg16Snorm; - case GalFrameBufferFormat.R11G11B10Float: return PixelInternalFormat.R11fG11fB10f; - case GalFrameBufferFormat.R32Float: return PixelInternalFormat.R32f; - case GalFrameBufferFormat.R16Float: return PixelInternalFormat.R16f; - case GalFrameBufferFormat.R8Unorm: return PixelInternalFormat.R8; - case GalFrameBufferFormat.R8Snorm: return PixelInternalFormat.R8Snorm; - case GalFrameBufferFormat.R8Sint: return PixelInternalFormat.R8i; - case GalFrameBufferFormat.R8Uint: return PixelInternalFormat.R8ui; + case GalImageFormat.R32G32B32A32: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.Float); + case GalImageFormat.R16G16B16A16: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.HalfFloat); + case GalImageFormat.A8B8G8R8: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte); + case GalImageFormat.A2B10G10R10: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed); + case GalImageFormat.R32: return (PixelInternalFormat.Rgba8, PixelFormat.Red, PixelType.Float); + case GalImageFormat.A1B5G5R5: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedShort5551); + case GalImageFormat.B5G6R5: return (PixelInternalFormat.Rgba8, PixelFormat.Rgb, PixelType.UnsignedShort565); + case GalImageFormat.G8R8: return (PixelInternalFormat.Rgba8, PixelFormat.Rg, PixelType.UnsignedByte); + case GalImageFormat.R16: return (PixelInternalFormat.Rgba8, PixelFormat.Red, PixelType.HalfFloat); + case GalImageFormat.R8: return (PixelInternalFormat.Rgba8, PixelFormat.Red, PixelType.UnsignedByte); + case GalImageFormat.ZF32: return (PixelInternalFormat.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float); + case GalImageFormat.BF10GF11RF11: return (PixelInternalFormat.Rgba8, PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev); + case GalImageFormat.Z24S8: return (PixelInternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248); } throw new NotImplementedException(Format.ToString()); } - public static (PixelFormat Format, PixelType Type) GetFrameBufferFormat(GalFrameBufferFormat Format) + public static InternalFormat GetCompressedImageFormat(GalImageFormat Format) { switch (Format) { - case 0: return (PixelFormat.Rgba, PixelType.UnsignedByte); - - case GalFrameBufferFormat.RGBA32Float: return (PixelFormat.Rgba, PixelType.Float); - case GalFrameBufferFormat.RGBA32Sint: return (PixelFormat.Rgba, PixelType.Int); - case GalFrameBufferFormat.RGBA32Uint: return (PixelFormat.Rgba, PixelType.UnsignedInt); - case GalFrameBufferFormat.RGBA16Unorm: return (PixelFormat.Rgba, PixelType.UnsignedShort); - case GalFrameBufferFormat.RGBA16Snorm: return (PixelFormat.Rgba, PixelType.Short); - case GalFrameBufferFormat.RGBA16Sint: return (PixelFormat.Rgba, PixelType.Short); - case GalFrameBufferFormat.RGBA16Uint: return (PixelFormat.Rgba, PixelType.UnsignedShort); - case GalFrameBufferFormat.RGBA16Float: return (PixelFormat.Rgba, PixelType.HalfFloat); - case GalFrameBufferFormat.RG32Float: return (PixelFormat.Rg, PixelType.Float); - case GalFrameBufferFormat.RG32Sint: return (PixelFormat.Rg, PixelType.Int); - case GalFrameBufferFormat.RG32Uint: return (PixelFormat.Rg, PixelType.UnsignedInt); - case GalFrameBufferFormat.RGB10A2Unorm: return (PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed); - case GalFrameBufferFormat.RGB10A2Uint: return (PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed); - case GalFrameBufferFormat.RGBA8Unorm: return (PixelFormat.Rgba, PixelType.UnsignedByte); - case GalFrameBufferFormat.RGBA8Srgb: return (PixelFormat.Rgba, PixelType.UnsignedByte); - case GalFrameBufferFormat.RG16Snorm: return (PixelFormat.Rg, PixelType.Short); - case GalFrameBufferFormat.R11G11B10Float: return (PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev); - case GalFrameBufferFormat.R32Float: return (PixelFormat.Red, PixelType.Float); - case GalFrameBufferFormat.R16Float: return (PixelFormat.Red, PixelType.HalfFloat); - case GalFrameBufferFormat.R8Unorm: return (PixelFormat.Red, PixelType.UnsignedByte); - case GalFrameBufferFormat.R8Snorm: return (PixelFormat.Red, PixelType.Byte); - case GalFrameBufferFormat.R8Sint: return (PixelFormat.Red, PixelType.Byte); - case GalFrameBufferFormat.R8Uint: return (PixelFormat.Red, PixelType.UnsignedByte); - } - - throw new NotImplementedException(Format.ToString()); - } - - public static (PixelFormat, PixelType) GetTextureFormat(GalTextureFormat Format) - { - switch (Format) - { - case GalTextureFormat.R32G32B32A32: return (PixelFormat.Rgba, PixelType.Float); - case GalTextureFormat.R16G16B16A16: return (PixelFormat.Rgba, PixelType.HalfFloat); - case GalTextureFormat.A8B8G8R8: return (PixelFormat.Rgba, PixelType.UnsignedByte); - case GalTextureFormat.A2B10G10R10: return (PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed); - case GalTextureFormat.R32: return (PixelFormat.Red, PixelType.Float); - case GalTextureFormat.A1B5G5R5: return (PixelFormat.Rgba, PixelType.UnsignedShort5551); - case GalTextureFormat.B5G6R5: return (PixelFormat.Rgb, PixelType.UnsignedShort565); - case GalTextureFormat.G8R8: return (PixelFormat.Rg, PixelType.UnsignedByte); - case GalTextureFormat.R16: return (PixelFormat.Red, PixelType.HalfFloat); - case GalTextureFormat.R8: return (PixelFormat.Red, PixelType.UnsignedByte); - case GalTextureFormat.ZF32: return (PixelFormat.DepthComponent, PixelType.Float); - case GalTextureFormat.BF10GF11RF11: return (PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev); - case GalTextureFormat.Z24S8: return (PixelFormat.DepthStencil, PixelType.UnsignedInt248); - } - - throw new NotImplementedException(Format.ToString()); - } - - public static InternalFormat GetCompressedTextureFormat(GalTextureFormat Format) - { - switch (Format) - { - case GalTextureFormat.BC6H_UF16: return InternalFormat.CompressedRgbBptcUnsignedFloat; - case GalTextureFormat.BC6H_SF16: return InternalFormat.CompressedRgbBptcSignedFloat; - case GalTextureFormat.BC7U: return InternalFormat.CompressedRgbaBptcUnorm; - case GalTextureFormat.BC1: return InternalFormat.CompressedRgbaS3tcDxt1Ext; - case GalTextureFormat.BC2: return InternalFormat.CompressedRgbaS3tcDxt3Ext; - case GalTextureFormat.BC3: return InternalFormat.CompressedRgbaS3tcDxt5Ext; - case GalTextureFormat.BC4: return InternalFormat.CompressedRedRgtc1; - case GalTextureFormat.BC5: return InternalFormat.CompressedRgRgtc2; + case GalImageFormat.BC6H_UF16: return InternalFormat.CompressedRgbBptcUnsignedFloat; + case GalImageFormat.BC6H_SF16: return InternalFormat.CompressedRgbBptcSignedFloat; + case GalImageFormat.BC7U: return InternalFormat.CompressedRgbaBptcUnorm; + case GalImageFormat.BC1: return InternalFormat.CompressedRgbaS3tcDxt1Ext; + case GalImageFormat.BC2: return InternalFormat.CompressedRgbaS3tcDxt3Ext; + case GalImageFormat.BC3: return InternalFormat.CompressedRgbaS3tcDxt5Ext; + case GalImageFormat.BC4: return InternalFormat.CompressedRedRgtc1; + case GalImageFormat.BC5: return InternalFormat.CompressedRgRgtc2; } throw new NotImplementedException(Format.ToString()); diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs index 9da9853dae..9e915cbc5e 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs @@ -23,126 +23,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL } } - private class Texture - { - public int Width { get; private set; } - public int Height { get; private set; } - - public PixelInternalFormat InternalFormat { get; private set; } - public PixelFormat Format { get; private set; } - public PixelType Type { get; private set; } - - public int Handle { get; private set; } - - private bool Initialized; - - public Texture() - { - Handle = GL.GenTexture(); - } - - public void EnsureSetup( - int Width, - int Height, - PixelInternalFormat InternalFormat, - PixelFormat Format, - PixelType Type) - { - if (!Initialized || - this.Width != Width || - this.Height != Height || - this.InternalFormat != InternalFormat) - { - int CopyBuffer = 0; - - bool ChangingFormat = Initialized && this.InternalFormat != InternalFormat; - - GL.BindTexture(TextureTarget.Texture2D, Handle); - - if (ChangingFormat) - { - CopyBuffer = GL.GenBuffer(); - - GL.BindBuffer(BufferTarget.PixelPackBuffer, CopyBuffer); - GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyBuffer); - - int MaxWidth = Math.Max(Width, this.Width); - int MaxHeight = Math.Max(Height, this.Height); - - //TODO: Dehardcode size number - GL.BufferData(BufferTarget.PixelPackBuffer, MaxWidth * MaxHeight * MaxBpp, IntPtr.Zero, BufferUsageHint.StaticCopy); - - GL.GetTexImage(TextureTarget.Texture2D, 0, this.Format, this.Type, 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; - - GL.TexImage2D( - TextureTarget.Texture2D, - Level, - InternalFormat, - Width, - Height, - Border, - Format, - Type, - IntPtr.Zero); - - if (ChangingFormat) - { - GL.BindBuffer(BufferTarget.PixelPackBuffer, 0); - GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0); - - GL.DeleteBuffer(CopyBuffer); - } - - this.Width = Width; - this.Height = Height; - this.InternalFormat = InternalFormat; - this.Format = Format; - this.Type = Type; - - Initialized = true; - } - } - - public void EnsureSetup(int Width, int Height, GalFrameBufferFormat Format) - { - //TODO: Convert color format - - EnsureSetup( - Width, - Height, - PixelInternalFormat.Rgba8, - PixelFormat.Rgba, - PixelType.UnsignedByte); - } - - public void EnsureSetup(int Width, int Height, GalZetaFormat Format) - { - //TODO: Convert zeta format - - EnsureSetup( - Width, - Height, - PixelInternalFormat.Depth24Stencil8, - PixelFormat.DepthStencil, - PixelType.UnsignedInt248); - } - } + private static readonly DrawBuffersEnum[] DrawBuffers = new DrawBuffersEnum[] { @@ -159,16 +40,13 @@ namespace Ryujinx.Graphics.Gal.OpenGL private const int NativeWidth = 1280; private const int NativeHeight = 720; - //TODO: Use a variable value here - private const int MaxBpp = 16; + private const GalImageFormat RawFormat = GalImageFormat.A8B8G8R8; - private const GalTextureFormat RawFormat = GalTextureFormat.A8B8G8R8; + private Dictionary ColorTextures; + private Dictionary ZetaTextures; - private Dictionary ColorTextures; - private Dictionary ZetaTextures; - - private Texture RawTex; - private Texture ReadTex; + private TCE RawTex; + private TCE ReadTex; private Rect Viewport; private Rect Window; @@ -188,26 +66,28 @@ namespace Ryujinx.Graphics.Gal.OpenGL public OGLFrameBuffer() { - ColorTextures = new Dictionary(); + ColorTextures = new Dictionary(); - ZetaTextures = new Dictionary(); + ZetaTextures = new Dictionary(); } public void CreateColor(long Key, int Width, int Height, GalFrameBufferFormat Format) { - if (!ColorTextures.TryGetValue(Key, out Texture Tex)) + if (!ColorTextures.TryGetValue(Key, out TCE Tex)) { - Tex = new Texture(); + Tex = new TCE(); ColorTextures.Add(Key, Tex); } - Tex.EnsureSetup(Width, Height, Format); + GalImageFormat ImageFormat = ImageFormatConverter.ConvertFrameBuffer(Format); + + Tex.EnsureSetup(new GalImage(Width, Height, ImageFormat)); } public void BindColor(long Key, int Attachment) { - if (ColorTextures.TryGetValue(Key, out Texture Tex)) + if (ColorTextures.TryGetValue(Key, out TCE Tex)) { EnsureFrameBuffer(); @@ -236,19 +116,21 @@ namespace Ryujinx.Graphics.Gal.OpenGL public void CreateZeta(long Key, int Width, int Height, GalZetaFormat Format) { - if (!ZetaTextures.TryGetValue(Key, out Texture Tex)) + if (!ZetaTextures.TryGetValue(Key, out TCE Tex)) { - Tex = new Texture(); + Tex = new TCE(); ZetaTextures.Add(Key, Tex); } - Tex.EnsureSetup(Width, Height, Format); + GalImageFormat ImageFormat = ImageFormatConverter.ConvertZeta(Format); + + Tex.EnsureSetup(new GalImage(Width, Height, ImageFormat)); } public void BindZeta(long Key) { - if (ZetaTextures.TryGetValue(Key, out Texture Tex)) + if (ZetaTextures.TryGetValue(Key, out TCE Tex)) { EnsureFrameBuffer(); @@ -277,7 +159,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL public void BindTexture(long Key, int Index) { - Texture Tex; + TCE Tex; if (ColorTextures.TryGetValue(Key, out Tex) || ZetaTextures.TryGetValue(Key, out Tex)) @@ -290,7 +172,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL public void Set(long Key) { - if (ColorTextures.TryGetValue(Key, out Texture Tex)) + if (ColorTextures.TryGetValue(Key, out TCE Tex)) { ReadTex = Tex; } @@ -300,16 +182,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL { if (RawTex == null) { - RawTex = new Texture(); + RawTex = new TCE(); } - RawTex.EnsureSetup(Width, Height, PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte); + RawTex.EnsureSetup(new GalImage(Width, Height, RawFormat)); GL.BindTexture(TextureTarget.Texture2D, RawTex.Handle); - (PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(RawFormat); - - GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, Width, Height, Format, Type, Data); + GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, Width, Height, RawTex.PixelFormat, RawTex.PixelType, Data); ReadTex = RawTex; } @@ -429,8 +309,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL { bool Found = false; - if (ColorTextures.TryGetValue(SrcKey, out Texture SrcTex) && - ColorTextures.TryGetValue(DstKey, out Texture DstTex)) + if (ColorTextures.TryGetValue(SrcKey, out TCE SrcTex) && + ColorTextures.TryGetValue(DstKey, out TCE DstTex)) { CopyTextures( SrcX0, SrcY0, SrcX1, SrcY1, @@ -444,8 +324,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL Found = true; } - if (ZetaTextures.TryGetValue(SrcKey, out Texture ZetaSrcTex) && - ZetaTextures.TryGetValue(DstKey, out Texture ZetaDstTex)) + if (ZetaTextures.TryGetValue(SrcKey, out TCE ZetaSrcTex) && + ZetaTextures.TryGetValue(DstKey, out TCE ZetaDstTex)) { CopyTextures( SrcX0, SrcY0, SrcX1, SrcY1, @@ -467,21 +347,20 @@ namespace Ryujinx.Graphics.Gal.OpenGL public void GetBufferData(long Key, Action Callback) { - Texture Tex; + TCE Tex; if (ColorTextures.TryGetValue(Key, out Tex) || ZetaTextures.TryGetValue(Key, out Tex)) { - //Note: Change this value when framebuffer sizes are dehardcoded - byte[] Data = new byte[Tex.Width * Tex.Height * MaxBpp]; + byte[] Data = new byte[Tex.Width * Tex.Height * TCE.MaxBpp]; GL.BindTexture(TextureTarget.Texture2D, Tex.Handle); GL.GetTexImage( TextureTarget.Texture2D, 0, - Tex.Format, - Tex.Type, + Tex.PixelFormat, + Tex.PixelType, Data); Callback(Data); @@ -494,7 +373,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL int Height, byte[] Buffer) { - Texture Tex; + TCE Tex; if (ColorTextures.TryGetValue(Key, out Tex) || ZetaTextures.TryGetValue(Key, out Tex)) @@ -511,8 +390,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL Width, Height, Border, - Tex.Format, - Tex.Type, + Tex.PixelFormat, + Tex.PixelType, Buffer); } } diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs index ac30e6fd81..95f12acd03 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs @@ -6,19 +6,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL { public class OGLTexture : IGalTexture { - private class TCE - { - public int Handle; - - public GalTexture Texture; - - public TCE(int Handle, GalTexture Texture) - { - this.Handle = Handle; - this.Texture = Texture; - } - } - private OGLCachedResource TextureCache; public OGLTexture() @@ -41,68 +28,66 @@ namespace Ryujinx.Graphics.Gal.OpenGL GL.DeleteTexture(CachedTexture.Handle); } - public void Create(long Key, byte[] Data, GalTexture Texture) + public void Create(long Key, byte[] Data, GalImage Image) { int Handle = GL.GenTexture(); - TextureCache.AddOrUpdate(Key, new TCE(Handle, Texture), (uint)Data.Length); + TextureCache.AddOrUpdate(Key, new TCE(Handle, Image), (uint)Data.Length); GL.BindTexture(TextureTarget.Texture2D, Handle); const int Level = 0; //TODO: Support mipmap textures. const int Border = 0; - if (IsCompressedTextureFormat(Texture.Format)) + if (IsCompressedTextureFormat(Image.Format)) { - InternalFormat InternalFmt = OGLEnumConverter.GetCompressedTextureFormat(Texture.Format); + InternalFormat InternalFmt = OGLEnumConverter.GetCompressedImageFormat(Image.Format); GL.CompressedTexImage2D( TextureTarget.Texture2D, Level, InternalFmt, - Texture.Width, - Texture.Height, + Image.Width, + Image.Height, Border, Data.Length, Data); } else { - if (Texture.Format >= GalTextureFormat.Astc2D4x4) + if (Image.Format > GalImageFormat.ConvertedBegin && Image.Format < GalImageFormat.ConvertedEnd) { - int TextureBlockWidth = GetAstcBlockWidth(Texture.Format); - int TextureBlockHeight = GetAstcBlockHeight(Texture.Format); + int TextureBlockWidth = GetAstcBlockWidth(Image.Format); + int TextureBlockHeight = GetAstcBlockHeight(Image.Format); Data = ASTCDecoder.DecodeToRGBA8888( Data, TextureBlockWidth, TextureBlockHeight, 1, - Texture.Width, - Texture.Height, 1); + Image.Width, + Image.Height, 1); - Texture.Format = GalTextureFormat.A8B8G8R8; + Image.Format = GalImageFormat.A8B8G8R8; } - const PixelInternalFormat InternalFmt = PixelInternalFormat.Rgba; - - (PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(Texture.Format); + (PixelInternalFormat InternalFormat, PixelFormat Format, PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format); GL.TexImage2D( TextureTarget.Texture2D, Level, - InternalFmt, - Texture.Width, - Texture.Height, + InternalFormat, + Image.Width, + Image.Height, Border, Format, Type, Data); } - int SwizzleR = (int)OGLEnumConverter.GetTextureSwizzle(Texture.XSource); - int SwizzleG = (int)OGLEnumConverter.GetTextureSwizzle(Texture.YSource); - int SwizzleB = (int)OGLEnumConverter.GetTextureSwizzle(Texture.ZSource); - int SwizzleA = (int)OGLEnumConverter.GetTextureSwizzle(Texture.WSource); + 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); @@ -110,65 +95,65 @@ namespace Ryujinx.Graphics.Gal.OpenGL GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleA, SwizzleA); } - private static int GetAstcBlockWidth(GalTextureFormat Format) + private static int GetAstcBlockWidth(GalImageFormat Format) { switch (Format) { - case GalTextureFormat.Astc2D4x4: return 4; - case GalTextureFormat.Astc2D5x5: return 5; - case GalTextureFormat.Astc2D6x6: return 6; - case GalTextureFormat.Astc2D8x8: return 8; - case GalTextureFormat.Astc2D10x10: return 10; - case GalTextureFormat.Astc2D12x12: return 12; - case GalTextureFormat.Astc2D5x4: return 5; - case GalTextureFormat.Astc2D6x5: return 6; - case GalTextureFormat.Astc2D8x6: return 8; - case GalTextureFormat.Astc2D10x8: return 10; - case GalTextureFormat.Astc2D12x10: return 12; - case GalTextureFormat.Astc2D8x5: return 8; - case GalTextureFormat.Astc2D10x5: return 10; - case GalTextureFormat.Astc2D10x6: return 10; + case GalImageFormat.Astc2D4x4: return 4; + case GalImageFormat.Astc2D5x5: return 5; + case GalImageFormat.Astc2D6x6: return 6; + case GalImageFormat.Astc2D8x8: return 8; + case GalImageFormat.Astc2D10x10: return 10; + case GalImageFormat.Astc2D12x12: return 12; + case GalImageFormat.Astc2D5x4: return 5; + case GalImageFormat.Astc2D6x5: return 6; + case GalImageFormat.Astc2D8x6: return 8; + case GalImageFormat.Astc2D10x8: return 10; + case GalImageFormat.Astc2D12x10: return 12; + case GalImageFormat.Astc2D8x5: return 8; + case GalImageFormat.Astc2D10x5: return 10; + case GalImageFormat.Astc2D10x6: return 10; } throw new ArgumentException(nameof(Format)); } - private static int GetAstcBlockHeight(GalTextureFormat Format) + private static int GetAstcBlockHeight(GalImageFormat Format) { switch (Format) { - case GalTextureFormat.Astc2D4x4: return 4; - case GalTextureFormat.Astc2D5x5: return 5; - case GalTextureFormat.Astc2D6x6: return 6; - case GalTextureFormat.Astc2D8x8: return 8; - case GalTextureFormat.Astc2D10x10: return 10; - case GalTextureFormat.Astc2D12x12: return 12; - case GalTextureFormat.Astc2D5x4: return 4; - case GalTextureFormat.Astc2D6x5: return 5; - case GalTextureFormat.Astc2D8x6: return 6; - case GalTextureFormat.Astc2D10x8: return 8; - case GalTextureFormat.Astc2D12x10: return 10; - case GalTextureFormat.Astc2D8x5: return 5; - case GalTextureFormat.Astc2D10x5: return 5; - case GalTextureFormat.Astc2D10x6: return 6; + case GalImageFormat.Astc2D4x4: return 4; + case GalImageFormat.Astc2D5x5: return 5; + case GalImageFormat.Astc2D6x6: return 6; + case GalImageFormat.Astc2D8x8: return 8; + case GalImageFormat.Astc2D10x10: return 10; + case GalImageFormat.Astc2D12x12: return 12; + case GalImageFormat.Astc2D5x4: return 4; + case GalImageFormat.Astc2D6x5: return 5; + case GalImageFormat.Astc2D8x6: return 6; + case GalImageFormat.Astc2D10x8: return 8; + case GalImageFormat.Astc2D12x10: return 10; + case GalImageFormat.Astc2D8x5: return 5; + case GalImageFormat.Astc2D10x5: return 5; + case GalImageFormat.Astc2D10x6: return 6; } throw new ArgumentException(nameof(Format)); } - public bool TryGetCachedTexture(long Key, long DataSize, out GalTexture Texture) + public bool TryGetCachedTexture(long Key, long DataSize, out GalImage Image) { if (TextureCache.TryGetSize(Key, out long Size) && Size == DataSize) { if (TextureCache.TryGetValue(Key, out TCE CachedTexture)) { - Texture = CachedTexture.Texture; + Image = CachedTexture.Image; return true; } } - Texture = default(GalTexture); + Image = default(GalImage); return false; } @@ -208,18 +193,18 @@ namespace Ryujinx.Graphics.Gal.OpenGL GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBorderColor, Color); } - private static bool IsCompressedTextureFormat(GalTextureFormat Format) + private static bool IsCompressedTextureFormat(GalImageFormat Format) { switch (Format) { - case GalTextureFormat.BC6H_UF16: - case GalTextureFormat.BC6H_SF16: - case GalTextureFormat.BC7U: - case GalTextureFormat.BC1: - case GalTextureFormat.BC2: - case GalTextureFormat.BC3: - case GalTextureFormat.BC4: - case GalTextureFormat.BC5: + case GalImageFormat.BC6H_UF16: + case GalImageFormat.BC6H_SF16: + case GalImageFormat.BC7U: + case GalImageFormat.BC1: + case GalImageFormat.BC2: + case GalImageFormat.BC3: + case GalImageFormat.BC4: + case GalImageFormat.BC5: return true; } diff --git a/Ryujinx.Graphics/Gal/OpenGL/TCE.cs b/Ryujinx.Graphics/Gal/OpenGL/TCE.cs new file mode 100644 index 0000000000..d39dba7d0e --- /dev/null +++ b/Ryujinx.Graphics/Gal/OpenGL/TCE.cs @@ -0,0 +1,112 @@ +using OpenTK.Graphics.OpenGL; +using System; + +namespace Ryujinx.Graphics.Gal.OpenGL +{ + class TCE + { + //TODO: Use a variable value here + public const int MaxBpp = 16; + + public GalImage Image { get; private set; } + + public int Width { get => Image.Width; } + public int Height { get => Image.Height; } + public GalImageFormat Format { get => 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 TCE() + { + Handle = GL.GenTexture(); + } + + public TCE(int Handle, GalImage Image) + { + this.Handle = Handle; + + this.Image = Image; + } + + public void EnsureSetup(GalImage Image) + { + if (this.Width != Image.Width || + this.Height != Image.Height || + this.Format != Image.Format || + !Initialized) + { + (PixelInternalFormat InternalFormat, PixelFormat PixelFormat, PixelType PixelType) = + OGLEnumConverter.GetImageFormat(Image.Format); + + int CopyBuffer = 0; + + bool ChangingFormat = Initialized && this.InternalFormat != InternalFormat; + + GL.BindTexture(TextureTarget.Texture2D, Handle); + + if (ChangingFormat) + { + CopyBuffer = GL.GenBuffer(); + + GL.BindBuffer(BufferTarget.PixelPackBuffer, CopyBuffer); + GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyBuffer); + + int MaxWidth = Math.Max(Image.Width, this.Width); + int MaxHeight = Math.Max(Image.Height, this.Height); + + GL.BufferData(BufferTarget.PixelPackBuffer, MaxWidth * MaxHeight * MaxBpp, IntPtr.Zero, BufferUsageHint.StaticCopy); + + 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; + + GL.TexImage2D( + TextureTarget.Texture2D, + Level, + InternalFormat, + Image.Width, + Image.Height, + Border, + PixelFormat, + PixelType, + IntPtr.Zero); + + if (ChangingFormat) + { + GL.BindBuffer(BufferTarget.PixelPackBuffer, 0); + GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0); + + GL.DeleteBuffer(CopyBuffer); + } + + this.Image = Image; + + this.InternalFormat = InternalFormat; + this.PixelFormat = PixelFormat; + this.PixelType = PixelType; + + Initialized = true; + } + } + } +} diff --git a/Ryujinx.Graphics/Ryujinx.Graphics.csproj b/Ryujinx.Graphics/Ryujinx.Graphics.csproj index 7d86cbe134..cddb670782 100644 --- a/Ryujinx.Graphics/Ryujinx.Graphics.csproj +++ b/Ryujinx.Graphics/Ryujinx.Graphics.csproj @@ -13,6 +13,10 @@ true + + + + diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs index 19488e7e0a..a3c79d4a15 100644 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs @@ -166,7 +166,7 @@ namespace Ryujinx.HLE.Gpu.Engines int Format = ReadRegister(NvGpuEngine3dReg.FrameBufferNFormat + FbIndex * 0x10); - if (VA == 0 || Format == 0) + if (VA == 0/* || Format == 0*/) { Gpu.Renderer.FrameBuffer.UnbindColor(FbIndex); @@ -479,13 +479,13 @@ namespace Ryujinx.HLE.Gpu.Engines } else { - GalTexture NewTexture = TextureFactory.MakeTexture(Vmm, TicPosition); + GalImage NewTexture = TextureFactory.MakeTexture(Vmm, TicPosition); long Size = (uint)TextureHelper.GetTextureSize(NewTexture); bool HasCachedTexture = false; - if (Gpu.Renderer.Texture.TryGetCachedTexture(Key, Size, out GalTexture Texture)) + if (Gpu.Renderer.Texture.TryGetCachedTexture(Key, Size, out GalImage Texture)) { if (NewTexture.Equals(Texture) && !QueryKeyUpload(Vmm, Key, Size, NvGpuBufferType.Texture)) { diff --git a/Ryujinx.HLE/Gpu/Texture/TextureFactory.cs b/Ryujinx.HLE/Gpu/Texture/TextureFactory.cs index 4db0b6f106..a9fa6dbd1e 100644 --- a/Ryujinx.HLE/Gpu/Texture/TextureFactory.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureFactory.cs @@ -6,11 +6,11 @@ namespace Ryujinx.HLE.Gpu.Texture { static class TextureFactory { - public static GalTexture MakeTexture(NvGpuVmm Vmm, long TicPosition) + public static GalImage MakeTexture(NvGpuVmm Vmm, long TicPosition) { int[] Tic = ReadWords(Vmm, TicPosition, 8); - GalTextureFormat Format = (GalTextureFormat)(Tic[0] & 0x7f); + GalImageFormat Format = ImageFormatConverter.ConvertTexture((GalTextureFormat)(Tic[0] & 0x7f)); GalTextureSource XSource = (GalTextureSource)((Tic[0] >> 19) & 7); GalTextureSource YSource = (GalTextureSource)((Tic[0] >> 22) & 7); @@ -20,7 +20,7 @@ namespace Ryujinx.HLE.Gpu.Texture int Width = (Tic[4] & 0xffff) + 1; int Height = (Tic[5] & 0xffff) + 1; - return new GalTexture( + return new GalImage( Width, Height, Format, diff --git a/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs index 1d621c9226..1b1b4be841 100644 --- a/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs @@ -30,117 +30,117 @@ namespace Ryujinx.HLE.Gpu.Texture throw new NotImplementedException(Texture.Swizzle.ToString()); } - public static int GetTextureSize(GalTexture Texture) + public static int GetTextureSize(GalImage Image) { - switch (Texture.Format) + switch (Image.Format) { - case GalTextureFormat.R32G32B32A32: - return Texture.Width * Texture.Height * 16; + case GalImageFormat.R32G32B32A32: + return Image.Width * Image.Height * 16; - case GalTextureFormat.R16G16B16A16: - return Texture.Width * Texture.Height * 8; + case GalImageFormat.R16G16B16A16: + return Image.Width * Image.Height * 8; - case GalTextureFormat.A8B8G8R8: - case GalTextureFormat.A2B10G10R10: - case GalTextureFormat.R32: - case GalTextureFormat.ZF32: - case GalTextureFormat.BF10GF11RF11: - case GalTextureFormat.Z24S8: - return Texture.Width * Texture.Height * 4; + case GalImageFormat.A8B8G8R8: + case GalImageFormat.A2B10G10R10: + case GalImageFormat.R32: + case GalImageFormat.ZF32: + case GalImageFormat.BF10GF11RF11: + case GalImageFormat.Z24S8: + return Image.Width * Image.Height * 4; - case GalTextureFormat.A1B5G5R5: - case GalTextureFormat.B5G6R5: - case GalTextureFormat.G8R8: - case GalTextureFormat.R16: - return Texture.Width * Texture.Height * 2; + case GalImageFormat.A1B5G5R5: + case GalImageFormat.B5G6R5: + case GalImageFormat.G8R8: + case GalImageFormat.R16: + return Image.Width * Image.Height * 2; - case GalTextureFormat.R8: - return Texture.Width * Texture.Height; + case GalImageFormat.R8: + return Image.Width * Image.Height; - case GalTextureFormat.BC1: - case GalTextureFormat.BC4: + case GalImageFormat.BC1: + case GalImageFormat.BC4: { - return CompressedTextureSize(Texture.Width, Texture.Height, 4, 4, 8); + return CompressedTextureSize(Image.Width, Image.Height, 4, 4, 8); } - case GalTextureFormat.BC6H_SF16: - case GalTextureFormat.BC6H_UF16: - case GalTextureFormat.BC7U: - case GalTextureFormat.BC2: - case GalTextureFormat.BC3: - case GalTextureFormat.BC5: - case GalTextureFormat.Astc2D4x4: + case GalImageFormat.BC6H_SF16: + case GalImageFormat.BC6H_UF16: + case GalImageFormat.BC7U: + case GalImageFormat.BC2: + case GalImageFormat.BC3: + case GalImageFormat.BC5: + case GalImageFormat.Astc2D4x4: { - return CompressedTextureSize(Texture.Width, Texture.Height, 4, 4, 16); + return CompressedTextureSize(Image.Width, Image.Height, 4, 4, 16); } - case GalTextureFormat.Astc2D5x5: + case GalImageFormat.Astc2D5x5: { - return CompressedTextureSize(Texture.Width, Texture.Height, 5, 5, 16); + return CompressedTextureSize(Image.Width, Image.Height, 5, 5, 16); } - case GalTextureFormat.Astc2D6x6: + case GalImageFormat.Astc2D6x6: { - return CompressedTextureSize(Texture.Width, Texture.Height, 6, 6, 16); + return CompressedTextureSize(Image.Width, Image.Height, 6, 6, 16); } - case GalTextureFormat.Astc2D8x8: + case GalImageFormat.Astc2D8x8: { - return CompressedTextureSize(Texture.Width, Texture.Height, 8, 8, 16); + return CompressedTextureSize(Image.Width, Image.Height, 8, 8, 16); } - case GalTextureFormat.Astc2D10x10: + case GalImageFormat.Astc2D10x10: { - return CompressedTextureSize(Texture.Width, Texture.Height, 10, 10, 16); + return CompressedTextureSize(Image.Width, Image.Height, 10, 10, 16); } - case GalTextureFormat.Astc2D12x12: + case GalImageFormat.Astc2D12x12: { - return CompressedTextureSize(Texture.Width, Texture.Height, 12, 12, 16); + return CompressedTextureSize(Image.Width, Image.Height, 12, 12, 16); } - case GalTextureFormat.Astc2D5x4: + case GalImageFormat.Astc2D5x4: { - return CompressedTextureSize(Texture.Width, Texture.Height, 5, 4, 16); + return CompressedTextureSize(Image.Width, Image.Height, 5, 4, 16); } - case GalTextureFormat.Astc2D6x5: + case GalImageFormat.Astc2D6x5: { - return CompressedTextureSize(Texture.Width, Texture.Height, 6, 5, 16); + return CompressedTextureSize(Image.Width, Image.Height, 6, 5, 16); } - case GalTextureFormat.Astc2D8x6: + case GalImageFormat.Astc2D8x6: { - return CompressedTextureSize(Texture.Width, Texture.Height, 8, 6, 16); + return CompressedTextureSize(Image.Width, Image.Height, 8, 6, 16); } - case GalTextureFormat.Astc2D10x8: + case GalImageFormat.Astc2D10x8: { - return CompressedTextureSize(Texture.Width, Texture.Height, 10, 8, 16); + return CompressedTextureSize(Image.Width, Image.Height, 10, 8, 16); } - case GalTextureFormat.Astc2D12x10: + case GalImageFormat.Astc2D12x10: { - return CompressedTextureSize(Texture.Width, Texture.Height, 12, 10, 16); + return CompressedTextureSize(Image.Width, Image.Height, 12, 10, 16); } - case GalTextureFormat.Astc2D8x5: + case GalImageFormat.Astc2D8x5: { - return CompressedTextureSize(Texture.Width, Texture.Height, 8, 5, 16); + return CompressedTextureSize(Image.Width, Image.Height, 8, 5, 16); } - case GalTextureFormat.Astc2D10x5: + case GalImageFormat.Astc2D10x5: { - return CompressedTextureSize(Texture.Width, Texture.Height, 10, 5, 16); + return CompressedTextureSize(Image.Width, Image.Height, 10, 5, 16); } - case GalTextureFormat.Astc2D10x6: + case GalImageFormat.Astc2D10x6: { - return CompressedTextureSize(Texture.Width, Texture.Height, 10, 6, 16); + return CompressedTextureSize(Image.Width, Image.Height, 10, 6, 16); } } - throw new NotImplementedException(Texture.Format.ToString()); + throw new NotImplementedException(Image.Format.ToString()); } public static int CompressedTextureSize(int TextureWidth, int TextureHeight, int BlockWidth, int BlockHeight, int Bpb) From 5ea1382aff5e9a7156a36872a7a2d9cc1331b8f7 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sat, 11 Aug 2018 01:44:25 -0300 Subject: [PATCH 05/13] Share images between framebuffers and textures --- Ryujinx.Graphics/Gal/IGalFrameBuffer.cs | 4 - Ryujinx.Graphics/Gal/IGalTexture.cs | 2 + Ryujinx.Graphics/Gal/ImageFormatConverter.cs | 10 + Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs | 204 ++++++++++-------- Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs | 28 +-- Ryujinx.Graphics/Gal/OpenGL/OGLRenderer.cs | 6 +- Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs | 26 ++- Ryujinx.Graphics/Gal/OpenGL/TCE.cs | 41 ++-- Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs | 36 +++- 9 files changed, 211 insertions(+), 146 deletions(-) diff --git a/Ryujinx.Graphics/Gal/IGalFrameBuffer.cs b/Ryujinx.Graphics/Gal/IGalFrameBuffer.cs index 91608ffa77..bce1981a47 100644 --- a/Ryujinx.Graphics/Gal/IGalFrameBuffer.cs +++ b/Ryujinx.Graphics/Gal/IGalFrameBuffer.cs @@ -4,14 +4,10 @@ namespace Ryujinx.Graphics.Gal { public interface IGalFrameBuffer { - void CreateColor(long Key, int Width, int Height, GalFrameBufferFormat Format); - void BindColor(long Key, int Attachment); void UnbindColor(int Attachment); - void CreateZeta(long Key, int Width, int Height, GalZetaFormat Format); - void BindZeta(long Key); void UnbindZeta(); diff --git a/Ryujinx.Graphics/Gal/IGalTexture.cs b/Ryujinx.Graphics/Gal/IGalTexture.cs index f6caa29791..292f59efa1 100644 --- a/Ryujinx.Graphics/Gal/IGalTexture.cs +++ b/Ryujinx.Graphics/Gal/IGalTexture.cs @@ -7,6 +7,8 @@ namespace Ryujinx.Graphics.Gal void Create(long Key, byte[] Data, GalImage Image); + void CreateFb(long Key, long Size, GalImage Image); + bool TryGetCachedTexture(long Key, long DataSize, out GalImage Image); void Bind(long Key, int Index); diff --git a/Ryujinx.Graphics/Gal/ImageFormatConverter.cs b/Ryujinx.Graphics/Gal/ImageFormatConverter.cs index 6e38292208..af0f2caecf 100644 --- a/Ryujinx.Graphics/Gal/ImageFormatConverter.cs +++ b/Ryujinx.Graphics/Gal/ImageFormatConverter.cs @@ -50,12 +50,22 @@ namespace Ryujinx.Graphics.Gal public static GalImageFormat ConvertFrameBuffer(GalFrameBufferFormat Format) { + switch (Format) + { + case GalFrameBufferFormat.R32Float: return GalImageFormat.R32; + } + //Stubbed. return GalImageFormat.A8B8G8R8; } public static GalImageFormat ConvertZeta(GalZetaFormat Format) { + switch (Format) + { + case GalZetaFormat.Z32Float: return GalImageFormat.ZF32; + } + //Stubbed. return GalImageFormat.Z24S8; } diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs index 9e915cbc5e..a73c6935b7 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; namespace Ryujinx.Graphics.Gal.OpenGL { - public class OGLFrameBuffer : IGalFrameBuffer + class OGLFrameBuffer : IGalFrameBuffer { private struct Rect { @@ -23,8 +23,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL } } - - private static readonly DrawBuffersEnum[] DrawBuffers = new DrawBuffersEnum[] { DrawBuffersEnum.ColorAttachment0, @@ -42,8 +40,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL private const GalImageFormat RawFormat = GalImageFormat.A8B8G8R8; - private Dictionary ColorTextures; - private Dictionary ZetaTextures; + private OGLTexture Texture; private TCE RawTex; private TCE ReadTex; @@ -64,35 +61,19 @@ namespace Ryujinx.Graphics.Gal.OpenGL private int SrcFb; private int DstFb; - public OGLFrameBuffer() + public OGLFrameBuffer(OGLTexture Texture) { - ColorTextures = new Dictionary(); - - ZetaTextures = new Dictionary(); - } - - public void CreateColor(long Key, int Width, int Height, GalFrameBufferFormat Format) - { - if (!ColorTextures.TryGetValue(Key, out TCE Tex)) - { - Tex = new TCE(); - - ColorTextures.Add(Key, Tex); - } - - GalImageFormat ImageFormat = ImageFormatConverter.ConvertFrameBuffer(Format); - - Tex.EnsureSetup(new GalImage(Width, Height, ImageFormat)); + this.Texture = Texture; } public void BindColor(long Key, int Attachment) { - if (ColorTextures.TryGetValue(Key, out TCE Tex)) + if (Texture.TryGetTCE(Key, out TCE Tex)) { EnsureFrameBuffer(); GL.FramebufferTexture( - FramebufferTarget.Framebuffer, + FramebufferTarget.DrawFramebuffer, FramebufferAttachment.ColorAttachment0 + Attachment, Tex.Handle, 0); @@ -108,37 +89,58 @@ namespace Ryujinx.Graphics.Gal.OpenGL EnsureFrameBuffer(); GL.FramebufferTexture( - FramebufferTarget.Framebuffer, + FramebufferTarget.DrawFramebuffer, FramebufferAttachment.ColorAttachment0 + Attachment, 0, 0); } - - public void CreateZeta(long Key, int Width, int Height, GalZetaFormat Format) - { - if (!ZetaTextures.TryGetValue(Key, out TCE Tex)) - { - Tex = new TCE(); - - ZetaTextures.Add(Key, Tex); - } - - GalImageFormat ImageFormat = ImageFormatConverter.ConvertZeta(Format); - - Tex.EnsureSetup(new GalImage(Width, Height, ImageFormat)); - } - + public void BindZeta(long Key) { - if (ZetaTextures.TryGetValue(Key, out TCE Tex)) + if (Texture.TryGetTCE(Key, out TCE Tex)) { EnsureFrameBuffer(); - GL.FramebufferTexture( - FramebufferTarget.Framebuffer, - FramebufferAttachment.DepthStencilAttachment, - Tex.Handle, - 0); + if (Tex.HasDepth && Tex.HasStencil) + { + GL.FramebufferTexture( + FramebufferTarget.DrawFramebuffer, + FramebufferAttachment.DepthStencilAttachment, + Tex.Handle, + 0); + } + else if (Tex.HasDepth) + { + GL.FramebufferTexture( + FramebufferTarget.DrawFramebuffer, + FramebufferAttachment.DepthAttachment, + Tex.Handle, + 0); + + GL.FramebufferTexture( + FramebufferTarget.DrawFramebuffer, + FramebufferAttachment.StencilAttachment, + 0, + 0); + } + else if (Tex.HasStencil) + { + GL.FramebufferTexture( + FramebufferTarget.DrawFramebuffer, + FramebufferAttachment.DepthAttachment, + Tex.Handle, + 0); + + GL.FramebufferTexture( + FramebufferTarget.DrawFramebuffer, + FramebufferAttachment.StencilAttachment, + 0, + 0); + } + else + { + throw new InvalidOperationException(); + } } else { @@ -151,7 +153,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL EnsureFrameBuffer(); GL.FramebufferTexture( - FramebufferTarget.Framebuffer, + FramebufferTarget.DrawFramebuffer, FramebufferAttachment.DepthStencilAttachment, 0, 0); @@ -159,10 +161,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL public void BindTexture(long Key, int Index) { - TCE Tex; - - if (ColorTextures.TryGetValue(Key, out Tex) || - ZetaTextures.TryGetValue(Key, out Tex)) + if (Texture.TryGetTCE(Key, out TCE Tex)) { GL.ActiveTexture(TextureUnit.Texture0 + Index); @@ -172,7 +171,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL public void Set(long Key) { - if (ColorTextures.TryGetValue(Key, out TCE Tex)) + if (Texture.TryGetTCE(Key, out TCE Tex)) { ReadTex = Tex; } @@ -307,50 +306,72 @@ namespace Ryujinx.Graphics.Gal.OpenGL int DstX1, int DstY1) { - bool Found = false; - - if (ColorTextures.TryGetValue(SrcKey, out TCE SrcTex) && - ColorTextures.TryGetValue(DstKey, out TCE DstTex)) + if (Texture.TryGetTCE(SrcKey, out TCE SrcTex) && + Texture.TryGetTCE(DstKey, out TCE DstTex)) { - CopyTextures( - SrcX0, SrcY0, SrcX1, SrcY1, - DstX0, DstY0, DstX1, DstY1, - SrcTex.Handle, - DstTex.Handle, - FramebufferAttachment.ColorAttachment0, - ClearBufferMask.ColorBufferBit, - true); + if (SrcTex.HasColor != DstTex.HasColor || + SrcTex.HasDepth != DstTex.HasDepth || + SrcTex.HasStencil != DstTex.HasStencil) + { + throw new NotImplementedException(); + } - Found = true; - } + if (SrcTex.HasColor) + { + CopyTextures( + SrcX0, SrcY0, SrcX1, SrcY1, + DstX0, DstY0, DstX1, DstY1, + SrcTex.Handle, + DstTex.Handle, + FramebufferAttachment.ColorAttachment0, + ClearBufferMask.ColorBufferBit, + true); + } + 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) + { + CopyTextures( + SrcX0, SrcY0, SrcX1, SrcY1, + DstX0, DstY0, DstX1, DstY1, + SrcTex.Handle, + DstTex.Handle, + FramebufferAttachment.StencilAttachment, + ClearBufferMask.StencilBufferBit, + false); + } + else + { + throw new InvalidOperationException(); + } - if (ZetaTextures.TryGetValue(SrcKey, out TCE ZetaSrcTex) && - ZetaTextures.TryGetValue(DstKey, out TCE ZetaDstTex)) - { - CopyTextures( - SrcX0, SrcY0, SrcX1, SrcY1, - DstX0, DstY0, DstX1, DstY1, - ZetaSrcTex.Handle, - ZetaDstTex.Handle, - FramebufferAttachment.DepthStencilAttachment, - ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit, - false); - - Found = true; - } - - if (Found) - { EnsureFrameBuffer(); } } public void GetBufferData(long Key, Action Callback) { - TCE Tex; - - if (ColorTextures.TryGetValue(Key, out Tex) || - ZetaTextures.TryGetValue(Key, out Tex)) + if (Texture.TryGetTCE(Key, out TCE Tex)) { byte[] Data = new byte[Tex.Width * Tex.Height * TCE.MaxBpp]; @@ -373,10 +394,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL int Height, byte[] Buffer) { - TCE Tex; - - if (ColorTextures.TryGetValue(Key, out Tex) || - ZetaTextures.TryGetValue(Key, out Tex)) + if (Texture.TryGetTCE(Key, out TCE Tex)) { GL.BindTexture(TextureTarget.Texture2D, Tex.Handle); @@ -403,7 +421,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL DummyFrameBuffer = GL.GenFramebuffer(); } - GL.BindFramebuffer(FramebufferTarget.Framebuffer, DummyFrameBuffer); + GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, DummyFrameBuffer); GL.DrawBuffers(8, DrawBuffers); } diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs index c0e4bd0f53..3cb362cfbf 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs @@ -50,33 +50,23 @@ namespace Ryujinx.Graphics.Gal.OpenGL float Depth, int Stencil) { - //TODO: Handle attachment - - ClearBufferMask Mask = ClearBufferMask.ColorBufferBit; - - if (Flags.HasFlag(GalClearBufferFlags.Depth)) - { - Mask |= ClearBufferMask.DepthBufferBit; - } - - if (Flags.HasFlag(GalClearBufferFlags.Stencil)) - { - Mask |= ClearBufferMask.StencilBufferBit; - } - GL.ColorMask( Flags.HasFlag(GalClearBufferFlags.ColorRed), Flags.HasFlag(GalClearBufferFlags.ColorGreen), Flags.HasFlag(GalClearBufferFlags.ColorBlue), Flags.HasFlag(GalClearBufferFlags.ColorAlpha)); - GL.ClearColor(Red, Green, Blue, Alpha); + GL.ClearBuffer(ClearBuffer.Color, Attachment, new float[] { Red, Green, Blue, Alpha }); - GL.ClearDepth(Depth); + if (Flags.HasFlag(GalClearBufferFlags.Depth)) + { + GL.ClearBuffer(ClearBuffer.Depth, 0, ref Depth); + } - GL.ClearStencil(Stencil); - - GL.Clear(Mask); + if (Flags.HasFlag(GalClearBufferFlags.Stencil)) + { + GL.ClearBuffer(ClearBuffer.Stencil, 0, ref Stencil); + } GL.ColorMask(true, true, true, true); } diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderer.cs index b0f6da45e5..985f1086f0 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderer.cs @@ -23,7 +23,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL { Buffer = new OGLConstBuffer(); - FrameBuffer = new OGLFrameBuffer(); + Texture = new OGLTexture(); + + FrameBuffer = new OGLFrameBuffer(Texture as OGLTexture); Rasterizer = new OGLRasterizer(); @@ -31,8 +33,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL Pipeline = new OGLPipeline(Buffer as OGLConstBuffer, Rasterizer as OGLRasterizer, Shader as OGLShader); - Texture = new OGLTexture(); - ActionsQueue = new ConcurrentQueue(); } diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs index 95f12acd03..24dd83b006 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs @@ -4,7 +4,7 @@ using System; namespace Ryujinx.Graphics.Gal.OpenGL { - public class OGLTexture : IGalTexture + class OGLTexture : IGalTexture { private OGLCachedResource TextureCache; @@ -95,6 +95,30 @@ namespace Ryujinx.Graphics.Gal.OpenGL GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleA, SwizzleA); } + public void CreateFb(long Key, long Size, GalImage Image) + { + if (!TryGetTCE(Key, out TCE Texture)) + { + Texture = new TCE(); + + TextureCache.AddOrUpdate(Key, Texture, Size); + } + + Texture.EnsureSetup(Image); + } + + public bool TryGetTCE(long Key, out TCE CachedTexture) + { + if (TextureCache.TryGetValue(Key, out CachedTexture)) + { + return true; + } + + CachedTexture = null; + + return false; + } + private static int GetAstcBlockWidth(GalImageFormat Format) { switch (Format) diff --git a/Ryujinx.Graphics/Gal/OpenGL/TCE.cs b/Ryujinx.Graphics/Gal/OpenGL/TCE.cs index d39dba7d0e..2b60f01155 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/TCE.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/TCE.cs @@ -8,6 +8,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL //TODO: Use a variable value here public const int MaxBpp = 16; + private static int CopyBuffer = 0; + private static int CopyBufferSize = 0; + public GalImage Image { get; private set; } public int Width { get => Image.Width; } @@ -36,31 +39,37 @@ namespace Ryujinx.Graphics.Gal.OpenGL public void EnsureSetup(GalImage Image) { - if (this.Width != Image.Width || - this.Height != Image.Height || - this.Format != Image.Format || + if (Width != Image.Width || + Height != Image.Height || + Format != Image.Format || !Initialized) { (PixelInternalFormat InternalFormat, PixelFormat PixelFormat, PixelType PixelType) = OGLEnumConverter.GetImageFormat(Image.Format); - int CopyBuffer = 0; - - bool ChangingFormat = Initialized && this.InternalFormat != InternalFormat; - GL.BindTexture(TextureTarget.Texture2D, Handle); - if (ChangingFormat) + if (Initialized) { - CopyBuffer = GL.GenBuffer(); + if (CopyBuffer == 0) + { + CopyBuffer = GL.GenBuffer(); + } + + int MaxWidth = Math.Max(Image.Width, Width); + int MaxHeight = Math.Max(Image.Height, Height); + + int CurrentSize = MaxWidth * MaxHeight * MaxBpp; GL.BindBuffer(BufferTarget.PixelPackBuffer, CopyBuffer); GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyBuffer); - int MaxWidth = Math.Max(Image.Width, this.Width); - int MaxHeight = Math.Max(Image.Height, this.Height); + if (CopyBufferSize < CurrentSize) + { + CopyBufferSize = CurrentSize; - GL.BufferData(BufferTarget.PixelPackBuffer, MaxWidth * MaxHeight * MaxBpp, IntPtr.Zero, BufferUsageHint.StaticCopy); + GL.BufferData(BufferTarget.PixelPackBuffer, CurrentSize, IntPtr.Zero, BufferUsageHint.DynamicCopy); + } GL.GetTexImage(TextureTarget.Texture2D, 0, this.PixelFormat, this.PixelType, IntPtr.Zero); @@ -91,12 +100,10 @@ namespace Ryujinx.Graphics.Gal.OpenGL PixelType, IntPtr.Zero); - if (ChangingFormat) + if (Initialized) { GL.BindBuffer(BufferTarget.PixelPackBuffer, 0); GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0); - - GL.DeleteBuffer(CopyBuffer); } this.Image = Image; @@ -108,5 +115,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL Initialized = true; } } + + public bool HasColor { get => ImageFormatConverter.HasColor(Format); } + public bool HasDepth { get => ImageFormatConverter.HasDepth(Format); } + public bool HasStencil { get => ImageFormatConverter.HasStencil(Format); } } } diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs index a3c79d4a15..f89ac0595c 100644 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs @@ -102,8 +102,10 @@ namespace Ryujinx.HLE.Gpu.Engines SetAlphaBlending(State); SetPrimitiveRestart(State); - SetFrameBuffer(Vmm, 0); - + for (int FbIndex = 0; FbIndex < 8; FbIndex++) + { + SetFrameBuffer(Vmm, FbIndex); + } SetZeta(Vmm); long[] Keys = UploadShaders(Vmm); @@ -151,6 +153,7 @@ namespace Ryujinx.HLE.Gpu.Engines int Stencil = ReadRegister(NvGpuEngine3dReg.ClearStencil); SetFrameBuffer(Vmm, FbIndex); + SetZeta(Vmm); Gpu.Renderer.Rasterizer.ClearBuffers( Flags, @@ -166,7 +169,7 @@ namespace Ryujinx.HLE.Gpu.Engines int Format = ReadRegister(NvGpuEngine3dReg.FrameBufferNFormat + FbIndex * 0x10); - if (VA == 0/* || Format == 0*/) + if (VA == 0 || Format == 0) { Gpu.Renderer.FrameBuffer.UnbindColor(FbIndex); @@ -192,7 +195,13 @@ namespace Ryujinx.HLE.Gpu.Engines int VpW = (int)(TX + MathF.Abs(SX)) - VpX; int VpH = (int)(TY + MathF.Abs(SY)) - VpY; - Gpu.Renderer.FrameBuffer.CreateColor(Key, Width, Height, (GalFrameBufferFormat)Format); + GalImageFormat ImageFormat = ImageFormatConverter.ConvertFrameBuffer((GalFrameBufferFormat)Format); + + GalImage Image = new GalImage(Width, Height, ImageFormat); + + long Size = TextureHelper.GetTextureSize(Image); + + Gpu.Renderer.Texture.CreateFb(Key, Size, Image); Gpu.Renderer.FrameBuffer.BindColor(Key, FbIndex); Gpu.Renderer.FrameBuffer.SetViewport(VpX, VpY, VpW, VpH); @@ -214,12 +223,17 @@ namespace Ryujinx.HLE.Gpu.Engines } long Key = Vmm.GetPhysicalAddress(ZA); - + int Width = ReadRegister(NvGpuEngine3dReg.ZetaHoriz); int Height = ReadRegister(NvGpuEngine3dReg.ZetaVert); - Gpu.Renderer.FrameBuffer.CreateZeta(Key, Width, Height, (GalZetaFormat)Format); + GalImageFormat ImageFormat = ImageFormatConverter.ConvertZeta((GalZetaFormat)Format); + GalImage Image = new GalImage(Width, Height, ImageFormat); + + long Size = TextureHelper.GetTextureSize(Image); + + Gpu.Renderer.Texture.CreateFb(Key, Size, Image); Gpu.Renderer.FrameBuffer.BindZeta(Key); } @@ -479,15 +493,15 @@ namespace Ryujinx.HLE.Gpu.Engines } else { - GalImage NewTexture = TextureFactory.MakeTexture(Vmm, TicPosition); + GalImage NewImage = TextureFactory.MakeTexture(Vmm, TicPosition); - long Size = (uint)TextureHelper.GetTextureSize(NewTexture); + long Size = (uint)TextureHelper.GetTextureSize(NewImage); bool HasCachedTexture = false; - if (Gpu.Renderer.Texture.TryGetCachedTexture(Key, Size, out GalImage Texture)) + if (Gpu.Renderer.Texture.TryGetCachedTexture(Key, Size, out GalImage Image)) { - if (NewTexture.Equals(Texture) && !QueryKeyUpload(Vmm, Key, Size, NvGpuBufferType.Texture)) + if (NewImage.Equals(Image) && !QueryKeyUpload(Vmm, Key, Size, NvGpuBufferType.Texture)) { Gpu.Renderer.Texture.Bind(Key, TexIndex); @@ -499,7 +513,7 @@ namespace Ryujinx.HLE.Gpu.Engines { byte[] Data = TextureFactory.GetTextureData(Vmm, TicPosition); - Gpu.Renderer.Texture.Create(Key, Data, NewTexture); + Gpu.Renderer.Texture.Create(Key, Data, NewImage); } Gpu.Renderer.Texture.Bind(Key, TexIndex); From c8417c3f2f1bb4f2aa7f0afd20ed52c81e727707 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 12 Aug 2018 19:08:45 -0300 Subject: [PATCH 06/13] Unstub formats --- Ryujinx.Graphics/Gal/GalImageFormat.cs | 1 + Ryujinx.Graphics/Gal/ImageFormatConverter.cs | 18 +++++++++++----- .../Gal/OpenGL/OGLEnumConverter.cs | 21 ++++++++++--------- Ryujinx.Graphics/Gal/OpenGL/TCE.cs | 2 +- Ryujinx.HLE/Gpu/Texture/TextureHelper.cs | 1 + 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/Ryujinx.Graphics/Gal/GalImageFormat.cs b/Ryujinx.Graphics/Gal/GalImageFormat.cs index 4de248b16b..7a4faf245f 100644 --- a/Ryujinx.Graphics/Gal/GalImageFormat.cs +++ b/Ryujinx.Graphics/Gal/GalImageFormat.cs @@ -12,6 +12,7 @@ A1B5G5R5, B5G6R5, BC7U, + G16R16, G8R8, R16, R8, diff --git a/Ryujinx.Graphics/Gal/ImageFormatConverter.cs b/Ryujinx.Graphics/Gal/ImageFormatConverter.cs index af0f2caecf..1ed638b10e 100644 --- a/Ryujinx.Graphics/Gal/ImageFormatConverter.cs +++ b/Ryujinx.Graphics/Gal/ImageFormatConverter.cs @@ -52,11 +52,19 @@ namespace Ryujinx.Graphics.Gal { switch (Format) { - case GalFrameBufferFormat.R32Float: return GalImageFormat.R32; + case GalFrameBufferFormat.R32Float: return GalImageFormat.R32; + case GalFrameBufferFormat.RGB10A2Unorm: return GalImageFormat.A2B10G10R10; + case GalFrameBufferFormat.RGBA8Srgb: return GalImageFormat.A8B8G8R8; //Stubbed + case GalFrameBufferFormat.RGBA16Float: return GalImageFormat.R16G16B16A16; + case GalFrameBufferFormat.R16Float: return GalImageFormat.R16; + case GalFrameBufferFormat.R8Unorm: return GalImageFormat.R8; + case GalFrameBufferFormat.RGBA8Unorm: return GalImageFormat.A8B8G8R8; + case GalFrameBufferFormat.R11G11B10Float: return GalImageFormat.BF10GF11RF11; + case GalFrameBufferFormat.RGBA32Float: return GalImageFormat.R32G32B32A32; + case GalFrameBufferFormat.RG16Snorm: return GalImageFormat.G16R16; } - //Stubbed. - return GalImageFormat.A8B8G8R8; + throw new NotImplementedException(Format.ToString()); } public static GalImageFormat ConvertZeta(GalZetaFormat Format) @@ -66,8 +74,7 @@ namespace Ryujinx.Graphics.Gal case GalZetaFormat.Z32Float: return GalImageFormat.ZF32; } - //Stubbed. - return GalImageFormat.Z24S8; + throw new NotImplementedException(Format.ToString()); } public static bool HasColor(GalImageFormat Format) @@ -84,6 +91,7 @@ namespace Ryujinx.Graphics.Gal case GalImageFormat.A1B5G5R5: case GalImageFormat.B5G6R5: case GalImageFormat.BC7U: + case GalImageFormat.G16R16: case GalImageFormat.G8R8: case GalImageFormat.R16: case GalImageFormat.R8: diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs index dccebb1c48..840373684e 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs @@ -129,18 +129,19 @@ namespace Ryujinx.Graphics.Gal.OpenGL { switch (Format) { - case GalImageFormat.R32G32B32A32: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.Float); - case GalImageFormat.R16G16B16A16: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.HalfFloat); + case GalImageFormat.R32G32B32A32: return (PixelInternalFormat.Rgba32f, PixelFormat.Rgba, PixelType.Float); + case GalImageFormat.R16G16B16A16: return (PixelInternalFormat.Rgba16f, PixelFormat.Rgba, PixelType.HalfFloat); case GalImageFormat.A8B8G8R8: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte); - case GalImageFormat.A2B10G10R10: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed); - case GalImageFormat.R32: return (PixelInternalFormat.Rgba8, PixelFormat.Red, PixelType.Float); - case GalImageFormat.A1B5G5R5: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedShort5551); - case GalImageFormat.B5G6R5: return (PixelInternalFormat.Rgba8, PixelFormat.Rgb, PixelType.UnsignedShort565); - case GalImageFormat.G8R8: return (PixelInternalFormat.Rgba8, PixelFormat.Rg, PixelType.UnsignedByte); - case GalImageFormat.R16: return (PixelInternalFormat.Rgba8, PixelFormat.Red, PixelType.HalfFloat); - case GalImageFormat.R8: return (PixelInternalFormat.Rgba8, PixelFormat.Red, PixelType.UnsignedByte); + case GalImageFormat.A2B10G10R10: return (PixelInternalFormat.Rgb10A2, PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed); + case GalImageFormat.R32: return (PixelInternalFormat.R32f, PixelFormat.Red, PixelType.Float); + case GalImageFormat.A1B5G5R5: return (PixelInternalFormat.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort5551); + case GalImageFormat.B5G6R5: return (PixelInternalFormat.Rgba, PixelFormat.Rgb, PixelType.UnsignedShort565); //Stubbed. + case GalImageFormat.G16R16: return (PixelInternalFormat.Rg16f, PixelFormat.Rg, PixelType.HalfFloat); + case GalImageFormat.G8R8: return (PixelInternalFormat.Rg8, PixelFormat.Rg, PixelType.UnsignedByte); + case GalImageFormat.R16: return (PixelInternalFormat.R16, PixelFormat.Red, PixelType.HalfFloat); + case GalImageFormat.R8: return (PixelInternalFormat.R8, PixelFormat.Red, PixelType.UnsignedByte); case GalImageFormat.ZF32: return (PixelInternalFormat.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float); - case GalImageFormat.BF10GF11RF11: return (PixelInternalFormat.Rgba8, PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev); + case GalImageFormat.BF10GF11RF11: return (PixelInternalFormat.R11fG11fB10f, PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev); case GalImageFormat.Z24S8: return (PixelInternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248); } diff --git a/Ryujinx.Graphics/Gal/OpenGL/TCE.cs b/Ryujinx.Graphics/Gal/OpenGL/TCE.cs index 2b60f01155..5f7cff8fc9 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/TCE.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/TCE.cs @@ -68,7 +68,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL { CopyBufferSize = CurrentSize; - GL.BufferData(BufferTarget.PixelPackBuffer, CurrentSize, IntPtr.Zero, BufferUsageHint.DynamicCopy); + GL.BufferData(BufferTarget.PixelPackBuffer, CurrentSize, IntPtr.Zero, BufferUsageHint.StreamCopy); } GL.GetTexImage(TextureTarget.Texture2D, 0, this.PixelFormat, this.PixelType, IntPtr.Zero); diff --git a/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs index 1b1b4be841..c35cdcb092 100644 --- a/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs @@ -42,6 +42,7 @@ namespace Ryujinx.HLE.Gpu.Texture case GalImageFormat.A8B8G8R8: case GalImageFormat.A2B10G10R10: + case GalImageFormat.G16R16: case GalImageFormat.R32: case GalImageFormat.ZF32: case GalImageFormat.BF10GF11RF11: From 2e589fe98c3df9ba8c9939dcae0a719706f05893 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 12 Aug 2018 19:37:08 -0300 Subject: [PATCH 07/13] Add some formats --- Ryujinx.Graphics/Gal/GalImageFormat.cs | 1 + Ryujinx.Graphics/Gal/ImageFormatConverter.cs | 5 ++++- Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs | 1 + Ryujinx.HLE/Gpu/Texture/TextureHelper.cs | 1 + 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Ryujinx.Graphics/Gal/GalImageFormat.cs b/Ryujinx.Graphics/Gal/GalImageFormat.cs index 7a4faf245f..904de16118 100644 --- a/Ryujinx.Graphics/Gal/GalImageFormat.cs +++ b/Ryujinx.Graphics/Gal/GalImageFormat.cs @@ -24,6 +24,7 @@ BC5, Z24S8, ZF32, + Z16, ConvertedBegin, Astc2D4x4, diff --git a/Ryujinx.Graphics/Gal/ImageFormatConverter.cs b/Ryujinx.Graphics/Gal/ImageFormatConverter.cs index 1ed638b10e..09166cf66a 100644 --- a/Ryujinx.Graphics/Gal/ImageFormatConverter.cs +++ b/Ryujinx.Graphics/Gal/ImageFormatConverter.cs @@ -71,7 +71,9 @@ namespace Ryujinx.Graphics.Gal { switch (Format) { - case GalZetaFormat.Z32Float: return GalImageFormat.ZF32; + case GalZetaFormat.Z32Float: return GalImageFormat.ZF32; + case GalZetaFormat.S8Z24Unorm: return GalImageFormat.Z24S8; + case GalZetaFormat.Z16Unorm: return GalImageFormat.Z16; } throw new NotImplementedException(Format.ToString()); @@ -127,6 +129,7 @@ namespace Ryujinx.Graphics.Gal { case GalImageFormat.Z24S8: case GalImageFormat.ZF32: + case GalImageFormat.Z16: return true; } diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs index 840373684e..6a60a785d3 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs @@ -141,6 +141,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL case GalImageFormat.R16: return (PixelInternalFormat.R16, PixelFormat.Red, PixelType.HalfFloat); case GalImageFormat.R8: return (PixelInternalFormat.R8, PixelFormat.Red, PixelType.UnsignedByte); case GalImageFormat.ZF32: return (PixelInternalFormat.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float); + case GalImageFormat.Z16: return (PixelInternalFormat.DepthComponent16, PixelFormat.DepthComponent, PixelType.HalfFloat); case GalImageFormat.BF10GF11RF11: return (PixelInternalFormat.R11fG11fB10f, PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev); case GalImageFormat.Z24S8: return (PixelInternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248); } diff --git a/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs index c35cdcb092..bcfe4a7e25 100644 --- a/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs @@ -53,6 +53,7 @@ namespace Ryujinx.HLE.Gpu.Texture case GalImageFormat.B5G6R5: case GalImageFormat.G8R8: case GalImageFormat.R16: + case GalImageFormat.Z16: return Image.Width * Image.Height * 2; case GalImageFormat.R8: From c308158296a12a2012021f40d1eea65b11271780 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 13 Aug 2018 19:19:27 -0300 Subject: [PATCH 08/13] Disable multiple attachments --- Ryujinx.Graphics/Gal/ImageFormatConverter.cs | 2 ++ Ryujinx.Graphics/Gal/OpenGL/OGLConstBuffer.cs | 6 ++---- Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs | 2 +- Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs | 5 ++++- Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs | 5 +---- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Ryujinx.Graphics/Gal/ImageFormatConverter.cs b/Ryujinx.Graphics/Gal/ImageFormatConverter.cs index 09166cf66a..07385545c5 100644 --- a/Ryujinx.Graphics/Gal/ImageFormatConverter.cs +++ b/Ryujinx.Graphics/Gal/ImageFormatConverter.cs @@ -62,6 +62,8 @@ namespace Ryujinx.Graphics.Gal case GalFrameBufferFormat.R11G11B10Float: return GalImageFormat.BF10GF11RF11; case GalFrameBufferFormat.RGBA32Float: return GalImageFormat.R32G32B32A32; case GalFrameBufferFormat.RG16Snorm: return GalImageFormat.G16R16; + case GalFrameBufferFormat.RG16Float: return GalImageFormat.G16R16; //Stubbed + case GalFrameBufferFormat.RG8Snorm: return GalImageFormat.R8; //Stubbed } throw new NotImplementedException(Format.ToString()); diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLConstBuffer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLConstBuffer.cs index 5082554135..4958b53b3b 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLConstBuffer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLConstBuffer.cs @@ -36,12 +36,10 @@ namespace Ryujinx.Graphics.Gal.OpenGL public void SetData(long Key, long Size, IntPtr HostAddress) { - if (!Cache.TryGetValue(Key, out OGLStreamBuffer Buffer)) + if (Cache.TryGetValue(Key, out OGLStreamBuffer Buffer)) { - throw new InvalidOperationException(); + Buffer.SetData(Size, HostAddress); } - - Buffer.SetData(Size, HostAddress); } public bool TryGetUbo(long Key, out int UboHandle) diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs index 6a60a785d3..525d3facfc 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs @@ -160,7 +160,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL case GalImageFormat.BC2: return InternalFormat.CompressedRgbaS3tcDxt3Ext; case GalImageFormat.BC3: return InternalFormat.CompressedRgbaS3tcDxt5Ext; case GalImageFormat.BC4: return InternalFormat.CompressedRedRgtc1; - case GalImageFormat.BC5: return InternalFormat.CompressedRgRgtc2; + case GalImageFormat.BC5: return InternalFormat.CompressedSignedRgRgtc2; } throw new NotImplementedException(Format.ToString()); diff --git a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs index 08d3f64cdd..981058e72b 100644 --- a/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs +++ b/Ryujinx.Graphics/Gal/Shader/GlslDecompiler.cs @@ -829,8 +829,11 @@ namespace Ryujinx.Graphics.Gal.Shader { return "gl_PointSize"; } + } - throw new InvalidOperationException(); + if (DeclInfo.Index >= 16) + { + throw new InvalidOperationException($"Shader attribute offset {Abuf.Offs} is invalid."); } if (Decl.ShaderType == GalShaderType.Geometry) diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs index f89ac0595c..28142e6418 100644 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs @@ -102,10 +102,7 @@ namespace Ryujinx.HLE.Gpu.Engines SetAlphaBlending(State); SetPrimitiveRestart(State); - for (int FbIndex = 0; FbIndex < 8; FbIndex++) - { - SetFrameBuffer(Vmm, FbIndex); - } + SetFrameBuffer(Vmm, 0); SetZeta(Vmm); long[] Keys = UploadShaders(Vmm); From 93e985e1b18d390d9c00b5e864ecebe0f56b3c13 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 15 Aug 2018 16:44:46 -0300 Subject: [PATCH 09/13] Cache framebuffer attachments --- Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs | 96 +++++++++++-------- 1 file changed, 54 insertions(+), 42 deletions(-) diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs index a73c6935b7..4c573d1016 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs @@ -61,8 +61,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL private int SrcFb; private int DstFb; + private int[] ColorAttachments; + private int DepthAttachment; + private int StencilAttachment; + public OGLFrameBuffer(OGLTexture Texture) { + ColorAttachments = new int[8]; + this.Texture = Texture; } @@ -72,11 +78,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL { EnsureFrameBuffer(); - GL.FramebufferTexture( - FramebufferTarget.DrawFramebuffer, - FramebufferAttachment.ColorAttachment0 + Attachment, - Tex.Handle, - 0); + Attach(ref ColorAttachments[Attachment], Tex.Handle, FramebufferAttachment.ColorAttachment0 + Attachment); } else { @@ -88,11 +90,21 @@ namespace Ryujinx.Graphics.Gal.OpenGL { EnsureFrameBuffer(); - GL.FramebufferTexture( - FramebufferTarget.DrawFramebuffer, - FramebufferAttachment.ColorAttachment0 + Attachment, - 0, - 0); + Attach(ref ColorAttachments[Attachment], 0, FramebufferAttachment.ColorAttachment0 + Attachment); + } + + private void Attach(ref int OldHandle, int NewHandle, FramebufferAttachment FbAttachment) + { + if (OldHandle != NewHandle) + { + GL.FramebufferTexture( + FramebufferTarget.DrawFramebuffer, + FbAttachment, + NewHandle, + 0); + + OldHandle = NewHandle; + } } public void BindZeta(long Key) @@ -103,39 +115,31 @@ namespace Ryujinx.Graphics.Gal.OpenGL if (Tex.HasDepth && Tex.HasStencil) { - GL.FramebufferTexture( - FramebufferTarget.DrawFramebuffer, - FramebufferAttachment.DepthStencilAttachment, - Tex.Handle, - 0); + if (DepthAttachment != Tex.Handle || + StencilAttachment != Tex.Handle) + { + GL.FramebufferTexture( + FramebufferTarget.DrawFramebuffer, + FramebufferAttachment.DepthStencilAttachment, + Tex.Handle, + 0); + + DepthAttachment = Tex.Handle; + + StencilAttachment = Tex.Handle; + } } else if (Tex.HasDepth) { - GL.FramebufferTexture( - FramebufferTarget.DrawFramebuffer, - FramebufferAttachment.DepthAttachment, - Tex.Handle, - 0); + Attach(ref DepthAttachment, Tex.Handle, FramebufferAttachment.DepthAttachment); - GL.FramebufferTexture( - FramebufferTarget.DrawFramebuffer, - FramebufferAttachment.StencilAttachment, - 0, - 0); + Attach(ref StencilAttachment, 0, FramebufferAttachment.StencilAttachment); } else if (Tex.HasStencil) { - GL.FramebufferTexture( - FramebufferTarget.DrawFramebuffer, - FramebufferAttachment.DepthAttachment, - Tex.Handle, - 0); + Attach(ref DepthAttachment, 0, FramebufferAttachment.DepthAttachment); - GL.FramebufferTexture( - FramebufferTarget.DrawFramebuffer, - FramebufferAttachment.StencilAttachment, - 0, - 0); + Attach(ref StencilAttachment, Tex.Handle, FramebufferAttachment.StencilAttachment); } else { @@ -152,11 +156,19 @@ namespace Ryujinx.Graphics.Gal.OpenGL { EnsureFrameBuffer(); - GL.FramebufferTexture( - FramebufferTarget.DrawFramebuffer, - FramebufferAttachment.DepthStencilAttachment, - 0, - 0); + if (DepthAttachment != 0 || + StencilAttachment != 0) + { + GL.FramebufferTexture( + FramebufferTarget.DrawFramebuffer, + FramebufferAttachment.DepthStencilAttachment, + 0, + 0); + + DepthAttachment = 0; + + StencilAttachment = 0; + } } public void BindTexture(long Key, int Index) @@ -364,8 +376,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL { throw new InvalidOperationException(); } - - EnsureFrameBuffer(); } } @@ -471,6 +481,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL DstX0, DstY0, DstX1, DstY1, Mask, Color ? BlitFramebufferFilter.Linear : BlitFramebufferFilter.Nearest); + + EnsureFrameBuffer(); } } } \ No newline at end of file From 679c2dde27d1ba198f73ae10f401e52d27f40c73 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 16 Aug 2018 02:03:45 -0300 Subject: [PATCH 10/13] Handle format types --- Ryujinx.Graphics/Gal/GalImageFormat.cs | 230 +++++++++++--- Ryujinx.Graphics/Gal/GalTextureType.cs | 13 + Ryujinx.Graphics/Gal/ImageFormatConverter.cs | 296 ++++++++++++------ .../Gal/OpenGL/OGLEnumConverter.cs | 73 +++-- Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs | 2 +- Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs | 85 ++--- Ryujinx.Graphics/Gal/OpenGL/TCE.cs | 7 + Ryujinx.HLE/Gpu/Texture/TextureFactory.cs | 7 +- Ryujinx.HLE/Gpu/Texture/TextureHelper.cs | 105 ++++--- 9 files changed, 587 insertions(+), 231 deletions(-) create mode 100644 Ryujinx.Graphics/Gal/GalTextureType.cs diff --git a/Ryujinx.Graphics/Gal/GalImageFormat.cs b/Ryujinx.Graphics/Gal/GalImageFormat.cs index 904de16118..6fcded4164 100644 --- a/Ryujinx.Graphics/Gal/GalImageFormat.cs +++ b/Ryujinx.Graphics/Gal/GalImageFormat.cs @@ -1,46 +1,198 @@ namespace Ryujinx.Graphics.Gal { + //These are Vulkan-based enumerations, do not take them as Tegra values public enum GalImageFormat { - R32G32B32A32, - R16G16B16A16, - A8B8G8R8, - A2B10G10R10, - R32, - BC6H_SF16, - BC6H_UF16, - A1B5G5R5, - B5G6R5, - BC7U, - G16R16, - G8R8, - R16, - R8, - BF10GF11RF11, - BC1, - BC2, - BC3, - BC4, - BC5, - Z24S8, - ZF32, - Z16, + Undefined = 0, - ConvertedBegin, - Astc2D4x4, - Astc2D5x5, - Astc2D6x6, - Astc2D8x8, - Astc2D10x10, - Astc2D12x12, - Astc2D5x4, - Astc2D6x5, - Astc2D8x6, - Astc2D10x8, - Astc2D12x10, - Astc2D8x5, - Astc2D10x5, - Astc2D10x6, - ConvertedEnd + R4G4_UNORM_PACK8 = 1, + R4G4B4A4_UNORM_PACK16 = 2, + B4G4R4A4_UNORM_PACK16 = 3, + R5G6B5_UNORM_PACK16 = 4, + B5G6R5_UNORM_PACK16 = 5, + R5G5B5A1_UNORM_PACK16 = 6, + B5G5R5A1_UNORM_PACK16 = 7, + A1R5G5B5_UNORM_PACK16 = 8, + R8_UNORM = 9, + R8_SNORM = 10, + R8_USCALED = 11, + R8_SSCALED = 12, + R8_UINT = 13, + R8_SINT = 14, + R8_SRGB = 15, + R8G8_UNORM = 16, + R8G8_SNORM = 17, + R8G8_USCALED = 18, + R8G8_SSCALED = 19, + R8G8_UINT = 20, + R8G8_SINT = 21, + R8G8_SRGB = 22, + R8G8B8_UNORM = 23, + R8G8B8_SNORM = 24, + R8G8B8_USCALED = 25, + R8G8B8_SSCALED = 26, + R8G8B8_UINT = 27, + R8G8B8_SINT = 28, + R8G8B8_SRGB = 29, + B8G8R8_UNORM = 30, + B8G8R8_SNORM = 31, + B8G8R8_USCALED = 32, + B8G8R8_SSCALED = 33, + B8G8R8_UINT = 34, + B8G8R8_SINT = 35, + B8G8R8_SRGB = 36, + R8G8B8A8_UNORM = 37, + R8G8B8A8_SNORM = 38, + R8G8B8A8_USCALED = 39, + R8G8B8A8_SSCALED = 40, + R8G8B8A8_UINT = 41, + R8G8B8A8_SINT = 42, + R8G8B8A8_SRGB = 43, + B8G8R8A8_UNORM = 44, + B8G8R8A8_SNORM = 45, + B8G8R8A8_USCALED = 46, + B8G8R8A8_SSCALED = 47, + B8G8R8A8_UINT = 48, + B8G8R8A8_SINT = 49, + B8G8R8A8_SRGB = 50, + A8B8G8R8_UNORM_PACK32 = 51, + A8B8G8R8_SNORM_PACK32 = 52, + A8B8G8R8_USCALED_PACK32 = 53, + A8B8G8R8_SSCALED_PACK32 = 54, + A8B8G8R8_UINT_PACK32 = 55, + A8B8G8R8_SINT_PACK32 = 56, + A8B8G8R8_SRGB_PACK32 = 57, + A2R10G10B10_UNORM_PACK32 = 58, + A2R10G10B10_SNORM_PACK32 = 59, + A2R10G10B10_USCALED_PACK32 = 60, + A2R10G10B10_SSCALED_PACK32 = 61, + A2R10G10B10_UINT_PACK32 = 62, + A2R10G10B10_SINT_PACK32 = 63, + A2B10G10R10_UNORM_PACK32 = 64, + A2B10G10R10_SNORM_PACK32 = 65, + A2B10G10R10_USCALED_PACK32 = 66, + A2B10G10R10_SSCALED_PACK32 = 67, + A2B10G10R10_UINT_PACK32 = 68, + A2B10G10R10_SINT_PACK32 = 69, + R16_UNORM = 70, + R16_SNORM = 71, + R16_USCALED = 72, + R16_SSCALED = 73, + R16_UINT = 74, + R16_SINT = 75, + R16_SFLOAT = 76, + R16G16_UNORM = 77, + R16G16_SNORM = 78, + R16G16_USCALED = 79, + R16G16_SSCALED = 80, + R16G16_UINT = 81, + R16G16_SINT = 82, + R16G16_SFLOAT = 83, + R16G16B16_UNORM = 84, + R16G16B16_SNORM = 85, + R16G16B16_USCALED = 86, + R16G16B16_SSCALED = 87, + R16G16B16_UINT = 88, + R16G16B16_SINT = 89, + R16G16B16_SFLOAT = 90, + R16G16B16A16_UNORM = 91, + R16G16B16A16_SNORM = 92, + R16G16B16A16_USCALED = 93, + R16G16B16A16_SSCALED = 94, + R16G16B16A16_UINT = 95, + R16G16B16A16_SINT = 96, + R16G16B16A16_SFLOAT = 97, + R32_UINT = 98, + R32_SINT = 99, + R32_SFLOAT = 100, + R32G32_UINT = 101, + R32G32_SINT = 102, + R32G32_SFLOAT = 103, + R32G32B32_UINT = 104, + R32G32B32_SINT = 105, + R32G32B32_SFLOAT = 106, + R32G32B32A32_UINT = 107, + R32G32B32A32_SINT = 108, + R32G32B32A32_SFLOAT = 109, + R64_UINT = 110, + R64_SINT = 111, + R64_SFLOAT = 112, + R64G64_UINT = 113, + R64G64_SINT = 114, + R64G64_SFLOAT = 115, + R64G64B64_UINT = 116, + R64G64B64_SINT = 117, + R64G64B64_SFLOAT = 118, + R64G64B64A64_UINT = 119, + R64G64B64A64_SINT = 120, + R64G64B64A64_SFLOAT = 121, + B10G11R11_UFLOAT_PACK32 = 122, + E5B9G9R9_UFLOAT_PACK32 = 123, + D16_UNORM = 124, + X8_D24_UNORM_PACK32 = 125, + D32_SFLOAT = 126, + S8_UINT = 127, + D16_UNORM_S8_UINT = 128, + D24_UNORM_S8_UINT = 129, + D32_SFLOAT_S8_UINT = 130, + BC1_RGB_UNORM_BLOCK = 131, + BC1_RGB_SRGB_BLOCK = 132, + BC1_RGBA_UNORM_BLOCK = 133, + BC1_RGBA_SRGB_BLOCK = 134, + BC2_UNORM_BLOCK = 135, + BC2_SRGB_BLOCK = 136, + BC3_UNORM_BLOCK = 137, + BC3_SRGB_BLOCK = 138, + BC4_UNORM_BLOCK = 139, + BC4_SNORM_BLOCK = 140, + BC5_UNORM_BLOCK = 141, + BC5_SNORM_BLOCK = 142, + BC6H_UFLOAT_BLOCK = 143, + BC6H_SFLOAT_BLOCK = 144, + BC7_UNORM_BLOCK = 145, + BC7_SRGB_BLOCK = 146, + ETC2_R8G8B8_UNORM_BLOCK = 147, + ETC2_R8G8B8_SRGB_BLOCK = 148, + ETC2_R8G8B8A1_UNORM_BLOCK = 149, + ETC2_R8G8B8A1_SRGB_BLOCK = 150, + ETC2_R8G8B8A8_UNORM_BLOCK = 151, + ETC2_R8G8B8A8_SRGB_BLOCK = 152, + EAC_R11_UNORM_BLOCK = 153, + EAC_R11_SNORM_BLOCK = 154, + EAC_R11G11_UNORM_BLOCK = 155, + EAC_R11G11_SNORM_BLOCK = 156, + + ASTC_BEGIN = ASTC_4x4_UNORM_BLOCK, + + ASTC_4x4_UNORM_BLOCK = 157, + ASTC_4x4_SRGB_BLOCK = 158, + ASTC_5x4_UNORM_BLOCK = 159, + ASTC_5x4_SRGB_BLOCK = 160, + ASTC_5x5_UNORM_BLOCK = 161, + ASTC_5x5_SRGB_BLOCK = 162, + ASTC_6x5_UNORM_BLOCK = 163, + ASTC_6x5_SRGB_BLOCK = 164, + ASTC_6x6_UNORM_BLOCK = 165, + ASTC_6x6_SRGB_BLOCK = 166, + ASTC_8x5_UNORM_BLOCK = 167, + ASTC_8x5_SRGB_BLOCK = 168, + ASTC_8x6_UNORM_BLOCK = 169, + ASTC_8x6_SRGB_BLOCK = 170, + ASTC_8x8_UNORM_BLOCK = 171, + ASTC_8x8_SRGB_BLOCK = 172, + ASTC_10x5_UNORM_BLOCK = 173, + ASTC_10x5_SRGB_BLOCK = 174, + ASTC_10x6_UNORM_BLOCK = 175, + ASTC_10x6_SRGB_BLOCK = 176, + ASTC_10x8_UNORM_BLOCK = 177, + ASTC_10x8_SRGB_BLOCK = 178, + ASTC_10x10_UNORM_BLOCK = 179, + ASTC_10x10_SRGB_BLOCK = 180, + ASTC_12x10_UNORM_BLOCK = 181, + ASTC_12x10_SRGB_BLOCK = 182, + ASTC_12x12_UNORM_BLOCK = 183, + ASTC_12x12_SRGB_BLOCK = 184, + + ASTC_END = ASTC_12x12_SRGB_BLOCK, } } \ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalTextureType.cs b/Ryujinx.Graphics/Gal/GalTextureType.cs new file mode 100644 index 0000000000..f7dd16d15a --- /dev/null +++ b/Ryujinx.Graphics/Gal/GalTextureType.cs @@ -0,0 +1,13 @@ +namespace Ryujinx.Graphics.Gal +{ + public enum GalTextureType + { + Snorm = 1, + Unorm = 2, + Sint = 3, + Uint = 4, + Snorm_Force_Fp16 = 5, + Unorm_Force_Fp16 = 6, + Float = 7 + } +} \ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/ImageFormatConverter.cs b/Ryujinx.Graphics/Gal/ImageFormatConverter.cs index 07385545c5..305f192f76 100644 --- a/Ryujinx.Graphics/Gal/ImageFormatConverter.cs +++ b/Ryujinx.Graphics/Gal/ImageFormatConverter.cs @@ -4,66 +4,147 @@ namespace Ryujinx.Graphics.Gal { public static class ImageFormatConverter { - public static GalImageFormat ConvertTexture(GalTextureFormat Format) + public static GalImageFormat ConvertTexture( + GalTextureFormat Format, + GalTextureType RType, + GalTextureType GType, + GalTextureType BType, + GalTextureType AType) { - switch (Format) + if (RType != GType || RType != BType || RType != AType) { - case GalTextureFormat.R32G32B32A32: return GalImageFormat.R32G32B32A32; - case GalTextureFormat.R16G16B16A16: return GalImageFormat.R16G16B16A16; - case GalTextureFormat.A8B8G8R8: return GalImageFormat.A8B8G8R8; - case GalTextureFormat.A2B10G10R10: return GalImageFormat.A2B10G10R10; - case GalTextureFormat.R32: return GalImageFormat.R32; - case GalTextureFormat.BC6H_SF16: return GalImageFormat.BC6H_SF16; - case GalTextureFormat.BC6H_UF16: return GalImageFormat.BC6H_UF16; - case GalTextureFormat.A1B5G5R5: return GalImageFormat.A1B5G5R5; - case GalTextureFormat.B5G6R5: return GalImageFormat.B5G6R5; - case GalTextureFormat.BC7U: return GalImageFormat.BC7U; - case GalTextureFormat.G8R8: return GalImageFormat.G8R8; - case GalTextureFormat.R16: return GalImageFormat.R16; - case GalTextureFormat.R8: return GalImageFormat.R8; - case GalTextureFormat.BF10GF11RF11: return GalImageFormat.BF10GF11RF11; - case GalTextureFormat.BC1: return GalImageFormat.BC1; - case GalTextureFormat.BC2: return GalImageFormat.BC2; - case GalTextureFormat.BC3: return GalImageFormat.BC3; - case GalTextureFormat.BC4: return GalImageFormat.BC4; - case GalTextureFormat.BC5: return GalImageFormat.BC5; - case GalTextureFormat.Z24S8: return GalImageFormat.Z24S8; - case GalTextureFormat.ZF32: return GalImageFormat.ZF32; - case GalTextureFormat.Astc2D4x4: return GalImageFormat.Astc2D4x4; - case GalTextureFormat.Astc2D5x5: return GalImageFormat.Astc2D5x5; - case GalTextureFormat.Astc2D6x6: return GalImageFormat.Astc2D6x6; - case GalTextureFormat.Astc2D8x8: return GalImageFormat.Astc2D8x8; - case GalTextureFormat.Astc2D10x10: return GalImageFormat.Astc2D10x10; - case GalTextureFormat.Astc2D12x12: return GalImageFormat.Astc2D12x12; - case GalTextureFormat.Astc2D5x4: return GalImageFormat.Astc2D5x4; - case GalTextureFormat.Astc2D6x5: return GalImageFormat.Astc2D6x5; - case GalTextureFormat.Astc2D8x6: return GalImageFormat.Astc2D8x6; - case GalTextureFormat.Astc2D10x8: return GalImageFormat.Astc2D10x8; - case GalTextureFormat.Astc2D12x10: return GalImageFormat.Astc2D12x10; - case GalTextureFormat.Astc2D8x5: return GalImageFormat.Astc2D8x5; - case GalTextureFormat.Astc2D10x5: return GalImageFormat.Astc2D10x5; - case GalTextureFormat.Astc2D10x6: return GalImageFormat.Astc2D10x6; + throw new NotImplementedException("Per component types are not implemented"); } - throw new NotImplementedException(Format.ToString()); + GalTextureType Type = RType; + + switch (Type) + { + case GalTextureType.Snorm: + switch (Format) + { + case GalTextureFormat.R16G16B16A16: return GalImageFormat.R16G16B16A16_SNORM; + case GalTextureFormat.A8B8G8R8: return GalImageFormat.A8B8G8R8_SNORM_PACK32; + case GalTextureFormat.A2B10G10R10: return GalImageFormat.A2B10G10R10_SNORM_PACK32; + case GalTextureFormat.G8R8: return GalImageFormat.R8G8_SNORM; + case GalTextureFormat.R16: return GalImageFormat.R16_SNORM; + case GalTextureFormat.R8: return GalImageFormat.R8_SNORM; + case GalTextureFormat.BC4: return GalImageFormat.BC4_SNORM_BLOCK; + case GalTextureFormat.BC5: return GalImageFormat.BC5_SNORM_BLOCK; + } + break; + + case GalTextureType.Unorm: + switch (Format) + { + case GalTextureFormat.R16G16B16A16: return GalImageFormat.R16G16B16A16_UNORM; + case GalTextureFormat.A8B8G8R8: return GalImageFormat.A8B8G8R8_UNORM_PACK32; + case GalTextureFormat.A2B10G10R10: return GalImageFormat.A2B10G10R10_UNORM_PACK32; + case GalTextureFormat.A1B5G5R5: return GalImageFormat.A1R5G5B5_UNORM_PACK16; + case GalTextureFormat.B5G6R5: return GalImageFormat.B5G6R5_UNORM_PACK16; + case GalTextureFormat.BC7U: return GalImageFormat.BC7_UNORM_BLOCK; + case GalTextureFormat.G8R8: return GalImageFormat.R8G8_UNORM; + case GalTextureFormat.R16: return GalImageFormat.R16_UNORM; + case GalTextureFormat.R8: return GalImageFormat.R8_UNORM; + case GalTextureFormat.BC1: return GalImageFormat.BC1_RGBA_UNORM_BLOCK; + case GalTextureFormat.BC2: return GalImageFormat.BC2_UNORM_BLOCK; + case GalTextureFormat.BC3: return GalImageFormat.BC3_UNORM_BLOCK; + case GalTextureFormat.BC4: return GalImageFormat.BC4_UNORM_BLOCK; + case GalTextureFormat.BC5: return GalImageFormat.BC5_UNORM_BLOCK; + case GalTextureFormat.Z24S8: return GalImageFormat.D24_UNORM_S8_UINT; + case GalTextureFormat.Astc2D4x4: return GalImageFormat.ASTC_4x4_UNORM_BLOCK; + case GalTextureFormat.Astc2D5x5: return GalImageFormat.ASTC_5x5_UNORM_BLOCK; + case GalTextureFormat.Astc2D6x6: return GalImageFormat.ASTC_6x6_UNORM_BLOCK; + case GalTextureFormat.Astc2D8x8: return GalImageFormat.ASTC_8x8_UNORM_BLOCK; + case GalTextureFormat.Astc2D10x10: return GalImageFormat.ASTC_10x10_UNORM_BLOCK; + case GalTextureFormat.Astc2D12x12: return GalImageFormat.ASTC_12x12_UNORM_BLOCK; + case GalTextureFormat.Astc2D5x4: return GalImageFormat.ASTC_5x4_UNORM_BLOCK; + case GalTextureFormat.Astc2D6x5: return GalImageFormat.ASTC_6x5_UNORM_BLOCK; + case GalTextureFormat.Astc2D8x6: return GalImageFormat.ASTC_8x6_UNORM_BLOCK; + case GalTextureFormat.Astc2D10x8: return GalImageFormat.ASTC_10x8_UNORM_BLOCK; + case GalTextureFormat.Astc2D12x10: return GalImageFormat.ASTC_12x10_UNORM_BLOCK; + case GalTextureFormat.Astc2D8x5: return GalImageFormat.ASTC_8x5_UNORM_BLOCK; + case GalTextureFormat.Astc2D10x5: return GalImageFormat.ASTC_10x5_UNORM_BLOCK; + case GalTextureFormat.Astc2D10x6: return GalImageFormat.ASTC_10x6_UNORM_BLOCK; + } + break; + + case GalTextureType.Sint: + switch (Format) + { + case GalTextureFormat.R32G32B32A32: return GalImageFormat.R32G32B32A32_SINT; + case GalTextureFormat.R16G16B16A16: return GalImageFormat.R16G16B16A16_SINT; + case GalTextureFormat.A8B8G8R8: return GalImageFormat.A8B8G8R8_SINT_PACK32; + case GalTextureFormat.A2B10G10R10: return GalImageFormat.A2B10G10R10_SINT_PACK32; + case GalTextureFormat.R32: return GalImageFormat.R32_SINT; + case GalTextureFormat.G8R8: return GalImageFormat.R8G8_SINT; + case GalTextureFormat.R16: return GalImageFormat.R16_SINT; + case GalTextureFormat.R8: return GalImageFormat.R8_SINT; + } + break; + + case GalTextureType.Uint: + switch (Format) + { + case GalTextureFormat.R32G32B32A32: return GalImageFormat.R32G32B32A32_UINT; + case GalTextureFormat.R16G16B16A16: return GalImageFormat.R16G16B16A16_UINT; + case GalTextureFormat.A8B8G8R8: return GalImageFormat.A8B8G8R8_UINT_PACK32; + case GalTextureFormat.A2B10G10R10: return GalImageFormat.A2B10G10R10_UINT_PACK32; + case GalTextureFormat.R32: return GalImageFormat.R32_UINT; + case GalTextureFormat.G8R8: return GalImageFormat.R8G8_UINT; + case GalTextureFormat.R16: return GalImageFormat.R16_UINT; + case GalTextureFormat.R8: return GalImageFormat.R8_UINT; + } + break; + + case GalTextureType.Snorm_Force_Fp16: + switch (Format) + { + //TODO + } + break; + + case GalTextureType.Unorm_Force_Fp16: + switch (Format) + { + //TODO + } + break; + + case GalTextureType.Float: + switch (Format) + { + case GalTextureFormat.R32G32B32A32: return GalImageFormat.R32G32B32A32_SFLOAT; + case GalTextureFormat.R16G16B16A16: return GalImageFormat.R16G16B16A16_SFLOAT; + case GalTextureFormat.R32: return GalImageFormat.R32_SFLOAT; + case GalTextureFormat.BC6H_SF16: return GalImageFormat.BC6H_SFLOAT_BLOCK; + case GalTextureFormat.BC6H_UF16: return GalImageFormat.BC6H_UFLOAT_BLOCK; + case GalTextureFormat.R16: return GalImageFormat.R16_SFLOAT; + case GalTextureFormat.BF10GF11RF11: return GalImageFormat.B10G11R11_UFLOAT_PACK32; + case GalTextureFormat.ZF32: return GalImageFormat.D32_SFLOAT; + } + break; + } + + throw new NotImplementedException(Format.ToString() + " " + Type.ToString()); } public static GalImageFormat ConvertFrameBuffer(GalFrameBufferFormat Format) { switch (Format) { - case GalFrameBufferFormat.R32Float: return GalImageFormat.R32; - case GalFrameBufferFormat.RGB10A2Unorm: return GalImageFormat.A2B10G10R10; - case GalFrameBufferFormat.RGBA8Srgb: return GalImageFormat.A8B8G8R8; //Stubbed - case GalFrameBufferFormat.RGBA16Float: return GalImageFormat.R16G16B16A16; - case GalFrameBufferFormat.R16Float: return GalImageFormat.R16; - case GalFrameBufferFormat.R8Unorm: return GalImageFormat.R8; - case GalFrameBufferFormat.RGBA8Unorm: return GalImageFormat.A8B8G8R8; - case GalFrameBufferFormat.R11G11B10Float: return GalImageFormat.BF10GF11RF11; - case GalFrameBufferFormat.RGBA32Float: return GalImageFormat.R32G32B32A32; - case GalFrameBufferFormat.RG16Snorm: return GalImageFormat.G16R16; - case GalFrameBufferFormat.RG16Float: return GalImageFormat.G16R16; //Stubbed - case GalFrameBufferFormat.RG8Snorm: return GalImageFormat.R8; //Stubbed + case GalFrameBufferFormat.R32Float: return GalImageFormat.R32_SFLOAT; + case GalFrameBufferFormat.RGB10A2Unorm: return GalImageFormat.A2B10G10R10_UNORM_PACK32; + case GalFrameBufferFormat.RGBA8Srgb: return GalImageFormat.A8B8G8R8_SRGB_PACK32; + case GalFrameBufferFormat.RGBA16Float: return GalImageFormat.R16G16B16A16_SFLOAT; + case GalFrameBufferFormat.R16Float: return GalImageFormat.R16_SFLOAT; + case GalFrameBufferFormat.R8Unorm: return GalImageFormat.R8_UNORM; + case GalFrameBufferFormat.RGBA8Unorm: return GalImageFormat.A8B8G8R8_UNORM_PACK32; + case GalFrameBufferFormat.R11G11B10Float: return GalImageFormat.B10G11R11_UFLOAT_PACK32; + case GalFrameBufferFormat.RGBA32Float: return GalImageFormat.R32G32B32A32_SFLOAT; + case GalFrameBufferFormat.RG16Snorm: return GalImageFormat.R16G16_SNORM; + case GalFrameBufferFormat.RG16Float: return GalImageFormat.R16G16_SFLOAT; + case GalFrameBufferFormat.RG8Snorm: return GalImageFormat.R8_SNORM; } throw new NotImplementedException(Format.ToString()); @@ -73,9 +154,9 @@ namespace Ryujinx.Graphics.Gal { switch (Format) { - case GalZetaFormat.Z32Float: return GalImageFormat.ZF32; - case GalZetaFormat.S8Z24Unorm: return GalImageFormat.Z24S8; - case GalZetaFormat.Z16Unorm: return GalImageFormat.Z16; + case GalZetaFormat.Z32Float: return GalImageFormat.D32_SFLOAT; + case GalZetaFormat.S8Z24Unorm: return GalImageFormat.D24_UNORM_S8_UINT; + case GalZetaFormat.Z16Unorm: return GalImageFormat.D16_UNORM; } throw new NotImplementedException(Format.ToString()); @@ -85,56 +166,87 @@ namespace Ryujinx.Graphics.Gal { switch (Format) { - case GalImageFormat.R32G32B32A32: - case GalImageFormat.R16G16B16A16: - case GalImageFormat.A8B8G8R8: - case GalImageFormat.A2B10G10R10: - case GalImageFormat.R32: - case GalImageFormat.BC6H_SF16: - case GalImageFormat.BC6H_UF16: - case GalImageFormat.A1B5G5R5: - case GalImageFormat.B5G6R5: - case GalImageFormat.BC7U: - case GalImageFormat.G16R16: - case GalImageFormat.G8R8: - case GalImageFormat.R16: - case GalImageFormat.R8: - case GalImageFormat.BF10GF11RF11: - case GalImageFormat.BC1: - case GalImageFormat.BC2: - case GalImageFormat.BC3: - case GalImageFormat.BC4: - case GalImageFormat.BC5: - case GalImageFormat.Astc2D4x4: - case GalImageFormat.Astc2D5x5: - case GalImageFormat.Astc2D6x6: - case GalImageFormat.Astc2D8x8: - case GalImageFormat.Astc2D10x10: - case GalImageFormat.Astc2D12x12: - case GalImageFormat.Astc2D5x4: - case GalImageFormat.Astc2D6x5: - case GalImageFormat.Astc2D8x6: - case GalImageFormat.Astc2D10x8: - case GalImageFormat.Astc2D12x10: - case GalImageFormat.Astc2D8x5: - case GalImageFormat.Astc2D10x5: - case GalImageFormat.Astc2D10x6: + case GalImageFormat.R32G32B32A32_SFLOAT: + case GalImageFormat.R32G32B32A32_SINT: + case GalImageFormat.R32G32B32A32_UINT: + case GalImageFormat.R16G16B16A16_SFLOAT: + case GalImageFormat.R16G16B16A16_SINT: + case GalImageFormat.R16G16B16A16_UINT: + case GalImageFormat.A8B8G8R8_SNORM_PACK32: + case GalImageFormat.A8B8G8R8_UNORM_PACK32: + case GalImageFormat.A8B8G8R8_SINT_PACK32: + case GalImageFormat.A8B8G8R8_UINT_PACK32: + case GalImageFormat.A2B10G10R10_SINT_PACK32: + case GalImageFormat.A2B10G10R10_SNORM_PACK32: + case GalImageFormat.A2B10G10R10_UINT_PACK32: + case GalImageFormat.A2B10G10R10_UNORM_PACK32: + case GalImageFormat.R32_SFLOAT: + case GalImageFormat.R32_SINT: + case GalImageFormat.R32_UINT: + case GalImageFormat.BC6H_SFLOAT_BLOCK: + case GalImageFormat.BC6H_UFLOAT_BLOCK: + case GalImageFormat.A1R5G5B5_UNORM_PACK16: + case GalImageFormat.B5G6R5_UNORM_PACK16: + case GalImageFormat.BC7_UNORM_BLOCK: + case GalImageFormat.R16G16_SFLOAT: + case GalImageFormat.R16G16_SINT: + case GalImageFormat.R16G16_SNORM: + case GalImageFormat.R16G16_UNORM: + case GalImageFormat.R8G8_SINT: + case GalImageFormat.R8G8_SNORM: + case GalImageFormat.R8G8_UINT: + case GalImageFormat.R8G8_UNORM: + case GalImageFormat.R16_SFLOAT: + case GalImageFormat.R16_SINT: + case GalImageFormat.R16_SNORM: + case GalImageFormat.R16_UINT: + case GalImageFormat.R16_UNORM: + case GalImageFormat.R8_SINT: + case GalImageFormat.R8_SNORM: + case GalImageFormat.R8_UINT: + case GalImageFormat.R8_UNORM: + case GalImageFormat.B10G11R11_UFLOAT_PACK32: + case GalImageFormat.BC1_RGBA_UNORM_BLOCK: + case GalImageFormat.BC2_UNORM_BLOCK: + case GalImageFormat.BC3_UNORM_BLOCK: + case GalImageFormat.BC4_UNORM_BLOCK: + case GalImageFormat.BC5_UNORM_BLOCK: + case GalImageFormat.ASTC_4x4_UNORM_BLOCK: + case GalImageFormat.ASTC_5x5_UNORM_BLOCK: + case GalImageFormat.ASTC_6x6_UNORM_BLOCK: + case GalImageFormat.ASTC_8x8_UNORM_BLOCK: + case GalImageFormat.ASTC_10x10_UNORM_BLOCK: + case GalImageFormat.ASTC_12x12_UNORM_BLOCK: + case GalImageFormat.ASTC_5x4_UNORM_BLOCK: + case GalImageFormat.ASTC_6x5_UNORM_BLOCK: + case GalImageFormat.ASTC_8x6_UNORM_BLOCK: + case GalImageFormat.ASTC_10x8_UNORM_BLOCK: + case GalImageFormat.ASTC_12x10_UNORM_BLOCK: + case GalImageFormat.ASTC_8x5_UNORM_BLOCK: + case GalImageFormat.ASTC_10x5_UNORM_BLOCK: + case GalImageFormat.ASTC_10x6_UNORM_BLOCK: + return true; + + case GalImageFormat.D24_UNORM_S8_UINT: + case GalImageFormat.D32_SFLOAT: + case GalImageFormat.D16_UNORM: return true; } - return false; + throw new NotImplementedException(Format.ToString()); } public static bool HasDepth(GalImageFormat Format) { switch (Format) { - case GalImageFormat.Z24S8: - case GalImageFormat.ZF32: - case GalImageFormat.Z16: + case GalImageFormat.D24_UNORM_S8_UINT: + case GalImageFormat.D32_SFLOAT: + case GalImageFormat.D16_UNORM: return true; } + //Depth formats are easier to maintain so not false case, just return false return false; } @@ -142,7 +254,7 @@ namespace Ryujinx.Graphics.Gal { switch (Format) { - case GalImageFormat.Z24S8: + case GalImageFormat.D24_UNORM_S8_UINT: return true; } diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs index 525d3facfc..49fca698f6 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs @@ -129,21 +129,46 @@ namespace Ryujinx.Graphics.Gal.OpenGL { switch (Format) { - case GalImageFormat.R32G32B32A32: return (PixelInternalFormat.Rgba32f, PixelFormat.Rgba, PixelType.Float); - case GalImageFormat.R16G16B16A16: return (PixelInternalFormat.Rgba16f, PixelFormat.Rgba, PixelType.HalfFloat); - case GalImageFormat.A8B8G8R8: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte); - case GalImageFormat.A2B10G10R10: return (PixelInternalFormat.Rgb10A2, PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed); - case GalImageFormat.R32: return (PixelInternalFormat.R32f, PixelFormat.Red, PixelType.Float); - case GalImageFormat.A1B5G5R5: return (PixelInternalFormat.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort5551); - case GalImageFormat.B5G6R5: return (PixelInternalFormat.Rgba, PixelFormat.Rgb, PixelType.UnsignedShort565); //Stubbed. - case GalImageFormat.G16R16: return (PixelInternalFormat.Rg16f, PixelFormat.Rg, PixelType.HalfFloat); - case GalImageFormat.G8R8: return (PixelInternalFormat.Rg8, PixelFormat.Rg, PixelType.UnsignedByte); - case GalImageFormat.R16: return (PixelInternalFormat.R16, PixelFormat.Red, PixelType.HalfFloat); - case GalImageFormat.R8: return (PixelInternalFormat.R8, PixelFormat.Red, PixelType.UnsignedByte); - case GalImageFormat.ZF32: return (PixelInternalFormat.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float); - case GalImageFormat.Z16: return (PixelInternalFormat.DepthComponent16, PixelFormat.DepthComponent, PixelType.HalfFloat); - case GalImageFormat.BF10GF11RF11: return (PixelInternalFormat.R11fG11fB10f, PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev); - case GalImageFormat.Z24S8: return (PixelInternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248); + case GalImageFormat.R32G32B32A32_SFLOAT: return (PixelInternalFormat.Rgba32f, PixelFormat.Rgba, PixelType.Float); + case GalImageFormat.R32G32B32A32_SINT: return (PixelInternalFormat.Rgba32i, PixelFormat.RgbaInteger, PixelType.Int); + case GalImageFormat.R32G32B32A32_UINT: return (PixelInternalFormat.Rgba32ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt); + case GalImageFormat.R16G16B16A16_SFLOAT: return (PixelInternalFormat.Rgba16f, PixelFormat.Rgba, PixelType.Float); + case GalImageFormat.R16G16B16A16_SINT: return (PixelInternalFormat.Rgba16i, PixelFormat.RgbaInteger, PixelType.Short); + case GalImageFormat.R16G16B16A16_UINT: return (PixelInternalFormat.Rgba16ui, PixelFormat.RgbaInteger, PixelType.UnsignedShort); + case GalImageFormat.A8B8G8R8_SNORM_PACK32: return (PixelInternalFormat.Rgba8Snorm, PixelFormat.Rgba, PixelType.Byte); + case GalImageFormat.A8B8G8R8_UNORM_PACK32: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte); + case GalImageFormat.A8B8G8R8_SINT_PACK32: return (PixelInternalFormat.Rgba8i, PixelFormat.RgbaInteger, PixelType.Byte); + case GalImageFormat.A8B8G8R8_UINT_PACK32: return (PixelInternalFormat.Rgba8ui, PixelFormat.RgbaInteger, PixelType.UnsignedByte); + case GalImageFormat.A8B8G8R8_SRGB_PACK32: return (PixelInternalFormat.Srgb8Alpha8, PixelFormat.Rgba, PixelType.UnsignedByte); + case GalImageFormat.A2B10G10R10_UINT_PACK32: return (PixelInternalFormat.Rgb10A2ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt2101010Reversed); + case GalImageFormat.A2B10G10R10_UNORM_PACK32: return (PixelInternalFormat.Rgb10A2, PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed); + case GalImageFormat.R32_SFLOAT: return (PixelInternalFormat.R32f, PixelFormat.Red, PixelType.Float); + case GalImageFormat.R32_SINT: return (PixelInternalFormat.R32i, PixelFormat.Red, PixelType.Int); + case GalImageFormat.R32_UINT: return (PixelInternalFormat.R32ui, PixelFormat.Red, PixelType.UnsignedInt); + case GalImageFormat.A1R5G5B5_UNORM_PACK16: return (PixelInternalFormat.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort5551); + case GalImageFormat.B5G6R5_UNORM_PACK16: return (PixelInternalFormat.Rgba, PixelFormat.Rgb, PixelType.UnsignedShort565); + case GalImageFormat.R16G16_SFLOAT: return (PixelInternalFormat.Rg16f, PixelFormat.Rg, PixelType.Float); + case GalImageFormat.R16G16_SINT: return (PixelInternalFormat.Rg16i, PixelFormat.RgInteger, PixelType.Short); + case GalImageFormat.R16G16_SNORM: return (PixelInternalFormat.Rg16Snorm, PixelFormat.Rg, PixelType.Byte); + case GalImageFormat.R16G16_UNORM: return (PixelInternalFormat.Rg16, PixelFormat.Rg, PixelType.UnsignedShort); + case GalImageFormat.R8G8_SINT: return (PixelInternalFormat.Rg8i, PixelFormat.RgInteger, PixelType.Byte); + case GalImageFormat.R8G8_SNORM: return (PixelInternalFormat.Rg8Snorm, PixelFormat.Rg, PixelType.Byte); + case GalImageFormat.R8G8_UINT: return (PixelInternalFormat.Rg8ui, PixelFormat.RgInteger, PixelType.UnsignedByte); + case GalImageFormat.R8G8_UNORM: return (PixelInternalFormat.Rg8, PixelFormat.Rg, PixelType.UnsignedByte); + case GalImageFormat.R16_SFLOAT: return (PixelInternalFormat.R16f, PixelFormat.Red, PixelType.Float); + case GalImageFormat.R16_SINT: return (PixelInternalFormat.R16i, PixelFormat.RedInteger, PixelType.Short); + case GalImageFormat.R16_SNORM: return (PixelInternalFormat.R16Snorm, PixelFormat.Red, PixelType.Byte); + case GalImageFormat.R16_UINT: return (PixelInternalFormat.R16ui, PixelFormat.RedInteger, PixelType.UnsignedShort); + case GalImageFormat.R16_UNORM: return (PixelInternalFormat.R16, PixelFormat.Red, PixelType.UnsignedShort); + case GalImageFormat.R8_SINT: return (PixelInternalFormat.R8i, PixelFormat.RedInteger, PixelType.Byte); + case GalImageFormat.R8_SNORM: return (PixelInternalFormat.R8Snorm, PixelFormat.Red, PixelType.Byte); + case GalImageFormat.R8_UINT: return (PixelInternalFormat.R8ui, PixelFormat.RedInteger, PixelType.UnsignedByte); + case GalImageFormat.R8_UNORM: return (PixelInternalFormat.R8, PixelFormat.Red, PixelType.UnsignedByte); + case GalImageFormat.B10G11R11_UFLOAT_PACK32: return (PixelInternalFormat.R11fG11fB10f, PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev); + + case GalImageFormat.D24_UNORM_S8_UINT: return (PixelInternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248); + case GalImageFormat.D32_SFLOAT: return (PixelInternalFormat.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float); + case GalImageFormat.D16_UNORM: return (PixelInternalFormat.DepthComponent16, PixelFormat.DepthComponent, PixelType.UnsignedShort); } throw new NotImplementedException(Format.ToString()); @@ -153,14 +178,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL { switch (Format) { - case GalImageFormat.BC6H_UF16: return InternalFormat.CompressedRgbBptcUnsignedFloat; - case GalImageFormat.BC6H_SF16: return InternalFormat.CompressedRgbBptcSignedFloat; - case GalImageFormat.BC7U: return InternalFormat.CompressedRgbaBptcUnorm; - case GalImageFormat.BC1: return InternalFormat.CompressedRgbaS3tcDxt1Ext; - case GalImageFormat.BC2: return InternalFormat.CompressedRgbaS3tcDxt3Ext; - case GalImageFormat.BC3: return InternalFormat.CompressedRgbaS3tcDxt5Ext; - case GalImageFormat.BC4: return InternalFormat.CompressedRedRgtc1; - case GalImageFormat.BC5: return InternalFormat.CompressedSignedRgRgtc2; + case GalImageFormat.BC6H_UFLOAT_BLOCK: return InternalFormat.CompressedRgbBptcUnsignedFloat; + case GalImageFormat.BC6H_SFLOAT_BLOCK: return InternalFormat.CompressedRgbBptcSignedFloat; + case GalImageFormat.BC7_UNORM_BLOCK: return InternalFormat.CompressedRgbaBptcUnorm; + case GalImageFormat.BC1_RGBA_UNORM_BLOCK: return InternalFormat.CompressedRgbaS3tcDxt1Ext; + case GalImageFormat.BC2_UNORM_BLOCK: return InternalFormat.CompressedRgbaS3tcDxt3Ext; + case GalImageFormat.BC3_UNORM_BLOCK: return InternalFormat.CompressedRgbaS3tcDxt5Ext; + case GalImageFormat.BC4_SNORM_BLOCK: return InternalFormat.CompressedSignedRedRgtc1; + case GalImageFormat.BC4_UNORM_BLOCK: return InternalFormat.CompressedRedRgtc1; + case GalImageFormat.BC5_SNORM_BLOCK: return InternalFormat.CompressedSignedRgRgtc2; + case GalImageFormat.BC5_UNORM_BLOCK: return InternalFormat.CompressedRgRgtc2; } throw new NotImplementedException(Format.ToString()); diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs index 4c573d1016..7f8cb63ffc 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs @@ -38,7 +38,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL private const int NativeWidth = 1280; private const int NativeHeight = 720; - private const GalImageFormat RawFormat = GalImageFormat.A8B8G8R8; + private const GalImageFormat RawFormat = GalImageFormat.A8B8G8R8_UNORM_PACK32; private OGLTexture Texture; diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs index 24dd83b006..fe865cf422 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs @@ -55,7 +55,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL } else { - if (Image.Format > GalImageFormat.ConvertedBegin && Image.Format < GalImageFormat.ConvertedEnd) + if (Image.Format >= GalImageFormat.ASTC_BEGIN && Image.Format <= GalImageFormat.ASTC_END) { int TextureBlockWidth = GetAstcBlockWidth(Image.Format); int TextureBlockHeight = GetAstcBlockHeight(Image.Format); @@ -67,11 +67,13 @@ namespace Ryujinx.Graphics.Gal.OpenGL Image.Width, Image.Height, 1); - Image.Format = GalImageFormat.A8B8G8R8; + Image.Format = GalImageFormat.A8B8G8R8_UNORM_PACK32; } (PixelInternalFormat InternalFormat, PixelFormat Format, PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format); + GL.GetError(); + GL.TexImage2D( TextureTarget.Texture2D, Level, @@ -82,6 +84,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL Format, Type, Data); + + if (GL.GetError() != ErrorCode.NoError) + { + throw new InvalidOperationException($"{InternalFormat} {Format} {Type}"); + } } int SwizzleR = (int)OGLEnumConverter.GetTextureSwizzle(Image.XSource); @@ -123,20 +130,20 @@ namespace Ryujinx.Graphics.Gal.OpenGL { switch (Format) { - case GalImageFormat.Astc2D4x4: return 4; - case GalImageFormat.Astc2D5x5: return 5; - case GalImageFormat.Astc2D6x6: return 6; - case GalImageFormat.Astc2D8x8: return 8; - case GalImageFormat.Astc2D10x10: return 10; - case GalImageFormat.Astc2D12x12: return 12; - case GalImageFormat.Astc2D5x4: return 5; - case GalImageFormat.Astc2D6x5: return 6; - case GalImageFormat.Astc2D8x6: return 8; - case GalImageFormat.Astc2D10x8: return 10; - case GalImageFormat.Astc2D12x10: return 12; - case GalImageFormat.Astc2D8x5: return 8; - case GalImageFormat.Astc2D10x5: return 10; - case GalImageFormat.Astc2D10x6: return 10; + case GalImageFormat.ASTC_4x4_UNORM_BLOCK: return 4; + case GalImageFormat.ASTC_5x5_UNORM_BLOCK: return 5; + case GalImageFormat.ASTC_6x6_UNORM_BLOCK: return 6; + case GalImageFormat.ASTC_8x8_UNORM_BLOCK: return 8; + case GalImageFormat.ASTC_10x10_UNORM_BLOCK: return 10; + case GalImageFormat.ASTC_12x12_UNORM_BLOCK: return 12; + case GalImageFormat.ASTC_5x4_UNORM_BLOCK: return 5; + case GalImageFormat.ASTC_6x5_UNORM_BLOCK: return 6; + case GalImageFormat.ASTC_8x6_UNORM_BLOCK: return 8; + case GalImageFormat.ASTC_10x8_UNORM_BLOCK: return 10; + case GalImageFormat.ASTC_12x10_UNORM_BLOCK: return 12; + case GalImageFormat.ASTC_8x5_UNORM_BLOCK: return 8; + case GalImageFormat.ASTC_10x5_UNORM_BLOCK: return 10; + case GalImageFormat.ASTC_10x6_UNORM_BLOCK: return 10; } throw new ArgumentException(nameof(Format)); @@ -146,20 +153,20 @@ namespace Ryujinx.Graphics.Gal.OpenGL { switch (Format) { - case GalImageFormat.Astc2D4x4: return 4; - case GalImageFormat.Astc2D5x5: return 5; - case GalImageFormat.Astc2D6x6: return 6; - case GalImageFormat.Astc2D8x8: return 8; - case GalImageFormat.Astc2D10x10: return 10; - case GalImageFormat.Astc2D12x12: return 12; - case GalImageFormat.Astc2D5x4: return 4; - case GalImageFormat.Astc2D6x5: return 5; - case GalImageFormat.Astc2D8x6: return 6; - case GalImageFormat.Astc2D10x8: return 8; - case GalImageFormat.Astc2D12x10: return 10; - case GalImageFormat.Astc2D8x5: return 5; - case GalImageFormat.Astc2D10x5: return 5; - case GalImageFormat.Astc2D10x6: return 6; + case GalImageFormat.ASTC_4x4_UNORM_BLOCK: return 4; + case GalImageFormat.ASTC_5x5_UNORM_BLOCK: return 5; + case GalImageFormat.ASTC_6x6_UNORM_BLOCK: return 6; + case GalImageFormat.ASTC_8x8_UNORM_BLOCK: return 8; + case GalImageFormat.ASTC_10x10_UNORM_BLOCK: return 10; + case GalImageFormat.ASTC_12x12_UNORM_BLOCK: return 12; + case GalImageFormat.ASTC_5x4_UNORM_BLOCK: return 4; + case GalImageFormat.ASTC_6x5_UNORM_BLOCK: return 5; + case GalImageFormat.ASTC_8x6_UNORM_BLOCK: return 6; + case GalImageFormat.ASTC_10x8_UNORM_BLOCK: return 8; + case GalImageFormat.ASTC_12x10_UNORM_BLOCK: return 10; + case GalImageFormat.ASTC_8x5_UNORM_BLOCK: return 5; + case GalImageFormat.ASTC_10x5_UNORM_BLOCK: return 5; + case GalImageFormat.ASTC_10x6_UNORM_BLOCK: return 6; } throw new ArgumentException(nameof(Format)); @@ -221,14 +228,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL { switch (Format) { - case GalImageFormat.BC6H_UF16: - case GalImageFormat.BC6H_SF16: - case GalImageFormat.BC7U: - case GalImageFormat.BC1: - case GalImageFormat.BC2: - case GalImageFormat.BC3: - case GalImageFormat.BC4: - case GalImageFormat.BC5: + case GalImageFormat.BC6H_UFLOAT_BLOCK: + case GalImageFormat.BC6H_SFLOAT_BLOCK: + case GalImageFormat.BC7_UNORM_BLOCK: + case GalImageFormat.BC1_RGBA_UNORM_BLOCK: + case GalImageFormat.BC2_UNORM_BLOCK: + case GalImageFormat.BC3_UNORM_BLOCK: + case GalImageFormat.BC4_SNORM_BLOCK: + case GalImageFormat.BC4_UNORM_BLOCK: + case GalImageFormat.BC5_SNORM_BLOCK: + case GalImageFormat.BC5_UNORM_BLOCK: return true; } diff --git a/Ryujinx.Graphics/Gal/OpenGL/TCE.cs b/Ryujinx.Graphics/Gal/OpenGL/TCE.cs index 5f7cff8fc9..ea130e086b 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/TCE.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/TCE.cs @@ -89,6 +89,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL const int Level = 0; const int Border = 0; + GL.GetError(); + GL.TexImage2D( TextureTarget.Texture2D, Level, @@ -100,6 +102,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL PixelType, IntPtr.Zero); + if (GL.GetError() != ErrorCode.NoError) + { + throw new InvalidOperationException($"{InternalFormat} {PixelFormat} {PixelType}"); + } + if (Initialized) { GL.BindBuffer(BufferTarget.PixelPackBuffer, 0); diff --git a/Ryujinx.HLE/Gpu/Texture/TextureFactory.cs b/Ryujinx.HLE/Gpu/Texture/TextureFactory.cs index a9fa6dbd1e..0ef33d3b72 100644 --- a/Ryujinx.HLE/Gpu/Texture/TextureFactory.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureFactory.cs @@ -10,7 +10,12 @@ namespace Ryujinx.HLE.Gpu.Texture { int[] Tic = ReadWords(Vmm, TicPosition, 8); - GalImageFormat Format = ImageFormatConverter.ConvertTexture((GalTextureFormat)(Tic[0] & 0x7f)); + GalTextureType RType = (GalTextureType)((Tic[0] >> 7) & 7); + GalTextureType GType = (GalTextureType)((Tic[0] >> 10) & 7); + GalTextureType BType = (GalTextureType)((Tic[0] >> 13) & 7); + GalTextureType AType = (GalTextureType)((Tic[0] >> 16) & 7); + + GalImageFormat Format = ImageFormatConverter.ConvertTexture((GalTextureFormat)(Tic[0] & 0x7f), RType, GType, BType, AType); GalTextureSource XSource = (GalTextureSource)((Tic[0] >> 19) & 7); GalTextureSource YSource = (GalTextureSource)((Tic[0] >> 22) & 7); diff --git a/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs index bcfe4a7e25..c3501cc2eb 100644 --- a/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs @@ -34,109 +34,140 @@ namespace Ryujinx.HLE.Gpu.Texture { switch (Image.Format) { - case GalImageFormat.R32G32B32A32: + case GalImageFormat.R32G32B32A32_SFLOAT: + case GalImageFormat.R32G32B32A32_SINT: + case GalImageFormat.R32G32B32A32_UINT: return Image.Width * Image.Height * 16; - case GalImageFormat.R16G16B16A16: + case GalImageFormat.R16G16B16A16_SFLOAT: + case GalImageFormat.R16G16B16A16_SINT: + case GalImageFormat.R16G16B16A16_SNORM: + case GalImageFormat.R16G16B16A16_UINT: + case GalImageFormat.R16G16B16A16_UNORM: return Image.Width * Image.Height * 8; - case GalImageFormat.A8B8G8R8: - case GalImageFormat.A2B10G10R10: - case GalImageFormat.G16R16: - case GalImageFormat.R32: - case GalImageFormat.ZF32: - case GalImageFormat.BF10GF11RF11: - case GalImageFormat.Z24S8: + case GalImageFormat.A8B8G8R8_SINT_PACK32: + case GalImageFormat.A8B8G8R8_SNORM_PACK32: + case GalImageFormat.A8B8G8R8_UINT_PACK32: + case GalImageFormat.A8B8G8R8_UNORM_PACK32: + case GalImageFormat.A8B8G8R8_SRGB_PACK32: + case GalImageFormat.A2B10G10R10_SINT_PACK32: + case GalImageFormat.A2B10G10R10_SNORM_PACK32: + case GalImageFormat.A2B10G10R10_UINT_PACK32: + case GalImageFormat.A2B10G10R10_UNORM_PACK32: + case GalImageFormat.R16G16_SFLOAT: + case GalImageFormat.R16G16_SINT: + case GalImageFormat.R16G16_SNORM: + case GalImageFormat.R16G16_UINT: + case GalImageFormat.R16G16_UNORM: + case GalImageFormat.R32_SFLOAT: + case GalImageFormat.R32_SINT: + case GalImageFormat.R32_UINT: + case GalImageFormat.D32_SFLOAT: + case GalImageFormat.B10G11R11_UFLOAT_PACK32: + case GalImageFormat.D24_UNORM_S8_UINT: return Image.Width * Image.Height * 4; - case GalImageFormat.A1B5G5R5: - case GalImageFormat.B5G6R5: - case GalImageFormat.G8R8: - case GalImageFormat.R16: - case GalImageFormat.Z16: + case GalImageFormat.A1R5G5B5_UNORM_PACK16: + case GalImageFormat.B5G6R5_UNORM_PACK16: + case GalImageFormat.R8G8_SINT: + case GalImageFormat.R8G8_SNORM: + case GalImageFormat.R8G8_UINT: + case GalImageFormat.R8G8_UNORM: + case GalImageFormat.R16_SFLOAT: + case GalImageFormat.R16_SINT: + case GalImageFormat.R16_SNORM: + case GalImageFormat.R16_UINT: + case GalImageFormat.R16_UNORM: + case GalImageFormat.D16_UNORM: return Image.Width * Image.Height * 2; - case GalImageFormat.R8: + case GalImageFormat.R8_SINT: + case GalImageFormat.R8_SNORM: + case GalImageFormat.R8_UINT: + case GalImageFormat.R8_UNORM: return Image.Width * Image.Height; - case GalImageFormat.BC1: - case GalImageFormat.BC4: + case GalImageFormat.BC1_RGBA_UNORM_BLOCK: + case GalImageFormat.BC4_SNORM_BLOCK: + case GalImageFormat.BC4_UNORM_BLOCK: { return CompressedTextureSize(Image.Width, Image.Height, 4, 4, 8); } - case GalImageFormat.BC6H_SF16: - case GalImageFormat.BC6H_UF16: - case GalImageFormat.BC7U: - case GalImageFormat.BC2: - case GalImageFormat.BC3: - case GalImageFormat.BC5: - case GalImageFormat.Astc2D4x4: + case GalImageFormat.BC6H_SFLOAT_BLOCK: + case GalImageFormat.BC6H_UFLOAT_BLOCK: + case GalImageFormat.BC7_UNORM_BLOCK: + case GalImageFormat.BC2_UNORM_BLOCK: + case GalImageFormat.BC3_UNORM_BLOCK: + case GalImageFormat.BC5_SNORM_BLOCK: + case GalImageFormat.BC5_UNORM_BLOCK: + case GalImageFormat.ASTC_4x4_UNORM_BLOCK: { return CompressedTextureSize(Image.Width, Image.Height, 4, 4, 16); } - case GalImageFormat.Astc2D5x5: + case GalImageFormat.ASTC_5x5_UNORM_BLOCK: { return CompressedTextureSize(Image.Width, Image.Height, 5, 5, 16); } - case GalImageFormat.Astc2D6x6: + case GalImageFormat.ASTC_6x6_UNORM_BLOCK: { return CompressedTextureSize(Image.Width, Image.Height, 6, 6, 16); } - case GalImageFormat.Astc2D8x8: + case GalImageFormat.ASTC_8x8_UNORM_BLOCK: { return CompressedTextureSize(Image.Width, Image.Height, 8, 8, 16); } - case GalImageFormat.Astc2D10x10: + case GalImageFormat.ASTC_10x10_UNORM_BLOCK: { return CompressedTextureSize(Image.Width, Image.Height, 10, 10, 16); } - case GalImageFormat.Astc2D12x12: + case GalImageFormat.ASTC_12x12_UNORM_BLOCK: { return CompressedTextureSize(Image.Width, Image.Height, 12, 12, 16); } - case GalImageFormat.Astc2D5x4: + case GalImageFormat.ASTC_5x4_UNORM_BLOCK: { return CompressedTextureSize(Image.Width, Image.Height, 5, 4, 16); } - case GalImageFormat.Astc2D6x5: + case GalImageFormat.ASTC_6x5_UNORM_BLOCK: { return CompressedTextureSize(Image.Width, Image.Height, 6, 5, 16); } - case GalImageFormat.Astc2D8x6: + case GalImageFormat.ASTC_8x6_UNORM_BLOCK: { return CompressedTextureSize(Image.Width, Image.Height, 8, 6, 16); } - case GalImageFormat.Astc2D10x8: + case GalImageFormat.ASTC_10x8_UNORM_BLOCK: { return CompressedTextureSize(Image.Width, Image.Height, 10, 8, 16); } - case GalImageFormat.Astc2D12x10: + case GalImageFormat.ASTC_12x10_UNORM_BLOCK: { return CompressedTextureSize(Image.Width, Image.Height, 12, 10, 16); } - case GalImageFormat.Astc2D8x5: + case GalImageFormat.ASTC_8x5_UNORM_BLOCK: { return CompressedTextureSize(Image.Width, Image.Height, 8, 5, 16); } - case GalImageFormat.Astc2D10x5: + case GalImageFormat.ASTC_10x5_UNORM_BLOCK: { return CompressedTextureSize(Image.Width, Image.Height, 10, 5, 16); } - case GalImageFormat.Astc2D10x6: + case GalImageFormat.ASTC_10x6_UNORM_BLOCK: { return CompressedTextureSize(Image.Width, Image.Height, 10, 6, 16); } From 7acfc952548015fb4e19ab05e2cdf43a4f2e0c08 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 16 Aug 2018 20:05:56 -0300 Subject: [PATCH 11/13] Add some rendertarget formats --- Ryujinx.Graphics/Gal/ImageFormatConverter.cs | 12 ++++-------- Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/Ryujinx.Graphics/Gal/ImageFormatConverter.cs b/Ryujinx.Graphics/Gal/ImageFormatConverter.cs index 305f192f76..a713939425 100644 --- a/Ryujinx.Graphics/Gal/ImageFormatConverter.cs +++ b/Ryujinx.Graphics/Gal/ImageFormatConverter.cs @@ -98,17 +98,11 @@ namespace Ryujinx.Graphics.Gal break; case GalTextureType.Snorm_Force_Fp16: - switch (Format) - { - //TODO - } + //TODO break; case GalTextureType.Unorm_Force_Fp16: - switch (Format) - { - //TODO - } + //TODO break; case GalTextureType.Float: @@ -145,6 +139,8 @@ namespace Ryujinx.Graphics.Gal case GalFrameBufferFormat.RG16Snorm: return GalImageFormat.R16G16_SNORM; case GalFrameBufferFormat.RG16Float: return GalImageFormat.R16G16_SFLOAT; case GalFrameBufferFormat.RG8Snorm: return GalImageFormat.R8_SNORM; + case GalFrameBufferFormat.RGBA8Snorm: return GalImageFormat.A8B8G8R8_SNORM_PACK32; + case GalFrameBufferFormat.RG8Unorm: return GalImageFormat.R8G8_UNORM; } throw new NotImplementedException(Format.ToString()); diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs index 3cb362cfbf..7896b419b2 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; namespace Ryujinx.Graphics.Gal.OpenGL { - public class OGLRasterizer : IGalRasterizer + class OGLRasterizer : IGalRasterizer { private int[] VertexBuffers; From 6e48aa253cefe59deb449a2ab70e4c8ce9de556a Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 16 Aug 2018 20:20:01 -0300 Subject: [PATCH 12/13] Code cleanup --- Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs | 34 +++++++++++-------- Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs | 7 ---- Ryujinx.Graphics/Gal/OpenGL/TCE.cs | 7 ---- Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs | 1 + 4 files changed, 20 insertions(+), 29 deletions(-) diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs index 7f8cb63ffc..5badfcfb2a 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs @@ -1,7 +1,6 @@ using OpenTK; using OpenTK.Graphics.OpenGL; using System; -using System.Collections.Generic; namespace Ryujinx.Graphics.Gal.OpenGL { @@ -56,12 +55,17 @@ namespace Ryujinx.Graphics.Gal.OpenGL private int CropRight; private int CropBottom; + //This framebuffer is used to attach guest rendertargets, + //think of it as a dummy OpenGL VAO private int DummyFrameBuffer; + //These framebuffers are used to blit images private int SrcFb; private int DstFb; + //Holds current attachments, used to avoid unnecesary calls to OpenGL private int[] ColorAttachments; + private int DepthAttachment; private int StencilAttachment; @@ -92,20 +96,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL Attach(ref ColorAttachments[Attachment], 0, FramebufferAttachment.ColorAttachment0 + Attachment); } - - private void Attach(ref int OldHandle, int NewHandle, FramebufferAttachment FbAttachment) - { - if (OldHandle != NewHandle) - { - GL.FramebufferTexture( - FramebufferTarget.DrawFramebuffer, - FbAttachment, - NewHandle, - 0); - - OldHandle = NewHandle; - } - } public void BindZeta(long Key) { @@ -436,6 +426,20 @@ namespace Ryujinx.Graphics.Gal.OpenGL GL.DrawBuffers(8, DrawBuffers); } + private void Attach(ref int OldHandle, int NewHandle, FramebufferAttachment FbAttachment) + { + if (OldHandle != NewHandle) + { + GL.FramebufferTexture( + FramebufferTarget.DrawFramebuffer, + FbAttachment, + NewHandle, + 0); + + OldHandle = NewHandle; + } + } + private void CopyTextures( int SrcX0, int SrcY0, diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs index fe865cf422..ba43951005 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs @@ -72,8 +72,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL (PixelInternalFormat InternalFormat, PixelFormat Format, PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format); - GL.GetError(); - GL.TexImage2D( TextureTarget.Texture2D, Level, @@ -84,11 +82,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL Format, Type, Data); - - if (GL.GetError() != ErrorCode.NoError) - { - throw new InvalidOperationException($"{InternalFormat} {Format} {Type}"); - } } int SwizzleR = (int)OGLEnumConverter.GetTextureSwizzle(Image.XSource); diff --git a/Ryujinx.Graphics/Gal/OpenGL/TCE.cs b/Ryujinx.Graphics/Gal/OpenGL/TCE.cs index ea130e086b..5f7cff8fc9 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/TCE.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/TCE.cs @@ -89,8 +89,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL const int Level = 0; const int Border = 0; - GL.GetError(); - GL.TexImage2D( TextureTarget.Texture2D, Level, @@ -102,11 +100,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL PixelType, IntPtr.Zero); - if (GL.GetError() != ErrorCode.NoError) - { - throw new InvalidOperationException($"{InternalFormat} {PixelFormat} {PixelType}"); - } - if (Initialized) { GL.BindBuffer(BufferTarget.PixelPackBuffer, 0); diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs index 28142e6418..f04eee5f62 100644 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine3d.cs @@ -102,6 +102,7 @@ namespace Ryujinx.HLE.Gpu.Engines SetAlphaBlending(State); SetPrimitiveRestart(State); + //Enabling multiple framebuffer attachments cause graphics reggresions SetFrameBuffer(Vmm, 0); SetZeta(Vmm); From ac2cba91c762ac9541fab08a757136af3dd28e27 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 16 Aug 2018 20:41:31 -0300 Subject: [PATCH 13/13] Fixup half float types --- Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs index 49fca698f6..9d7e132385 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs @@ -132,7 +132,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL case GalImageFormat.R32G32B32A32_SFLOAT: return (PixelInternalFormat.Rgba32f, PixelFormat.Rgba, PixelType.Float); case GalImageFormat.R32G32B32A32_SINT: return (PixelInternalFormat.Rgba32i, PixelFormat.RgbaInteger, PixelType.Int); case GalImageFormat.R32G32B32A32_UINT: return (PixelInternalFormat.Rgba32ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt); - case GalImageFormat.R16G16B16A16_SFLOAT: return (PixelInternalFormat.Rgba16f, PixelFormat.Rgba, PixelType.Float); + case GalImageFormat.R16G16B16A16_SFLOAT: return (PixelInternalFormat.Rgba16f, PixelFormat.Rgba, PixelType.HalfFloat); case GalImageFormat.R16G16B16A16_SINT: return (PixelInternalFormat.Rgba16i, PixelFormat.RgbaInteger, PixelType.Short); case GalImageFormat.R16G16B16A16_UINT: return (PixelInternalFormat.Rgba16ui, PixelFormat.RgbaInteger, PixelType.UnsignedShort); case GalImageFormat.A8B8G8R8_SNORM_PACK32: return (PixelInternalFormat.Rgba8Snorm, PixelFormat.Rgba, PixelType.Byte); @@ -147,7 +147,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL case GalImageFormat.R32_UINT: return (PixelInternalFormat.R32ui, PixelFormat.Red, PixelType.UnsignedInt); case GalImageFormat.A1R5G5B5_UNORM_PACK16: return (PixelInternalFormat.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort5551); case GalImageFormat.B5G6R5_UNORM_PACK16: return (PixelInternalFormat.Rgba, PixelFormat.Rgb, PixelType.UnsignedShort565); - case GalImageFormat.R16G16_SFLOAT: return (PixelInternalFormat.Rg16f, PixelFormat.Rg, PixelType.Float); + case GalImageFormat.R16G16_SFLOAT: return (PixelInternalFormat.Rg16f, PixelFormat.Rg, PixelType.HalfFloat); case GalImageFormat.R16G16_SINT: return (PixelInternalFormat.Rg16i, PixelFormat.RgInteger, PixelType.Short); case GalImageFormat.R16G16_SNORM: return (PixelInternalFormat.Rg16Snorm, PixelFormat.Rg, PixelType.Byte); case GalImageFormat.R16G16_UNORM: return (PixelInternalFormat.Rg16, PixelFormat.Rg, PixelType.UnsignedShort); @@ -155,7 +155,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL case GalImageFormat.R8G8_SNORM: return (PixelInternalFormat.Rg8Snorm, PixelFormat.Rg, PixelType.Byte); case GalImageFormat.R8G8_UINT: return (PixelInternalFormat.Rg8ui, PixelFormat.RgInteger, PixelType.UnsignedByte); case GalImageFormat.R8G8_UNORM: return (PixelInternalFormat.Rg8, PixelFormat.Rg, PixelType.UnsignedByte); - case GalImageFormat.R16_SFLOAT: return (PixelInternalFormat.R16f, PixelFormat.Red, PixelType.Float); + case GalImageFormat.R16_SFLOAT: return (PixelInternalFormat.R16f, PixelFormat.Red, PixelType.HalfFloat); case GalImageFormat.R16_SINT: return (PixelInternalFormat.R16i, PixelFormat.RedInteger, PixelType.Short); case GalImageFormat.R16_SNORM: return (PixelInternalFormat.R16Snorm, PixelFormat.Red, PixelType.Byte); case GalImageFormat.R16_UINT: return (PixelInternalFormat.R16ui, PixelFormat.RedInteger, PixelType.UnsignedShort);