1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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);
}
}
}
}
}
|