diff --git a/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs b/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs index e700be05d..3ab874d53 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/ImageHandler.cs @@ -39,7 +39,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL public void EnsureSetup(GalImage Image) { - if (Width != Image.Width || + if (Width != Image.Width || Height != Image.Height || Format != Image.Format || !Initialized) diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLHelper.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLHelper.cs new file mode 100644 index 000000000..f137dc273 --- /dev/null +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLHelper.cs @@ -0,0 +1,164 @@ +using OpenTK.Graphics.OpenGL; +using System; + +namespace Ryujinx.Graphics.Gal.OpenGL +{ + public static class OGLHelper + { + public static unsafe void TexImage( + TextureTarget Target, + int Level, + PixelInternalFormat InternalFormat, + int Width, + int Height, + int Depth, + int Border, + PixelFormat PixelFormat, + PixelType PixelType, + byte[] Data) + { + switch (Target) + { + case TextureTarget.Texture2D: + GL.TexImage2D( + Target, + Level, + InternalFormat, + Width, + Height, + Border, + PixelFormat, + PixelType, + Data); + break; + + case TextureTarget.Texture2DArray: + GL.TexImage3D( + Target, + Level, + InternalFormat, + Width, + Height, + Depth, + Border, + PixelFormat, + PixelType, + Data); + break; + + case TextureTarget.TextureCubeMap: + { + long FaceSize = Data.LongLength / 6; + + for (int Face = 0; Face < 6; Face++) + { + fixed (byte* DataPtr = Data) + { + IntPtr Addr; + + if (Data != null) + { + Addr = new IntPtr(DataPtr + FaceSize * Face); + } + else + { + Addr = new IntPtr(0); + } + + GL.TexImage2D( + TextureTarget.TextureCubeMapPositiveX + Face, + Level, + InternalFormat, + Width, + Height, + Border, + PixelFormat, + PixelType, + Addr); + } + } + break; + } + + default: + throw new NotImplementedException(Target.ToString()); + } + } + + public static unsafe void CompressedTexImage( + TextureTarget Target, + int Level, + InternalFormat InternalFormat, + int Width, + int Height, + int Depth, + int Border, + byte[] Data) + { + switch (Target) + { + case TextureTarget.Texture2D: + GL.CompressedTexImage2D( + Target, + Level, + InternalFormat, + Width, + Height, + Border, + Data.Length, + Data); + break; + + case TextureTarget.Texture2DArray: + GL.CompressedTexImage3D( + Target, + Level, + InternalFormat, + Width, + Height, + Depth, + Border, + Data.Length, + Data); + break; + + case TextureTarget.TextureCubeMap: + { + //FIXME: This implies that all 6 faces are equal + int FaceSize = Data.Length / 6; + + for (int Face = 0; Face < 6; Face++) + { + fixed (byte* DataPtr = Data) + { + IntPtr Addr; + + if (Data != null) + { + Addr = new IntPtr(DataPtr + FaceSize * Face); + } + else + { + Addr = new IntPtr(0); + } + + GL.CompressedTexImage2D( + TextureTarget.TextureCubeMapPositiveX + Face, + Level, + InternalFormat, + Width, + Height, + Border, + FaceSize, + Addr); + } + } + break; + } + + default: + throw new NotImplementedException(Target.ToString()); + } + } + } +} \ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs index 619a8368e..35edb68ec 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs @@ -45,67 +45,21 @@ namespace Ryujinx.Graphics.Gal.OpenGL { InternalFormat InternalFmt = OGLEnumConverter.GetCompressedImageFormat(Image.Format); - switch (Target) - { - case TextureTarget.Texture2D: - GL.CompressedTexImage2D( - Target, - Level, - InternalFmt, - Image.Width, - Image.Height, - Border, - Data.Length, - Data); - break; - - case TextureTarget.Texture2DArray: - GL.CompressedTexImage3D( - Target, - Level, - InternalFmt, - Image.Width, - Image.Height, - Image.Depth, - Border, - Data.Length, - Data); - break; - - case TextureTarget.TextureCubeMap: - { - int FaceSize = Data.Length / 6; - - for (int i = 0; i < 6; i++) - { - unsafe - { - fixed (byte* DataPtr = Data) - { - GL.CompressedTexImage2D( - TextureTarget.TextureCubeMapPositiveX + i, - Level, - InternalFmt, - Image.Width, - Image.Height, - Border, - FaceSize, - (IntPtr)(DataPtr + FaceSize * i)); - } - } - } - break; - } - - default: - throw new NotImplementedException(Target.ToString()); - } + OGLHelper.CompressedTexImage( + Target, + Level, + InternalFmt, + Image.Width, + Image.Height, + Image.Depth, + Border, + Data); } else { if (Image.Format >= GalImageFormat.ASTC_BEGIN && Image.Format <= GalImageFormat.ASTC_END) { - int TextureBlockWidth = GetAstcBlockWidth(Image.Format); + int TextureBlockWidth = GetAstcBlockWidth (Image.Format); int TextureBlockHeight = GetAstcBlockHeight(Image.Format); Data = ASTCDecoder.DecodeToRGBA8888( @@ -120,64 +74,17 @@ namespace Ryujinx.Graphics.Gal.OpenGL (PixelInternalFormat InternalFormat, PixelFormat Format, PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format); - switch (Target) - { - case TextureTarget.Texture2D: - GL.TexImage2D( - Target, - Level, - InternalFormat, - Image.Width, - Image.Height, - Border, - Format, - Type, - Data); - break; - - case TextureTarget.TextureCubeMap: - { - long FaceSize = Data.LongLength / 6; - - for (int i = 0; i < 6; i++) - { - unsafe - { - fixed (byte* DataPtr = Data) - { - GL.TexImage2D( - TextureTarget.TextureCubeMapPositiveX + i, - Level, - InternalFormat, - Image.Width, - Image.Height, - Border, - Format, - Type, - (IntPtr)(DataPtr + FaceSize * i)); - } - } - } - break; - } - - case TextureTarget.Texture2DArray: - GL.TexImage3D( - Target, - Level, - InternalFormat, - Image.Width, - Image.Height, - Image.Depth, - Border, - Format, - Type, - Data); - break; - - default: - throw new NotImplementedException(Target.ToString()); - } + OGLHelper.TexImage( + Target, + Level, + InternalFormat, + Image.Width, + Image.Height, + Image.Depth, + Border, + Format, + Type, + Data); } int SwizzleR = (int)OGLEnumConverter.GetTextureSwizzle(Image.XSource);