32

总是使用 alginment 1 的缺点是什么?

glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
glPixelStorei(GL_PACK_ALIGNMENT, 1)

它会影响现代 GPU 的性能吗?

4

3 回答 3

46

数据怎么可能不是 1 字节对齐的?

这强烈表明缺乏对像素传输操作中行对齐的含义的理解。

您传递给 OpenGL 的图像数据预计会分组到行中。每行包含width多个像素,每个像素的大小由格式和类型参数定义。GL_RGB因此,类型为的格式GL_UNSIGNED_BYTE将产生一个 24 位大小的像素。否则,像素会被打包,因此一行 16 个像素将占用 48 个字节。

正如GL_PACK/UNPACK_ALIGNMENT. 这意味着您添加到指针以到达下一行的值是:align(pixel_size * width, GL_*_ALIGNMENT)。如果像素大小为 3 字节,宽度为 2,对齐方式为 1,则行字节大小为 6。如果对齐方式为 4,则行字节大小为8

看到问题了吗?

图像数据,可能来自某些图像加载器加载的图像文件格式,具有行对齐。有时这是 1 字节对齐的,有时不是. DDS 图像具有指定为格式的一部分的对齐方式。在许多情况下,图像具有 4 字节的行对齐;因此,小于 32 位的像素大小将在具有特定宽度的行末尾有填充。如果您给 OpenGL 的对齐方式与该对齐方式不匹配,那么您会得到一个格式错误的纹理。

您设置对齐方式以匹配图像格式的对齐方式。如果您知道或可以确保您的行对齐始终为 1(除非您编写了自己的图像格式或 DDS 编写器,否则这不太可能),您需要将行对齐设置为与您的图像格式使用的完全相同。

于 2012-06-15T05:52:08.020 回答
11

它会影响现代 GPU 的性能吗?

不,因为像素存储设置仅与从 GPU 传输数据或向 GPU 传输数据相关,即数据的对齐。一旦进入 GPU 内存,它就会以 GPU 和驱动程序所需的任何方式对齐。

于 2012-06-14T23:50:30.503 回答
0

不会对性能产生影响。设置更高的对齐(在 openGL 中)不会改善任何东西,也不会加速任何东西。

所有对齐都是告诉openGL在哪里期望下一行像素。如果您的图像像素紧密排列,即如果在一行字节的结束位置和新行的开始位置之间没有间隙,则应始终使用 1 对齐。

默认对齐方式为 4(即,openGL 期望下一行像素在内存中可被 4 整除的跳转之后),这可能会在您加载不是 4 字节浮点数的 R、RG 或 RGB 纹理的情况下导致问题,或者宽度不能被 4 整除。如果您的图像像素紧密排列,您必须将对齐更改为 1 才能使解包工作。

你可以(我个人没有遇到过它们)有一个 3x3 RGB ubyte 的图像,它的行是第 4 对齐的,最后有 3 个额外的字节用作填充。哪些行可能如下所示:

R - G - B - R - G - B - R - G - B - X - X - X(共16字节)

其原因是对齐的数据提高了处理器的性能(不确定在今天的处理器上它是真实的/合理的)。如果您对原始图像的组成方式有任何控制权,那么可能以一种或另一种方式对齐它会改善对它的处理。但这是在 openGL 之前完成的。OpenGL 无法对此进行任何更改,它只关心在哪里找到像素。

所以,回到上面的 3x3 图像行 - 将对齐设置为 4 会很好(并且有必要)跳过最后一个填充。如果您将其设置为 1,它会弄乱您的结果,因此您需要将其保留/恢复为 4。(请注意,您也可以使用 ROW_LENGTH 跳过它,因为这是处理子集时使用的参数图像,在这种情况下,有时您必须跳多于 3 或 7 个字节(这是对齐参数 8 可以给您的最大值)。在我们的示例中,如果您提供 4 的行长度和 1 的对齐方式也将工作)。

打包也是一样。您可以告诉 openGL 将像素行对齐到 1、2、4 和 8。如果要保存 3x3 RGB ubyte,则应将对齐方式设置为 1。从技术上讲,如果您希望结果行紧密排列,您应该总是给 1。如果你想(无论出于什么原因)创建一些填充,你可以给另一个值。给(在我们的示例中)一个 4 的 PACK_ALIGNMENT 将导致创建看起来像上面的行的行(最后有 3 个额外的填充)。请注意,在这种情况下,您的包含对象(openCV mat、位图等)应该能够接收额外的填充。

于 2019-03-28T20:39:38.643 回答