Abstract texture and framebuffer targets as an image
This commit is contained in:
parent
b723bd5e4a
commit
65c7842d6d
13 changed files with 484 additions and 448 deletions
|
@ -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;
|
44
Ryujinx.Graphics/Gal/GalImageFormat.cs
Normal file
44
Ryujinx.Graphics/Gal/GalImageFormat.cs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
||||||
|
|
129
Ryujinx.Graphics/Gal/ImageFormatConverter.cs
Normal file
129
Ryujinx.Graphics/Gal/ImageFormatConverter.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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());
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
112
Ryujinx.Graphics/Gal/OpenGL/TCE.cs
Normal file
112
Ryujinx.Graphics/Gal/OpenGL/TCE.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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>
|
||||||
|
|
|
@ -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))
|
||||||
{
|
{
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue