diff options
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/TextureCopyUnscaled.cs')
-rw-r--r-- | Ryujinx.Graphics.OpenGL/TextureCopyUnscaled.cs | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.OpenGL/TextureCopyUnscaled.cs b/Ryujinx.Graphics.OpenGL/TextureCopyUnscaled.cs new file mode 100644 index 00000000..dae492d9 --- /dev/null +++ b/Ryujinx.Graphics.OpenGL/TextureCopyUnscaled.cs @@ -0,0 +1,85 @@ +using Ryujinx.Common; +using Ryujinx.Graphics.GAL.Texture; +using OpenTK.Graphics.OpenGL; +using System; + +namespace Ryujinx.Graphics.OpenGL +{ + static class TextureCopyUnscaled + { + public static void Copy(TextureView src, TextureView dst, int dstLayer, int dstLevel) + { + int srcWidth = src.Width; + int srcHeight = src.Height; + int srcDepth = src.DepthOrLayers; + int srcLevels = src.Levels; + + srcWidth = Math.Max(1, srcWidth >> dstLevel); + srcHeight = Math.Max(1, srcHeight >> dstLevel); + + if (src.Target == Target.Texture3D) + { + srcDepth = Math.Max(1, srcDepth >> dstLevel); + } + + int dstWidth = dst.Width; + int dstHeight = dst.Height; + int dstDepth = dst.DepthOrLayers; + int dstLevels = dst.Levels; + + // When copying from a compressed to a non-compressed format, + // the non-compressed texture will have the size of the texture + // in blocks (not in texels), so we must adjust that size to + // match the size in texels of the compressed texture. + if (!src.IsCompressed && dst.IsCompressed) + { + dstWidth = BitUtils.DivRoundUp(dstWidth, dst.BlockWidth); + dstHeight = BitUtils.DivRoundUp(dstHeight, dst.BlockHeight); + } + else if (src.IsCompressed && !dst.IsCompressed) + { + dstWidth *= dst.BlockWidth; + dstHeight *= dst.BlockHeight; + } + + int width = Math.Min(srcWidth, dstWidth); + int height = Math.Min(srcHeight, dstHeight); + int depth = Math.Min(srcDepth, dstDepth); + int levels = Math.Min(srcLevels, dstLevels); + + for (int level = 0; level < levels; level++) + { + // Stop copy if we are already out of the levels range. + if (level >= src.Levels || dstLevel + level >= dst.Levels) + { + break; + } + + GL.CopyImageSubData( + src.Handle, + src.Target.ConvertToImageTarget(), + level, + 0, + 0, + 0, + dst.Handle, + dst.Target.ConvertToImageTarget(), + dstLevel + level, + 0, + 0, + dstLayer, + width, + height, + depth); + + width = Math.Max(1, width >> 1); + height = Math.Max(1, height >> 1); + + if (src.Target == Target.Texture3D) + { + depth = Math.Max(1, depth >> 1); + } + } + } + } +} |