Abstract texture and framebuffer targets as an image

This commit is contained in:
ReinUsesLisp 2018-08-10 01:12:39 -03:00
parent b723bd5e4a
commit 65c7842d6d
13 changed files with 484 additions and 448 deletions

View file

@ -1,25 +1,25 @@
namespace Ryujinx.Graphics.Gal
{
public struct GalTexture
public struct GalImage
{
public int Width;
public int Height;
public GalTextureFormat Format;
public GalImageFormat Format;
public GalTextureSource XSource;
public GalTextureSource YSource;
public GalTextureSource ZSource;
public GalTextureSource WSource;
public GalTexture(
public GalImage(
int Width,
int Height,
GalTextureFormat Format,
GalTextureSource XSource,
GalTextureSource YSource,
GalTextureSource ZSource,
GalTextureSource WSource)
GalImageFormat Format,
GalTextureSource XSource = GalTextureSource.Red,
GalTextureSource YSource = GalTextureSource.Green,
GalTextureSource ZSource = GalTextureSource.Blue,
GalTextureSource WSource = GalTextureSource.Alpha)
{
this.Width = Width;
this.Height = Height;

View file

@ -0,0 +1,44 @@
namespace Ryujinx.Graphics.Gal
{
public enum GalImageFormat
{
R32G32B32A32,
R16G16B16A16,
A8B8G8R8,
A2B10G10R10,
R32,
BC6H_SF16,
BC6H_UF16,
A1B5G5R5,
B5G6R5,
BC7U,
G8R8,
R16,
R8,
BF10GF11RF11,
BC1,
BC2,
BC3,
BC4,
BC5,
Z24S8,
ZF32,
ConvertedBegin,
Astc2D4x4,
Astc2D5x5,
Astc2D6x6,
Astc2D8x8,
Astc2D10x10,
Astc2D12x12,
Astc2D5x4,
Astc2D6x5,
Astc2D8x6,
Astc2D10x8,
Astc2D12x10,
Astc2D8x5,
Astc2D10x5,
Astc2D10x6,
ConvertedEnd
}
}

View file

@ -5,9 +5,9 @@ namespace Ryujinx.Graphics.Gal
void LockCache();
void UnlockCache();
void Create(long Key, byte[] Data, GalTexture Texture);
void Create(long Key, byte[] Data, GalImage Image);
bool TryGetCachedTexture(long Key, long DataSize, out GalTexture Texture);
bool TryGetCachedTexture(long Key, long DataSize, out GalImage Image);
void Bind(long Key, int Index);

View file

@ -0,0 +1,129 @@
using System;
namespace Ryujinx.Graphics.Gal
{
public static class ImageFormatConverter
{
public static GalImageFormat ConvertTexture(GalTextureFormat Format)
{
switch (Format)
{
case GalTextureFormat.R32G32B32A32: return GalImageFormat.R32G32B32A32;
case GalTextureFormat.R16G16B16A16: return GalImageFormat.R16G16B16A16;
case GalTextureFormat.A8B8G8R8: return GalImageFormat.A8B8G8R8;
case GalTextureFormat.A2B10G10R10: return GalImageFormat.A2B10G10R10;
case GalTextureFormat.R32: return GalImageFormat.R32;
case GalTextureFormat.BC6H_SF16: return GalImageFormat.BC6H_SF16;
case GalTextureFormat.BC6H_UF16: return GalImageFormat.BC6H_UF16;
case GalTextureFormat.A1B5G5R5: return GalImageFormat.A1B5G5R5;
case GalTextureFormat.B5G6R5: return GalImageFormat.B5G6R5;
case GalTextureFormat.BC7U: return GalImageFormat.BC7U;
case GalTextureFormat.G8R8: return GalImageFormat.G8R8;
case GalTextureFormat.R16: return GalImageFormat.R16;
case GalTextureFormat.R8: return GalImageFormat.R8;
case GalTextureFormat.BF10GF11RF11: return GalImageFormat.BF10GF11RF11;
case GalTextureFormat.BC1: return GalImageFormat.BC1;
case GalTextureFormat.BC2: return GalImageFormat.BC2;
case GalTextureFormat.BC3: return GalImageFormat.BC3;
case GalTextureFormat.BC4: return GalImageFormat.BC4;
case GalTextureFormat.BC5: return GalImageFormat.BC5;
case GalTextureFormat.Z24S8: return GalImageFormat.Z24S8;
case GalTextureFormat.ZF32: return GalImageFormat.ZF32;
case GalTextureFormat.Astc2D4x4: return GalImageFormat.Astc2D4x4;
case GalTextureFormat.Astc2D5x5: return GalImageFormat.Astc2D5x5;
case GalTextureFormat.Astc2D6x6: return GalImageFormat.Astc2D6x6;
case GalTextureFormat.Astc2D8x8: return GalImageFormat.Astc2D8x8;
case GalTextureFormat.Astc2D10x10: return GalImageFormat.Astc2D10x10;
case GalTextureFormat.Astc2D12x12: return GalImageFormat.Astc2D12x12;
case GalTextureFormat.Astc2D5x4: return GalImageFormat.Astc2D5x4;
case GalTextureFormat.Astc2D6x5: return GalImageFormat.Astc2D6x5;
case GalTextureFormat.Astc2D8x6: return GalImageFormat.Astc2D8x6;
case GalTextureFormat.Astc2D10x8: return GalImageFormat.Astc2D10x8;
case GalTextureFormat.Astc2D12x10: return GalImageFormat.Astc2D12x10;
case GalTextureFormat.Astc2D8x5: return GalImageFormat.Astc2D8x5;
case GalTextureFormat.Astc2D10x5: return GalImageFormat.Astc2D10x5;
case GalTextureFormat.Astc2D10x6: return GalImageFormat.Astc2D10x6;
}
throw new NotImplementedException(Format.ToString());
}
public static GalImageFormat ConvertFrameBuffer(GalFrameBufferFormat Format)
{
//Stubbed.
return GalImageFormat.A8B8G8R8;
}
public static GalImageFormat ConvertZeta(GalZetaFormat Format)
{
//Stubbed.
return GalImageFormat.Z24S8;
}
public static bool HasColor(GalImageFormat Format)
{
switch (Format)
{
case GalImageFormat.R32G32B32A32:
case GalImageFormat.R16G16B16A16:
case GalImageFormat.A8B8G8R8:
case GalImageFormat.A2B10G10R10:
case GalImageFormat.R32:
case GalImageFormat.BC6H_SF16:
case GalImageFormat.BC6H_UF16:
case GalImageFormat.A1B5G5R5:
case GalImageFormat.B5G6R5:
case GalImageFormat.BC7U:
case GalImageFormat.G8R8:
case GalImageFormat.R16:
case GalImageFormat.R8:
case GalImageFormat.BF10GF11RF11:
case GalImageFormat.BC1:
case GalImageFormat.BC2:
case GalImageFormat.BC3:
case GalImageFormat.BC4:
case GalImageFormat.BC5:
case GalImageFormat.Astc2D4x4:
case GalImageFormat.Astc2D5x5:
case GalImageFormat.Astc2D6x6:
case GalImageFormat.Astc2D8x8:
case GalImageFormat.Astc2D10x10:
case GalImageFormat.Astc2D12x12:
case GalImageFormat.Astc2D5x4:
case GalImageFormat.Astc2D6x5:
case GalImageFormat.Astc2D8x6:
case GalImageFormat.Astc2D10x8:
case GalImageFormat.Astc2D12x10:
case GalImageFormat.Astc2D8x5:
case GalImageFormat.Astc2D10x5:
case GalImageFormat.Astc2D10x6:
return true;
}
return false;
}
public static bool HasDepth(GalImageFormat Format)
{
switch (Format)
{
case GalImageFormat.Z24S8:
case GalImageFormat.ZF32:
return true;
}
return false;
}
public static bool HasStencil(GalImageFormat Format)
{
switch (Format)
{
case GalImageFormat.Z24S8:
return true;
}
return false;
}
}
}

View file

@ -1,48 +0,0 @@
using OpenTK.Graphics.OpenGL;
namespace Ryujinx.Graphics.Gal.OpenGL
{
public class OGLBlend : IGalBlend
{
public void Enable()
{
GL.Enable(EnableCap.Blend);
}
public void Disable()
{
GL.Disable(EnableCap.Blend);
}
public void Set(
GalBlendEquation Equation,
GalBlendFactor FuncSrc,
GalBlendFactor FuncDst)
{
GL.BlendEquation(OGLEnumConverter.GetBlendEquation(Equation));
GL.BlendFunc(
OGLEnumConverter.GetBlendFactor(FuncSrc),
OGLEnumConverter.GetBlendFactor(FuncDst));
}
public void SetSeparate(
GalBlendEquation EquationRgb,
GalBlendEquation EquationAlpha,
GalBlendFactor FuncSrcRgb,
GalBlendFactor FuncDstRgb,
GalBlendFactor FuncSrcAlpha,
GalBlendFactor FuncDstAlpha)
{
GL.BlendEquationSeparate(
OGLEnumConverter.GetBlendEquation(EquationRgb),
OGLEnumConverter.GetBlendEquation(EquationAlpha));
GL.BlendFuncSeparate(
(BlendingFactorSrc)OGLEnumConverter.GetBlendFactor(FuncSrcRgb),
(BlendingFactorDest)OGLEnumConverter.GetBlendFactor(FuncDstRgb),
(BlendingFactorSrc)OGLEnumConverter.GetBlendFactor(FuncSrcAlpha),
(BlendingFactorDest)OGLEnumConverter.GetBlendFactor(FuncDstAlpha));
}
}
}

View file

@ -125,109 +125,40 @@ namespace Ryujinx.Graphics.Gal.OpenGL
throw new ArgumentException(nameof(Type));
}
public static PixelInternalFormat GetFrameBufferInternalFormat(GalFrameBufferFormat Format)
public static (PixelInternalFormat, PixelFormat, PixelType) GetImageFormat(GalImageFormat Format)
{
switch (Format)
{
//Sometimes it's not set, use a safe format
case 0: return PixelInternalFormat.Rgba8;
case GalFrameBufferFormat.RGBA32Float: return PixelInternalFormat.Rgba32f;
case GalFrameBufferFormat.RGBA32Sint: return PixelInternalFormat.Rgba32i;
case GalFrameBufferFormat.RGBA32Uint: return PixelInternalFormat.Rgba32ui;
case GalFrameBufferFormat.RGBA16Unorm: return PixelInternalFormat.Rgba16;
case GalFrameBufferFormat.RGBA16Snorm: return PixelInternalFormat.Rgba16Snorm;
case GalFrameBufferFormat.RGBA16Sint: return PixelInternalFormat.Rgba16i;
case GalFrameBufferFormat.RGBA16Uint: return PixelInternalFormat.Rgba16ui;
case GalFrameBufferFormat.RGBA16Float: return PixelInternalFormat.Rgba16f;
case GalFrameBufferFormat.RG32Float: return PixelInternalFormat.Rg32f;
case GalFrameBufferFormat.RG32Sint: return PixelInternalFormat.Rg32i;
case GalFrameBufferFormat.RG32Uint: return PixelInternalFormat.Rg32ui;
case GalFrameBufferFormat.RGB10A2Unorm: return PixelInternalFormat.Rgb10A2;
case GalFrameBufferFormat.RGB10A2Uint: return PixelInternalFormat.Rgb10A2ui;
case GalFrameBufferFormat.RGBA8Unorm: return PixelInternalFormat.Rgba8;
case GalFrameBufferFormat.RGBA8Srgb: return PixelInternalFormat.Srgb8;
case GalFrameBufferFormat.RG16Snorm: return PixelInternalFormat.Rg16Snorm;
case GalFrameBufferFormat.R11G11B10Float: return PixelInternalFormat.R11fG11fB10f;
case GalFrameBufferFormat.R32Float: return PixelInternalFormat.R32f;
case GalFrameBufferFormat.R16Float: return PixelInternalFormat.R16f;
case GalFrameBufferFormat.R8Unorm: return PixelInternalFormat.R8;
case GalFrameBufferFormat.R8Snorm: return PixelInternalFormat.R8Snorm;
case GalFrameBufferFormat.R8Sint: return PixelInternalFormat.R8i;
case GalFrameBufferFormat.R8Uint: return PixelInternalFormat.R8ui;
case GalImageFormat.R32G32B32A32: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.Float);
case GalImageFormat.R16G16B16A16: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.HalfFloat);
case GalImageFormat.A8B8G8R8: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte);
case GalImageFormat.A2B10G10R10: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed);
case GalImageFormat.R32: return (PixelInternalFormat.Rgba8, PixelFormat.Red, PixelType.Float);
case GalImageFormat.A1B5G5R5: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedShort5551);
case GalImageFormat.B5G6R5: return (PixelInternalFormat.Rgba8, PixelFormat.Rgb, PixelType.UnsignedShort565);
case GalImageFormat.G8R8: return (PixelInternalFormat.Rgba8, PixelFormat.Rg, PixelType.UnsignedByte);
case GalImageFormat.R16: return (PixelInternalFormat.Rgba8, PixelFormat.Red, PixelType.HalfFloat);
case GalImageFormat.R8: return (PixelInternalFormat.Rgba8, PixelFormat.Red, PixelType.UnsignedByte);
case GalImageFormat.ZF32: return (PixelInternalFormat.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float);
case GalImageFormat.BF10GF11RF11: return (PixelInternalFormat.Rgba8, PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev);
case GalImageFormat.Z24S8: return (PixelInternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248);
}
throw new NotImplementedException(Format.ToString());
}
public static (PixelFormat Format, PixelType Type) GetFrameBufferFormat(GalFrameBufferFormat Format)
public static InternalFormat GetCompressedImageFormat(GalImageFormat Format)
{
switch (Format)
{
case 0: return (PixelFormat.Rgba, PixelType.UnsignedByte);
case GalFrameBufferFormat.RGBA32Float: return (PixelFormat.Rgba, PixelType.Float);
case GalFrameBufferFormat.RGBA32Sint: return (PixelFormat.Rgba, PixelType.Int);
case GalFrameBufferFormat.RGBA32Uint: return (PixelFormat.Rgba, PixelType.UnsignedInt);
case GalFrameBufferFormat.RGBA16Unorm: return (PixelFormat.Rgba, PixelType.UnsignedShort);
case GalFrameBufferFormat.RGBA16Snorm: return (PixelFormat.Rgba, PixelType.Short);
case GalFrameBufferFormat.RGBA16Sint: return (PixelFormat.Rgba, PixelType.Short);
case GalFrameBufferFormat.RGBA16Uint: return (PixelFormat.Rgba, PixelType.UnsignedShort);
case GalFrameBufferFormat.RGBA16Float: return (PixelFormat.Rgba, PixelType.HalfFloat);
case GalFrameBufferFormat.RG32Float: return (PixelFormat.Rg, PixelType.Float);
case GalFrameBufferFormat.RG32Sint: return (PixelFormat.Rg, PixelType.Int);
case GalFrameBufferFormat.RG32Uint: return (PixelFormat.Rg, PixelType.UnsignedInt);
case GalFrameBufferFormat.RGB10A2Unorm: return (PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed);
case GalFrameBufferFormat.RGB10A2Uint: return (PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed);
case GalFrameBufferFormat.RGBA8Unorm: return (PixelFormat.Rgba, PixelType.UnsignedByte);
case GalFrameBufferFormat.RGBA8Srgb: return (PixelFormat.Rgba, PixelType.UnsignedByte);
case GalFrameBufferFormat.RG16Snorm: return (PixelFormat.Rg, PixelType.Short);
case GalFrameBufferFormat.R11G11B10Float: return (PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev);
case GalFrameBufferFormat.R32Float: return (PixelFormat.Red, PixelType.Float);
case GalFrameBufferFormat.R16Float: return (PixelFormat.Red, PixelType.HalfFloat);
case GalFrameBufferFormat.R8Unorm: return (PixelFormat.Red, PixelType.UnsignedByte);
case GalFrameBufferFormat.R8Snorm: return (PixelFormat.Red, PixelType.Byte);
case GalFrameBufferFormat.R8Sint: return (PixelFormat.Red, PixelType.Byte);
case GalFrameBufferFormat.R8Uint: return (PixelFormat.Red, PixelType.UnsignedByte);
}
throw new NotImplementedException(Format.ToString());
}
public static (PixelFormat, PixelType) GetTextureFormat(GalTextureFormat Format)
{
switch (Format)
{
case GalTextureFormat.R32G32B32A32: return (PixelFormat.Rgba, PixelType.Float);
case GalTextureFormat.R16G16B16A16: return (PixelFormat.Rgba, PixelType.HalfFloat);
case GalTextureFormat.A8B8G8R8: return (PixelFormat.Rgba, PixelType.UnsignedByte);
case GalTextureFormat.A2B10G10R10: return (PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed);
case GalTextureFormat.R32: return (PixelFormat.Red, PixelType.Float);
case GalTextureFormat.A1B5G5R5: return (PixelFormat.Rgba, PixelType.UnsignedShort5551);
case GalTextureFormat.B5G6R5: return (PixelFormat.Rgb, PixelType.UnsignedShort565);
case GalTextureFormat.G8R8: return (PixelFormat.Rg, PixelType.UnsignedByte);
case GalTextureFormat.R16: return (PixelFormat.Red, PixelType.HalfFloat);
case GalTextureFormat.R8: return (PixelFormat.Red, PixelType.UnsignedByte);
case GalTextureFormat.ZF32: return (PixelFormat.DepthComponent, PixelType.Float);
case GalTextureFormat.BF10GF11RF11: return (PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev);
case GalTextureFormat.Z24S8: return (PixelFormat.DepthStencil, PixelType.UnsignedInt248);
}
throw new NotImplementedException(Format.ToString());
}
public static InternalFormat GetCompressedTextureFormat(GalTextureFormat Format)
{
switch (Format)
{
case GalTextureFormat.BC6H_UF16: return InternalFormat.CompressedRgbBptcUnsignedFloat;
case GalTextureFormat.BC6H_SF16: return InternalFormat.CompressedRgbBptcSignedFloat;
case GalTextureFormat.BC7U: return InternalFormat.CompressedRgbaBptcUnorm;
case GalTextureFormat.BC1: return InternalFormat.CompressedRgbaS3tcDxt1Ext;
case GalTextureFormat.BC2: return InternalFormat.CompressedRgbaS3tcDxt3Ext;
case GalTextureFormat.BC3: return InternalFormat.CompressedRgbaS3tcDxt5Ext;
case GalTextureFormat.BC4: return InternalFormat.CompressedRedRgtc1;
case GalTextureFormat.BC5: return InternalFormat.CompressedRgRgtc2;
case GalImageFormat.BC6H_UF16: return InternalFormat.CompressedRgbBptcUnsignedFloat;
case GalImageFormat.BC6H_SF16: return InternalFormat.CompressedRgbBptcSignedFloat;
case GalImageFormat.BC7U: return InternalFormat.CompressedRgbaBptcUnorm;
case GalImageFormat.BC1: return InternalFormat.CompressedRgbaS3tcDxt1Ext;
case GalImageFormat.BC2: return InternalFormat.CompressedRgbaS3tcDxt3Ext;
case GalImageFormat.BC3: return InternalFormat.CompressedRgbaS3tcDxt5Ext;
case GalImageFormat.BC4: return InternalFormat.CompressedRedRgtc1;
case GalImageFormat.BC5: return InternalFormat.CompressedRgRgtc2;
}
throw new NotImplementedException(Format.ToString());

View file

@ -23,126 +23,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
}
}
private class Texture
{
public int Width { get; private set; }
public int Height { get; private set; }
public PixelInternalFormat InternalFormat { get; private set; }
public PixelFormat Format { get; private set; }
public PixelType Type { get; private set; }
public int Handle { get; private set; }
private bool Initialized;
public Texture()
{
Handle = GL.GenTexture();
}
public void EnsureSetup(
int Width,
int Height,
PixelInternalFormat InternalFormat,
PixelFormat Format,
PixelType Type)
{
if (!Initialized ||
this.Width != Width ||
this.Height != Height ||
this.InternalFormat != InternalFormat)
{
int CopyBuffer = 0;
bool ChangingFormat = Initialized && this.InternalFormat != InternalFormat;
GL.BindTexture(TextureTarget.Texture2D, Handle);
if (ChangingFormat)
{
CopyBuffer = GL.GenBuffer();
GL.BindBuffer(BufferTarget.PixelPackBuffer, CopyBuffer);
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyBuffer);
int MaxWidth = Math.Max(Width, this.Width);
int MaxHeight = Math.Max(Height, this.Height);
//TODO: Dehardcode size number
GL.BufferData(BufferTarget.PixelPackBuffer, MaxWidth * MaxHeight * MaxBpp, IntPtr.Zero, BufferUsageHint.StaticCopy);
GL.GetTexImage(TextureTarget.Texture2D, 0, this.Format, this.Type, IntPtr.Zero);
GL.DeleteTexture(Handle);
Handle = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, Handle);
}
const int MinFilter = (int)TextureMinFilter.Linear;
const int MagFilter = (int)TextureMagFilter.Linear;
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, MinFilter);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, MagFilter);
const int Level = 0;
const int Border = 0;
GL.TexImage2D(
TextureTarget.Texture2D,
Level,
InternalFormat,
Width,
Height,
Border,
Format,
Type,
IntPtr.Zero);
if (ChangingFormat)
{
GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);
GL.DeleteBuffer(CopyBuffer);
}
this.Width = Width;
this.Height = Height;
this.InternalFormat = InternalFormat;
this.Format = Format;
this.Type = Type;
Initialized = true;
}
}
public void EnsureSetup(int Width, int Height, GalFrameBufferFormat Format)
{
//TODO: Convert color format
EnsureSetup(
Width,
Height,
PixelInternalFormat.Rgba8,
PixelFormat.Rgba,
PixelType.UnsignedByte);
}
public void EnsureSetup(int Width, int Height, GalZetaFormat Format)
{
//TODO: Convert zeta format
EnsureSetup(
Width,
Height,
PixelInternalFormat.Depth24Stencil8,
PixelFormat.DepthStencil,
PixelType.UnsignedInt248);
}
}
private static readonly DrawBuffersEnum[] DrawBuffers = new DrawBuffersEnum[]
{
@ -159,16 +40,13 @@ namespace Ryujinx.Graphics.Gal.OpenGL
private const int NativeWidth = 1280;
private const int NativeHeight = 720;
//TODO: Use a variable value here
private const int MaxBpp = 16;
private const GalImageFormat RawFormat = GalImageFormat.A8B8G8R8;
private const GalTextureFormat RawFormat = GalTextureFormat.A8B8G8R8;
private Dictionary<long, TCE> ColorTextures;
private Dictionary<long, TCE> ZetaTextures;
private Dictionary<long, Texture> ColorTextures;
private Dictionary<long, Texture> ZetaTextures;
private Texture RawTex;
private Texture ReadTex;
private TCE RawTex;
private TCE ReadTex;
private Rect Viewport;
private Rect Window;
@ -188,26 +66,28 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public OGLFrameBuffer()
{
ColorTextures = new Dictionary<long, Texture>();
ColorTextures = new Dictionary<long, TCE>();
ZetaTextures = new Dictionary<long, Texture>();
ZetaTextures = new Dictionary<long, TCE>();
}
public void CreateColor(long Key, int Width, int Height, GalFrameBufferFormat Format)
{
if (!ColorTextures.TryGetValue(Key, out Texture Tex))
if (!ColorTextures.TryGetValue(Key, out TCE Tex))
{
Tex = new Texture();
Tex = new TCE();
ColorTextures.Add(Key, Tex);
}
Tex.EnsureSetup(Width, Height, Format);
GalImageFormat ImageFormat = ImageFormatConverter.ConvertFrameBuffer(Format);
Tex.EnsureSetup(new GalImage(Width, Height, ImageFormat));
}
public void BindColor(long Key, int Attachment)
{
if (ColorTextures.TryGetValue(Key, out Texture Tex))
if (ColorTextures.TryGetValue(Key, out TCE Tex))
{
EnsureFrameBuffer();
@ -236,19 +116,21 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public void CreateZeta(long Key, int Width, int Height, GalZetaFormat Format)
{
if (!ZetaTextures.TryGetValue(Key, out Texture Tex))
if (!ZetaTextures.TryGetValue(Key, out TCE Tex))
{
Tex = new Texture();
Tex = new TCE();
ZetaTextures.Add(Key, Tex);
}
Tex.EnsureSetup(Width, Height, Format);
GalImageFormat ImageFormat = ImageFormatConverter.ConvertZeta(Format);
Tex.EnsureSetup(new GalImage(Width, Height, ImageFormat));
}
public void BindZeta(long Key)
{
if (ZetaTextures.TryGetValue(Key, out Texture Tex))
if (ZetaTextures.TryGetValue(Key, out TCE Tex))
{
EnsureFrameBuffer();
@ -277,7 +159,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public void BindTexture(long Key, int Index)
{
Texture Tex;
TCE Tex;
if (ColorTextures.TryGetValue(Key, out Tex) ||
ZetaTextures.TryGetValue(Key, out Tex))
@ -290,7 +172,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public void Set(long Key)
{
if (ColorTextures.TryGetValue(Key, out Texture Tex))
if (ColorTextures.TryGetValue(Key, out TCE Tex))
{
ReadTex = Tex;
}
@ -300,16 +182,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
if (RawTex == null)
{
RawTex = new Texture();
RawTex = new TCE();
}
RawTex.EnsureSetup(Width, Height, PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte);
RawTex.EnsureSetup(new GalImage(Width, Height, RawFormat));
GL.BindTexture(TextureTarget.Texture2D, RawTex.Handle);
(PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(RawFormat);
GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, Width, Height, Format, Type, Data);
GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, Width, Height, RawTex.PixelFormat, RawTex.PixelType, Data);
ReadTex = RawTex;
}
@ -429,8 +309,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
bool Found = false;
if (ColorTextures.TryGetValue(SrcKey, out Texture SrcTex) &&
ColorTextures.TryGetValue(DstKey, out Texture DstTex))
if (ColorTextures.TryGetValue(SrcKey, out TCE SrcTex) &&
ColorTextures.TryGetValue(DstKey, out TCE DstTex))
{
CopyTextures(
SrcX0, SrcY0, SrcX1, SrcY1,
@ -444,8 +324,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Found = true;
}
if (ZetaTextures.TryGetValue(SrcKey, out Texture ZetaSrcTex) &&
ZetaTextures.TryGetValue(DstKey, out Texture ZetaDstTex))
if (ZetaTextures.TryGetValue(SrcKey, out TCE ZetaSrcTex) &&
ZetaTextures.TryGetValue(DstKey, out TCE ZetaDstTex))
{
CopyTextures(
SrcX0, SrcY0, SrcX1, SrcY1,
@ -467,21 +347,20 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public void GetBufferData(long Key, Action<byte[]> Callback)
{
Texture Tex;
TCE Tex;
if (ColorTextures.TryGetValue(Key, out Tex) ||
ZetaTextures.TryGetValue(Key, out Tex))
{
//Note: Change this value when framebuffer sizes are dehardcoded
byte[] Data = new byte[Tex.Width * Tex.Height * MaxBpp];
byte[] Data = new byte[Tex.Width * Tex.Height * TCE.MaxBpp];
GL.BindTexture(TextureTarget.Texture2D, Tex.Handle);
GL.GetTexImage(
TextureTarget.Texture2D,
0,
Tex.Format,
Tex.Type,
Tex.PixelFormat,
Tex.PixelType,
Data);
Callback(Data);
@ -494,7 +373,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
int Height,
byte[] Buffer)
{
Texture Tex;
TCE Tex;
if (ColorTextures.TryGetValue(Key, out Tex) ||
ZetaTextures.TryGetValue(Key, out Tex))
@ -511,8 +390,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Width,
Height,
Border,
Tex.Format,
Tex.Type,
Tex.PixelFormat,
Tex.PixelType,
Buffer);
}
}

View file

@ -6,19 +6,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{
public class OGLTexture : IGalTexture
{
private class TCE
{
public int Handle;
public GalTexture Texture;
public TCE(int Handle, GalTexture Texture)
{
this.Handle = Handle;
this.Texture = Texture;
}
}
private OGLCachedResource<TCE> TextureCache;
public OGLTexture()
@ -41,68 +28,66 @@ namespace Ryujinx.Graphics.Gal.OpenGL
GL.DeleteTexture(CachedTexture.Handle);
}
public void Create(long Key, byte[] Data, GalTexture Texture)
public void Create(long Key, byte[] Data, GalImage Image)
{
int Handle = GL.GenTexture();
TextureCache.AddOrUpdate(Key, new TCE(Handle, Texture), (uint)Data.Length);
TextureCache.AddOrUpdate(Key, new TCE(Handle, Image), (uint)Data.Length);
GL.BindTexture(TextureTarget.Texture2D, Handle);
const int Level = 0; //TODO: Support mipmap textures.
const int Border = 0;
if (IsCompressedTextureFormat(Texture.Format))
if (IsCompressedTextureFormat(Image.Format))
{
InternalFormat InternalFmt = OGLEnumConverter.GetCompressedTextureFormat(Texture.Format);
InternalFormat InternalFmt = OGLEnumConverter.GetCompressedImageFormat(Image.Format);
GL.CompressedTexImage2D(
TextureTarget.Texture2D,
Level,
InternalFmt,
Texture.Width,
Texture.Height,
Image.Width,
Image.Height,
Border,
Data.Length,
Data);
}
else
{
if (Texture.Format >= GalTextureFormat.Astc2D4x4)
if (Image.Format > GalImageFormat.ConvertedBegin && Image.Format < GalImageFormat.ConvertedEnd)
{
int TextureBlockWidth = GetAstcBlockWidth(Texture.Format);
int TextureBlockHeight = GetAstcBlockHeight(Texture.Format);
int TextureBlockWidth = GetAstcBlockWidth(Image.Format);
int TextureBlockHeight = GetAstcBlockHeight(Image.Format);
Data = ASTCDecoder.DecodeToRGBA8888(
Data,
TextureBlockWidth,
TextureBlockHeight, 1,
Texture.Width,
Texture.Height, 1);
Image.Width,
Image.Height, 1);
Texture.Format = GalTextureFormat.A8B8G8R8;
Image.Format = GalImageFormat.A8B8G8R8;
}
const PixelInternalFormat InternalFmt = PixelInternalFormat.Rgba;
(PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(Texture.Format);
(PixelInternalFormat InternalFormat, PixelFormat Format, PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format);
GL.TexImage2D(
TextureTarget.Texture2D,
Level,
InternalFmt,
Texture.Width,
Texture.Height,
InternalFormat,
Image.Width,
Image.Height,
Border,
Format,
Type,
Data);
}
int SwizzleR = (int)OGLEnumConverter.GetTextureSwizzle(Texture.XSource);
int SwizzleG = (int)OGLEnumConverter.GetTextureSwizzle(Texture.YSource);
int SwizzleB = (int)OGLEnumConverter.GetTextureSwizzle(Texture.ZSource);
int SwizzleA = (int)OGLEnumConverter.GetTextureSwizzle(Texture.WSource);
int SwizzleR = (int)OGLEnumConverter.GetTextureSwizzle(Image.XSource);
int SwizzleG = (int)OGLEnumConverter.GetTextureSwizzle(Image.YSource);
int SwizzleB = (int)OGLEnumConverter.GetTextureSwizzle(Image.ZSource);
int SwizzleA = (int)OGLEnumConverter.GetTextureSwizzle(Image.WSource);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleR, SwizzleR);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleG, SwizzleG);
@ -110,65 +95,65 @@ namespace Ryujinx.Graphics.Gal.OpenGL
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleA, SwizzleA);
}
private static int GetAstcBlockWidth(GalTextureFormat Format)
private static int GetAstcBlockWidth(GalImageFormat Format)
{
switch (Format)
{
case GalTextureFormat.Astc2D4x4: return 4;
case GalTextureFormat.Astc2D5x5: return 5;
case GalTextureFormat.Astc2D6x6: return 6;
case GalTextureFormat.Astc2D8x8: return 8;
case GalTextureFormat.Astc2D10x10: return 10;
case GalTextureFormat.Astc2D12x12: return 12;
case GalTextureFormat.Astc2D5x4: return 5;
case GalTextureFormat.Astc2D6x5: return 6;
case GalTextureFormat.Astc2D8x6: return 8;
case GalTextureFormat.Astc2D10x8: return 10;
case GalTextureFormat.Astc2D12x10: return 12;
case GalTextureFormat.Astc2D8x5: return 8;
case GalTextureFormat.Astc2D10x5: return 10;
case GalTextureFormat.Astc2D10x6: return 10;
case GalImageFormat.Astc2D4x4: return 4;
case GalImageFormat.Astc2D5x5: return 5;
case GalImageFormat.Astc2D6x6: return 6;
case GalImageFormat.Astc2D8x8: return 8;
case GalImageFormat.Astc2D10x10: return 10;
case GalImageFormat.Astc2D12x12: return 12;
case GalImageFormat.Astc2D5x4: return 5;
case GalImageFormat.Astc2D6x5: return 6;
case GalImageFormat.Astc2D8x6: return 8;
case GalImageFormat.Astc2D10x8: return 10;
case GalImageFormat.Astc2D12x10: return 12;
case GalImageFormat.Astc2D8x5: return 8;
case GalImageFormat.Astc2D10x5: return 10;
case GalImageFormat.Astc2D10x6: return 10;
}
throw new ArgumentException(nameof(Format));
}
private static int GetAstcBlockHeight(GalTextureFormat Format)
private static int GetAstcBlockHeight(GalImageFormat Format)
{
switch (Format)
{
case GalTextureFormat.Astc2D4x4: return 4;
case GalTextureFormat.Astc2D5x5: return 5;
case GalTextureFormat.Astc2D6x6: return 6;
case GalTextureFormat.Astc2D8x8: return 8;
case GalTextureFormat.Astc2D10x10: return 10;
case GalTextureFormat.Astc2D12x12: return 12;
case GalTextureFormat.Astc2D5x4: return 4;
case GalTextureFormat.Astc2D6x5: return 5;
case GalTextureFormat.Astc2D8x6: return 6;
case GalTextureFormat.Astc2D10x8: return 8;
case GalTextureFormat.Astc2D12x10: return 10;
case GalTextureFormat.Astc2D8x5: return 5;
case GalTextureFormat.Astc2D10x5: return 5;
case GalTextureFormat.Astc2D10x6: return 6;
case GalImageFormat.Astc2D4x4: return 4;
case GalImageFormat.Astc2D5x5: return 5;
case GalImageFormat.Astc2D6x6: return 6;
case GalImageFormat.Astc2D8x8: return 8;
case GalImageFormat.Astc2D10x10: return 10;
case GalImageFormat.Astc2D12x12: return 12;
case GalImageFormat.Astc2D5x4: return 4;
case GalImageFormat.Astc2D6x5: return 5;
case GalImageFormat.Astc2D8x6: return 6;
case GalImageFormat.Astc2D10x8: return 8;
case GalImageFormat.Astc2D12x10: return 10;
case GalImageFormat.Astc2D8x5: return 5;
case GalImageFormat.Astc2D10x5: return 5;
case GalImageFormat.Astc2D10x6: return 6;
}
throw new ArgumentException(nameof(Format));
}
public bool TryGetCachedTexture(long Key, long DataSize, out GalTexture Texture)
public bool TryGetCachedTexture(long Key, long DataSize, out GalImage Image)
{
if (TextureCache.TryGetSize(Key, out long Size) && Size == DataSize)
{
if (TextureCache.TryGetValue(Key, out TCE CachedTexture))
{
Texture = CachedTexture.Texture;
Image = CachedTexture.Image;
return true;
}
}
Texture = default(GalTexture);
Image = default(GalImage);
return false;
}
@ -208,18 +193,18 @@ namespace Ryujinx.Graphics.Gal.OpenGL
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBorderColor, Color);
}
private static bool IsCompressedTextureFormat(GalTextureFormat Format)
private static bool IsCompressedTextureFormat(GalImageFormat Format)
{
switch (Format)
{
case GalTextureFormat.BC6H_UF16:
case GalTextureFormat.BC6H_SF16:
case GalTextureFormat.BC7U:
case GalTextureFormat.BC1:
case GalTextureFormat.BC2:
case GalTextureFormat.BC3:
case GalTextureFormat.BC4:
case GalTextureFormat.BC5:
case GalImageFormat.BC6H_UF16:
case GalImageFormat.BC6H_SF16:
case GalImageFormat.BC7U:
case GalImageFormat.BC1:
case GalImageFormat.BC2:
case GalImageFormat.BC3:
case GalImageFormat.BC4:
case GalImageFormat.BC5:
return true;
}

View file

@ -0,0 +1,112 @@
using OpenTK.Graphics.OpenGL;
using System;
namespace Ryujinx.Graphics.Gal.OpenGL
{
class TCE
{
//TODO: Use a variable value here
public const int MaxBpp = 16;
public GalImage Image { get; private set; }
public int Width { get => Image.Width; }
public int Height { get => Image.Height; }
public GalImageFormat Format { get => Image.Format; }
public PixelInternalFormat InternalFormat { get; private set; }
public PixelFormat PixelFormat { get; private set; }
public PixelType PixelType { get; private set; }
public int Handle { get; private set; }
private bool Initialized;
public TCE()
{
Handle = GL.GenTexture();
}
public TCE(int Handle, GalImage Image)
{
this.Handle = Handle;
this.Image = Image;
}
public void EnsureSetup(GalImage Image)
{
if (this.Width != Image.Width ||
this.Height != Image.Height ||
this.Format != Image.Format ||
!Initialized)
{
(PixelInternalFormat InternalFormat, PixelFormat PixelFormat, PixelType PixelType) =
OGLEnumConverter.GetImageFormat(Image.Format);
int CopyBuffer = 0;
bool ChangingFormat = Initialized && this.InternalFormat != InternalFormat;
GL.BindTexture(TextureTarget.Texture2D, Handle);
if (ChangingFormat)
{
CopyBuffer = GL.GenBuffer();
GL.BindBuffer(BufferTarget.PixelPackBuffer, CopyBuffer);
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyBuffer);
int MaxWidth = Math.Max(Image.Width, this.Width);
int MaxHeight = Math.Max(Image.Height, this.Height);
GL.BufferData(BufferTarget.PixelPackBuffer, MaxWidth * MaxHeight * MaxBpp, IntPtr.Zero, BufferUsageHint.StaticCopy);
GL.GetTexImage(TextureTarget.Texture2D, 0, this.PixelFormat, this.PixelType, IntPtr.Zero);
GL.DeleteTexture(Handle);
Handle = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, Handle);
}
const int MinFilter = (int)TextureMinFilter.Linear;
const int MagFilter = (int)TextureMagFilter.Linear;
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, MinFilter);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, MagFilter);
const int Level = 0;
const int Border = 0;
GL.TexImage2D(
TextureTarget.Texture2D,
Level,
InternalFormat,
Image.Width,
Image.Height,
Border,
PixelFormat,
PixelType,
IntPtr.Zero);
if (ChangingFormat)
{
GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);
GL.DeleteBuffer(CopyBuffer);
}
this.Image = Image;
this.InternalFormat = InternalFormat;
this.PixelFormat = PixelFormat;
this.PixelType = PixelType;
Initialized = true;
}
}
}
}

View file

@ -13,6 +13,10 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<None Include="Gal\OpenGL\TCE.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="OpenTK.NetStandard" Version="1.0.4" />
</ItemGroup>

View file

@ -166,7 +166,7 @@ namespace Ryujinx.HLE.Gpu.Engines
int Format = ReadRegister(NvGpuEngine3dReg.FrameBufferNFormat + FbIndex * 0x10);
if (VA == 0 || Format == 0)
if (VA == 0/* || Format == 0*/)
{
Gpu.Renderer.FrameBuffer.UnbindColor(FbIndex);
@ -479,13 +479,13 @@ namespace Ryujinx.HLE.Gpu.Engines
}
else
{
GalTexture NewTexture = TextureFactory.MakeTexture(Vmm, TicPosition);
GalImage NewTexture = TextureFactory.MakeTexture(Vmm, TicPosition);
long Size = (uint)TextureHelper.GetTextureSize(NewTexture);
bool HasCachedTexture = false;
if (Gpu.Renderer.Texture.TryGetCachedTexture(Key, Size, out GalTexture Texture))
if (Gpu.Renderer.Texture.TryGetCachedTexture(Key, Size, out GalImage Texture))
{
if (NewTexture.Equals(Texture) && !QueryKeyUpload(Vmm, Key, Size, NvGpuBufferType.Texture))
{

View file

@ -6,11 +6,11 @@ namespace Ryujinx.HLE.Gpu.Texture
{
static class TextureFactory
{
public static GalTexture MakeTexture(NvGpuVmm Vmm, long TicPosition)
public static GalImage MakeTexture(NvGpuVmm Vmm, long TicPosition)
{
int[] Tic = ReadWords(Vmm, TicPosition, 8);
GalTextureFormat Format = (GalTextureFormat)(Tic[0] & 0x7f);
GalImageFormat Format = ImageFormatConverter.ConvertTexture((GalTextureFormat)(Tic[0] & 0x7f));
GalTextureSource XSource = (GalTextureSource)((Tic[0] >> 19) & 7);
GalTextureSource YSource = (GalTextureSource)((Tic[0] >> 22) & 7);
@ -20,7 +20,7 @@ namespace Ryujinx.HLE.Gpu.Texture
int Width = (Tic[4] & 0xffff) + 1;
int Height = (Tic[5] & 0xffff) + 1;
return new GalTexture(
return new GalImage(
Width,
Height,
Format,

View file

@ -30,117 +30,117 @@ namespace Ryujinx.HLE.Gpu.Texture
throw new NotImplementedException(Texture.Swizzle.ToString());
}
public static int GetTextureSize(GalTexture Texture)
public static int GetTextureSize(GalImage Image)
{
switch (Texture.Format)
switch (Image.Format)
{
case GalTextureFormat.R32G32B32A32:
return Texture.Width * Texture.Height * 16;
case GalImageFormat.R32G32B32A32:
return Image.Width * Image.Height * 16;
case GalTextureFormat.R16G16B16A16:
return Texture.Width * Texture.Height * 8;
case GalImageFormat.R16G16B16A16:
return Image.Width * Image.Height * 8;
case GalTextureFormat.A8B8G8R8:
case GalTextureFormat.A2B10G10R10:
case GalTextureFormat.R32:
case GalTextureFormat.ZF32:
case GalTextureFormat.BF10GF11RF11:
case GalTextureFormat.Z24S8:
return Texture.Width * Texture.Height * 4;
case GalImageFormat.A8B8G8R8:
case GalImageFormat.A2B10G10R10:
case GalImageFormat.R32:
case GalImageFormat.ZF32:
case GalImageFormat.BF10GF11RF11:
case GalImageFormat.Z24S8:
return Image.Width * Image.Height * 4;
case GalTextureFormat.A1B5G5R5:
case GalTextureFormat.B5G6R5:
case GalTextureFormat.G8R8:
case GalTextureFormat.R16:
return Texture.Width * Texture.Height * 2;
case GalImageFormat.A1B5G5R5:
case GalImageFormat.B5G6R5:
case GalImageFormat.G8R8:
case GalImageFormat.R16:
return Image.Width * Image.Height * 2;
case GalTextureFormat.R8:
return Texture.Width * Texture.Height;
case GalImageFormat.R8:
return Image.Width * Image.Height;
case GalTextureFormat.BC1:
case GalTextureFormat.BC4:
case GalImageFormat.BC1:
case GalImageFormat.BC4:
{
return CompressedTextureSize(Texture.Width, Texture.Height, 4, 4, 8);
return CompressedTextureSize(Image.Width, Image.Height, 4, 4, 8);
}
case GalTextureFormat.BC6H_SF16:
case GalTextureFormat.BC6H_UF16:
case GalTextureFormat.BC7U:
case GalTextureFormat.BC2:
case GalTextureFormat.BC3:
case GalTextureFormat.BC5:
case GalTextureFormat.Astc2D4x4:
case GalImageFormat.BC6H_SF16:
case GalImageFormat.BC6H_UF16:
case GalImageFormat.BC7U:
case GalImageFormat.BC2:
case GalImageFormat.BC3:
case GalImageFormat.BC5:
case GalImageFormat.Astc2D4x4:
{
return CompressedTextureSize(Texture.Width, Texture.Height, 4, 4, 16);
return CompressedTextureSize(Image.Width, Image.Height, 4, 4, 16);
}
case GalTextureFormat.Astc2D5x5:
case GalImageFormat.Astc2D5x5:
{
return CompressedTextureSize(Texture.Width, Texture.Height, 5, 5, 16);
return CompressedTextureSize(Image.Width, Image.Height, 5, 5, 16);
}
case GalTextureFormat.Astc2D6x6:
case GalImageFormat.Astc2D6x6:
{
return CompressedTextureSize(Texture.Width, Texture.Height, 6, 6, 16);
return CompressedTextureSize(Image.Width, Image.Height, 6, 6, 16);
}
case GalTextureFormat.Astc2D8x8:
case GalImageFormat.Astc2D8x8:
{
return CompressedTextureSize(Texture.Width, Texture.Height, 8, 8, 16);
return CompressedTextureSize(Image.Width, Image.Height, 8, 8, 16);
}
case GalTextureFormat.Astc2D10x10:
case GalImageFormat.Astc2D10x10:
{
return CompressedTextureSize(Texture.Width, Texture.Height, 10, 10, 16);
return CompressedTextureSize(Image.Width, Image.Height, 10, 10, 16);
}
case GalTextureFormat.Astc2D12x12:
case GalImageFormat.Astc2D12x12:
{
return CompressedTextureSize(Texture.Width, Texture.Height, 12, 12, 16);
return CompressedTextureSize(Image.Width, Image.Height, 12, 12, 16);
}
case GalTextureFormat.Astc2D5x4:
case GalImageFormat.Astc2D5x4:
{
return CompressedTextureSize(Texture.Width, Texture.Height, 5, 4, 16);
return CompressedTextureSize(Image.Width, Image.Height, 5, 4, 16);
}
case GalTextureFormat.Astc2D6x5:
case GalImageFormat.Astc2D6x5:
{
return CompressedTextureSize(Texture.Width, Texture.Height, 6, 5, 16);
return CompressedTextureSize(Image.Width, Image.Height, 6, 5, 16);
}
case GalTextureFormat.Astc2D8x6:
case GalImageFormat.Astc2D8x6:
{
return CompressedTextureSize(Texture.Width, Texture.Height, 8, 6, 16);
return CompressedTextureSize(Image.Width, Image.Height, 8, 6, 16);
}
case GalTextureFormat.Astc2D10x8:
case GalImageFormat.Astc2D10x8:
{
return CompressedTextureSize(Texture.Width, Texture.Height, 10, 8, 16);
return CompressedTextureSize(Image.Width, Image.Height, 10, 8, 16);
}
case GalTextureFormat.Astc2D12x10:
case GalImageFormat.Astc2D12x10:
{
return CompressedTextureSize(Texture.Width, Texture.Height, 12, 10, 16);
return CompressedTextureSize(Image.Width, Image.Height, 12, 10, 16);
}
case GalTextureFormat.Astc2D8x5:
case GalImageFormat.Astc2D8x5:
{
return CompressedTextureSize(Texture.Width, Texture.Height, 8, 5, 16);
return CompressedTextureSize(Image.Width, Image.Height, 8, 5, 16);
}
case GalTextureFormat.Astc2D10x5:
case GalImageFormat.Astc2D10x5:
{
return CompressedTextureSize(Texture.Width, Texture.Height, 10, 5, 16);
return CompressedTextureSize(Image.Width, Image.Height, 10, 5, 16);
}
case GalTextureFormat.Astc2D10x6:
case GalImageFormat.Astc2D10x6:
{
return CompressedTextureSize(Texture.Width, Texture.Height, 10, 6, 16);
return CompressedTextureSize(Image.Width, Image.Height, 10, 6, 16);
}
}
throw new NotImplementedException(Texture.Format.ToString());
throw new NotImplementedException(Image.Format.ToString());
}
public static int CompressedTextureSize(int TextureWidth, int TextureHeight, int BlockWidth, int BlockHeight, int Bpb)