diff options
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs')
-rw-r--r-- | Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs | 76 |
1 files changed, 65 insertions, 11 deletions
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs b/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs index 61b48dc4..5ea9ee2f 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureCompatibility.cs @@ -71,11 +71,15 @@ namespace Ryujinx.Graphics.Gpu.Image { if (info.FormatInfo.Format.IsAstcUnorm()) { - return new FormatInfo(Format.R8G8B8A8Unorm, 1, 1, 4, 4); + return GraphicsConfig.EnableTextureRecompression + ? new FormatInfo(Format.Bc7Unorm, 4, 4, 16, 4) + : new FormatInfo(Format.R8G8B8A8Unorm, 1, 1, 4, 4); } else if (info.FormatInfo.Format.IsAstcSrgb()) { - return new FormatInfo(Format.R8G8B8A8Srgb, 1, 1, 4, 4); + return GraphicsConfig.EnableTextureRecompression + ? new FormatInfo(Format.Bc7Srgb, 4, 4, 16, 4) + : new FormatInfo(Format.R8G8B8A8Srgb, 1, 1, 4, 4); } } @@ -84,9 +88,9 @@ namespace Ryujinx.Graphics.Gpu.Image return new FormatInfo(Format.R4G4B4A4Unorm, 1, 1, 2, 4); } - if (!caps.Supports3DTextureCompression && info.Target == Target.Texture3D) + if (!HostSupportsBcFormat(info.FormatInfo.Format, info.Target, caps)) { - // The host API does not support 3D compressed formats. + // The host API does not this compressed format. // We assume software decompression will be done for those textures, // and so we adjust the format here to match the decompressor output. switch (info.FormatInfo.Format) @@ -94,10 +98,12 @@ namespace Ryujinx.Graphics.Gpu.Image case Format.Bc1RgbaSrgb: case Format.Bc2Srgb: case Format.Bc3Srgb: + case Format.Bc7Srgb: return new FormatInfo(Format.R8G8B8A8Srgb, 1, 1, 4, 4); case Format.Bc1RgbaUnorm: case Format.Bc2Unorm: case Format.Bc3Unorm: + case Format.Bc7Unorm: return new FormatInfo(Format.R8G8B8A8Unorm, 1, 1, 4, 4); case Format.Bc4Unorm: return new FormatInfo(Format.R8Unorm, 1, 1, 1, 1); @@ -107,6 +113,9 @@ namespace Ryujinx.Graphics.Gpu.Image return new FormatInfo(Format.R8G8Unorm, 1, 1, 2, 2); case Format.Bc5Snorm: return new FormatInfo(Format.R8G8Snorm, 1, 1, 2, 2); + case Format.Bc6HSfloat: + case Format.Bc6HUfloat: + return new FormatInfo(Format.R16G16B16A16Float, 1, 1, 8, 4); } } @@ -114,6 +123,41 @@ namespace Ryujinx.Graphics.Gpu.Image } /// <summary> + /// Checks if the host API supports a given texture compression format of the BC family. + /// </summary> + /// <param name="format">BC format to be checked</param> + /// <param name="target">Target usage of the texture</param> + /// <param name="caps">Host GPU Capabilities</param> + /// <returns>True if the texture host supports the format with the given target usage, false otherwise</returns> + public static bool HostSupportsBcFormat(Format format, Target target, Capabilities caps) + { + bool not3DOr3DCompressionSupported = target != Target.Texture3D || caps.Supports3DTextureCompression; + + switch (format) + { + case Format.Bc1RgbaSrgb: + case Format.Bc1RgbaUnorm: + case Format.Bc2Srgb: + case Format.Bc2Unorm: + case Format.Bc3Srgb: + case Format.Bc3Unorm: + return caps.SupportsBc123Compression && not3DOr3DCompressionSupported; + case Format.Bc4Unorm: + case Format.Bc4Snorm: + case Format.Bc5Unorm: + case Format.Bc5Snorm: + return caps.SupportsBc45Compression && not3DOr3DCompressionSupported; + case Format.Bc6HSfloat: + case Format.Bc6HUfloat: + case Format.Bc7Srgb: + case Format.Bc7Unorm: + return caps.SupportsBc67Compression && not3DOr3DCompressionSupported; + } + + return true; + } + + /// <summary> /// Determines whether a texture can flush its data back to guest memory. /// </summary> /// <param name="info">Texture information</param> @@ -627,9 +671,9 @@ namespace Ryujinx.Graphics.Gpu.Image /// </summary> /// <param name="lhs">Texture information of the texture view</param /// <param name="rhs">Texture information of the texture view</param> - /// <param name="isCopy">True to check for copy rather than view compatibility</param> + /// <param name="caps">Host GPU capabilities</param> /// <returns>True if the targets are compatible, false otherwise</returns> - public static TextureViewCompatibility ViewTargetCompatible(TextureInfo lhs, TextureInfo rhs) + public static TextureViewCompatibility ViewTargetCompatible(TextureInfo lhs, TextureInfo rhs, ref Capabilities caps) { bool result = false; switch (lhs.Target) @@ -646,14 +690,24 @@ namespace Ryujinx.Graphics.Gpu.Image break; case Target.Texture2DArray: + result = rhs.Target == Target.Texture2D || + rhs.Target == Target.Texture2DArray; + + if (rhs.Target == Target.Cubemap || rhs.Target == Target.CubemapArray) + { + return caps.SupportsCubemapView ? TextureViewCompatibility.Full : TextureViewCompatibility.CopyOnly; + } + break; case Target.Cubemap: case Target.CubemapArray: - result = rhs.Target == Target.Texture2D || - rhs.Target == Target.Texture2DArray || - rhs.Target == Target.Cubemap || + result = rhs.Target == Target.Cubemap || rhs.Target == Target.CubemapArray; - break; + if (rhs.Target == Target.Texture2D || rhs.Target == Target.Texture2DArray) + { + return caps.SupportsCubemapView ? TextureViewCompatibility.Full : TextureViewCompatibility.CopyOnly; + } + break; case Target.Texture2DMultisample: case Target.Texture2DMultisampleArray: if (rhs.Target == Target.Texture2D || rhs.Target == Target.Texture2DArray) @@ -744,7 +798,7 @@ namespace Ryujinx.Graphics.Gpu.Image /// <returns>True if the texture target and samples count matches, false otherwise</returns> public static bool TargetAndSamplesCompatible(TextureInfo lhs, TextureInfo rhs) { - return lhs.Target == rhs.Target && + return lhs.Target == rhs.Target && lhs.SamplesInX == rhs.SamplesInX && lhs.SamplesInY == rhs.SamplesInY; } |