From 43c4e7c78d98b09e8dc51e3450396cd99b2b3a92 Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Sat, 25 Aug 2018 16:39:08 -0300
Subject: [PATCH] Use mirrored texture wraps when available (#361)

---
 .../Gal/OpenGL/OGLEnumConverter.cs            | 33 ++++++++++++++-----
 Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs   | 11 +++++++
 2 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs
index e04a59d444..64f670a5e5 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs
@@ -215,16 +215,31 @@ namespace Ryujinx.Graphics.Gal.OpenGL
         {
             switch (Wrap)
             {
-                case GalTextureWrap.Repeat:              return TextureWrapMode.Repeat;
-                case GalTextureWrap.MirroredRepeat:      return TextureWrapMode.MirroredRepeat;
-                case GalTextureWrap.ClampToEdge:         return TextureWrapMode.ClampToEdge;
-                case GalTextureWrap.ClampToBorder:       return TextureWrapMode.ClampToBorder;
-                case GalTextureWrap.Clamp:               return TextureWrapMode.Clamp;
+                case GalTextureWrap.Repeat:         return TextureWrapMode.Repeat;
+                case GalTextureWrap.MirroredRepeat: return TextureWrapMode.MirroredRepeat;
+                case GalTextureWrap.ClampToEdge:    return TextureWrapMode.ClampToEdge;
+                case GalTextureWrap.ClampToBorder:  return TextureWrapMode.ClampToBorder;
+                case GalTextureWrap.Clamp:          return TextureWrapMode.Clamp;
+            }
 
-                //TODO: Those needs extensions (and are currently wrong).
-                case GalTextureWrap.MirrorClampToEdge:   return TextureWrapMode.ClampToEdge;
-                case GalTextureWrap.MirrorClampToBorder: return TextureWrapMode.ClampToBorder;
-                case GalTextureWrap.MirrorClamp:         return TextureWrapMode.Clamp;
+            if (OGLExtension.HasTextureMirrorClamp())
+            {
+                switch (Wrap)
+                {
+                    case GalTextureWrap.MirrorClampToEdge:   return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampToEdgeExt;
+                    case GalTextureWrap.MirrorClampToBorder: return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampToBorderExt;
+                    case GalTextureWrap.MirrorClamp:         return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampExt;
+                }
+            }
+            else
+            {
+                //Fallback to non-mirrored clamps
+                switch (Wrap)
+                {
+                    case GalTextureWrap.MirrorClampToEdge:   return TextureWrapMode.ClampToEdge;
+                    case GalTextureWrap.MirrorClampToBorder: return TextureWrapMode.ClampToBorder;
+                    case GalTextureWrap.MirrorClamp:         return TextureWrapMode.Clamp;
+                }
             }
 
             throw new ArgumentException(nameof(Wrap));
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs
index 69fce6d31d..5ad422980c 100644
--- a/Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLExtension.cs
@@ -8,6 +8,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
 
         private static bool EnhancedLayouts;
 
+        private static bool TextureMirrorClamp;
+
         public static bool HasEnhancedLayouts()
         {
             EnsureInitialized();
@@ -15,6 +17,13 @@ namespace Ryujinx.Graphics.Gal.OpenGL
             return EnhancedLayouts;
         }
 
+        public static bool HasTextureMirrorClamp()
+        {
+            EnsureInitialized();
+
+            return TextureMirrorClamp;
+        }
+
         private static void EnsureInitialized()
         {
             if (Initialized)
@@ -23,6 +32,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
             }
 
             EnhancedLayouts = HasExtension("GL_ARB_enhanced_layouts");
+
+            TextureMirrorClamp = HasExtension("GL_EXT_texture_mirror_clamp");
         }
 
         private static bool HasExtension(string Name)