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
|
||||
{
|
||||
public struct GalTexture
|
||||
public struct GalImage
|
||||
{
|
||||
public int Width;
|
||||
public int Height;
|
||||
|
||||
public GalTextureFormat Format;
|
||||
public GalImageFormat Format;
|
||||
|
||||
public GalTextureSource XSource;
|
||||
public GalTextureSource YSource;
|
||||
public GalTextureSource ZSource;
|
||||
public GalTextureSource WSource;
|
||||
|
||||
public GalTexture(
|
||||
public GalImage(
|
||||
int Width,
|
||||
int Height,
|
||||
GalTextureFormat Format,
|
||||
GalTextureSource XSource,
|
||||
GalTextureSource YSource,
|
||||
GalTextureSource ZSource,
|
||||
GalTextureSource WSource)
|
||||
GalImageFormat Format,
|
||||
GalTextureSource XSource = GalTextureSource.Red,
|
||||
GalTextureSource YSource = GalTextureSource.Green,
|
||||
GalTextureSource ZSource = GalTextureSource.Blue,
|
||||
GalTextureSource WSource = GalTextureSource.Alpha)
|
||||
{
|
||||
this.Width = Width;
|
||||
this.Height = Height;
|
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 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);
|
||||
|
||||
|
|
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));
|
||||
}
|
||||
|
||||
public static PixelInternalFormat GetFrameBufferInternalFormat(GalFrameBufferFormat Format)
|
||||
public static (PixelInternalFormat, PixelFormat, PixelType) GetImageFormat(GalImageFormat Format)
|
||||
{
|
||||
switch (Format)
|
||||
{
|
||||
//Sometimes it's not set, use a safe format
|
||||
case 0: return PixelInternalFormat.Rgba8;
|
||||
|
||||
case GalFrameBufferFormat.RGBA32Float: return PixelInternalFormat.Rgba32f;
|
||||
case GalFrameBufferFormat.RGBA32Sint: return PixelInternalFormat.Rgba32i;
|
||||
case GalFrameBufferFormat.RGBA32Uint: return PixelInternalFormat.Rgba32ui;
|
||||
case GalFrameBufferFormat.RGBA16Unorm: return PixelInternalFormat.Rgba16;
|
||||
case GalFrameBufferFormat.RGBA16Snorm: return PixelInternalFormat.Rgba16Snorm;
|
||||
case GalFrameBufferFormat.RGBA16Sint: return PixelInternalFormat.Rgba16i;
|
||||
case GalFrameBufferFormat.RGBA16Uint: return PixelInternalFormat.Rgba16ui;
|
||||
case GalFrameBufferFormat.RGBA16Float: return PixelInternalFormat.Rgba16f;
|
||||
case GalFrameBufferFormat.RG32Float: return PixelInternalFormat.Rg32f;
|
||||
case GalFrameBufferFormat.RG32Sint: return PixelInternalFormat.Rg32i;
|
||||
case GalFrameBufferFormat.RG32Uint: return PixelInternalFormat.Rg32ui;
|
||||
case GalFrameBufferFormat.RGB10A2Unorm: return PixelInternalFormat.Rgb10A2;
|
||||
case GalFrameBufferFormat.RGB10A2Uint: return PixelInternalFormat.Rgb10A2ui;
|
||||
case GalFrameBufferFormat.RGBA8Unorm: return PixelInternalFormat.Rgba8;
|
||||
case GalFrameBufferFormat.RGBA8Srgb: return PixelInternalFormat.Srgb8;
|
||||
case GalFrameBufferFormat.RG16Snorm: return PixelInternalFormat.Rg16Snorm;
|
||||
case GalFrameBufferFormat.R11G11B10Float: return PixelInternalFormat.R11fG11fB10f;
|
||||
case GalFrameBufferFormat.R32Float: return PixelInternalFormat.R32f;
|
||||
case GalFrameBufferFormat.R16Float: return PixelInternalFormat.R16f;
|
||||
case GalFrameBufferFormat.R8Unorm: return PixelInternalFormat.R8;
|
||||
case GalFrameBufferFormat.R8Snorm: return PixelInternalFormat.R8Snorm;
|
||||
case GalFrameBufferFormat.R8Sint: return PixelInternalFormat.R8i;
|
||||
case GalFrameBufferFormat.R8Uint: return PixelInternalFormat.R8ui;
|
||||
case GalImageFormat.R32G32B32A32: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.Float);
|
||||
case GalImageFormat.R16G16B16A16: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.HalfFloat);
|
||||
case GalImageFormat.A8B8G8R8: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte);
|
||||
case GalImageFormat.A2B10G10R10: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed);
|
||||
case GalImageFormat.R32: return (PixelInternalFormat.Rgba8, PixelFormat.Red, PixelType.Float);
|
||||
case GalImageFormat.A1B5G5R5: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedShort5551);
|
||||
case GalImageFormat.B5G6R5: return (PixelInternalFormat.Rgba8, PixelFormat.Rgb, PixelType.UnsignedShort565);
|
||||
case GalImageFormat.G8R8: return (PixelInternalFormat.Rgba8, PixelFormat.Rg, PixelType.UnsignedByte);
|
||||
case GalImageFormat.R16: return (PixelInternalFormat.Rgba8, PixelFormat.Red, PixelType.HalfFloat);
|
||||
case GalImageFormat.R8: return (PixelInternalFormat.Rgba8, PixelFormat.Red, PixelType.UnsignedByte);
|
||||
case GalImageFormat.ZF32: return (PixelInternalFormat.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float);
|
||||
case GalImageFormat.BF10GF11RF11: return (PixelInternalFormat.Rgba8, PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev);
|
||||
case GalImageFormat.Z24S8: return (PixelInternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248);
|
||||
}
|
||||
|
||||
throw new NotImplementedException(Format.ToString());
|
||||
}
|
||||
|
||||
public static (PixelFormat Format, PixelType Type) GetFrameBufferFormat(GalFrameBufferFormat Format)
|
||||
public static InternalFormat GetCompressedImageFormat(GalImageFormat Format)
|
||||
{
|
||||
switch (Format)
|
||||
{
|
||||
case 0: return (PixelFormat.Rgba, PixelType.UnsignedByte);
|
||||
|
||||
case GalFrameBufferFormat.RGBA32Float: return (PixelFormat.Rgba, PixelType.Float);
|
||||
case GalFrameBufferFormat.RGBA32Sint: return (PixelFormat.Rgba, PixelType.Int);
|
||||
case GalFrameBufferFormat.RGBA32Uint: return (PixelFormat.Rgba, PixelType.UnsignedInt);
|
||||
case GalFrameBufferFormat.RGBA16Unorm: return (PixelFormat.Rgba, PixelType.UnsignedShort);
|
||||
case GalFrameBufferFormat.RGBA16Snorm: return (PixelFormat.Rgba, PixelType.Short);
|
||||
case GalFrameBufferFormat.RGBA16Sint: return (PixelFormat.Rgba, PixelType.Short);
|
||||
case GalFrameBufferFormat.RGBA16Uint: return (PixelFormat.Rgba, PixelType.UnsignedShort);
|
||||
case GalFrameBufferFormat.RGBA16Float: return (PixelFormat.Rgba, PixelType.HalfFloat);
|
||||
case GalFrameBufferFormat.RG32Float: return (PixelFormat.Rg, PixelType.Float);
|
||||
case GalFrameBufferFormat.RG32Sint: return (PixelFormat.Rg, PixelType.Int);
|
||||
case GalFrameBufferFormat.RG32Uint: return (PixelFormat.Rg, PixelType.UnsignedInt);
|
||||
case GalFrameBufferFormat.RGB10A2Unorm: return (PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed);
|
||||
case GalFrameBufferFormat.RGB10A2Uint: return (PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed);
|
||||
case GalFrameBufferFormat.RGBA8Unorm: return (PixelFormat.Rgba, PixelType.UnsignedByte);
|
||||
case GalFrameBufferFormat.RGBA8Srgb: return (PixelFormat.Rgba, PixelType.UnsignedByte);
|
||||
case GalFrameBufferFormat.RG16Snorm: return (PixelFormat.Rg, PixelType.Short);
|
||||
case GalFrameBufferFormat.R11G11B10Float: return (PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev);
|
||||
case GalFrameBufferFormat.R32Float: return (PixelFormat.Red, PixelType.Float);
|
||||
case GalFrameBufferFormat.R16Float: return (PixelFormat.Red, PixelType.HalfFloat);
|
||||
case GalFrameBufferFormat.R8Unorm: return (PixelFormat.Red, PixelType.UnsignedByte);
|
||||
case GalFrameBufferFormat.R8Snorm: return (PixelFormat.Red, PixelType.Byte);
|
||||
case GalFrameBufferFormat.R8Sint: return (PixelFormat.Red, PixelType.Byte);
|
||||
case GalFrameBufferFormat.R8Uint: return (PixelFormat.Red, PixelType.UnsignedByte);
|
||||
}
|
||||
|
||||
throw new NotImplementedException(Format.ToString());
|
||||
}
|
||||
|
||||
public static (PixelFormat, PixelType) GetTextureFormat(GalTextureFormat Format)
|
||||
{
|
||||
switch (Format)
|
||||
{
|
||||
case GalTextureFormat.R32G32B32A32: return (PixelFormat.Rgba, PixelType.Float);
|
||||
case GalTextureFormat.R16G16B16A16: return (PixelFormat.Rgba, PixelType.HalfFloat);
|
||||
case GalTextureFormat.A8B8G8R8: return (PixelFormat.Rgba, PixelType.UnsignedByte);
|
||||
case GalTextureFormat.A2B10G10R10: return (PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed);
|
||||
case GalTextureFormat.R32: return (PixelFormat.Red, PixelType.Float);
|
||||
case GalTextureFormat.A1B5G5R5: return (PixelFormat.Rgba, PixelType.UnsignedShort5551);
|
||||
case GalTextureFormat.B5G6R5: return (PixelFormat.Rgb, PixelType.UnsignedShort565);
|
||||
case GalTextureFormat.G8R8: return (PixelFormat.Rg, PixelType.UnsignedByte);
|
||||
case GalTextureFormat.R16: return (PixelFormat.Red, PixelType.HalfFloat);
|
||||
case GalTextureFormat.R8: return (PixelFormat.Red, PixelType.UnsignedByte);
|
||||
case GalTextureFormat.ZF32: return (PixelFormat.DepthComponent, PixelType.Float);
|
||||
case GalTextureFormat.BF10GF11RF11: return (PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev);
|
||||
case GalTextureFormat.Z24S8: return (PixelFormat.DepthStencil, PixelType.UnsignedInt248);
|
||||
}
|
||||
|
||||
throw new NotImplementedException(Format.ToString());
|
||||
}
|
||||
|
||||
public static InternalFormat GetCompressedTextureFormat(GalTextureFormat Format)
|
||||
{
|
||||
switch (Format)
|
||||
{
|
||||
case GalTextureFormat.BC6H_UF16: return InternalFormat.CompressedRgbBptcUnsignedFloat;
|
||||
case GalTextureFormat.BC6H_SF16: return InternalFormat.CompressedRgbBptcSignedFloat;
|
||||
case GalTextureFormat.BC7U: return InternalFormat.CompressedRgbaBptcUnorm;
|
||||
case GalTextureFormat.BC1: return InternalFormat.CompressedRgbaS3tcDxt1Ext;
|
||||
case GalTextureFormat.BC2: return InternalFormat.CompressedRgbaS3tcDxt3Ext;
|
||||
case GalTextureFormat.BC3: return InternalFormat.CompressedRgbaS3tcDxt5Ext;
|
||||
case GalTextureFormat.BC4: return InternalFormat.CompressedRedRgtc1;
|
||||
case GalTextureFormat.BC5: return InternalFormat.CompressedRgRgtc2;
|
||||
case GalImageFormat.BC6H_UF16: return InternalFormat.CompressedRgbBptcUnsignedFloat;
|
||||
case GalImageFormat.BC6H_SF16: return InternalFormat.CompressedRgbBptcSignedFloat;
|
||||
case GalImageFormat.BC7U: return InternalFormat.CompressedRgbaBptcUnorm;
|
||||
case GalImageFormat.BC1: return InternalFormat.CompressedRgbaS3tcDxt1Ext;
|
||||
case GalImageFormat.BC2: return InternalFormat.CompressedRgbaS3tcDxt3Ext;
|
||||
case GalImageFormat.BC3: return InternalFormat.CompressedRgbaS3tcDxt5Ext;
|
||||
case GalImageFormat.BC4: return InternalFormat.CompressedRedRgtc1;
|
||||
case GalImageFormat.BC5: return InternalFormat.CompressedRgRgtc2;
|
||||
}
|
||||
|
||||
throw new NotImplementedException(Format.ToString());
|
||||
|
|
|
@ -23,126 +23,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
}
|
||||
}
|
||||
|
||||
private class Texture
|
||||
{
|
||||
public int Width { get; private set; }
|
||||
public int Height { get; private set; }
|
||||
|
||||
public PixelInternalFormat InternalFormat { get; private set; }
|
||||
public PixelFormat Format { get; private set; }
|
||||
public PixelType Type { get; private set; }
|
||||
|
||||
public int Handle { get; private set; }
|
||||
|
||||
private bool Initialized;
|
||||
|
||||
public Texture()
|
||||
{
|
||||
Handle = GL.GenTexture();
|
||||
}
|
||||
|
||||
public void EnsureSetup(
|
||||
int Width,
|
||||
int Height,
|
||||
PixelInternalFormat InternalFormat,
|
||||
PixelFormat Format,
|
||||
PixelType Type)
|
||||
{
|
||||
if (!Initialized ||
|
||||
this.Width != Width ||
|
||||
this.Height != Height ||
|
||||
this.InternalFormat != InternalFormat)
|
||||
{
|
||||
int CopyBuffer = 0;
|
||||
|
||||
bool ChangingFormat = Initialized && this.InternalFormat != InternalFormat;
|
||||
|
||||
GL.BindTexture(TextureTarget.Texture2D, Handle);
|
||||
|
||||
if (ChangingFormat)
|
||||
{
|
||||
CopyBuffer = GL.GenBuffer();
|
||||
|
||||
GL.BindBuffer(BufferTarget.PixelPackBuffer, CopyBuffer);
|
||||
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyBuffer);
|
||||
|
||||
int MaxWidth = Math.Max(Width, this.Width);
|
||||
int MaxHeight = Math.Max(Height, this.Height);
|
||||
|
||||
//TODO: Dehardcode size number
|
||||
GL.BufferData(BufferTarget.PixelPackBuffer, MaxWidth * MaxHeight * MaxBpp, IntPtr.Zero, BufferUsageHint.StaticCopy);
|
||||
|
||||
GL.GetTexImage(TextureTarget.Texture2D, 0, this.Format, this.Type, IntPtr.Zero);
|
||||
|
||||
GL.DeleteTexture(Handle);
|
||||
|
||||
Handle = GL.GenTexture();
|
||||
|
||||
GL.BindTexture(TextureTarget.Texture2D, Handle);
|
||||
}
|
||||
|
||||
const int MinFilter = (int)TextureMinFilter.Linear;
|
||||
const int MagFilter = (int)TextureMagFilter.Linear;
|
||||
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, MinFilter);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, MagFilter);
|
||||
|
||||
const int Level = 0;
|
||||
const int Border = 0;
|
||||
|
||||
GL.TexImage2D(
|
||||
TextureTarget.Texture2D,
|
||||
Level,
|
||||
InternalFormat,
|
||||
Width,
|
||||
Height,
|
||||
Border,
|
||||
Format,
|
||||
Type,
|
||||
IntPtr.Zero);
|
||||
|
||||
if (ChangingFormat)
|
||||
{
|
||||
GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
|
||||
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);
|
||||
|
||||
GL.DeleteBuffer(CopyBuffer);
|
||||
}
|
||||
|
||||
this.Width = Width;
|
||||
this.Height = Height;
|
||||
this.InternalFormat = InternalFormat;
|
||||
this.Format = Format;
|
||||
this.Type = Type;
|
||||
|
||||
Initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void EnsureSetup(int Width, int Height, GalFrameBufferFormat Format)
|
||||
{
|
||||
//TODO: Convert color format
|
||||
|
||||
EnsureSetup(
|
||||
Width,
|
||||
Height,
|
||||
PixelInternalFormat.Rgba8,
|
||||
PixelFormat.Rgba,
|
||||
PixelType.UnsignedByte);
|
||||
}
|
||||
|
||||
public void EnsureSetup(int Width, int Height, GalZetaFormat Format)
|
||||
{
|
||||
//TODO: Convert zeta format
|
||||
|
||||
EnsureSetup(
|
||||
Width,
|
||||
Height,
|
||||
PixelInternalFormat.Depth24Stencil8,
|
||||
PixelFormat.DepthStencil,
|
||||
PixelType.UnsignedInt248);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static readonly DrawBuffersEnum[] DrawBuffers = new DrawBuffersEnum[]
|
||||
{
|
||||
|
@ -159,16 +40,13 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
private const int NativeWidth = 1280;
|
||||
private const int NativeHeight = 720;
|
||||
|
||||
//TODO: Use a variable value here
|
||||
private const int MaxBpp = 16;
|
||||
private const GalImageFormat RawFormat = GalImageFormat.A8B8G8R8;
|
||||
|
||||
private const GalTextureFormat RawFormat = GalTextureFormat.A8B8G8R8;
|
||||
private Dictionary<long, TCE> ColorTextures;
|
||||
private Dictionary<long, TCE> ZetaTextures;
|
||||
|
||||
private Dictionary<long, Texture> ColorTextures;
|
||||
private Dictionary<long, Texture> ZetaTextures;
|
||||
|
||||
private Texture RawTex;
|
||||
private Texture ReadTex;
|
||||
private TCE RawTex;
|
||||
private TCE ReadTex;
|
||||
|
||||
private Rect Viewport;
|
||||
private Rect Window;
|
||||
|
@ -188,26 +66,28 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
|
||||
public OGLFrameBuffer()
|
||||
{
|
||||
ColorTextures = new Dictionary<long, Texture>();
|
||||
ColorTextures = new Dictionary<long, TCE>();
|
||||
|
||||
ZetaTextures = new Dictionary<long, Texture>();
|
||||
ZetaTextures = new Dictionary<long, TCE>();
|
||||
}
|
||||
|
||||
public void CreateColor(long Key, int Width, int Height, GalFrameBufferFormat Format)
|
||||
{
|
||||
if (!ColorTextures.TryGetValue(Key, out Texture Tex))
|
||||
if (!ColorTextures.TryGetValue(Key, out TCE Tex))
|
||||
{
|
||||
Tex = new Texture();
|
||||
Tex = new TCE();
|
||||
|
||||
ColorTextures.Add(Key, Tex);
|
||||
}
|
||||
|
||||
Tex.EnsureSetup(Width, Height, Format);
|
||||
GalImageFormat ImageFormat = ImageFormatConverter.ConvertFrameBuffer(Format);
|
||||
|
||||
Tex.EnsureSetup(new GalImage(Width, Height, ImageFormat));
|
||||
}
|
||||
|
||||
public void BindColor(long Key, int Attachment)
|
||||
{
|
||||
if (ColorTextures.TryGetValue(Key, out Texture Tex))
|
||||
if (ColorTextures.TryGetValue(Key, out TCE Tex))
|
||||
{
|
||||
EnsureFrameBuffer();
|
||||
|
||||
|
@ -236,19 +116,21 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
|
||||
public void CreateZeta(long Key, int Width, int Height, GalZetaFormat Format)
|
||||
{
|
||||
if (!ZetaTextures.TryGetValue(Key, out Texture Tex))
|
||||
if (!ZetaTextures.TryGetValue(Key, out TCE Tex))
|
||||
{
|
||||
Tex = new Texture();
|
||||
Tex = new TCE();
|
||||
|
||||
ZetaTextures.Add(Key, Tex);
|
||||
}
|
||||
|
||||
Tex.EnsureSetup(Width, Height, Format);
|
||||
GalImageFormat ImageFormat = ImageFormatConverter.ConvertZeta(Format);
|
||||
|
||||
Tex.EnsureSetup(new GalImage(Width, Height, ImageFormat));
|
||||
}
|
||||
|
||||
public void BindZeta(long Key)
|
||||
{
|
||||
if (ZetaTextures.TryGetValue(Key, out Texture Tex))
|
||||
if (ZetaTextures.TryGetValue(Key, out TCE Tex))
|
||||
{
|
||||
EnsureFrameBuffer();
|
||||
|
||||
|
@ -277,7 +159,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
|
||||
public void BindTexture(long Key, int Index)
|
||||
{
|
||||
Texture Tex;
|
||||
TCE Tex;
|
||||
|
||||
if (ColorTextures.TryGetValue(Key, out Tex) ||
|
||||
ZetaTextures.TryGetValue(Key, out Tex))
|
||||
|
@ -290,7 +172,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
|
||||
public void Set(long Key)
|
||||
{
|
||||
if (ColorTextures.TryGetValue(Key, out Texture Tex))
|
||||
if (ColorTextures.TryGetValue(Key, out TCE Tex))
|
||||
{
|
||||
ReadTex = Tex;
|
||||
}
|
||||
|
@ -300,16 +182,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
{
|
||||
if (RawTex == null)
|
||||
{
|
||||
RawTex = new Texture();
|
||||
RawTex = new TCE();
|
||||
}
|
||||
|
||||
RawTex.EnsureSetup(Width, Height, PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte);
|
||||
RawTex.EnsureSetup(new GalImage(Width, Height, RawFormat));
|
||||
|
||||
GL.BindTexture(TextureTarget.Texture2D, RawTex.Handle);
|
||||
|
||||
(PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(RawFormat);
|
||||
|
||||
GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, Width, Height, Format, Type, Data);
|
||||
GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, Width, Height, RawTex.PixelFormat, RawTex.PixelType, Data);
|
||||
|
||||
ReadTex = RawTex;
|
||||
}
|
||||
|
@ -429,8 +309,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
{
|
||||
bool Found = false;
|
||||
|
||||
if (ColorTextures.TryGetValue(SrcKey, out Texture SrcTex) &&
|
||||
ColorTextures.TryGetValue(DstKey, out Texture DstTex))
|
||||
if (ColorTextures.TryGetValue(SrcKey, out TCE SrcTex) &&
|
||||
ColorTextures.TryGetValue(DstKey, out TCE DstTex))
|
||||
{
|
||||
CopyTextures(
|
||||
SrcX0, SrcY0, SrcX1, SrcY1,
|
||||
|
@ -444,8 +324,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
Found = true;
|
||||
}
|
||||
|
||||
if (ZetaTextures.TryGetValue(SrcKey, out Texture ZetaSrcTex) &&
|
||||
ZetaTextures.TryGetValue(DstKey, out Texture ZetaDstTex))
|
||||
if (ZetaTextures.TryGetValue(SrcKey, out TCE ZetaSrcTex) &&
|
||||
ZetaTextures.TryGetValue(DstKey, out TCE ZetaDstTex))
|
||||
{
|
||||
CopyTextures(
|
||||
SrcX0, SrcY0, SrcX1, SrcY1,
|
||||
|
@ -467,21 +347,20 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
|
||||
public void GetBufferData(long Key, Action<byte[]> Callback)
|
||||
{
|
||||
Texture Tex;
|
||||
TCE Tex;
|
||||
|
||||
if (ColorTextures.TryGetValue(Key, out Tex) ||
|
||||
ZetaTextures.TryGetValue(Key, out Tex))
|
||||
{
|
||||
//Note: Change this value when framebuffer sizes are dehardcoded
|
||||
byte[] Data = new byte[Tex.Width * Tex.Height * MaxBpp];
|
||||
byte[] Data = new byte[Tex.Width * Tex.Height * TCE.MaxBpp];
|
||||
|
||||
GL.BindTexture(TextureTarget.Texture2D, Tex.Handle);
|
||||
|
||||
GL.GetTexImage(
|
||||
TextureTarget.Texture2D,
|
||||
0,
|
||||
Tex.Format,
|
||||
Tex.Type,
|
||||
Tex.PixelFormat,
|
||||
Tex.PixelType,
|
||||
Data);
|
||||
|
||||
Callback(Data);
|
||||
|
@ -494,7 +373,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
int Height,
|
||||
byte[] Buffer)
|
||||
{
|
||||
Texture Tex;
|
||||
TCE Tex;
|
||||
|
||||
if (ColorTextures.TryGetValue(Key, out Tex) ||
|
||||
ZetaTextures.TryGetValue(Key, out Tex))
|
||||
|
@ -511,8 +390,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
Width,
|
||||
Height,
|
||||
Border,
|
||||
Tex.Format,
|
||||
Tex.Type,
|
||||
Tex.PixelFormat,
|
||||
Tex.PixelType,
|
||||
Buffer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,19 +6,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
{
|
||||
public class OGLTexture : IGalTexture
|
||||
{
|
||||
private class TCE
|
||||
{
|
||||
public int Handle;
|
||||
|
||||
public GalTexture Texture;
|
||||
|
||||
public TCE(int Handle, GalTexture Texture)
|
||||
{
|
||||
this.Handle = Handle;
|
||||
this.Texture = Texture;
|
||||
}
|
||||
}
|
||||
|
||||
private OGLCachedResource<TCE> TextureCache;
|
||||
|
||||
public OGLTexture()
|
||||
|
@ -41,68 +28,66 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
GL.DeleteTexture(CachedTexture.Handle);
|
||||
}
|
||||
|
||||
public void Create(long Key, byte[] Data, GalTexture Texture)
|
||||
public void Create(long Key, byte[] Data, GalImage Image)
|
||||
{
|
||||
int Handle = GL.GenTexture();
|
||||
|
||||
TextureCache.AddOrUpdate(Key, new TCE(Handle, Texture), (uint)Data.Length);
|
||||
TextureCache.AddOrUpdate(Key, new TCE(Handle, Image), (uint)Data.Length);
|
||||
|
||||
GL.BindTexture(TextureTarget.Texture2D, Handle);
|
||||
|
||||
const int Level = 0; //TODO: Support mipmap textures.
|
||||
const int Border = 0;
|
||||
|
||||
if (IsCompressedTextureFormat(Texture.Format))
|
||||
if (IsCompressedTextureFormat(Image.Format))
|
||||
{
|
||||
InternalFormat InternalFmt = OGLEnumConverter.GetCompressedTextureFormat(Texture.Format);
|
||||
InternalFormat InternalFmt = OGLEnumConverter.GetCompressedImageFormat(Image.Format);
|
||||
|
||||
GL.CompressedTexImage2D(
|
||||
TextureTarget.Texture2D,
|
||||
Level,
|
||||
InternalFmt,
|
||||
Texture.Width,
|
||||
Texture.Height,
|
||||
Image.Width,
|
||||
Image.Height,
|
||||
Border,
|
||||
Data.Length,
|
||||
Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Texture.Format >= GalTextureFormat.Astc2D4x4)
|
||||
if (Image.Format > GalImageFormat.ConvertedBegin && Image.Format < GalImageFormat.ConvertedEnd)
|
||||
{
|
||||
int TextureBlockWidth = GetAstcBlockWidth(Texture.Format);
|
||||
int TextureBlockHeight = GetAstcBlockHeight(Texture.Format);
|
||||
int TextureBlockWidth = GetAstcBlockWidth(Image.Format);
|
||||
int TextureBlockHeight = GetAstcBlockHeight(Image.Format);
|
||||
|
||||
Data = ASTCDecoder.DecodeToRGBA8888(
|
||||
Data,
|
||||
TextureBlockWidth,
|
||||
TextureBlockHeight, 1,
|
||||
Texture.Width,
|
||||
Texture.Height, 1);
|
||||
Image.Width,
|
||||
Image.Height, 1);
|
||||
|
||||
Texture.Format = GalTextureFormat.A8B8G8R8;
|
||||
Image.Format = GalImageFormat.A8B8G8R8;
|
||||
}
|
||||
|
||||
const PixelInternalFormat InternalFmt = PixelInternalFormat.Rgba;
|
||||
|
||||
(PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(Texture.Format);
|
||||
(PixelInternalFormat InternalFormat, PixelFormat Format, PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format);
|
||||
|
||||
GL.TexImage2D(
|
||||
TextureTarget.Texture2D,
|
||||
Level,
|
||||
InternalFmt,
|
||||
Texture.Width,
|
||||
Texture.Height,
|
||||
InternalFormat,
|
||||
Image.Width,
|
||||
Image.Height,
|
||||
Border,
|
||||
Format,
|
||||
Type,
|
||||
Data);
|
||||
}
|
||||
|
||||
int SwizzleR = (int)OGLEnumConverter.GetTextureSwizzle(Texture.XSource);
|
||||
int SwizzleG = (int)OGLEnumConverter.GetTextureSwizzle(Texture.YSource);
|
||||
int SwizzleB = (int)OGLEnumConverter.GetTextureSwizzle(Texture.ZSource);
|
||||
int SwizzleA = (int)OGLEnumConverter.GetTextureSwizzle(Texture.WSource);
|
||||
int SwizzleR = (int)OGLEnumConverter.GetTextureSwizzle(Image.XSource);
|
||||
int SwizzleG = (int)OGLEnumConverter.GetTextureSwizzle(Image.YSource);
|
||||
int SwizzleB = (int)OGLEnumConverter.GetTextureSwizzle(Image.ZSource);
|
||||
int SwizzleA = (int)OGLEnumConverter.GetTextureSwizzle(Image.WSource);
|
||||
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleR, SwizzleR);
|
||||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleG, SwizzleG);
|
||||
|
@ -110,65 +95,65 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleA, SwizzleA);
|
||||
}
|
||||
|
||||
private static int GetAstcBlockWidth(GalTextureFormat Format)
|
||||
private static int GetAstcBlockWidth(GalImageFormat Format)
|
||||
{
|
||||
switch (Format)
|
||||
{
|
||||
case GalTextureFormat.Astc2D4x4: return 4;
|
||||
case GalTextureFormat.Astc2D5x5: return 5;
|
||||
case GalTextureFormat.Astc2D6x6: return 6;
|
||||
case GalTextureFormat.Astc2D8x8: return 8;
|
||||
case GalTextureFormat.Astc2D10x10: return 10;
|
||||
case GalTextureFormat.Astc2D12x12: return 12;
|
||||
case GalTextureFormat.Astc2D5x4: return 5;
|
||||
case GalTextureFormat.Astc2D6x5: return 6;
|
||||
case GalTextureFormat.Astc2D8x6: return 8;
|
||||
case GalTextureFormat.Astc2D10x8: return 10;
|
||||
case GalTextureFormat.Astc2D12x10: return 12;
|
||||
case GalTextureFormat.Astc2D8x5: return 8;
|
||||
case GalTextureFormat.Astc2D10x5: return 10;
|
||||
case GalTextureFormat.Astc2D10x6: return 10;
|
||||
case GalImageFormat.Astc2D4x4: return 4;
|
||||
case GalImageFormat.Astc2D5x5: return 5;
|
||||
case GalImageFormat.Astc2D6x6: return 6;
|
||||
case GalImageFormat.Astc2D8x8: return 8;
|
||||
case GalImageFormat.Astc2D10x10: return 10;
|
||||
case GalImageFormat.Astc2D12x12: return 12;
|
||||
case GalImageFormat.Astc2D5x4: return 5;
|
||||
case GalImageFormat.Astc2D6x5: return 6;
|
||||
case GalImageFormat.Astc2D8x6: return 8;
|
||||
case GalImageFormat.Astc2D10x8: return 10;
|
||||
case GalImageFormat.Astc2D12x10: return 12;
|
||||
case GalImageFormat.Astc2D8x5: return 8;
|
||||
case GalImageFormat.Astc2D10x5: return 10;
|
||||
case GalImageFormat.Astc2D10x6: return 10;
|
||||
}
|
||||
|
||||
throw new ArgumentException(nameof(Format));
|
||||
}
|
||||
|
||||
private static int GetAstcBlockHeight(GalTextureFormat Format)
|
||||
private static int GetAstcBlockHeight(GalImageFormat Format)
|
||||
{
|
||||
switch (Format)
|
||||
{
|
||||
case GalTextureFormat.Astc2D4x4: return 4;
|
||||
case GalTextureFormat.Astc2D5x5: return 5;
|
||||
case GalTextureFormat.Astc2D6x6: return 6;
|
||||
case GalTextureFormat.Astc2D8x8: return 8;
|
||||
case GalTextureFormat.Astc2D10x10: return 10;
|
||||
case GalTextureFormat.Astc2D12x12: return 12;
|
||||
case GalTextureFormat.Astc2D5x4: return 4;
|
||||
case GalTextureFormat.Astc2D6x5: return 5;
|
||||
case GalTextureFormat.Astc2D8x6: return 6;
|
||||
case GalTextureFormat.Astc2D10x8: return 8;
|
||||
case GalTextureFormat.Astc2D12x10: return 10;
|
||||
case GalTextureFormat.Astc2D8x5: return 5;
|
||||
case GalTextureFormat.Astc2D10x5: return 5;
|
||||
case GalTextureFormat.Astc2D10x6: return 6;
|
||||
case GalImageFormat.Astc2D4x4: return 4;
|
||||
case GalImageFormat.Astc2D5x5: return 5;
|
||||
case GalImageFormat.Astc2D6x6: return 6;
|
||||
case GalImageFormat.Astc2D8x8: return 8;
|
||||
case GalImageFormat.Astc2D10x10: return 10;
|
||||
case GalImageFormat.Astc2D12x12: return 12;
|
||||
case GalImageFormat.Astc2D5x4: return 4;
|
||||
case GalImageFormat.Astc2D6x5: return 5;
|
||||
case GalImageFormat.Astc2D8x6: return 6;
|
||||
case GalImageFormat.Astc2D10x8: return 8;
|
||||
case GalImageFormat.Astc2D12x10: return 10;
|
||||
case GalImageFormat.Astc2D8x5: return 5;
|
||||
case GalImageFormat.Astc2D10x5: return 5;
|
||||
case GalImageFormat.Astc2D10x6: return 6;
|
||||
}
|
||||
|
||||
throw new ArgumentException(nameof(Format));
|
||||
}
|
||||
|
||||
public bool TryGetCachedTexture(long Key, long DataSize, out GalTexture Texture)
|
||||
public bool TryGetCachedTexture(long Key, long DataSize, out GalImage Image)
|
||||
{
|
||||
if (TextureCache.TryGetSize(Key, out long Size) && Size == DataSize)
|
||||
{
|
||||
if (TextureCache.TryGetValue(Key, out TCE CachedTexture))
|
||||
{
|
||||
Texture = CachedTexture.Texture;
|
||||
Image = CachedTexture.Image;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Texture = default(GalTexture);
|
||||
Image = default(GalImage);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -208,18 +193,18 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBorderColor, Color);
|
||||
}
|
||||
|
||||
private static bool IsCompressedTextureFormat(GalTextureFormat Format)
|
||||
private static bool IsCompressedTextureFormat(GalImageFormat Format)
|
||||
{
|
||||
switch (Format)
|
||||
{
|
||||
case GalTextureFormat.BC6H_UF16:
|
||||
case GalTextureFormat.BC6H_SF16:
|
||||
case GalTextureFormat.BC7U:
|
||||
case GalTextureFormat.BC1:
|
||||
case GalTextureFormat.BC2:
|
||||
case GalTextureFormat.BC3:
|
||||
case GalTextureFormat.BC4:
|
||||
case GalTextureFormat.BC5:
|
||||
case GalImageFormat.BC6H_UF16:
|
||||
case GalImageFormat.BC6H_SF16:
|
||||
case GalImageFormat.BC7U:
|
||||
case GalImageFormat.BC1:
|
||||
case GalImageFormat.BC2:
|
||||
case GalImageFormat.BC3:
|
||||
case GalImageFormat.BC4:
|
||||
case GalImageFormat.BC5:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
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>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="Gal\OpenGL\TCE.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="OpenTK.NetStandard" Version="1.0.4" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -166,7 +166,7 @@ namespace Ryujinx.HLE.Gpu.Engines
|
|||
|
||||
int Format = ReadRegister(NvGpuEngine3dReg.FrameBufferNFormat + FbIndex * 0x10);
|
||||
|
||||
if (VA == 0 || Format == 0)
|
||||
if (VA == 0/* || Format == 0*/)
|
||||
{
|
||||
Gpu.Renderer.FrameBuffer.UnbindColor(FbIndex);
|
||||
|
||||
|
@ -479,13 +479,13 @@ namespace Ryujinx.HLE.Gpu.Engines
|
|||
}
|
||||
else
|
||||
{
|
||||
GalTexture NewTexture = TextureFactory.MakeTexture(Vmm, TicPosition);
|
||||
GalImage NewTexture = TextureFactory.MakeTexture(Vmm, TicPosition);
|
||||
|
||||
long Size = (uint)TextureHelper.GetTextureSize(NewTexture);
|
||||
|
||||
bool HasCachedTexture = false;
|
||||
|
||||
if (Gpu.Renderer.Texture.TryGetCachedTexture(Key, Size, out GalTexture Texture))
|
||||
if (Gpu.Renderer.Texture.TryGetCachedTexture(Key, Size, out GalImage Texture))
|
||||
{
|
||||
if (NewTexture.Equals(Texture) && !QueryKeyUpload(Vmm, Key, Size, NvGpuBufferType.Texture))
|
||||
{
|
||||
|
|
|
@ -6,11 +6,11 @@ namespace Ryujinx.HLE.Gpu.Texture
|
|||
{
|
||||
static class TextureFactory
|
||||
{
|
||||
public static GalTexture MakeTexture(NvGpuVmm Vmm, long TicPosition)
|
||||
public static GalImage MakeTexture(NvGpuVmm Vmm, long TicPosition)
|
||||
{
|
||||
int[] Tic = ReadWords(Vmm, TicPosition, 8);
|
||||
|
||||
GalTextureFormat Format = (GalTextureFormat)(Tic[0] & 0x7f);
|
||||
GalImageFormat Format = ImageFormatConverter.ConvertTexture((GalTextureFormat)(Tic[0] & 0x7f));
|
||||
|
||||
GalTextureSource XSource = (GalTextureSource)((Tic[0] >> 19) & 7);
|
||||
GalTextureSource YSource = (GalTextureSource)((Tic[0] >> 22) & 7);
|
||||
|
@ -20,7 +20,7 @@ namespace Ryujinx.HLE.Gpu.Texture
|
|||
int Width = (Tic[4] & 0xffff) + 1;
|
||||
int Height = (Tic[5] & 0xffff) + 1;
|
||||
|
||||
return new GalTexture(
|
||||
return new GalImage(
|
||||
Width,
|
||||
Height,
|
||||
Format,
|
||||
|
|
|
@ -30,117 +30,117 @@ namespace Ryujinx.HLE.Gpu.Texture
|
|||
throw new NotImplementedException(Texture.Swizzle.ToString());
|
||||
}
|
||||
|
||||
public static int GetTextureSize(GalTexture Texture)
|
||||
public static int GetTextureSize(GalImage Image)
|
||||
{
|
||||
switch (Texture.Format)
|
||||
switch (Image.Format)
|
||||
{
|
||||
case GalTextureFormat.R32G32B32A32:
|
||||
return Texture.Width * Texture.Height * 16;
|
||||
case GalImageFormat.R32G32B32A32:
|
||||
return Image.Width * Image.Height * 16;
|
||||
|
||||
case GalTextureFormat.R16G16B16A16:
|
||||
return Texture.Width * Texture.Height * 8;
|
||||
case GalImageFormat.R16G16B16A16:
|
||||
return Image.Width * Image.Height * 8;
|
||||
|
||||
case GalTextureFormat.A8B8G8R8:
|
||||
case GalTextureFormat.A2B10G10R10:
|
||||
case GalTextureFormat.R32:
|
||||
case GalTextureFormat.ZF32:
|
||||
case GalTextureFormat.BF10GF11RF11:
|
||||
case GalTextureFormat.Z24S8:
|
||||
return Texture.Width * Texture.Height * 4;
|
||||
case GalImageFormat.A8B8G8R8:
|
||||
case GalImageFormat.A2B10G10R10:
|
||||
case GalImageFormat.R32:
|
||||
case GalImageFormat.ZF32:
|
||||
case GalImageFormat.BF10GF11RF11:
|
||||
case GalImageFormat.Z24S8:
|
||||
return Image.Width * Image.Height * 4;
|
||||
|
||||
case GalTextureFormat.A1B5G5R5:
|
||||
case GalTextureFormat.B5G6R5:
|
||||
case GalTextureFormat.G8R8:
|
||||
case GalTextureFormat.R16:
|
||||
return Texture.Width * Texture.Height * 2;
|
||||
case GalImageFormat.A1B5G5R5:
|
||||
case GalImageFormat.B5G6R5:
|
||||
case GalImageFormat.G8R8:
|
||||
case GalImageFormat.R16:
|
||||
return Image.Width * Image.Height * 2;
|
||||
|
||||
case GalTextureFormat.R8:
|
||||
return Texture.Width * Texture.Height;
|
||||
case GalImageFormat.R8:
|
||||
return Image.Width * Image.Height;
|
||||
|
||||
case GalTextureFormat.BC1:
|
||||
case GalTextureFormat.BC4:
|
||||
case GalImageFormat.BC1:
|
||||
case GalImageFormat.BC4:
|
||||
{
|
||||
return CompressedTextureSize(Texture.Width, Texture.Height, 4, 4, 8);
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 4, 4, 8);
|
||||
}
|
||||
|
||||
case GalTextureFormat.BC6H_SF16:
|
||||
case GalTextureFormat.BC6H_UF16:
|
||||
case GalTextureFormat.BC7U:
|
||||
case GalTextureFormat.BC2:
|
||||
case GalTextureFormat.BC3:
|
||||
case GalTextureFormat.BC5:
|
||||
case GalTextureFormat.Astc2D4x4:
|
||||
case GalImageFormat.BC6H_SF16:
|
||||
case GalImageFormat.BC6H_UF16:
|
||||
case GalImageFormat.BC7U:
|
||||
case GalImageFormat.BC2:
|
||||
case GalImageFormat.BC3:
|
||||
case GalImageFormat.BC5:
|
||||
case GalImageFormat.Astc2D4x4:
|
||||
{
|
||||
return CompressedTextureSize(Texture.Width, Texture.Height, 4, 4, 16);
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 4, 4, 16);
|
||||
}
|
||||
|
||||
case GalTextureFormat.Astc2D5x5:
|
||||
case GalImageFormat.Astc2D5x5:
|
||||
{
|
||||
return CompressedTextureSize(Texture.Width, Texture.Height, 5, 5, 16);
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 5, 5, 16);
|
||||
}
|
||||
|
||||
case GalTextureFormat.Astc2D6x6:
|
||||
case GalImageFormat.Astc2D6x6:
|
||||
{
|
||||
return CompressedTextureSize(Texture.Width, Texture.Height, 6, 6, 16);
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 6, 6, 16);
|
||||
}
|
||||
|
||||
case GalTextureFormat.Astc2D8x8:
|
||||
case GalImageFormat.Astc2D8x8:
|
||||
{
|
||||
return CompressedTextureSize(Texture.Width, Texture.Height, 8, 8, 16);
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 8, 8, 16);
|
||||
}
|
||||
|
||||
case GalTextureFormat.Astc2D10x10:
|
||||
case GalImageFormat.Astc2D10x10:
|
||||
{
|
||||
return CompressedTextureSize(Texture.Width, Texture.Height, 10, 10, 16);
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 10, 10, 16);
|
||||
}
|
||||
|
||||
case GalTextureFormat.Astc2D12x12:
|
||||
case GalImageFormat.Astc2D12x12:
|
||||
{
|
||||
return CompressedTextureSize(Texture.Width, Texture.Height, 12, 12, 16);
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 12, 12, 16);
|
||||
}
|
||||
|
||||
case GalTextureFormat.Astc2D5x4:
|
||||
case GalImageFormat.Astc2D5x4:
|
||||
{
|
||||
return CompressedTextureSize(Texture.Width, Texture.Height, 5, 4, 16);
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 5, 4, 16);
|
||||
}
|
||||
|
||||
case GalTextureFormat.Astc2D6x5:
|
||||
case GalImageFormat.Astc2D6x5:
|
||||
{
|
||||
return CompressedTextureSize(Texture.Width, Texture.Height, 6, 5, 16);
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 6, 5, 16);
|
||||
}
|
||||
|
||||
case GalTextureFormat.Astc2D8x6:
|
||||
case GalImageFormat.Astc2D8x6:
|
||||
{
|
||||
return CompressedTextureSize(Texture.Width, Texture.Height, 8, 6, 16);
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 8, 6, 16);
|
||||
}
|
||||
|
||||
case GalTextureFormat.Astc2D10x8:
|
||||
case GalImageFormat.Astc2D10x8:
|
||||
{
|
||||
return CompressedTextureSize(Texture.Width, Texture.Height, 10, 8, 16);
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 10, 8, 16);
|
||||
}
|
||||
|
||||
case GalTextureFormat.Astc2D12x10:
|
||||
case GalImageFormat.Astc2D12x10:
|
||||
{
|
||||
return CompressedTextureSize(Texture.Width, Texture.Height, 12, 10, 16);
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 12, 10, 16);
|
||||
}
|
||||
|
||||
case GalTextureFormat.Astc2D8x5:
|
||||
case GalImageFormat.Astc2D8x5:
|
||||
{
|
||||
return CompressedTextureSize(Texture.Width, Texture.Height, 8, 5, 16);
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 8, 5, 16);
|
||||
}
|
||||
|
||||
case GalTextureFormat.Astc2D10x5:
|
||||
case GalImageFormat.Astc2D10x5:
|
||||
{
|
||||
return CompressedTextureSize(Texture.Width, Texture.Height, 10, 5, 16);
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 10, 5, 16);
|
||||
}
|
||||
|
||||
case GalTextureFormat.Astc2D10x6:
|
||||
case GalImageFormat.Astc2D10x6:
|
||||
{
|
||||
return CompressedTextureSize(Texture.Width, Texture.Height, 10, 6, 16);
|
||||
return CompressedTextureSize(Image.Width, Image.Height, 10, 6, 16);
|
||||
}
|
||||
}
|
||||
|
||||
throw new NotImplementedException(Texture.Format.ToString());
|
||||
throw new NotImplementedException(Image.Format.ToString());
|
||||
}
|
||||
|
||||
public static int CompressedTextureSize(int TextureWidth, int TextureHeight, int BlockWidth, int BlockHeight, int Bpb)
|
||||
|
|
Loading…
Add table
Reference in a new issue