Abstract texture and framebuffer targets as an image

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

View file

@ -1,25 +1,25 @@
namespace Ryujinx.Graphics.Gal namespace Ryujinx.Graphics.Gal
{ {
public struct GalTexture public struct GalImage
{ {
public int Width; public int Width;
public int Height; public int Height;
public GalTextureFormat Format; public GalImageFormat Format;
public GalTextureSource XSource; public GalTextureSource XSource;
public GalTextureSource YSource; public GalTextureSource YSource;
public GalTextureSource ZSource; public GalTextureSource ZSource;
public GalTextureSource WSource; public GalTextureSource WSource;
public GalTexture( public GalImage(
int Width, int Width,
int Height, int Height,
GalTextureFormat Format, GalImageFormat Format,
GalTextureSource XSource, GalTextureSource XSource = GalTextureSource.Red,
GalTextureSource YSource, GalTextureSource YSource = GalTextureSource.Green,
GalTextureSource ZSource, GalTextureSource ZSource = GalTextureSource.Blue,
GalTextureSource WSource) GalTextureSource WSource = GalTextureSource.Alpha)
{ {
this.Width = Width; this.Width = Width;
this.Height = Height; 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 LockCache();
void UnlockCache(); 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); 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)); throw new ArgumentException(nameof(Type));
} }
public static PixelInternalFormat GetFrameBufferInternalFormat(GalFrameBufferFormat Format) public static (PixelInternalFormat, PixelFormat, PixelType) GetImageFormat(GalImageFormat Format)
{ {
switch (Format) switch (Format)
{ {
//Sometimes it's not set, use a safe format case GalImageFormat.R32G32B32A32: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.Float);
case 0: return PixelInternalFormat.Rgba8; case GalImageFormat.R16G16B16A16: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.HalfFloat);
case GalImageFormat.A8B8G8R8: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte);
case GalFrameBufferFormat.RGBA32Float: return PixelInternalFormat.Rgba32f; case GalImageFormat.A2B10G10R10: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed);
case GalFrameBufferFormat.RGBA32Sint: return PixelInternalFormat.Rgba32i; case GalImageFormat.R32: return (PixelInternalFormat.Rgba8, PixelFormat.Red, PixelType.Float);
case GalFrameBufferFormat.RGBA32Uint: return PixelInternalFormat.Rgba32ui; case GalImageFormat.A1B5G5R5: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedShort5551);
case GalFrameBufferFormat.RGBA16Unorm: return PixelInternalFormat.Rgba16; case GalImageFormat.B5G6R5: return (PixelInternalFormat.Rgba8, PixelFormat.Rgb, PixelType.UnsignedShort565);
case GalFrameBufferFormat.RGBA16Snorm: return PixelInternalFormat.Rgba16Snorm; case GalImageFormat.G8R8: return (PixelInternalFormat.Rgba8, PixelFormat.Rg, PixelType.UnsignedByte);
case GalFrameBufferFormat.RGBA16Sint: return PixelInternalFormat.Rgba16i; case GalImageFormat.R16: return (PixelInternalFormat.Rgba8, PixelFormat.Red, PixelType.HalfFloat);
case GalFrameBufferFormat.RGBA16Uint: return PixelInternalFormat.Rgba16ui; case GalImageFormat.R8: return (PixelInternalFormat.Rgba8, PixelFormat.Red, PixelType.UnsignedByte);
case GalFrameBufferFormat.RGBA16Float: return PixelInternalFormat.Rgba16f; case GalImageFormat.ZF32: return (PixelInternalFormat.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float);
case GalFrameBufferFormat.RG32Float: return PixelInternalFormat.Rg32f; case GalImageFormat.BF10GF11RF11: return (PixelInternalFormat.Rgba8, PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev);
case GalFrameBufferFormat.RG32Sint: return PixelInternalFormat.Rg32i; case GalImageFormat.Z24S8: return (PixelInternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248);
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;
} }
throw new NotImplementedException(Format.ToString()); throw new NotImplementedException(Format.ToString());
} }
public static (PixelFormat Format, PixelType Type) GetFrameBufferFormat(GalFrameBufferFormat Format) public static InternalFormat GetCompressedImageFormat(GalImageFormat Format)
{ {
switch (Format) switch (Format)
{ {
case 0: return (PixelFormat.Rgba, PixelType.UnsignedByte); case GalImageFormat.BC6H_UF16: return InternalFormat.CompressedRgbBptcUnsignedFloat;
case GalImageFormat.BC6H_SF16: return InternalFormat.CompressedRgbBptcSignedFloat;
case GalFrameBufferFormat.RGBA32Float: return (PixelFormat.Rgba, PixelType.Float); case GalImageFormat.BC7U: return InternalFormat.CompressedRgbaBptcUnorm;
case GalFrameBufferFormat.RGBA32Sint: return (PixelFormat.Rgba, PixelType.Int); case GalImageFormat.BC1: return InternalFormat.CompressedRgbaS3tcDxt1Ext;
case GalFrameBufferFormat.RGBA32Uint: return (PixelFormat.Rgba, PixelType.UnsignedInt); case GalImageFormat.BC2: return InternalFormat.CompressedRgbaS3tcDxt3Ext;
case GalFrameBufferFormat.RGBA16Unorm: return (PixelFormat.Rgba, PixelType.UnsignedShort); case GalImageFormat.BC3: return InternalFormat.CompressedRgbaS3tcDxt5Ext;
case GalFrameBufferFormat.RGBA16Snorm: return (PixelFormat.Rgba, PixelType.Short); case GalImageFormat.BC4: return InternalFormat.CompressedRedRgtc1;
case GalFrameBufferFormat.RGBA16Sint: return (PixelFormat.Rgba, PixelType.Short); case GalImageFormat.BC5: return InternalFormat.CompressedRgRgtc2;
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;
} }
throw new NotImplementedException(Format.ToString()); 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[] private static readonly DrawBuffersEnum[] DrawBuffers = new DrawBuffersEnum[]
{ {
@ -159,16 +40,13 @@ namespace Ryujinx.Graphics.Gal.OpenGL
private const int NativeWidth = 1280; private const int NativeWidth = 1280;
private const int NativeHeight = 720; private const int NativeHeight = 720;
//TODO: Use a variable value here private const GalImageFormat RawFormat = GalImageFormat.A8B8G8R8;
private const int MaxBpp = 16;
private const GalTextureFormat RawFormat = GalTextureFormat.A8B8G8R8; private Dictionary<long, TCE> ColorTextures;
private Dictionary<long, TCE> ZetaTextures;
private Dictionary<long, Texture> ColorTextures; private TCE RawTex;
private Dictionary<long, Texture> ZetaTextures; private TCE ReadTex;
private Texture RawTex;
private Texture ReadTex;
private Rect Viewport; private Rect Viewport;
private Rect Window; private Rect Window;
@ -188,26 +66,28 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public OGLFrameBuffer() 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) 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); 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) public void BindColor(long Key, int Attachment)
{ {
if (ColorTextures.TryGetValue(Key, out Texture Tex)) if (ColorTextures.TryGetValue(Key, out TCE Tex))
{ {
EnsureFrameBuffer(); EnsureFrameBuffer();
@ -236,19 +116,21 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public void CreateZeta(long Key, int Width, int Height, GalZetaFormat Format) 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); 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) public void BindZeta(long Key)
{ {
if (ZetaTextures.TryGetValue(Key, out Texture Tex)) if (ZetaTextures.TryGetValue(Key, out TCE Tex))
{ {
EnsureFrameBuffer(); EnsureFrameBuffer();
@ -277,7 +159,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public void BindTexture(long Key, int Index) public void BindTexture(long Key, int Index)
{ {
Texture Tex; TCE Tex;
if (ColorTextures.TryGetValue(Key, out Tex) || if (ColorTextures.TryGetValue(Key, out Tex) ||
ZetaTextures.TryGetValue(Key, out Tex)) ZetaTextures.TryGetValue(Key, out Tex))
@ -290,7 +172,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public void Set(long Key) public void Set(long Key)
{ {
if (ColorTextures.TryGetValue(Key, out Texture Tex)) if (ColorTextures.TryGetValue(Key, out TCE Tex))
{ {
ReadTex = Tex; ReadTex = Tex;
} }
@ -300,16 +182,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{ {
if (RawTex == null) 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); GL.BindTexture(TextureTarget.Texture2D, RawTex.Handle);
(PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(RawFormat); GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, Width, Height, RawTex.PixelFormat, RawTex.PixelType, Data);
GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, Width, Height, Format, Type, Data);
ReadTex = RawTex; ReadTex = RawTex;
} }
@ -429,8 +309,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{ {
bool Found = false; bool Found = false;
if (ColorTextures.TryGetValue(SrcKey, out Texture SrcTex) && if (ColorTextures.TryGetValue(SrcKey, out TCE SrcTex) &&
ColorTextures.TryGetValue(DstKey, out Texture DstTex)) ColorTextures.TryGetValue(DstKey, out TCE DstTex))
{ {
CopyTextures( CopyTextures(
SrcX0, SrcY0, SrcX1, SrcY1, SrcX0, SrcY0, SrcX1, SrcY1,
@ -444,8 +324,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Found = true; Found = true;
} }
if (ZetaTextures.TryGetValue(SrcKey, out Texture ZetaSrcTex) && if (ZetaTextures.TryGetValue(SrcKey, out TCE ZetaSrcTex) &&
ZetaTextures.TryGetValue(DstKey, out Texture ZetaDstTex)) ZetaTextures.TryGetValue(DstKey, out TCE ZetaDstTex))
{ {
CopyTextures( CopyTextures(
SrcX0, SrcY0, SrcX1, SrcY1, SrcX0, SrcY0, SrcX1, SrcY1,
@ -467,21 +347,20 @@ namespace Ryujinx.Graphics.Gal.OpenGL
public void GetBufferData(long Key, Action<byte[]> Callback) public void GetBufferData(long Key, Action<byte[]> Callback)
{ {
Texture Tex; TCE Tex;
if (ColorTextures.TryGetValue(Key, out Tex) || if (ColorTextures.TryGetValue(Key, out Tex) ||
ZetaTextures.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 * TCE.MaxBpp];
byte[] Data = new byte[Tex.Width * Tex.Height * MaxBpp];
GL.BindTexture(TextureTarget.Texture2D, Tex.Handle); GL.BindTexture(TextureTarget.Texture2D, Tex.Handle);
GL.GetTexImage( GL.GetTexImage(
TextureTarget.Texture2D, TextureTarget.Texture2D,
0, 0,
Tex.Format, Tex.PixelFormat,
Tex.Type, Tex.PixelType,
Data); Data);
Callback(Data); Callback(Data);
@ -494,7 +373,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
int Height, int Height,
byte[] Buffer) byte[] Buffer)
{ {
Texture Tex; TCE Tex;
if (ColorTextures.TryGetValue(Key, out Tex) || if (ColorTextures.TryGetValue(Key, out Tex) ||
ZetaTextures.TryGetValue(Key, out Tex)) ZetaTextures.TryGetValue(Key, out Tex))
@ -511,8 +390,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Width, Width,
Height, Height,
Border, Border,
Tex.Format, Tex.PixelFormat,
Tex.Type, Tex.PixelType,
Buffer); Buffer);
} }
} }

View file

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

View file

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

View file

@ -6,11 +6,11 @@ namespace Ryujinx.HLE.Gpu.Texture
{ {
static class TextureFactory 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); 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 XSource = (GalTextureSource)((Tic[0] >> 19) & 7);
GalTextureSource YSource = (GalTextureSource)((Tic[0] >> 22) & 7); GalTextureSource YSource = (GalTextureSource)((Tic[0] >> 22) & 7);
@ -20,7 +20,7 @@ namespace Ryujinx.HLE.Gpu.Texture
int Width = (Tic[4] & 0xffff) + 1; int Width = (Tic[4] & 0xffff) + 1;
int Height = (Tic[5] & 0xffff) + 1; int Height = (Tic[5] & 0xffff) + 1;
return new GalTexture( return new GalImage(
Width, Width,
Height, Height,
Format, Format,

View file

@ -30,117 +30,117 @@ namespace Ryujinx.HLE.Gpu.Texture
throw new NotImplementedException(Texture.Swizzle.ToString()); 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: case GalImageFormat.R32G32B32A32:
return Texture.Width * Texture.Height * 16; return Image.Width * Image.Height * 16;
case GalTextureFormat.R16G16B16A16: case GalImageFormat.R16G16B16A16:
return Texture.Width * Texture.Height * 8; return Image.Width * Image.Height * 8;
case GalTextureFormat.A8B8G8R8: case GalImageFormat.A8B8G8R8:
case GalTextureFormat.A2B10G10R10: case GalImageFormat.A2B10G10R10:
case GalTextureFormat.R32: case GalImageFormat.R32:
case GalTextureFormat.ZF32: case GalImageFormat.ZF32:
case GalTextureFormat.BF10GF11RF11: case GalImageFormat.BF10GF11RF11:
case GalTextureFormat.Z24S8: case GalImageFormat.Z24S8:
return Texture.Width * Texture.Height * 4; return Image.Width * Image.Height * 4;
case GalTextureFormat.A1B5G5R5: case GalImageFormat.A1B5G5R5:
case GalTextureFormat.B5G6R5: case GalImageFormat.B5G6R5:
case GalTextureFormat.G8R8: case GalImageFormat.G8R8:
case GalTextureFormat.R16: case GalImageFormat.R16:
return Texture.Width * Texture.Height * 2; return Image.Width * Image.Height * 2;
case GalTextureFormat.R8: case GalImageFormat.R8:
return Texture.Width * Texture.Height; return Image.Width * Image.Height;
case GalTextureFormat.BC1: case GalImageFormat.BC1:
case GalTextureFormat.BC4: 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 GalImageFormat.BC6H_SF16:
case GalTextureFormat.BC6H_UF16: case GalImageFormat.BC6H_UF16:
case GalTextureFormat.BC7U: case GalImageFormat.BC7U:
case GalTextureFormat.BC2: case GalImageFormat.BC2:
case GalTextureFormat.BC3: case GalImageFormat.BC3:
case GalTextureFormat.BC5: case GalImageFormat.BC5:
case GalTextureFormat.Astc2D4x4: 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) public static int CompressedTextureSize(int TextureWidth, int TextureHeight, int BlockWidth, int BlockHeight, int Bpb)