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
This commit is contained in:
gdkchan 2024-08-12 17:45:25 -03:00 committed by GitHub
parent 8d8983049e
commit 4f75e26ec7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 36 additions and 25 deletions

View File

@ -1,6 +1,5 @@
using Ryujinx.Common; using Ryujinx.Common;
using System; using System;
using System.Numerics;
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL
{ {
@ -113,25 +112,6 @@ namespace Ryujinx.Graphics.GAL
return 1; 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) private static int GetLevelSize(int size, int level)
{ {
return Math.Max(1, size >> level); return Math.Max(1, size >> level);

View File

@ -6,6 +6,7 @@ using Ryujinx.Memory.Range;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Numerics;
using System.Threading; using System.Threading;
namespace Ryujinx.Graphics.Gpu.Image namespace Ryujinx.Graphics.Gpu.Image
@ -490,6 +491,8 @@ namespace Ryujinx.Graphics.Gpu.Image
levels = (maxLod - minLod) + 1; levels = (maxLod - minLod) + 1;
} }
levels = ClampLevels(target, width, height, depthOrLayers, levels);
SwizzleComponent swizzleR = descriptor.UnpackSwizzleR().Convert(); SwizzleComponent swizzleR = descriptor.UnpackSwizzleR().Convert();
SwizzleComponent swizzleG = descriptor.UnpackSwizzleG().Convert(); SwizzleComponent swizzleG = descriptor.UnpackSwizzleG().Convert();
SwizzleComponent swizzleB = descriptor.UnpackSwizzleB().Convert(); SwizzleComponent swizzleB = descriptor.UnpackSwizzleB().Convert();
@ -540,6 +543,34 @@ namespace Ryujinx.Graphics.Gpu.Image
swizzleA); 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> /// <summary>
/// Gets the texture depth-stencil mode, based on the swizzle components of each color channel. /// 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. /// The depth-stencil mode is determined based on how the driver sets those parameters.

View File

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

View File

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