Prechádzať zdrojové kódy

Clamp amount of mipmap levels to max allowed for all backends (#7197)

* Clamp amount of mipmap levels to max allowed for all backends

* XML docs

* Remove using
gdkchan 1 rok pred
rodič
commit
4f75e26ec7

+ 0 - 20
src/Ryujinx.Graphics.GAL/TextureCreateInfo.cs

@@ -1,6 +1,5 @@
 using Ryujinx.Common;
 using System;
-using System.Numerics;
 
 namespace Ryujinx.Graphics.GAL
 {
@@ -113,25 +112,6 @@ namespace Ryujinx.Graphics.GAL
             return 1;
         }
 
-        public int GetLevelsClamped()
-        {
-            int maxSize = Width;
-
-            if (Target != Target.Texture1D &&
-                Target != Target.Texture1DArray)
-            {
-                maxSize = Math.Max(maxSize, Height);
-            }
-
-            if (Target == Target.Texture3D)
-            {
-                maxSize = Math.Max(maxSize, Depth);
-            }
-
-            int maxLevels = BitOperations.Log2((uint)maxSize) + 1;
-            return Math.Min(Levels, maxLevels);
-        }
-
         private static int GetLevelSize(int size, int level)
         {
             return Math.Max(1, size >> level);

+ 31 - 0
src/Ryujinx.Graphics.Gpu/Image/TexturePool.cs

@@ -6,6 +6,7 @@ using Ryujinx.Memory.Range;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
+using System.Numerics;
 using System.Threading;
 
 namespace Ryujinx.Graphics.Gpu.Image
@@ -490,6 +491,8 @@ namespace Ryujinx.Graphics.Gpu.Image
                 levels = (maxLod - minLod) + 1;
             }
 
+            levels = ClampLevels(target, width, height, depthOrLayers, levels);
+
             SwizzleComponent swizzleR = descriptor.UnpackSwizzleR().Convert();
             SwizzleComponent swizzleG = descriptor.UnpackSwizzleG().Convert();
             SwizzleComponent swizzleB = descriptor.UnpackSwizzleB().Convert();
@@ -540,6 +543,34 @@ namespace Ryujinx.Graphics.Gpu.Image
                 swizzleA);
         }
 
+        /// <summary>
+        /// Clamps the amount of mipmap levels to the maximum allowed for the given texture dimensions.
+        /// </summary>
+        /// <param name="target">Number of texture dimensions (1D, 2D, 3D, Cube, etc)</param>
+        /// <param name="width">Width of the texture</param>
+        /// <param name="height">Height of the texture, ignored for 1D textures</param>
+        /// <param name="depthOrLayers">Depth of the texture for 3D textures, otherwise ignored</param>
+        /// <param name="levels">Original amount of mipmap levels</param>
+        /// <returns>Clamped mipmap levels</returns>
+        private static int ClampLevels(Target target, int width, int height, int depthOrLayers, int levels)
+        {
+            int maxSize = width;
+
+            if (target != Target.Texture1D &&
+                target != Target.Texture1DArray)
+            {
+                maxSize = Math.Max(maxSize, height);
+            }
+
+            if (target == Target.Texture3D)
+            {
+                maxSize = Math.Max(maxSize, depthOrLayers);
+            }
+
+            int maxLevels = BitOperations.Log2((uint)maxSize) + 1;
+            return Math.Min(levels, maxLevels);
+        }
+
         /// <summary>
         /// Gets the texture depth-stencil mode, based on the swizzle components of each color channel.
         /// The depth-stencil mode is determined based on how the driver sets those parameters.

+ 1 - 1
src/Ryujinx.Graphics.OpenGL/Image/TextureStorage.cs

@@ -48,7 +48,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
                 internalFormat = (SizedInternalFormat)format.PixelInternalFormat;
             }
 
-            int levels = Info.GetLevelsClamped();
+            int levels = Info.Levels;
 
             switch (Info.Target)
             {

+ 4 - 4
src/Ryujinx.Graphics.OpenGL/Image/TextureView.cs

@@ -51,7 +51,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
                 pixelInternalFormat = format.PixelInternalFormat;
             }
 
-            int levels = Info.GetLevelsClamped();
+            int levels = Info.Levels;
 
             GL.TextureView(
                 Handle,
@@ -267,7 +267,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
         public unsafe PinnedSpan<byte> GetData()
         {
             int size = 0;
-            int levels = Info.GetLevelsClamped();
+            int levels = Info.Levels;
 
             for (int level = 0; level < levels; level++)
             {
@@ -426,7 +426,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
                 faces = 6;
             }
 
-            int levels = Info.GetLevelsClamped();
+            int levels = Info.Levels;
 
             for (int level = 0; level < levels; level++)
             {
@@ -716,7 +716,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
             int width = Info.Width;
             int height = Info.Height;
             int depth = Info.Depth;
-            int levels = Info.GetLevelsClamped();
+            int levels = Info.Levels;
 
             int offset = 0;