diff --git a/src/Ryujinx.Graphics.GAL/TextureCreateInfo.cs b/src/Ryujinx.Graphics.GAL/TextureCreateInfo.cs
index 44090291dd..79c84db016 100644
--- a/src/Ryujinx.Graphics.GAL/TextureCreateInfo.cs
+++ b/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);
diff --git a/src/Ryujinx.Graphics.Gpu/Image/TexturePool.cs b/src/Ryujinx.Graphics.Gpu/Image/TexturePool.cs
index a4035577d3..4ed0a93c17 100644
--- a/src/Ryujinx.Graphics.Gpu/Image/TexturePool.cs
+++ b/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);
}
+ ///
+ /// Clamps the amount of mipmap levels to the maximum allowed for the given texture dimensions.
+ ///
+ /// Number of texture dimensions (1D, 2D, 3D, Cube, etc)
+ /// Width of the texture
+ /// Height of the texture, ignored for 1D textures
+ /// Depth of the texture for 3D textures, otherwise ignored
+ /// Original amount of mipmap levels
+ /// Clamped mipmap levels
+ 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);
+ }
+
///
/// 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.
diff --git a/src/Ryujinx.Graphics.OpenGL/Image/TextureStorage.cs b/src/Ryujinx.Graphics.OpenGL/Image/TextureStorage.cs
index 79c6cb685b..0ebafb04e9 100644
--- a/src/Ryujinx.Graphics.OpenGL/Image/TextureStorage.cs
+++ b/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)
{
diff --git a/src/Ryujinx.Graphics.OpenGL/Image/TextureView.cs b/src/Ryujinx.Graphics.OpenGL/Image/TextureView.cs
index 8a18e6132a..946eb755cc 100644
--- a/src/Ryujinx.Graphics.OpenGL/Image/TextureView.cs
+++ b/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 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;