forked from Mirror/Ryujinx
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:
parent
8d8983049e
commit
4f75e26ec7
4 changed files with 36 additions and 25 deletions
|
@ -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);
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Reference in a new issue