diff options
Diffstat (limited to 'Ryujinx.Graphics/Gal/OpenGL')
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs | 143 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs | 111 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs (renamed from Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs) | 9 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLRenderer.cs | 4 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs | 99 |
5 files changed, 198 insertions, 168 deletions
diff --git a/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs b/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs index 74f18dcd..dda82538 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs @@ -1,13 +1,11 @@ using OpenTK.Graphics.OpenGL; +using Ryujinx.Graphics.Texture; using System; namespace Ryujinx.Graphics.Gal.OpenGL { class ImageHandler { - //TODO: Use a variable value here - public const int MaxBpp = 16; - private static int CopyBuffer = 0; private static int CopyBufferSize = 0; @@ -38,87 +36,124 @@ namespace Ryujinx.Graphics.Gal.OpenGL this.Image = Image; } - public void EnsureSetup(GalImage Image) + public void EnsureSetup(GalImage NewImage) { - if (Width != Image.Width || - Height != Image.Height || - Format != Image.Format || - !Initialized) + if (Width == NewImage.Width && + Height == NewImage.Height && + Format == NewImage.Format && + Initialized) { - (PixelInternalFormat InternalFormat, PixelFormat PixelFormat, PixelType PixelType) = - OGLEnumConverter.GetImageFormat(Image.Format); + return; + } - GL.BindTexture(TextureTarget.Texture2D, Handle); + PixelInternalFormat InternalFmt; + PixelFormat PixelFormat; + PixelType PixelType; - if (Initialized) - { - if (CopyBuffer == 0) - { - CopyBuffer = GL.GenBuffer(); - } + if (ImageUtils.IsCompressed(NewImage.Format)) + { + InternalFmt = (PixelInternalFormat)OGLEnumConverter.GetCompressedImageFormat(NewImage.Format); + + PixelFormat = default(PixelFormat); + PixelType = default(PixelType); + } + else + { + (InternalFmt, PixelFormat, PixelType) = OGLEnumConverter.GetImageFormat(NewImage.Format); + } - int MaxWidth = Math.Max(Image.Width, Width); - int MaxHeight = Math.Max(Image.Height, Height); + GL.BindTexture(TextureTarget.Texture2D, Handle); - int CurrentSize = MaxWidth * MaxHeight * MaxBpp; + if (Initialized) + { + if (CopyBuffer == 0) + { + CopyBuffer = GL.GenBuffer(); + } - GL.BindBuffer(BufferTarget.PixelPackBuffer, CopyBuffer); - GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyBuffer); + int CurrentSize = Math.Max(ImageUtils.GetSize(NewImage), + ImageUtils.GetSize(Image)); - if (CopyBufferSize < CurrentSize) - { - CopyBufferSize = CurrentSize; + GL.BindBuffer(BufferTarget.PixelPackBuffer, CopyBuffer); + GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyBuffer); - GL.BufferData(BufferTarget.PixelPackBuffer, CurrentSize, IntPtr.Zero, BufferUsageHint.StreamCopy); - } + if (CopyBufferSize < CurrentSize) + { + CopyBufferSize = CurrentSize; + GL.BufferData(BufferTarget.PixelPackBuffer, CurrentSize, IntPtr.Zero, BufferUsageHint.StreamCopy); + } + + if (ImageUtils.IsCompressed(Image.Format)) + { + GL.GetCompressedTexImage(TextureTarget.Texture2D, 0, IntPtr.Zero); + } + else + { GL.GetTexImage(TextureTarget.Texture2D, 0, this.PixelFormat, this.PixelType, IntPtr.Zero); + } - GL.DeleteTexture(Handle); + GL.DeleteTexture(Handle); - Handle = GL.GenTexture(); + Handle = GL.GenTexture(); - GL.BindTexture(TextureTarget.Texture2D, Handle); - } + GL.BindTexture(TextureTarget.Texture2D, Handle); + } - const int MinFilter = (int)TextureMinFilter.Linear; - const int MagFilter = (int)TextureMagFilter.Linear; + 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); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, MinFilter); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, MagFilter); - const int Level = 0; - const int Border = 0; + const int Level = 0; + const int Border = 0; + if (ImageUtils.IsCompressed(NewImage.Format)) + { + Console.WriteLine("Hit"); + + GL.CompressedTexImage2D( + TextureTarget.Texture2D, + Level, + (InternalFormat)InternalFmt, + NewImage.Width, + NewImage.Height, + Border, + ImageUtils.GetSize(NewImage), + IntPtr.Zero); + } + else + { GL.TexImage2D( TextureTarget.Texture2D, Level, - InternalFormat, - Image.Width, - Image.Height, + InternalFmt, + NewImage.Width, + NewImage.Height, Border, PixelFormat, PixelType, IntPtr.Zero); + } - if (Initialized) - { - GL.BindBuffer(BufferTarget.PixelPackBuffer, 0); - GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0); - } + if (Initialized) + { + GL.BindBuffer(BufferTarget.PixelPackBuffer, 0); + GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0); + } - this.Image = Image; + Image = NewImage; - this.InternalFormat = InternalFormat; - this.PixelFormat = PixelFormat; - this.PixelType = PixelType; + this.InternalFormat = InternalFmt; + this.PixelFormat = PixelFormat; + this.PixelType = PixelType; - Initialized = true; - } + Initialized = true; } - public bool HasColor { get => ImageFormatConverter.HasColor(Format); } - public bool HasDepth { get => ImageFormatConverter.HasDepth(Format); } - public bool HasStencil { get => ImageFormatConverter.HasStencil(Format); } + public bool HasColor => ImageUtils.HasColor(Image.Format); + public bool HasDepth => ImageUtils.HasDepth(Image.Format); + public bool HasStencil => ImageUtils.HasStencil(Image.Format); } } diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs index 959d0e32..1d4f4cf7 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs @@ -129,52 +129,51 @@ namespace Ryujinx.Graphics.Gal.OpenGL { switch (Format) { - case GalImageFormat.R32G32B32A32_SFLOAT: return (PixelInternalFormat.Rgba32f, PixelFormat.Rgba, PixelType.Float); - case GalImageFormat.R32G32B32A32_SINT: return (PixelInternalFormat.Rgba32i, PixelFormat.RgbaInteger, PixelType.Int); - case GalImageFormat.R32G32B32A32_UINT: return (PixelInternalFormat.Rgba32ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt); - case GalImageFormat.R16G16B16A16_SFLOAT: return (PixelInternalFormat.Rgba16f, PixelFormat.Rgba, PixelType.HalfFloat); - case GalImageFormat.R16G16B16A16_SINT: return (PixelInternalFormat.Rgba16i, PixelFormat.RgbaInteger, PixelType.Short); - case GalImageFormat.R16G16B16A16_UINT: return (PixelInternalFormat.Rgba16ui, PixelFormat.RgbaInteger, PixelType.UnsignedShort); - case GalImageFormat.R32G32_SFLOAT: return (PixelInternalFormat.Rg32f, PixelFormat.Rg, PixelType.Float); - case GalImageFormat.R32G32_SINT: return (PixelInternalFormat.Rg32i, PixelFormat.RgInteger, PixelType.Int); - case GalImageFormat.R32G32_UINT: return (PixelInternalFormat.Rg32ui, PixelFormat.RgInteger, PixelType.UnsignedInt); - case GalImageFormat.A8B8G8R8_SNORM_PACK32: return (PixelInternalFormat.Rgba8Snorm, PixelFormat.Rgba, PixelType.Byte); - case GalImageFormat.A8B8G8R8_UNORM_PACK32: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte); - case GalImageFormat.A8B8G8R8_SINT_PACK32: return (PixelInternalFormat.Rgba8i, PixelFormat.RgbaInteger, PixelType.Byte); - case GalImageFormat.A8B8G8R8_UINT_PACK32: return (PixelInternalFormat.Rgba8ui, PixelFormat.RgbaInteger, PixelType.UnsignedByte); - case GalImageFormat.A8B8G8R8_SRGB_PACK32: return (PixelInternalFormat.Srgb8Alpha8, PixelFormat.Rgba, PixelType.UnsignedByte); - case GalImageFormat.A2B10G10R10_UINT_PACK32: return (PixelInternalFormat.Rgb10A2ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt2101010Reversed); - case GalImageFormat.A2B10G10R10_UNORM_PACK32: return (PixelInternalFormat.Rgb10A2, PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed); - case GalImageFormat.R32_SFLOAT: return (PixelInternalFormat.R32f, PixelFormat.Red, PixelType.Float); - case GalImageFormat.R32_SINT: return (PixelInternalFormat.R32i, PixelFormat.Red, PixelType.Int); - case GalImageFormat.R32_UINT: return (PixelInternalFormat.R32ui, PixelFormat.Red, PixelType.UnsignedInt); - case GalImageFormat.A1R5G5B5_UNORM_PACK16: return (PixelInternalFormat.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort5551); - case GalImageFormat.B5G6R5_UNORM_PACK16: return (PixelInternalFormat.Rgba, PixelFormat.Rgb, PixelType.UnsignedShort565); - case GalImageFormat.R16G16_SFLOAT: return (PixelInternalFormat.Rg16f, PixelFormat.Rg, PixelType.HalfFloat); - case GalImageFormat.R16G16_SINT: return (PixelInternalFormat.Rg16i, PixelFormat.RgInteger, PixelType.Short); - case GalImageFormat.R16G16_SNORM: return (PixelInternalFormat.Rg16Snorm, PixelFormat.Rg, PixelType.Byte); - case GalImageFormat.R16G16_UNORM: return (PixelInternalFormat.Rg16, PixelFormat.Rg, PixelType.UnsignedShort); - case GalImageFormat.R8G8_SINT: return (PixelInternalFormat.Rg8i, PixelFormat.RgInteger, PixelType.Byte); - case GalImageFormat.R8G8_SNORM: return (PixelInternalFormat.Rg8Snorm, PixelFormat.Rg, PixelType.Byte); - case GalImageFormat.R8G8_UINT: return (PixelInternalFormat.Rg8ui, PixelFormat.RgInteger, PixelType.UnsignedByte); - case GalImageFormat.R8G8_UNORM: return (PixelInternalFormat.Rg8, PixelFormat.Rg, PixelType.UnsignedByte); - case GalImageFormat.R16_SFLOAT: return (PixelInternalFormat.R16f, PixelFormat.Red, PixelType.HalfFloat); - case GalImageFormat.R16_SINT: return (PixelInternalFormat.R16i, PixelFormat.RedInteger, PixelType.Short); - case GalImageFormat.R16_SNORM: return (PixelInternalFormat.R16Snorm, PixelFormat.Red, PixelType.Byte); - case GalImageFormat.R16_UINT: return (PixelInternalFormat.R16ui, PixelFormat.RedInteger, PixelType.UnsignedShort); - case GalImageFormat.R16_UNORM: return (PixelInternalFormat.R16, PixelFormat.Red, PixelType.UnsignedShort); - case GalImageFormat.R8_SINT: return (PixelInternalFormat.R8i, PixelFormat.RedInteger, PixelType.Byte); - case GalImageFormat.R8_SNORM: return (PixelInternalFormat.R8Snorm, PixelFormat.Red, PixelType.Byte); - case GalImageFormat.R8_UINT: return (PixelInternalFormat.R8ui, PixelFormat.RedInteger, PixelType.UnsignedByte); - case GalImageFormat.R8_UNORM: return (PixelInternalFormat.R8, PixelFormat.Red, PixelType.UnsignedByte); - case GalImageFormat.B10G11R11_UFLOAT_PACK32: return (PixelInternalFormat.R11fG11fB10f, PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev); - - case GalImageFormat.R4G4B4A4_UNORM_PACK16_REVERSED: return (PixelInternalFormat.Rgba4, PixelFormat.Rgba, PixelType.UnsignedShort4444Reversed); - - case GalImageFormat.D24_UNORM_S8_UINT: return (PixelInternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248); - case GalImageFormat.D32_SFLOAT: return (PixelInternalFormat.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float); - case GalImageFormat.D16_UNORM: return (PixelInternalFormat.DepthComponent16, PixelFormat.DepthComponent, PixelType.UnsignedShort); - case GalImageFormat.D32_SFLOAT_S8_UINT: return (PixelInternalFormat.Depth32fStencil8, PixelFormat.DepthStencil, PixelType.Float32UnsignedInt248Rev); + case GalImageFormat.R32G32B32A32 | GalImageFormat.Sfloat: return (PixelInternalFormat.Rgba32f, PixelFormat.Rgba, PixelType.Float); + case GalImageFormat.R32G32B32A32 | GalImageFormat.Sint: return (PixelInternalFormat.Rgba32i, PixelFormat.RgbaInteger, PixelType.Int); + case GalImageFormat.R32G32B32A32 | GalImageFormat.Uint: return (PixelInternalFormat.Rgba32ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt); + case GalImageFormat.R16G16B16A16 | GalImageFormat.Sfloat: return (PixelInternalFormat.Rgba16f, PixelFormat.Rgba, PixelType.HalfFloat); + case GalImageFormat.R16G16B16A16 | GalImageFormat.Sint: return (PixelInternalFormat.Rgba16i, PixelFormat.RgbaInteger, PixelType.Short); + case GalImageFormat.R16G16B16A16 | GalImageFormat.Uint: return (PixelInternalFormat.Rgba16ui, PixelFormat.RgbaInteger, PixelType.UnsignedShort); + case GalImageFormat.R32G32 | GalImageFormat.Sfloat: return (PixelInternalFormat.Rg32f, PixelFormat.Rg, PixelType.Float); + case GalImageFormat.R32G32 | GalImageFormat.Sint: return (PixelInternalFormat.Rg32i, PixelFormat.RgInteger, PixelType.Int); + case GalImageFormat.R32G32 | GalImageFormat.Uint: return (PixelInternalFormat.Rg32ui, PixelFormat.RgInteger, PixelType.UnsignedInt); + case GalImageFormat.A8B8G8R8 | GalImageFormat.Snorm: return (PixelInternalFormat.Rgba8Snorm, PixelFormat.Rgba, PixelType.Byte); + case GalImageFormat.A8B8G8R8 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte); + case GalImageFormat.A8B8G8R8 | GalImageFormat.Sint: return (PixelInternalFormat.Rgba8i, PixelFormat.RgbaInteger, PixelType.Byte); + case GalImageFormat.A8B8G8R8 | GalImageFormat.Uint: return (PixelInternalFormat.Rgba8ui, PixelFormat.RgbaInteger, PixelType.UnsignedByte); + case GalImageFormat.A8B8G8R8_SRGB: return (PixelInternalFormat.Srgb8Alpha8, PixelFormat.Rgba, PixelType.UnsignedByte); + case GalImageFormat.A4B4G4R4 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba4, PixelFormat.Rgba, PixelType.UnsignedShort4444Reversed); + case GalImageFormat.A2B10G10R10 | GalImageFormat.Uint: return (PixelInternalFormat.Rgb10A2ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt2101010Reversed); + case GalImageFormat.A2B10G10R10 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgb10A2, PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed); + case GalImageFormat.R32 | GalImageFormat.Sfloat: return (PixelInternalFormat.R32f, PixelFormat.Red, PixelType.Float); + case GalImageFormat.R32 | GalImageFormat.Sint: return (PixelInternalFormat.R32i, PixelFormat.Red, PixelType.Int); + case GalImageFormat.R32 | GalImageFormat.Uint: return (PixelInternalFormat.R32ui, PixelFormat.Red, PixelType.UnsignedInt); + case GalImageFormat.A1R5G5B5 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort5551); + case GalImageFormat.B5G6R5 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba, PixelFormat.Rgb, PixelType.UnsignedShort565); + case GalImageFormat.R16G16 | GalImageFormat.Sfloat: return (PixelInternalFormat.Rg16f, PixelFormat.Rg, PixelType.HalfFloat); + case GalImageFormat.R16G16 | GalImageFormat.Sint: return (PixelInternalFormat.Rg16i, PixelFormat.RgInteger, PixelType.Short); + case GalImageFormat.R16G16 | GalImageFormat.Snorm: return (PixelInternalFormat.Rg16Snorm, PixelFormat.Rg, PixelType.Byte); + case GalImageFormat.R16G16 | GalImageFormat.Unorm: return (PixelInternalFormat.Rg16, PixelFormat.Rg, PixelType.UnsignedShort); + case GalImageFormat.R8G8 | GalImageFormat.Sint: return (PixelInternalFormat.Rg8i, PixelFormat.RgInteger, PixelType.Byte); + case GalImageFormat.R8G8 | GalImageFormat.Snorm: return (PixelInternalFormat.Rg8Snorm, PixelFormat.Rg, PixelType.Byte); + case GalImageFormat.R8G8 | GalImageFormat.Uint: return (PixelInternalFormat.Rg8ui, PixelFormat.RgInteger, PixelType.UnsignedByte); + case GalImageFormat.R8G8 | GalImageFormat.Unorm: return (PixelInternalFormat.Rg8, PixelFormat.Rg, PixelType.UnsignedByte); + case GalImageFormat.R16 | GalImageFormat.Sfloat: return (PixelInternalFormat.R16f, PixelFormat.Red, PixelType.HalfFloat); + case GalImageFormat.R16 | GalImageFormat.Sint: return (PixelInternalFormat.R16i, PixelFormat.RedInteger, PixelType.Short); + case GalImageFormat.R16 | GalImageFormat.Snorm: return (PixelInternalFormat.R16Snorm, PixelFormat.Red, PixelType.Byte); + case GalImageFormat.R16 | GalImageFormat.Uint: return (PixelInternalFormat.R16ui, PixelFormat.RedInteger, PixelType.UnsignedShort); + case GalImageFormat.R16 | GalImageFormat.Unorm: return (PixelInternalFormat.R16, PixelFormat.Red, PixelType.UnsignedShort); + case GalImageFormat.R8 | GalImageFormat.Sint: return (PixelInternalFormat.R8i, PixelFormat.RedInteger, PixelType.Byte); + case GalImageFormat.R8 | GalImageFormat.Snorm: return (PixelInternalFormat.R8Snorm, PixelFormat.Red, PixelType.Byte); + case GalImageFormat.R8 | GalImageFormat.Uint: return (PixelInternalFormat.R8ui, PixelFormat.RedInteger, PixelType.UnsignedByte); + case GalImageFormat.R8 | GalImageFormat.Unorm: return (PixelInternalFormat.R8, PixelFormat.Red, PixelType.UnsignedByte); + case GalImageFormat.B10G11R11 | GalImageFormat.Sfloat: return (PixelInternalFormat.R11fG11fB10f, PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev); + + case GalImageFormat.D24_S8 | GalImageFormat.Unorm: return (PixelInternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248); + case GalImageFormat.D32 | GalImageFormat.Sfloat: return (PixelInternalFormat.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float); + case GalImageFormat.D16 | GalImageFormat.Unorm: return (PixelInternalFormat.DepthComponent16, PixelFormat.DepthComponent, PixelType.UnsignedShort); + case GalImageFormat.D32_S8 | GalImageFormat.Uint: return (PixelInternalFormat.Depth32fStencil8, PixelFormat.DepthStencil, PixelType.Float32UnsignedInt248Rev); } throw new NotImplementedException(Format.ToString()); @@ -184,16 +183,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL { switch (Format) { - case GalImageFormat.BC6H_UFLOAT_BLOCK: return InternalFormat.CompressedRgbBptcUnsignedFloat; - case GalImageFormat.BC6H_SFLOAT_BLOCK: return InternalFormat.CompressedRgbBptcSignedFloat; - case GalImageFormat.BC7_UNORM_BLOCK: return InternalFormat.CompressedRgbaBptcUnorm; - case GalImageFormat.BC1_RGBA_UNORM_BLOCK: return InternalFormat.CompressedRgbaS3tcDxt1Ext; - case GalImageFormat.BC2_UNORM_BLOCK: return InternalFormat.CompressedRgbaS3tcDxt3Ext; - case GalImageFormat.BC3_UNORM_BLOCK: return InternalFormat.CompressedRgbaS3tcDxt5Ext; - case GalImageFormat.BC4_SNORM_BLOCK: return InternalFormat.CompressedSignedRedRgtc1; - case GalImageFormat.BC4_UNORM_BLOCK: return InternalFormat.CompressedRedRgtc1; - case GalImageFormat.BC5_SNORM_BLOCK: return InternalFormat.CompressedSignedRgRgtc2; - case GalImageFormat.BC5_UNORM_BLOCK: return InternalFormat.CompressedRgRgtc2; + case GalImageFormat.BC6H_UF16 | GalImageFormat.Unorm: return InternalFormat.CompressedRgbBptcUnsignedFloat; + case GalImageFormat.BC6H_SF16 | GalImageFormat.Unorm: return InternalFormat.CompressedRgbBptcSignedFloat; + case GalImageFormat.BC7 | GalImageFormat.Unorm: return InternalFormat.CompressedRgbaBptcUnorm; + case GalImageFormat.BC1_RGBA | GalImageFormat.Unorm: return InternalFormat.CompressedRgbaS3tcDxt1Ext; + case GalImageFormat.BC2 | GalImageFormat.Unorm: return InternalFormat.CompressedRgbaS3tcDxt3Ext; + case GalImageFormat.BC3 | GalImageFormat.Unorm: return InternalFormat.CompressedRgbaS3tcDxt5Ext; + case GalImageFormat.BC4 | GalImageFormat.Snorm: return InternalFormat.CompressedSignedRedRgtc1; + case GalImageFormat.BC4 | GalImageFormat.Unorm: return InternalFormat.CompressedRedRgtc1; + case GalImageFormat.BC5 | GalImageFormat.Snorm: return InternalFormat.CompressedSignedRgRgtc2; + case GalImageFormat.BC5 | GalImageFormat.Unorm: return InternalFormat.CompressedRgRgtc2; } throw new NotImplementedException(Format.ToString()); diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs index 12239c4f..99bfa350 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs @@ -1,9 +1,10 @@ using OpenTK.Graphics.OpenGL; +using Ryujinx.Graphics.Texture; using System; namespace Ryujinx.Graphics.Gal.OpenGL { - class OGLFrameBuffer : IGalFrameBuffer + class OGLRenderTarget : IGalRenderTarget { private struct Rect { @@ -24,7 +25,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL private const int NativeWidth = 1280; private const int NativeHeight = 720; - private const GalImageFormat RawFormat = GalImageFormat.A8B8G8R8_UNORM_PACK32; + private const GalImageFormat RawFormat = GalImageFormat.A8B8G8R8 | GalImageFormat.Unorm; private OGLTexture Texture; @@ -56,7 +57,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL private int DepthAttachment; private int StencilAttachment; - public OGLFrameBuffer(OGLTexture Texture) + public OGLRenderTarget(OGLTexture Texture) { ColorAttachments = new int[8]; @@ -379,7 +380,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL { if (Texture.TryGetImage(Key, out ImageHandler Tex)) { - byte[] Data = new byte[Tex.Width * Tex.Height * ImageHandler.MaxBpp]; + byte[] Data = new byte[ImageUtils.GetSize(Tex.Image)]; GL.BindTexture(TextureTarget.Texture2D, Tex.Handle); diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderer.cs index 985f1086..a23541f3 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderer.cs @@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL { public IGalConstBuffer Buffer { get; private set; } - public IGalFrameBuffer FrameBuffer { get; private set; } + public IGalRenderTarget RenderTarget { get; private set; } public IGalRasterizer Rasterizer { get; private set; } @@ -25,7 +25,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL Texture = new OGLTexture(); - FrameBuffer = new OGLFrameBuffer(Texture as OGLTexture); + RenderTarget = new OGLRenderTarget(Texture as OGLTexture); Rasterizer = new OGLRasterizer(); diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs index e4d4bd64..82f9c913 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs @@ -1,5 +1,5 @@ using OpenTK.Graphics.OpenGL; -using Ryujinx.Graphics.Gal.Texture; +using Ryujinx.Graphics.Texture; using System; namespace Ryujinx.Graphics.Gal.OpenGL @@ -39,7 +39,11 @@ namespace Ryujinx.Graphics.Gal.OpenGL const int Level = 0; //TODO: Support mipmap textures. const int Border = 0; - if (IsCompressedTextureFormat(Image.Format)) + GalImageFormat TypeLess = Image.Format & GalImageFormat.FormatMask; + + bool IsASTC = TypeLess >= GalImageFormat.ASTC_BEGIN && TypeLess <= GalImageFormat.ASTC_END; + + if (ImageUtils.IsCompressed(Image.Format) && !IsASTC) { InternalFormat InternalFmt = OGLEnumConverter.GetCompressedImageFormat(Image.Format); @@ -55,7 +59,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL } else { - if (Image.Format >= GalImageFormat.ASTC_BEGIN && Image.Format <= GalImageFormat.ASTC_END) + //TODO: Use KHR_texture_compression_astc_hdr when available + if (IsASTC) { int TextureBlockWidth = GetAstcBlockWidth(Image.Format); int TextureBlockHeight = GetAstcBlockHeight(Image.Format); @@ -67,7 +72,17 @@ namespace Ryujinx.Graphics.Gal.OpenGL Image.Width, Image.Height, 1); - Image.Format = GalImageFormat.A8B8G8R8_UNORM_PACK32; + Image.Format = GalImageFormat.A8B8G8R8 | GalImageFormat.Unorm; + } + else if (TypeLess == GalImageFormat.G8R8) + { + Data = ImageConverter.G8R8ToR8G8( + Data, + Image.Width, + Image.Height, + 1); + + Image.Format = GalImageFormat.R8G8 | (Image.Format & GalImageFormat.FormatMask); } (PixelInternalFormat InternalFormat, PixelFormat Format, PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format); @@ -123,20 +138,20 @@ namespace Ryujinx.Graphics.Gal.OpenGL { switch (Format) { - case GalImageFormat.ASTC_4x4_UNORM_BLOCK: return 4; - case GalImageFormat.ASTC_5x5_UNORM_BLOCK: return 5; - case GalImageFormat.ASTC_6x6_UNORM_BLOCK: return 6; - case GalImageFormat.ASTC_8x8_UNORM_BLOCK: return 8; - case GalImageFormat.ASTC_10x10_UNORM_BLOCK: return 10; - case GalImageFormat.ASTC_12x12_UNORM_BLOCK: return 12; - case GalImageFormat.ASTC_5x4_UNORM_BLOCK: return 5; - case GalImageFormat.ASTC_6x5_UNORM_BLOCK: return 6; - case GalImageFormat.ASTC_8x6_UNORM_BLOCK: return 8; - case GalImageFormat.ASTC_10x8_UNORM_BLOCK: return 10; - case GalImageFormat.ASTC_12x10_UNORM_BLOCK: return 12; - case GalImageFormat.ASTC_8x5_UNORM_BLOCK: return 8; - case GalImageFormat.ASTC_10x5_UNORM_BLOCK: return 10; - case GalImageFormat.ASTC_10x6_UNORM_BLOCK: return 10; + case GalImageFormat.ASTC_4x4 | GalImageFormat.Unorm: return 4; + case GalImageFormat.ASTC_5x5 | GalImageFormat.Unorm: return 5; + case GalImageFormat.ASTC_6x6 | GalImageFormat.Unorm: return 6; + case GalImageFormat.ASTC_8x8 | GalImageFormat.Unorm: return 8; + case GalImageFormat.ASTC_10x10 | GalImageFormat.Unorm: return 10; + case GalImageFormat.ASTC_12x12 | GalImageFormat.Unorm: return 12; + case GalImageFormat.ASTC_5x4 | GalImageFormat.Unorm: return 5; + case GalImageFormat.ASTC_6x5 | GalImageFormat.Unorm: return 6; + case GalImageFormat.ASTC_8x6 | GalImageFormat.Unorm: return 8; + case GalImageFormat.ASTC_10x8 | GalImageFormat.Unorm: return 10; + case GalImageFormat.ASTC_12x10 | GalImageFormat.Unorm: return 12; + case GalImageFormat.ASTC_8x5 | GalImageFormat.Unorm: return 8; + case GalImageFormat.ASTC_10x5 | GalImageFormat.Unorm: return 10; + case GalImageFormat.ASTC_10x6 | GalImageFormat.Unorm: return 10; } throw new ArgumentException(nameof(Format)); @@ -146,20 +161,20 @@ namespace Ryujinx.Graphics.Gal.OpenGL { switch (Format) { - case GalImageFormat.ASTC_4x4_UNORM_BLOCK: return 4; - case GalImageFormat.ASTC_5x5_UNORM_BLOCK: return 5; - case GalImageFormat.ASTC_6x6_UNORM_BLOCK: return 6; - case GalImageFormat.ASTC_8x8_UNORM_BLOCK: return 8; - case GalImageFormat.ASTC_10x10_UNORM_BLOCK: return 10; - case GalImageFormat.ASTC_12x12_UNORM_BLOCK: return 12; - case GalImageFormat.ASTC_5x4_UNORM_BLOCK: return 4; - case GalImageFormat.ASTC_6x5_UNORM_BLOCK: return 5; - case GalImageFormat.ASTC_8x6_UNORM_BLOCK: return 6; - case GalImageFormat.ASTC_10x8_UNORM_BLOCK: return 8; - case GalImageFormat.ASTC_12x10_UNORM_BLOCK: return 10; - case GalImageFormat.ASTC_8x5_UNORM_BLOCK: return 5; - case GalImageFormat.ASTC_10x5_UNORM_BLOCK: return 5; - case GalImageFormat.ASTC_10x6_UNORM_BLOCK: return 6; + case GalImageFormat.ASTC_4x4 | GalImageFormat.Unorm: return 4; + case GalImageFormat.ASTC_5x5 | GalImageFormat.Unorm: return 5; + case GalImageFormat.ASTC_6x6 | GalImageFormat.Unorm: return 6; + case GalImageFormat.ASTC_8x8 | GalImageFormat.Unorm: return 8; + case GalImageFormat.ASTC_10x10 | GalImageFormat.Unorm: return 10; + case GalImageFormat.ASTC_12x12 | GalImageFormat.Unorm: return 12; + case GalImageFormat.ASTC_5x4 | GalImageFormat.Unorm: return 4; + case GalImageFormat.ASTC_6x5 | GalImageFormat.Unorm: return 5; + case GalImageFormat.ASTC_8x6 | GalImageFormat.Unorm: return 6; + case GalImageFormat.ASTC_10x8 | GalImageFormat.Unorm: return 8; + case GalImageFormat.ASTC_12x10 | GalImageFormat.Unorm: return 10; + case GalImageFormat.ASTC_8x5 | GalImageFormat.Unorm: return 5; + case GalImageFormat.ASTC_10x5 | GalImageFormat.Unorm: return 5; + case GalImageFormat.ASTC_10x6 | GalImageFormat.Unorm: return 6; } throw new ArgumentException(nameof(Format)); @@ -216,25 +231,5 @@ namespace Ryujinx.Graphics.Gal.OpenGL GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBorderColor, Color); } - - private static bool IsCompressedTextureFormat(GalImageFormat Format) - { - switch (Format) - { - case GalImageFormat.BC6H_UFLOAT_BLOCK: - case GalImageFormat.BC6H_SFLOAT_BLOCK: - case GalImageFormat.BC7_UNORM_BLOCK: - case GalImageFormat.BC1_RGBA_UNORM_BLOCK: - case GalImageFormat.BC2_UNORM_BLOCK: - case GalImageFormat.BC3_UNORM_BLOCK: - case GalImageFormat.BC4_SNORM_BLOCK: - case GalImageFormat.BC4_UNORM_BLOCK: - case GalImageFormat.BC5_SNORM_BLOCK: - case GalImageFormat.BC5_UNORM_BLOCK: - return true; - } - - return false; - } } } |
