diff options
Diffstat (limited to 'Ryujinx.Graphics/Gal/OpenGL')
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs | 1 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs | 25 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs | 7 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs | 55 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs | 2 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs | 256 |
6 files changed, 289 insertions, 57 deletions
diff --git a/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs b/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs index 8db0b8a8..5714f3d8 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs @@ -8,6 +8,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL public int Width => Image.Width; public int Height => Image.Height; + public int Depth => Image.Depth; public GalImageFormat Format => Image.Format; diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs index f2afe7b5..3a25fff7 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs @@ -189,6 +189,31 @@ namespace Ryujinx.Graphics.Gal.OpenGL throw new NotImplementedException($"{Format & GalImageFormat.FormatMask} {Format & GalImageFormat.TypeMask}"); } + public static All GetDepthCompareFunc(DepthCompareFunc DepthCompareFunc) + { + switch (DepthCompareFunc) + { + case DepthCompareFunc.LEqual: + return All.Lequal; + case DepthCompareFunc.GEqual: + return All.Gequal; + case DepthCompareFunc.Less: + return All.Less; + case DepthCompareFunc.Greater: + return All.Greater; + case DepthCompareFunc.Equal: + return All.Equal; + case DepthCompareFunc.NotEqual: + return All.Notequal; + case DepthCompareFunc.Always: + return All.Always; + case DepthCompareFunc.Never: + return All.Never; + default: + throw new ArgumentException(nameof(DepthCompareFunc) + " \"" + DepthCompareFunc + "\" is not valid!"); + } + } + public static InternalFormat GetCompressedImageFormat(GalImageFormat Format) { switch (Format) diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs index 11daeb59..52b3d0ce 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs @@ -9,9 +9,12 @@ namespace Ryujinx.Graphics.Gal.OpenGL private static Lazy<bool> s_TextureMirrorClamp = new Lazy<bool>(() => HasExtension("GL_EXT_texture_mirror_clamp")); private static Lazy<bool> s_ViewportArray = new Lazy<bool>(() => HasExtension("GL_ARB_viewport_array")); + private static Lazy<bool> s_NvidiaDriver = new Lazy<bool>(() => IsNvidiaDriver()); + public static bool EnhancedLayouts => s_EnhancedLayouts.Value; public static bool TextureMirrorClamp => s_TextureMirrorClamp.Value; public static bool ViewportArray => s_ViewportArray.Value; + public static bool NvidiaDrvier => s_NvidiaDriver.Value; private static bool HasExtension(string Name) { @@ -27,5 +30,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL return false; } + + private static bool IsNvidiaDriver() { + return GL.GetString(StringName.Vendor).Equals("NVIDIA Corporation"); + } } }
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs index 0d7bb3cd..8dd3b37f 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs @@ -389,16 +389,20 @@ namespace Ryujinx.Graphics.Gal.OpenGL } public void Copy( - long SrcKey, - long DstKey, - int SrcX0, - int SrcY0, - int SrcX1, - int SrcY1, - int DstX0, - int DstY0, - int DstX1, - int DstY1) + GalImage SrcImage, + GalImage DstImage, + long SrcKey, + long DstKey, + int SrcLayer, + int DstLayer, + int SrcX0, + int SrcY0, + int SrcX1, + int SrcY1, + int DstX0, + int DstY0, + int DstX1, + int DstY1) { if (Texture.TryGetImageHandler(SrcKey, out ImageHandler SrcTex) && Texture.TryGetImageHandler(DstKey, out ImageHandler DstTex)) @@ -425,8 +429,24 @@ namespace Ryujinx.Graphics.Gal.OpenGL FramebufferAttachment Attachment = GetAttachment(SrcTex); - GL.FramebufferTexture(FramebufferTarget.ReadFramebuffer, Attachment, SrcTex.Handle, 0); - GL.FramebufferTexture(FramebufferTarget.DrawFramebuffer, Attachment, DstTex.Handle, 0); + if (ImageUtils.IsArray(SrcImage.TextureTarget) && SrcLayer > 0) + { + GL.FramebufferTextureLayer(FramebufferTarget.ReadFramebuffer, Attachment, SrcTex.Handle, 0, SrcLayer); + } + else + { + GL.FramebufferTexture(FramebufferTarget.ReadFramebuffer, Attachment, SrcTex.Handle, 0); + } + + if (ImageUtils.IsArray(DstImage.TextureTarget) && DstLayer > 0) + { + GL.FramebufferTextureLayer(FramebufferTarget.DrawFramebuffer, Attachment, DstTex.Handle, 0, DstLayer); + } + else + { + GL.FramebufferTexture(FramebufferTarget.DrawFramebuffer, Attachment, DstTex.Handle, 0); + } + BlitFramebufferFilter Filter = BlitFramebufferFilter.Nearest; @@ -452,7 +472,10 @@ namespace Ryujinx.Graphics.Gal.OpenGL if (NewImage.Format == OldImage.Format && NewImage.Width == OldImage.Width && - NewImage.Height == OldImage.Height) + NewImage.Height == OldImage.Height && + NewImage.Depth == OldImage.Depth && + NewImage.LayerCount == OldImage.LayerCount && + NewImage.TextureTarget == OldImage.TextureTarget) { return; } @@ -477,9 +500,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL (_, PixelFormat Format, PixelType Type) = OGLEnumConverter.GetImageFormat(CachedImage.Format); - GL.BindTexture(TextureTarget.Texture2D, CachedImage.Handle); + TextureTarget Target = ImageUtils.GetTextureTarget(NewImage.TextureTarget); + + GL.BindTexture(Target, CachedImage.Handle); - GL.GetTexImage(TextureTarget.Texture2D, 0, Format, Type, IntPtr.Zero); + GL.GetTexImage(Target, 0, Format, Type, IntPtr.Zero); GL.BindBuffer(BufferTarget.PixelPackBuffer, 0); GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyPBO); diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs index 10a9120d..dc168ff9 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs @@ -53,7 +53,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL { GlslProgram Program; - GlslDecompiler Decompiler = new GlslDecompiler(OGLLimit.MaxUboSize); + GlslDecompiler Decompiler = new GlslDecompiler(OGLLimit.MaxUboSize, OGLExtension.NvidiaDrvier); int ShaderDumpIndex = ShaderDumper.DumpIndex; diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs index ef984b1e..4fef11d2 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs @@ -38,7 +38,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL { int Handle = GL.GenTexture(); - GL.BindTexture(TextureTarget.Texture2D, Handle); + TextureTarget Target = ImageUtils.GetTextureTarget(Image.TextureTarget); + + GL.BindTexture(Target, Handle); const int Level = 0; //TODO: Support mipmap textures. const int Border = 0; @@ -54,23 +56,70 @@ namespace Ryujinx.Graphics.Gal.OpenGL PixelFormat Format, PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format); - GL.TexImage2D( - TextureTarget.Texture2D, - Level, - InternalFmt, - Image.Width, - Image.Height, - Border, - Format, - Type, - IntPtr.Zero); + switch (Target) + { + case TextureTarget.Texture1D: + GL.TexImage1D( + Target, + Level, + InternalFmt, + Image.Width, + Border, + Format, + Type, + IntPtr.Zero); + break; + + case TextureTarget.Texture2D: + GL.TexImage2D( + Target, + Level, + InternalFmt, + Image.Width, + Image.Height, + Border, + Format, + Type, + IntPtr.Zero); + break; + case TextureTarget.Texture3D: + GL.TexImage3D( + Target, + Level, + InternalFmt, + Image.Width, + Image.Height, + Image.Depth, + Border, + Format, + Type, + IntPtr.Zero); + break; + case TextureTarget.Texture2DArray: + GL.TexImage3D( + Target, + Level, + InternalFmt, + Image.Width, + Image.Height, + Image.LayerCount, + Border, + Format, + Type, + IntPtr.Zero); + break; + default: + throw new NotImplementedException($"Unsupported texture target type: {Target}"); + } } public void Create(long Key, byte[] Data, GalImage Image) { int Handle = GL.GenTexture(); - GL.BindTexture(TextureTarget.Texture2D, Handle); + TextureTarget Target = ImageUtils.GetTextureTarget(Image.TextureTarget); + + GL.BindTexture(Target, Handle); const int Level = 0; //TODO: Support mipmap textures. const int Border = 0; @@ -81,15 +130,56 @@ namespace Ryujinx.Graphics.Gal.OpenGL { InternalFormat InternalFmt = OGLEnumConverter.GetCompressedImageFormat(Image.Format); - GL.CompressedTexImage2D( - TextureTarget.Texture2D, - Level, - InternalFmt, - Image.Width, - Image.Height, - Border, - Data.Length, - Data); + switch (Target) + { + case TextureTarget.Texture1D: + GL.CompressedTexImage1D( + Target, + Level, + InternalFmt, + Image.Width, + Border, + Data.Length, + Data); + break; + case TextureTarget.Texture2D: + GL.CompressedTexImage2D( + Target, + Level, + InternalFmt, + Image.Width, + Image.Height, + Border, + Data.Length, + Data); + break; + case TextureTarget.Texture3D: + GL.CompressedTexImage3D( + Target, + Level, + InternalFmt, + Image.Width, + Image.Height, + Image.Depth, + Border, + Data.Length, + Data); + break; + case TextureTarget.Texture2DArray: + GL.CompressedTexImage3D( + Target, + Level, + InternalFmt, + Image.Width, + Image.Height, + Image.LayerCount, + Border, + Data.Length, + Data); + break; + default: + throw new NotImplementedException($"Unsupported texture target type: {Target}"); + } } else { @@ -98,13 +188,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL { int TextureBlockWidth = ImageUtils.GetBlockWidth(Image.Format); int TextureBlockHeight = ImageUtils.GetBlockHeight(Image.Format); + int TextureBlockDepth = ImageUtils.GetBlockDepth(Image.Format); Data = ASTCDecoder.DecodeToRGBA8888( Data, TextureBlockWidth, - TextureBlockHeight, 1, + TextureBlockHeight, + TextureBlockDepth, Image.Width, - Image.Height, 1); + Image.Height, + Image.Depth); Image.Format = GalImageFormat.RGBA8 | (Image.Format & GalImageFormat.TypeMask); } @@ -113,16 +206,80 @@ namespace Ryujinx.Graphics.Gal.OpenGL PixelFormat Format, PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format); - GL.TexImage2D( - TextureTarget.Texture2D, - Level, - InternalFmt, - Image.Width, - Image.Height, - Border, - Format, - Type, - Data); + + switch (Target) + { + case TextureTarget.Texture1D: + GL.TexImage1D( + Target, + Level, + InternalFmt, + Image.Width, + Border, + Format, + Type, + Data); + break; + case TextureTarget.Texture2D: + GL.TexImage2D( + Target, + Level, + InternalFmt, + Image.Width, + Image.Height, + Border, + Format, + Type, + Data); + break; + case TextureTarget.Texture3D: + GL.TexImage3D( + Target, + Level, + InternalFmt, + Image.Width, + Image.Height, + Image.Depth, + Border, + Format, + Type, + Data); + break; + case TextureTarget.Texture2DArray: + GL.TexImage3D( + Target, + Level, + InternalFmt, + Image.Width, + Image.Height, + Image.LayerCount, + Border, + Format, + Type, + Data); + break; + case TextureTarget.TextureCubeMap: + Span<byte> Array = new Span<byte>(Data); + + int FaceSize = ImageUtils.GetSize(Image) / 6; + + for (int Face = 0; Face < 6; Face++) + { + GL.TexImage2D( + TextureTarget.TextureCubeMapPositiveX + Face, + Level, + InternalFmt, + Image.Width, + Image.Height, + Border, + Format, + Type, + Array.Slice(Face * FaceSize, FaceSize).ToArray()); + } + break; + default: + throw new NotImplementedException($"Unsupported texture target type: {Target}"); + } } } @@ -165,7 +322,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL { GL.ActiveTexture(TextureUnit.Texture0 + Index); - GL.BindTexture(TextureTarget.Texture2D, CachedImage.Handle); + TextureTarget Target = ImageUtils.GetTextureTarget(Image.TextureTarget); + + GL.BindTexture(Target, CachedImage.Handle); int[] SwizzleRgba = new int[] { @@ -175,23 +334,27 @@ namespace Ryujinx.Graphics.Gal.OpenGL (int)OGLEnumConverter.GetTextureSwizzle(Image.WSource) }; - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleRgba, SwizzleRgba); + GL.TexParameter(Target, TextureParameterName.TextureSwizzleRgba, SwizzleRgba); } } - public void SetSampler(GalTextureSampler Sampler) + public void SetSampler(GalImage Image, GalTextureSampler Sampler) { int WrapS = (int)OGLEnumConverter.GetTextureWrapMode(Sampler.AddressU); int WrapT = (int)OGLEnumConverter.GetTextureWrapMode(Sampler.AddressV); + int WrapR = (int)OGLEnumConverter.GetTextureWrapMode(Sampler.AddressP); int MinFilter = (int)OGLEnumConverter.GetTextureMinFilter(Sampler.MinFilter, Sampler.MipFilter); int MagFilter = (int)OGLEnumConverter.GetTextureMagFilter(Sampler.MagFilter); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, WrapS); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, WrapT); + TextureTarget Target = ImageUtils.GetTextureTarget(Image.TextureTarget); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, MinFilter); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, MagFilter); + GL.TexParameter(Target, TextureParameterName.TextureWrapS, WrapS); + GL.TexParameter(Target, TextureParameterName.TextureWrapT, WrapT); + GL.TexParameter(Target, TextureParameterName.TextureWrapR, WrapR); + + GL.TexParameter(Target, TextureParameterName.TextureMinFilter, MinFilter); + GL.TexParameter(Target, TextureParameterName.TextureMagFilter, MagFilter); float[] Color = new float[] { @@ -201,7 +364,18 @@ namespace Ryujinx.Graphics.Gal.OpenGL Sampler.BorderColor.Alpha }; - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBorderColor, Color); + GL.TexParameter(Target, TextureParameterName.TextureBorderColor, Color); + + if (Sampler.DepthCompare) + { + GL.TexParameter(Target, TextureParameterName.TextureCompareMode, (int)All.CompareRToTexture); + GL.TexParameter(Target, TextureParameterName.TextureCompareFunc, (int)OGLEnumConverter.GetDepthCompareFunc(Sampler.DepthCompareFunc)); + } + else + { + GL.TexParameter(Target, TextureParameterName.TextureCompareMode, (int)All.None); + GL.TexParameter(Target, TextureParameterName.TextureCompareFunc, (int)All.Never); + } } } } |
