我正在使用Metal将图像显示到2D平面中。使用Core Image将图像渲染为IOSurface的图块。渲染完每个图块之后,IOSurface会通过XPC发送到应用程序,并包裹在MTLTexture
中,然后使用blit编码器将其内容复制到主纹理中。然后,如有需要,可以重新使用IOSurface。
我对瓦片的大小和纹理的大小有完全的控制权,我想知道Metal是更喜欢使用少量的大纹理,大量的小纹理还是只是无关紧要?
我已经遇到了一些折衷,最值得注意的是,如果我使用较小的纹理,则(重新)生成mipmap的成本会更小。还有一个问题是最大尺寸为16384的纹理,这意味着任何大于该尺寸的图像都必须进行平铺。
请考虑以下内容:
下面使用的图像尺寸只是为了简化数学运算,在现实生活中,我正在处理DSLR图像,全景图,缝合图像等。
#1-覆盖整个图像的单个纹理:
Texture Type: MTLTextureType2D
Texture Size: 400 x 300 px
当Core Image渲染一个图块并将其复制到纹理中时,我必须为整个纹理重新生成mipmap,即使大多数纹理的内容没有改变。
#2-使用两个纹理:
Texture Type: MTLTextureType2DArray
Texture Array Count: 2
Texture Size: 200 x 300 px (x2)
有了两个覆盖图像内容的图块,我只需要为“脏”图块重新生成mipmap。
#3-使用许多纹理:
Texture Type: MTLTextureType2DArray
Texture Array Length: 12
Texture Size: 100 x 100 px (x12)
在这种情况下,我可以通过将纹理图块的大小与渲染图块的大小相匹配来最小化mipmap的生成,但这将需要大量的MTLTextures
。
MTLTextureDescriptor.arrayLength
被证明能够保持1..2048之间的值,这对我来说建议使用大量纹理并不是一件坏事。
将单个纹理传递到我的片段着色器,它所做的只是在适当的坐标处对颜色进行采样。
使用较小尺寸的纹理使我在标记需要无效的图像“脏”区域时更具保真度,但是我很好奇是否要避免使用大量纹理。
我目前衡量性能的尝试对我来说有些包容,我想知道这是否是因为从Metal的角度来看这根本不重要。最终,需要相同数量的内存(从我的角度来看),但我想知道是否存在我不知道的性能折衷。