Allow "reinterpretation" of framebuffer/zeta formats (#418)
* (Re)Implement format reinterpretation, other changes * Implement writeback to guest memory, some refactoring * More refactoring, implement reinterpretation the old way again * Clean up * Some fixes on M2MF (old Dma engine), added partial support for P2MF, fix conditional ssy, add Z24S8 zeta format, other fixes * nit: Formatting * Address PR feedback
This commit is contained in:
parent
bec95cacc1
commit
d4187aaa9d
52 changed files with 1594 additions and 1979 deletions
|
@ -1,33 +1,37 @@
|
|||
using Ryujinx.Graphics.Gal;
|
||||
using ChocolArm64.Memory;
|
||||
using Ryujinx.Graphics.Gal;
|
||||
using Ryujinx.Graphics.Memory;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.Graphics.Texture
|
||||
{
|
||||
static class ImageUtils
|
||||
public static class ImageUtils
|
||||
{
|
||||
struct ImageDescriptor
|
||||
[Flags]
|
||||
private enum TargetBuffer
|
||||
{
|
||||
public TextureReaderDelegate Reader;
|
||||
Color = 1 << 0,
|
||||
Depth = 1 << 1,
|
||||
Stencil = 1 << 2,
|
||||
|
||||
public bool HasColor;
|
||||
public bool HasDepth;
|
||||
public bool HasStencil;
|
||||
DepthStencil = Depth | Stencil
|
||||
}
|
||||
|
||||
public bool Compressed;
|
||||
private struct ImageDescriptor
|
||||
{
|
||||
public int BytesPerPixel { get; private set; }
|
||||
public int BlockWidth { get; private set; }
|
||||
public int BlockHeight { get; private set; }
|
||||
|
||||
public ImageDescriptor(
|
||||
TextureReaderDelegate Reader,
|
||||
bool HasColor,
|
||||
bool HasDepth,
|
||||
bool HasStencil,
|
||||
bool Compressed)
|
||||
public TargetBuffer Target { get; private set; }
|
||||
|
||||
public ImageDescriptor(int BytesPerPixel, int BlockWidth, int BlockHeight, TargetBuffer Target)
|
||||
{
|
||||
this.Reader = Reader;
|
||||
this.HasColor = HasColor;
|
||||
this.HasDepth = HasDepth;
|
||||
this.HasStencil = HasStencil;
|
||||
this.Compressed = Compressed;
|
||||
this.BytesPerPixel = BytesPerPixel;
|
||||
this.BlockWidth = BlockWidth;
|
||||
this.BlockHeight = BlockHeight;
|
||||
this.Target = Target;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,6 +52,7 @@ namespace Ryujinx.Graphics.Texture
|
|||
{ GalTextureFormat.G8R8, GalImageFormat.G8R8 | Snorm | Unorm | Sint | Uint },
|
||||
{ GalTextureFormat.R16, GalImageFormat.R16 | Snorm | Unorm | Sint | Uint | Sfloat },
|
||||
{ GalTextureFormat.R8, GalImageFormat.R8 | Snorm | Unorm | Sint | Uint },
|
||||
{ GalTextureFormat.R16G16, GalImageFormat.R16G16 | Snorm },
|
||||
{ GalTextureFormat.R32, GalImageFormat.R32 | Sint | Uint | Sfloat },
|
||||
{ GalTextureFormat.A4B4G4R4, GalImageFormat.A4B4G4R4 | Unorm },
|
||||
{ GalTextureFormat.A1B5G5R5, GalImageFormat.A1R5G5B5 | Unorm },
|
||||
|
@ -85,58 +90,58 @@ namespace Ryujinx.Graphics.Texture
|
|||
|
||||
private static readonly Dictionary<GalImageFormat, ImageDescriptor> s_ImageTable =
|
||||
new Dictionary<GalImageFormat, ImageDescriptor>()
|
||||
{
|
||||
{ GalImageFormat.R32G32B32A32, new ImageDescriptor(TextureReader.Read16Bpp, true, false, false, false) },
|
||||
{ GalImageFormat.R16G16B16A16, new ImageDescriptor(TextureReader.Read8Bpp, true, false, false, false) },
|
||||
{ GalImageFormat.R32G32, new ImageDescriptor(TextureReader.Read8Bpp, true, false, false, false) },
|
||||
{ GalImageFormat.A8B8G8R8, new ImageDescriptor(TextureReader.Read4Bpp, true, false, false, false) },
|
||||
{ GalImageFormat.A2B10G10R10, new ImageDescriptor(TextureReader.Read4Bpp, true, false, false, false) },
|
||||
{ GalImageFormat.R32, new ImageDescriptor(TextureReader.Read4Bpp, true, false, false, false) },
|
||||
{ GalImageFormat.A4B4G4R4, new ImageDescriptor(TextureReader.Read2Bpp, true, false, false, false) },
|
||||
{ GalImageFormat.BC6H_SF16, new ImageDescriptor(TextureReader.Read16BptCompressedTexture4x4, true, false, false, true) },
|
||||
{ GalImageFormat.BC6H_UF16, new ImageDescriptor(TextureReader.Read16BptCompressedTexture4x4, true, false, false, true) },
|
||||
{ GalImageFormat.A1R5G5B5, new ImageDescriptor(TextureReader.Read5551, true, false, false, false) },
|
||||
{ GalImageFormat.B5G6R5, new ImageDescriptor(TextureReader.Read565, true, false, false, false) },
|
||||
{ GalImageFormat.BC7, new ImageDescriptor(TextureReader.Read16BptCompressedTexture4x4, true, false, false, true) },
|
||||
{ GalImageFormat.R16G16, new ImageDescriptor(TextureReader.Read4Bpp, true, false, false, false) },
|
||||
{ GalImageFormat.R8G8, new ImageDescriptor(TextureReader.Read2Bpp, true, false, false, false) },
|
||||
{ GalImageFormat.G8R8, new ImageDescriptor(TextureReader.Read2Bpp, true, false, false, false) },
|
||||
{ GalImageFormat.R16, new ImageDescriptor(TextureReader.Read2Bpp, true, false, false, false) },
|
||||
{ GalImageFormat.R8, new ImageDescriptor(TextureReader.Read1Bpp, true, false, false, false) },
|
||||
{ GalImageFormat.B10G11R11, new ImageDescriptor(TextureReader.Read4Bpp, true, false, false, false) },
|
||||
{ GalImageFormat.A8B8G8R8_SRGB, new ImageDescriptor(TextureReader.Read4Bpp, true, false, false, false) },
|
||||
{ GalImageFormat.BC1_RGBA, new ImageDescriptor(TextureReader.Read8Bpt4x4, true, false, false, true) },
|
||||
{ GalImageFormat.BC2, new ImageDescriptor(TextureReader.Read16BptCompressedTexture4x4, true, false, false, true) },
|
||||
{ GalImageFormat.BC3, new ImageDescriptor(TextureReader.Read16BptCompressedTexture4x4, true, false, false, true) },
|
||||
{ GalImageFormat.BC4, new ImageDescriptor(TextureReader.Read8Bpt4x4, true, false, false, true) },
|
||||
{ GalImageFormat.BC5, new ImageDescriptor(TextureReader.Read16BptCompressedTexture4x4, true, false, false, true) },
|
||||
{ GalImageFormat.ASTC_4x4, new ImageDescriptor(TextureReader.Read16BptCompressedTexture4x4, true, false, false, true) },
|
||||
{ GalImageFormat.ASTC_5x5, new ImageDescriptor(TextureReader.Read16BptCompressedTexture5x5, true, false, false, true) },
|
||||
{ GalImageFormat.ASTC_6x6, new ImageDescriptor(TextureReader.Read16BptCompressedTexture6x6, true, false, false, true) },
|
||||
{ GalImageFormat.ASTC_8x8, new ImageDescriptor(TextureReader.Read16BptCompressedTexture8x8, true, false, false, true) },
|
||||
{ GalImageFormat.ASTC_10x10, new ImageDescriptor(TextureReader.Read16BptCompressedTexture10x10, true, false, false, true) },
|
||||
{ GalImageFormat.ASTC_12x12, new ImageDescriptor(TextureReader.Read16BptCompressedTexture12x12, true, false, false, true) },
|
||||
{ GalImageFormat.ASTC_5x4, new ImageDescriptor(TextureReader.Read16BptCompressedTexture5x4, true, false, false, true) },
|
||||
{ GalImageFormat.ASTC_6x5, new ImageDescriptor(TextureReader.Read16BptCompressedTexture6x5, true, false, false, true) },
|
||||
{ GalImageFormat.ASTC_8x6, new ImageDescriptor(TextureReader.Read16BptCompressedTexture8x6, true, false, false, true) },
|
||||
{ GalImageFormat.ASTC_10x8, new ImageDescriptor(TextureReader.Read16BptCompressedTexture10x8, true, false, false, true) },
|
||||
{ GalImageFormat.ASTC_12x10, new ImageDescriptor(TextureReader.Read16BptCompressedTexture12x10, true, false, false, true) },
|
||||
{ GalImageFormat.ASTC_8x5, new ImageDescriptor(TextureReader.Read16BptCompressedTexture8x5, true, false, false, true) },
|
||||
{ GalImageFormat.ASTC_10x5, new ImageDescriptor(TextureReader.Read16BptCompressedTexture10x5, true, false, false, true) },
|
||||
{ GalImageFormat.ASTC_10x6, new ImageDescriptor(TextureReader.Read16BptCompressedTexture10x6, true, false, false, true) },
|
||||
{
|
||||
{ GalImageFormat.R32G32B32A32, new ImageDescriptor(16, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.R16G16B16A16, new ImageDescriptor(8, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.R32G32, new ImageDescriptor(8, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.A8B8G8R8, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.A2B10G10R10, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.R32, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.A4B4G4R4, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.BC6H_SF16, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
|
||||
{ GalImageFormat.BC6H_UF16, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
|
||||
{ GalImageFormat.A1R5G5B5, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.B5G6R5, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.BC7, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
|
||||
{ GalImageFormat.R16G16, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.R8G8, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.G8R8, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.R16, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.R8, new ImageDescriptor(1, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.B10G11R11, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.A8B8G8R8_SRGB, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) },
|
||||
{ GalImageFormat.BC1_RGBA, new ImageDescriptor(8, 4, 4, TargetBuffer.Color) },
|
||||
{ GalImageFormat.BC2, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
|
||||
{ GalImageFormat.BC3, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
|
||||
{ GalImageFormat.BC4, new ImageDescriptor(8, 4, 4, TargetBuffer.Color) },
|
||||
{ GalImageFormat.BC5, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
|
||||
{ GalImageFormat.ASTC_4x4, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) },
|
||||
{ GalImageFormat.ASTC_5x5, new ImageDescriptor(16, 5, 5, TargetBuffer.Color) },
|
||||
{ GalImageFormat.ASTC_6x6, new ImageDescriptor(16, 6, 6, TargetBuffer.Color) },
|
||||
{ GalImageFormat.ASTC_8x8, new ImageDescriptor(16, 8, 8, TargetBuffer.Color) },
|
||||
{ GalImageFormat.ASTC_10x10, new ImageDescriptor(16, 10, 10, TargetBuffer.Color) },
|
||||
{ GalImageFormat.ASTC_12x12, new ImageDescriptor(16, 12, 12, TargetBuffer.Color) },
|
||||
{ GalImageFormat.ASTC_5x4, new ImageDescriptor(16, 5, 4, TargetBuffer.Color) },
|
||||
{ GalImageFormat.ASTC_6x5, new ImageDescriptor(16, 6, 5, TargetBuffer.Color) },
|
||||
{ GalImageFormat.ASTC_8x6, new ImageDescriptor(16, 8, 6, TargetBuffer.Color) },
|
||||
{ GalImageFormat.ASTC_10x8, new ImageDescriptor(16, 10, 8, TargetBuffer.Color) },
|
||||
{ GalImageFormat.ASTC_12x10, new ImageDescriptor(16, 12, 10, TargetBuffer.Color) },
|
||||
{ GalImageFormat.ASTC_8x5, new ImageDescriptor(16, 8, 5, TargetBuffer.Color) },
|
||||
{ GalImageFormat.ASTC_10x5, new ImageDescriptor(16, 10, 5, TargetBuffer.Color) },
|
||||
{ GalImageFormat.ASTC_10x6, new ImageDescriptor(16, 10, 6, TargetBuffer.Color) },
|
||||
|
||||
{ GalImageFormat.D24_S8, new ImageDescriptor(TextureReader.Read4Bpp, false, true, true, false) },
|
||||
{ GalImageFormat.D32, new ImageDescriptor(TextureReader.Read4Bpp, false, true, false, false) },
|
||||
{ GalImageFormat.D16, new ImageDescriptor(TextureReader.Read2Bpp, false, true, false, false) },
|
||||
{ GalImageFormat.D32_S8, new ImageDescriptor(TextureReader.Read8Bpp, false, true, true, false) },
|
||||
};
|
||||
{ GalImageFormat.D24_S8, new ImageDescriptor(4, 1, 1, TargetBuffer.DepthStencil) },
|
||||
{ GalImageFormat.D32, new ImageDescriptor(4, 1, 1, TargetBuffer.Depth) },
|
||||
{ GalImageFormat.D16, new ImageDescriptor(2, 1, 1, TargetBuffer.Depth) },
|
||||
{ GalImageFormat.D32_S8, new ImageDescriptor(8, 1, 1, TargetBuffer.DepthStencil) },
|
||||
};
|
||||
|
||||
public static GalImageFormat ConvertTexture(
|
||||
GalTextureFormat Format,
|
||||
GalTextureType RType,
|
||||
GalTextureType GType,
|
||||
GalTextureType BType,
|
||||
GalTextureType AType)
|
||||
GalTextureType RType,
|
||||
GalTextureType GType,
|
||||
GalTextureType BType,
|
||||
GalTextureType AType)
|
||||
{
|
||||
if (RType != GType || RType != BType || RType != AType)
|
||||
{
|
||||
|
@ -202,128 +207,157 @@ namespace Ryujinx.Graphics.Texture
|
|||
case GalZetaFormat.Z32Float: return GalImageFormat.D32 | Sfloat;
|
||||
case GalZetaFormat.S8Z24Unorm: return GalImageFormat.D24_S8 | Unorm;
|
||||
case GalZetaFormat.Z16Unorm: return GalImageFormat.D16 | Unorm;
|
||||
//This one might not be Uint, change when a texture uses this format
|
||||
case GalZetaFormat.Z32S8X24Float: return GalImageFormat.D32_S8 | Uint;
|
||||
case GalZetaFormat.Z24S8Unorm: return GalImageFormat.D24_S8 | Unorm;
|
||||
case GalZetaFormat.Z32S8X24Float: return GalImageFormat.D32_S8 | Sfloat;
|
||||
}
|
||||
|
||||
throw new NotImplementedException(Format.ToString());
|
||||
}
|
||||
|
||||
public static TextureReaderDelegate GetReader(GalImageFormat Format)
|
||||
public static byte[] ReadTexture(IAMemory Memory, GalImage Image, long Position)
|
||||
{
|
||||
return GetImageDescriptor(Format).Reader;
|
||||
AMemory CpuMemory;
|
||||
|
||||
if (Memory is NvGpuVmm Vmm)
|
||||
{
|
||||
CpuMemory = Vmm.Memory;
|
||||
}
|
||||
else
|
||||
{
|
||||
CpuMemory = (AMemory)Memory;
|
||||
}
|
||||
|
||||
ISwizzle Swizzle = TextureHelper.GetSwizzle(Image);
|
||||
|
||||
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
||||
|
||||
(int Width, int Height) = GetImageSizeInBlocks(Image);
|
||||
|
||||
int BytesPerPixel = Desc.BytesPerPixel;
|
||||
|
||||
int OutOffs = 0;
|
||||
|
||||
byte[] Data = new byte[Width * Height * BytesPerPixel];
|
||||
|
||||
for (int Y = 0; Y < Height; Y++)
|
||||
for (int X = 0; X < Width; X++)
|
||||
{
|
||||
long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y);
|
||||
|
||||
CpuMemory.ReadBytes(Position + Offset, Data, OutOffs, BytesPerPixel);
|
||||
|
||||
OutOffs += BytesPerPixel;
|
||||
}
|
||||
|
||||
return Data;
|
||||
}
|
||||
|
||||
public static void WriteTexture(NvGpuVmm Vmm, GalImage Image, long Position, byte[] Data)
|
||||
{
|
||||
ISwizzle Swizzle = TextureHelper.GetSwizzle(Image);
|
||||
|
||||
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
||||
|
||||
(int Width, int Height) = ImageUtils.GetImageSizeInBlocks(Image);
|
||||
|
||||
int BytesPerPixel = Desc.BytesPerPixel;
|
||||
|
||||
int InOffs = 0;
|
||||
|
||||
for (int Y = 0; Y < Height; Y++)
|
||||
for (int X = 0; X < Width; X++)
|
||||
{
|
||||
long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y);
|
||||
|
||||
Vmm.Memory.WriteBytes(Position + Offset, Data, InOffs, BytesPerPixel);
|
||||
|
||||
InOffs += BytesPerPixel;
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetSize(GalImage Image)
|
||||
{
|
||||
switch (Image.Format & GalImageFormat.FormatMask)
|
||||
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
||||
|
||||
int Width = DivRoundUp(Image.Width, Desc.BlockWidth);
|
||||
int Height = DivRoundUp(Image.Height, Desc.BlockHeight);
|
||||
|
||||
return Desc.BytesPerPixel * Width * Height;
|
||||
}
|
||||
|
||||
public static int GetPitch(GalImageFormat Format, int Width)
|
||||
{
|
||||
ImageDescriptor Desc = GetImageDescriptor(Format);
|
||||
|
||||
return Desc.BytesPerPixel * DivRoundUp(Width, Desc.BlockWidth);
|
||||
}
|
||||
|
||||
public static int GetBlockWidth(GalImageFormat Format)
|
||||
{
|
||||
return GetImageDescriptor(Format).BlockWidth;
|
||||
}
|
||||
|
||||
public static int GetBlockHeight(GalImageFormat Format)
|
||||
{
|
||||
return GetImageDescriptor(Format).BlockHeight;
|
||||
}
|
||||
|
||||
public static int GetAlignedWidth(GalImage Image)
|
||||
{
|
||||
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
||||
|
||||
int AlignMask;
|
||||
|
||||
if (Image.Layout == GalMemoryLayout.BlockLinear)
|
||||
{
|
||||
case GalImageFormat.R32G32B32A32:
|
||||
return Image.Width * Image.Height * 16;
|
||||
|
||||
case GalImageFormat.R16G16B16A16:
|
||||
case GalImageFormat.D32_S8:
|
||||
case GalImageFormat.R32G32:
|
||||
return Image.Width * Image.Height * 8;
|
||||
|
||||
case GalImageFormat.A8B8G8R8:
|
||||
case GalImageFormat.A8B8G8R8_SRGB:
|
||||
case GalImageFormat.A2B10G10R10:
|
||||
case GalImageFormat.R16G16:
|
||||
case GalImageFormat.R32:
|
||||
case GalImageFormat.D32:
|
||||
case GalImageFormat.B10G11R11:
|
||||
case GalImageFormat.D24_S8:
|
||||
return Image.Width * Image.Height * 4;
|
||||
|
||||
case GalImageFormat.B4G4R4A4:
|
||||
case GalImageFormat.A1R5G5B5:
|
||||
case GalImageFormat.B5G6R5:
|
||||
case GalImageFormat.R8G8:
|
||||
case GalImageFormat.G8R8:
|
||||
case GalImageFormat.R16:
|
||||
case GalImageFormat.D16:
|
||||
return Image.Width * Image.Height * 2;
|
||||
|
||||
case GalImageFormat.R8:
|
||||
return Image.Width * Image.Height;
|
||||
|
||||
case GalImageFormat.BC1_RGBA:
|
||||
case GalImageFormat.BC4:
|
||||
{
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 4, 4, 8);
|
||||
}
|
||||
|
||||
case GalImageFormat.BC6H_SF16:
|
||||
case GalImageFormat.BC6H_UF16:
|
||||
case GalImageFormat.BC7:
|
||||
case GalImageFormat.BC2:
|
||||
case GalImageFormat.BC3:
|
||||
case GalImageFormat.BC5:
|
||||
case GalImageFormat.ASTC_4x4:
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 4, 4, 16);
|
||||
|
||||
case GalImageFormat.ASTC_5x5:
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 5, 5, 16);
|
||||
|
||||
case GalImageFormat.ASTC_6x6:
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 6, 6, 16);
|
||||
|
||||
case GalImageFormat.ASTC_8x8:
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 8, 8, 16);
|
||||
|
||||
case GalImageFormat.ASTC_10x10:
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 10, 10, 16);
|
||||
|
||||
case GalImageFormat.ASTC_12x12:
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 12, 12, 16);
|
||||
|
||||
case GalImageFormat.ASTC_5x4:
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 5, 4, 16);
|
||||
|
||||
case GalImageFormat.ASTC_6x5:
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 6, 5, 16);
|
||||
|
||||
case GalImageFormat.ASTC_8x6:
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 8, 6, 16);
|
||||
|
||||
case GalImageFormat.ASTC_10x8:
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 10, 8, 16);
|
||||
|
||||
case GalImageFormat.ASTC_12x10:
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 12, 10, 16);
|
||||
|
||||
case GalImageFormat.ASTC_8x5:
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 8, 5, 16);
|
||||
|
||||
case GalImageFormat.ASTC_10x5:
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 10, 5, 16);
|
||||
|
||||
case GalImageFormat.ASTC_10x6:
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 10, 6, 16);
|
||||
AlignMask = Image.TileWidth * (64 / Desc.BytesPerPixel) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
AlignMask = (32 / Desc.BytesPerPixel) - 1;
|
||||
}
|
||||
|
||||
throw new NotImplementedException((Image.Format & GalImageFormat.FormatMask).ToString());
|
||||
return (Image.Width + AlignMask) & ~AlignMask;
|
||||
}
|
||||
|
||||
public static (int Width, int Height) GetImageSizeInBlocks(GalImage Image)
|
||||
{
|
||||
ImageDescriptor Desc = GetImageDescriptor(Image.Format);
|
||||
|
||||
return (DivRoundUp(Image.Width, Desc.BlockWidth),
|
||||
DivRoundUp(Image.Height, Desc.BlockHeight));
|
||||
}
|
||||
|
||||
public static int GetBytesPerPixel(GalImageFormat Format)
|
||||
{
|
||||
return GetImageDescriptor(Format).BytesPerPixel;
|
||||
}
|
||||
|
||||
private static int DivRoundUp(int LHS, int RHS)
|
||||
{
|
||||
return (LHS + (RHS - 1)) / RHS;
|
||||
}
|
||||
|
||||
public static bool HasColor(GalImageFormat Format)
|
||||
{
|
||||
return GetImageDescriptor(Format).HasColor;
|
||||
return (GetImageDescriptor(Format).Target & TargetBuffer.Color) != 0;
|
||||
}
|
||||
|
||||
public static bool HasDepth(GalImageFormat Format)
|
||||
{
|
||||
return GetImageDescriptor(Format).HasDepth;
|
||||
return (GetImageDescriptor(Format).Target & TargetBuffer.Depth) != 0;
|
||||
}
|
||||
|
||||
public static bool HasStencil(GalImageFormat Format)
|
||||
{
|
||||
return GetImageDescriptor(Format).HasStencil;
|
||||
return (GetImageDescriptor(Format).Target & TargetBuffer.Stencil) != 0;
|
||||
}
|
||||
|
||||
public static bool IsCompressed(GalImageFormat Format)
|
||||
{
|
||||
return GetImageDescriptor(Format).Compressed;
|
||||
ImageDescriptor Desc = GetImageDescriptor(Format);
|
||||
|
||||
return (Desc.BlockWidth | Desc.BlockHeight) != 1;
|
||||
}
|
||||
|
||||
private static ImageDescriptor GetImageDescriptor(GalImageFormat Format)
|
||||
|
@ -351,13 +385,5 @@ namespace Ryujinx.Graphics.Texture
|
|||
default: throw new NotImplementedException(((int)Type).ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private static int CompressedTextureSize(int TextureWidth, int TextureHeight, int BlockWidth, int BlockHeight, int Bpb)
|
||||
{
|
||||
int W = (TextureWidth + (BlockWidth - 1)) / BlockWidth;
|
||||
int H = (TextureHeight + (BlockHeight - 1)) / BlockHeight;
|
||||
|
||||
return W * H * Bpb;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue