diff options
| author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2018-08-19 22:25:26 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-08-19 22:25:26 -0300 |
| commit | 726de8c46ab10f1b0684fe14bca1ca96ba6d2832 (patch) | |
| tree | 5da68699e9062f1c01ef3da9d9eceb75657b2f93 /Ryujinx.Graphics/Gal/OpenGL | |
| parent | 056c2840b1851657c3855fb72776837c89ff59d3 (diff) | |
Rendertarget attachments, texture and image changes (#358)
* Add multiple color outputs for fragment shaders
* Add registers and gal enums
* Use textures for framebuffers and split color and zeta framebuffers
* Abstract texture and framebuffer targets as an image
* Share images between framebuffers and textures
* Unstub formats
* Add some formats
* Disable multiple attachments
* Cache framebuffer attachments
* Handle format types
* Add some rendertarget formats
* Code cleanup
* Fixup half float types
* Address feedback
* Disable multiple attachments in shaders
* Add A4B4G4R4 image format
* Add reversed section for image enums
Diffstat (limited to 'Ryujinx.Graphics/Gal/OpenGL')
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs | 124 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLConstBuffer.cs | 6 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs | 77 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs | 494 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs | 19 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLRenderer.cs | 6 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs | 181 |
7 files changed, 577 insertions, 330 deletions
diff --git a/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs b/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs new file mode 100644 index 00000000..74f18dcd --- /dev/null +++ b/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs @@ -0,0 +1,124 @@ +using OpenTK.Graphics.OpenGL; +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; + + public GalImage Image { get; private set; } + + public int Width => Image.Width; + public int Height => Image.Height; + + public GalImageFormat Format => 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 ImageHandler() + { + Handle = GL.GenTexture(); + } + + public ImageHandler(int Handle, GalImage Image) + { + this.Handle = Handle; + + this.Image = Image; + } + + public void EnsureSetup(GalImage Image) + { + if (Width != Image.Width || + Height != Image.Height || + Format != Image.Format || + !Initialized) + { + (PixelInternalFormat InternalFormat, PixelFormat PixelFormat, PixelType PixelType) = + OGLEnumConverter.GetImageFormat(Image.Format); + + GL.BindTexture(TextureTarget.Texture2D, Handle); + + if (Initialized) + { + if (CopyBuffer == 0) + { + CopyBuffer = GL.GenBuffer(); + } + + int MaxWidth = Math.Max(Image.Width, Width); + int MaxHeight = Math.Max(Image.Height, Height); + + int CurrentSize = MaxWidth * MaxHeight * MaxBpp; + + GL.BindBuffer(BufferTarget.PixelPackBuffer, CopyBuffer); + GL.BindBuffer(BufferTarget.PixelUnpackBuffer, CopyBuffer); + + if (CopyBufferSize < CurrentSize) + { + CopyBufferSize = CurrentSize; + + GL.BufferData(BufferTarget.PixelPackBuffer, CurrentSize, IntPtr.Zero, BufferUsageHint.StreamCopy); + } + + 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 (Initialized) + { + GL.BindBuffer(BufferTarget.PixelPackBuffer, 0); + GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0); + } + + this.Image = Image; + + this.InternalFormat = InternalFormat; + this.PixelFormat = PixelFormat; + this.PixelType = PixelType; + + Initialized = true; + } + } + + public bool HasColor { get => ImageFormatConverter.HasColor(Format); } + public bool HasDepth { get => ImageFormatConverter.HasDepth(Format); } + public bool HasStencil { get => ImageFormatConverter.HasStencil(Format); } + } +} diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLConstBuffer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLConstBuffer.cs index 50825541..4958b53b 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLConstBuffer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLConstBuffer.cs @@ -36,12 +36,10 @@ namespace Ryujinx.Graphics.Gal.OpenGL public void SetData(long Key, long Size, IntPtr HostAddress) { - if (!Cache.TryGetValue(Key, out OGLStreamBuffer Buffer)) + if (Cache.TryGetValue(Key, out OGLStreamBuffer Buffer)) { - throw new InvalidOperationException(); + Buffer.SetData(Size, HostAddress); } - - Buffer.SetData(Size, HostAddress); } public bool TryGetUbo(long Key, out int UboHandle) diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs index 3c42e5d3..e04a59d4 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs @@ -125,40 +125,71 @@ namespace Ryujinx.Graphics.Gal.OpenGL throw new ArgumentException(nameof(Type)); } - public static (PixelFormat, PixelType) GetTextureFormat(GalTextureFormat Format) + public static (PixelInternalFormat, PixelFormat, PixelType) GetImageFormat(GalImageFormat 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); + 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.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); } throw new NotImplementedException(Format.ToString()); } - public static InternalFormat GetCompressedTextureFormat(GalTextureFormat Format) + public static InternalFormat GetCompressedImageFormat(GalImageFormat 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_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; } throw new NotImplementedException(Format.ToString()); diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs index 62f82495..e0f12e4e 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs @@ -1,10 +1,9 @@ using OpenTK.Graphics.OpenGL; using System; -using System.Collections.Generic; namespace Ryujinx.Graphics.Gal.OpenGL { - public class OGLFrameBuffer : IGalFrameBuffer + class OGLFrameBuffer : IGalFrameBuffer { private struct Rect { @@ -15,49 +14,37 @@ namespace Ryujinx.Graphics.Gal.OpenGL public Rect(int X, int Y, int Width, int Height) { - this.X = X; - this.Y = Y; - this.Width = Width; + this.X = X; + this.Y = Y; + this.Width = Width; this.Height = Height; } } - private class FrameBuffer + private static readonly DrawBuffersEnum[] DrawBuffers = new DrawBuffersEnum[] { - public int Width { get; set; } - public int Height { get; set; } - - public int Handle { get; private set; } - public int RbHandle { get; private set; } - public int TexHandle { get; private set; } - - public FrameBuffer(int Width, int Height, bool HasRenderBuffer) - { - this.Width = Width; - this.Height = Height; - - Handle = GL.GenFramebuffer(); - TexHandle = GL.GenTexture(); - - if (HasRenderBuffer) - { - RbHandle = GL.GenRenderbuffer(); - } - } - } + DrawBuffersEnum.ColorAttachment0, + DrawBuffersEnum.ColorAttachment1, + DrawBuffersEnum.ColorAttachment2, + DrawBuffersEnum.ColorAttachment3, + DrawBuffersEnum.ColorAttachment4, + DrawBuffersEnum.ColorAttachment5, + DrawBuffersEnum.ColorAttachment6, + DrawBuffersEnum.ColorAttachment7, + }; private const int NativeWidth = 1280; private const int NativeHeight = 720; - private Dictionary<long, FrameBuffer> Fbs; + private const GalImageFormat RawFormat = GalImageFormat.A8B8G8R8_UNORM_PACK32; - private Rect Viewport; - private Rect Window; + private OGLTexture Texture; - private FrameBuffer CurrFb; - private FrameBuffer CurrReadFb; + private ImageHandler RawTex; + private ImageHandler ReadTex; - private FrameBuffer RawFb; + private Rect Viewport; + private Rect Window; private bool FlipX; private bool FlipY; @@ -67,111 +54,144 @@ namespace Ryujinx.Graphics.Gal.OpenGL private int CropRight; private int CropBottom; - public OGLFrameBuffer() - { - Fbs = new Dictionary<long, FrameBuffer>(); - } + //This framebuffer is used to attach guest rendertargets, + //think of it as a dummy OpenGL VAO + private int DummyFrameBuffer; - public void Create(long Key, int Width, int Height) - { - if (Fbs.TryGetValue(Key, out FrameBuffer Fb)) - { - if (Fb.Width != Width || - Fb.Height != Height) - { - SetupTexture(Fb.TexHandle, Width, Height); + //These framebuffers are used to blit images + private int SrcFb; + private int DstFb; - Fb.Width = Width; - Fb.Height = Height; - } + //Holds current attachments, used to avoid unnecesary calls to OpenGL + private int[] ColorAttachments; - return; - } + private int DepthAttachment; + private int StencilAttachment; - Fb = new FrameBuffer(Width, Height, true); + public OGLFrameBuffer(OGLTexture Texture) + { + ColorAttachments = new int[8]; - SetupTexture(Fb.TexHandle, Width, Height); + this.Texture = Texture; + } - GL.BindFramebuffer(FramebufferTarget.Framebuffer, Fb.Handle); + public void BindColor(long Key, int Attachment) + { + if (Texture.TryGetImage(Key, out ImageHandler Tex)) + { + EnsureFrameBuffer(); - GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, Fb.RbHandle); + Attach(ref ColorAttachments[Attachment], Tex.Handle, FramebufferAttachment.ColorAttachment0 + Attachment); + } + else + { + UnbindColor(Attachment); + } + } - GL.RenderbufferStorage( - RenderbufferTarget.Renderbuffer, - RenderbufferStorage.Depth24Stencil8, - Width, - Height); + public void UnbindColor(int Attachment) + { + EnsureFrameBuffer(); - GL.FramebufferRenderbuffer( - FramebufferTarget.Framebuffer, - FramebufferAttachment.DepthStencilAttachment, - RenderbufferTarget.Renderbuffer, - Fb.RbHandle); + Attach(ref ColorAttachments[Attachment], 0, FramebufferAttachment.ColorAttachment0 + Attachment); + } + + public void BindZeta(long Key) + { + if (Texture.TryGetImage(Key, out ImageHandler Tex)) + { + EnsureFrameBuffer(); - GL.FramebufferTexture( - FramebufferTarget.Framebuffer, - FramebufferAttachment.ColorAttachment0, - Fb.TexHandle, - 0); + if (Tex.HasDepth && Tex.HasStencil) + { + if (DepthAttachment != Tex.Handle || + StencilAttachment != Tex.Handle) + { + GL.FramebufferTexture( + FramebufferTarget.DrawFramebuffer, + FramebufferAttachment.DepthStencilAttachment, + Tex.Handle, + 0); + + DepthAttachment = Tex.Handle; + + StencilAttachment = Tex.Handle; + } + } + else if (Tex.HasDepth) + { + Attach(ref DepthAttachment, Tex.Handle, FramebufferAttachment.DepthAttachment); - GL.DrawBuffer(DrawBufferMode.ColorAttachment0); + Attach(ref StencilAttachment, 0, FramebufferAttachment.StencilAttachment); + } + else if (Tex.HasStencil) + { + Attach(ref DepthAttachment, 0, FramebufferAttachment.DepthAttachment); - Fbs.Add(Key, Fb); + Attach(ref StencilAttachment, Tex.Handle, FramebufferAttachment.StencilAttachment); + } + else + { + throw new InvalidOperationException(); + } + } + else + { + UnbindZeta(); + } } - public void Bind(long Key) + public void UnbindZeta() { - if (Fbs.TryGetValue(Key, out FrameBuffer Fb)) + EnsureFrameBuffer(); + + if (DepthAttachment != 0 || + StencilAttachment != 0) { - GL.BindFramebuffer(FramebufferTarget.Framebuffer, Fb.Handle); + GL.FramebufferTexture( + FramebufferTarget.DrawFramebuffer, + FramebufferAttachment.DepthStencilAttachment, + 0, + 0); + + DepthAttachment = 0; - CurrFb = Fb; + StencilAttachment = 0; } } public void BindTexture(long Key, int Index) { - if (Fbs.TryGetValue(Key, out FrameBuffer Fb)) + if (Texture.TryGetImage(Key, out ImageHandler Tex)) { GL.ActiveTexture(TextureUnit.Texture0 + Index); - GL.BindTexture(TextureTarget.Texture2D, Fb.TexHandle); + GL.BindTexture(TextureTarget.Texture2D, Tex.Handle); } } public void Set(long Key) { - if (Fbs.TryGetValue(Key, out FrameBuffer Fb)) + if (Texture.TryGetImage(Key, out ImageHandler Tex)) { - CurrReadFb = Fb; + ReadTex = Tex; } } public void Set(byte[] Data, int Width, int Height) { - if (RawFb == null) + if (RawTex == null) { - CreateRawFb(Width, Height); + RawTex = new ImageHandler(); } - if (RawFb.Width != Width || - RawFb.Height != Height) - { - SetupTexture(RawFb.TexHandle, Width, Height); - - RawFb.Width = Width; - RawFb.Height = Height; - } - - GL.ActiveTexture(TextureUnit.Texture0); - - GL.BindTexture(TextureTarget.Texture2D, RawFb.TexHandle); + RawTex.EnsureSetup(new GalImage(Width, Height, RawFormat)); - (PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(GalTextureFormat.A8B8G8R8); + GL.BindTexture(TextureTarget.Texture2D, RawTex.Handle); - 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); - CurrReadFb = RawFb; + ReadTex = RawTex; } public void SetTransform(bool FlipX, bool FlipY, int Top, int Left, int Right, int Bottom) @@ -208,60 +228,71 @@ namespace Ryujinx.Graphics.Gal.OpenGL public void Render() { - if (CurrReadFb != null) + if (ReadTex == null) { - int SrcX0, SrcX1, SrcY0, SrcY1; + return; + } - if (CropLeft == 0 && CropRight == 0) - { - SrcX0 = 0; - SrcX1 = CurrReadFb.Width; - } - else - { - SrcX0 = CropLeft; - SrcX1 = CropRight; - } + int SrcX0, SrcX1, SrcY0, SrcY1; - if (CropTop == 0 && CropBottom == 0) - { - SrcY0 = 0; - SrcY1 = CurrReadFb.Height; - } - else - { - SrcY0 = CropTop; - SrcY1 = CropBottom; - } + if (CropLeft == 0 && CropRight == 0) + { + SrcX0 = 0; + SrcX1 = ReadTex.Width; + } + else + { + SrcX0 = CropLeft; + SrcX1 = CropRight; + } + + if (CropTop == 0 && CropBottom == 0) + { + SrcY0 = 0; + SrcY1 = ReadTex.Height; + } + else + { + SrcY0 = CropTop; + SrcY1 = CropBottom; + } - float RatioX = MathF.Min(1f, (Window.Height * (float)NativeWidth) / ((float)NativeHeight * Window.Width)); - float RatioY = MathF.Min(1f, (Window.Width * (float)NativeHeight) / ((float)NativeWidth * Window.Height)); + float RatioX = MathF.Min(1f, (Window.Height * (float)NativeWidth) / ((float)NativeHeight * Window.Width)); + float RatioY = MathF.Min(1f, (Window.Width * (float)NativeHeight) / ((float)NativeWidth * Window.Height)); - int DstWidth = (int)(Window.Width * RatioX); - int DstHeight = (int)(Window.Height * RatioY); + int DstWidth = (int)(Window.Width * RatioX); + int DstHeight = (int)(Window.Height * RatioY); - int DstPaddingX = (Window.Width - DstWidth) / 2; - int DstPaddingY = (Window.Height - DstHeight) / 2; + int DstPaddingX = (Window.Width - DstWidth) / 2; + int DstPaddingY = (Window.Height - DstHeight) / 2; - int DstX0 = FlipX ? Window.Width - DstPaddingX : DstPaddingX; - int DstX1 = FlipX ? DstPaddingX : Window.Width - DstPaddingX; + int DstX0 = FlipX ? Window.Width - DstPaddingX : DstPaddingX; + int DstX1 = FlipX ? DstPaddingX : Window.Width - DstPaddingX; - int DstY0 = FlipY ? DstPaddingY : Window.Height - DstPaddingY; - int DstY1 = FlipY ? Window.Height - DstPaddingY : DstPaddingY; + int DstY0 = FlipY ? DstPaddingY : Window.Height - DstPaddingY; + int DstY1 = FlipY ? Window.Height - DstPaddingY : DstPaddingY; - GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); + if (SrcFb == 0) SrcFb = GL.GenFramebuffer(); - GL.Viewport(0, 0, Window.Width, Window.Height); + GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, 0); - GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, CurrReadFb.Handle); + GL.Viewport(0, 0, Window.Width, Window.Height); - GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); + GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, SrcFb); - GL.BlitFramebuffer( - SrcX0, SrcY0, SrcX1, SrcY1, - DstX0, DstY0, DstX1, DstY1, - ClearBufferMask.ColorBufferBit, BlitFramebufferFilter.Linear); - } + GL.FramebufferTexture(FramebufferTarget.ReadFramebuffer, FramebufferAttachment.ColorAttachment0, ReadTex.Handle, 0); + + GL.ReadBuffer(ReadBufferMode.ColorAttachment0); + GL.DrawBuffer(DrawBufferMode.ColorAttachment0); + + GL.Clear(ClearBufferMask.ColorBufferBit); + + GL.BlitFramebuffer( + SrcX0, SrcY0, SrcX1, SrcY1, + DstX0, DstY0, DstX1, DstY1, + ClearBufferMask.ColorBufferBit, BlitFramebufferFilter.Linear); + + EnsureFrameBuffer(); } public void Copy( @@ -276,39 +307,80 @@ namespace Ryujinx.Graphics.Gal.OpenGL int DstX1, int DstY1) { - if (Fbs.TryGetValue(SrcKey, out FrameBuffer SrcFb) && - Fbs.TryGetValue(DstKey, out FrameBuffer DstFb)) + if (Texture.TryGetImage(SrcKey, out ImageHandler SrcTex) && + Texture.TryGetImage(DstKey, out ImageHandler DstTex)) { - GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, SrcFb.Handle); - GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, DstFb.Handle); - - GL.Clear(ClearBufferMask.ColorBufferBit); + if (SrcTex.HasColor != DstTex.HasColor || + SrcTex.HasDepth != DstTex.HasDepth || + SrcTex.HasStencil != DstTex.HasStencil) + { + throw new NotImplementedException(); + } - GL.BlitFramebuffer( - SrcX0, SrcY0, SrcX1, SrcY1, - DstX0, DstY0, DstX1, DstY1, - ClearBufferMask.ColorBufferBit, - BlitFramebufferFilter.Linear); + if (SrcTex.HasColor) + { + CopyTextures( + SrcX0, SrcY0, SrcX1, SrcY1, + DstX0, DstY0, DstX1, DstY1, + SrcTex.Handle, + DstTex.Handle, + FramebufferAttachment.ColorAttachment0, + ClearBufferMask.ColorBufferBit, + true); + } + else if (SrcTex.HasDepth && SrcTex.HasStencil) + { + CopyTextures( + SrcX0, SrcY0, SrcX1, SrcY1, + DstX0, DstY0, DstX1, DstY1, + SrcTex.Handle, + DstTex.Handle, + FramebufferAttachment.DepthStencilAttachment, + ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit, + false); + } + else if (SrcTex.HasDepth) + { + CopyTextures( + SrcX0, SrcY0, SrcX1, SrcY1, + DstX0, DstY0, DstX1, DstY1, + SrcTex.Handle, + DstTex.Handle, + FramebufferAttachment.DepthAttachment, + ClearBufferMask.DepthBufferBit, + false); + } + else if (SrcTex.HasStencil) + { + CopyTextures( + SrcX0, SrcY0, SrcX1, SrcY1, + DstX0, DstY0, DstX1, DstY1, + SrcTex.Handle, + DstTex.Handle, + FramebufferAttachment.StencilAttachment, + ClearBufferMask.StencilBufferBit, + false); + } + else + { + throw new InvalidOperationException(); + } } -} + } public void GetBufferData(long Key, Action<byte[]> Callback) { - if (Fbs.TryGetValue(Key, out FrameBuffer Fb)) + if (Texture.TryGetImage(Key, out ImageHandler Tex)) { - GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, Fb.Handle); + byte[] Data = new byte[Tex.Width * Tex.Height * ImageHandler.MaxBpp]; - byte[] Data = new byte[Fb.Width * Fb.Height * 4]; + GL.BindTexture(TextureTarget.Texture2D, Tex.Handle); - (PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(GalTextureFormat.A8B8G8R8); - - GL.ReadPixels( - 0, + GL.GetTexImage( + TextureTarget.Texture2D, 0, - Fb.Width, - Fb.Height, - Format, - Type, + Tex.PixelFormat, + Tex.PixelType, Data); Callback(Data); @@ -319,83 +391,101 @@ namespace Ryujinx.Graphics.Gal.OpenGL long Key, int Width, int Height, - GalTextureFormat Format, byte[] Buffer) { - if (Fbs.TryGetValue(Key, out FrameBuffer Fb)) + if (Texture.TryGetImage(Key, out ImageHandler Tex)) { - GL.BindTexture(TextureTarget.Texture2D, Fb.TexHandle); + GL.BindTexture(TextureTarget.Texture2D, Tex.Handle); const int Level = 0; const int Border = 0; - const PixelInternalFormat InternalFmt = PixelInternalFormat.Rgba; - - (PixelFormat GlFormat, PixelType Type) = OGLEnumConverter.GetTextureFormat(Format); - GL.TexImage2D( TextureTarget.Texture2D, Level, - InternalFmt, + Tex.InternalFormat, Width, Height, Border, - GlFormat, - Type, + Tex.PixelFormat, + Tex.PixelType, Buffer); } } - private void CreateRawFb(int Width, int Height) + private void EnsureFrameBuffer() { - if (RawFb == null) + if (DummyFrameBuffer == 0) { - RawFb = new FrameBuffer(Width, Height, false); - - SetupTexture(RawFb.TexHandle, Width, Height); + DummyFrameBuffer = GL.GenFramebuffer(); + } - RawFb.Width = Width; - RawFb.Height = Height; + GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, DummyFrameBuffer); - GL.BindFramebuffer(FramebufferTarget.Framebuffer, RawFb.Handle); + GL.DrawBuffers(8, DrawBuffers); + } + private void Attach(ref int OldHandle, int NewHandle, FramebufferAttachment FbAttachment) + { + if (OldHandle != NewHandle) + { GL.FramebufferTexture( - FramebufferTarget.Framebuffer, - FramebufferAttachment.ColorAttachment0, - RawFb.TexHandle, + FramebufferTarget.DrawFramebuffer, + FbAttachment, + NewHandle, 0); - GL.Viewport(0, 0, Width, Height); + OldHandle = NewHandle; } } - private void SetupTexture(int Handle, int Width, int Height) + private void CopyTextures( + int SrcX0, + int SrcY0, + int SrcX1, + int SrcY1, + int DstX0, + int DstY0, + int DstX1, + int DstY1, + int SrcTexture, + int DstTexture, + FramebufferAttachment Attachment, + ClearBufferMask Mask, + bool Color) { - GL.BindTexture(TextureTarget.Texture2D, Handle); + if (SrcFb == 0) SrcFb = GL.GenFramebuffer(); + if (DstFb == 0) DstFb = GL.GenFramebuffer(); - const int MinFilter = (int)TextureMinFilter.Linear; - const int MagFilter = (int)TextureMagFilter.Linear; + GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, SrcFb); + GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, DstFb); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, MinFilter); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, MagFilter); + GL.FramebufferTexture( + FramebufferTarget.ReadFramebuffer, + Attachment, + SrcTexture, + 0); - (PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(GalTextureFormat.A8B8G8R8); + GL.FramebufferTexture( + FramebufferTarget.DrawFramebuffer, + Attachment, + DstTexture, + 0); + + if (Color) + { + GL.DrawBuffer(DrawBufferMode.ColorAttachment0); + } - const PixelInternalFormat InternalFmt = PixelInternalFormat.Rgba; + GL.Clear(Mask); - const int Level = 0; - const int Border = 0; + GL.BlitFramebuffer( + SrcX0, SrcY0, SrcX1, SrcY1, + DstX0, DstY0, DstX1, DstY1, + Mask, + Color ? BlitFramebufferFilter.Linear : BlitFramebufferFilter.Nearest); - GL.TexImage2D( - TextureTarget.Texture2D, - Level, - InternalFmt, - Width, - Height, - Border, - Format, - Type, - IntPtr.Zero); + EnsureFrameBuffer(); } } }
\ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs index b6e97454..45106692 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs @@ -3,7 +3,7 @@ using System; namespace Ryujinx.Graphics.Gal.OpenGL { - public class OGLRasterizer : IGalRasterizer + class OGLRasterizer : IGalRasterizer { private int[] VertexBuffers; @@ -44,36 +44,29 @@ namespace Ryujinx.Graphics.Gal.OpenGL public void ClearBuffers( GalClearBufferFlags Flags, + int Attachment, float Red, float Green, float Blue, float Alpha, float Depth, int Stencil) { - ClearBufferMask Mask = ClearBufferMask.ColorBufferBit; - GL.ColorMask( Flags.HasFlag(GalClearBufferFlags.ColorRed), Flags.HasFlag(GalClearBufferFlags.ColorGreen), Flags.HasFlag(GalClearBufferFlags.ColorBlue), Flags.HasFlag(GalClearBufferFlags.ColorAlpha)); + GL.ClearBuffer(ClearBuffer.Color, Attachment, new float[] { Red, Green, Blue, Alpha }); + if (Flags.HasFlag(GalClearBufferFlags.Depth)) { - Mask |= ClearBufferMask.DepthBufferBit; + GL.ClearBuffer(ClearBuffer.Depth, 0, ref Depth); } if (Flags.HasFlag(GalClearBufferFlags.Stencil)) { - Mask |= ClearBufferMask.StencilBufferBit; + GL.ClearBuffer(ClearBuffer.Stencil, 0, ref Stencil); } - GL.ClearColor(Red, Green, Blue, Alpha); - - GL.ClearDepth(Depth); - - GL.ClearStencil(Stencil); - - GL.Clear(Mask); - GL.ColorMask(true, true, true, true); } diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderer.cs index b0f6da45..985f1086 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderer.cs @@ -23,7 +23,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL { Buffer = new OGLConstBuffer(); - FrameBuffer = new OGLFrameBuffer(); + Texture = new OGLTexture(); + + FrameBuffer = new OGLFrameBuffer(Texture as OGLTexture); Rasterizer = new OGLRasterizer(); @@ -31,8 +33,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL Pipeline = new OGLPipeline(Buffer as OGLConstBuffer, Rasterizer as OGLRasterizer, Shader as OGLShader); - Texture = new OGLTexture(); - ActionsQueue = new ConcurrentQueue<Action>(); } diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs index ac30e6fd..e4d4bd64 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs @@ -4,26 +4,13 @@ using System; namespace Ryujinx.Graphics.Gal.OpenGL { - public class OGLTexture : IGalTexture + 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<ImageHandler> TextureCache; public OGLTexture() { - TextureCache = new OGLCachedResource<TCE>(DeleteTexture); + TextureCache = new OGLCachedResource<ImageHandler>(DeleteTexture); } public void LockCache() @@ -36,73 +23,71 @@ namespace Ryujinx.Graphics.Gal.OpenGL TextureCache.Unlock(); } - private static void DeleteTexture(TCE CachedTexture) + private static void DeleteTexture(ImageHandler CachedImage) { - GL.DeleteTexture(CachedTexture.Handle); + GL.DeleteTexture(CachedImage.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 ImageHandler(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.ASTC_BEGIN && Image.Format <= GalImageFormat.ASTC_END) { - 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_UNORM_PACK32; } - 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,76 +95,100 @@ namespace Ryujinx.Graphics.Gal.OpenGL GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleA, SwizzleA); } - private static int GetAstcBlockWidth(GalTextureFormat Format) + public void CreateFb(long Key, long Size, GalImage Image) + { + if (!TryGetImage(Key, out ImageHandler CachedImage)) + { + CachedImage = new ImageHandler(); + + TextureCache.AddOrUpdate(Key, CachedImage, Size); + } + + CachedImage.EnsureSetup(Image); + } + + public bool TryGetImage(long Key, out ImageHandler CachedImage) + { + if (TextureCache.TryGetValue(Key, out CachedImage)) + { + return true; + } + + CachedImage = null; + + return false; + } + + 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.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; } 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.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; } 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)) + if (TextureCache.TryGetValue(Key, out ImageHandler CachedImage)) { - Texture = CachedTexture.Texture; + Image = CachedImage.Image; return true; } } - Texture = default(GalTexture); + Image = default(GalImage); return false; } public void Bind(long Key, int Index) { - if (TextureCache.TryGetValue(Key, out TCE CachedTexture)) + if (TextureCache.TryGetValue(Key, out ImageHandler CachedImage)) { GL.ActiveTexture(TextureUnit.Texture0 + Index); - GL.BindTexture(TextureTarget.Texture2D, CachedTexture.Handle); + GL.BindTexture(TextureTarget.Texture2D, CachedImage.Handle); } } @@ -208,18 +217,20 @@ 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_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; } |
