【问题标题】:opengl tall texture vs wide texture for memory locality内存局部性的opengl高纹理与宽纹理
【发布时间】:2017-12-07 15:34:40
【问题描述】:

2D 纹理有两个坐标,x 和 y。要将二维数组存储在一维内存中,两种可能的格式是 [x + y * width] 和 [x * height + y]。 OpenGL 有各种令人困惑的行优先/列优先约定,所以我不确定它使用两种格式中的哪一种。这是相关的,因为如果纹理用于存储多个图像,例如在 sprite sheet 或 atlas 中,最好让图像的各个部分在内存中靠近在一起。例如,如果格式是 [x + y * width] 并且我们使用的是非常宽的纹理,那么 GPU 将不得不跳过较长的内存部分来找到它需要的纹素。

因此:高纹理图集优于宽纹理图集,还是相反?还是 GPU 没有内存局部性优势?

【问题讨论】:

  • "OpenGL 有各种令人困惑的行优先/列优先约定,所以我不确定它使用这两种格式中的哪一种。" 1) 矩阵存储与纹理存储。 2) OpenGL 只有一种矩阵约定。 3) 这并不是特别令人困惑。

标签: opengl multidimensional-array textures


【解决方案1】:

纹理图集最重要的方面是其中可以容纳多少张图像。即使涉及纹理图集,您也更有可能访问相邻的纹素而不是远处的纹素。

考虑一下。假设您渲染 2 个 32x32 的精灵。所以这是 2 个四边形,在一次渲染调用中。每个四边形将在屏幕上占据 32x32 像素;那是 1024 像素。

地点很重要;您从 1024 个局部相邻的纹素进行渲染,然后从另一组 1024 个局部相邻的纹素进行渲染。

无论如何,OpenGL 不会让您了解 GPU 图像格式的细节。您可以要求特定大小的纹素和多个通道。但是你没有得到比这更多的细节。您提供的数据将由驱动程序适当地转换为实际的内部 GPU 数据。

通常,GPU 会在内存中调配纹理。这意味着重新排列数据以保留局部性。也就是说,它们不是将纹素存储为x + y * widthx * height + y,而是以更复杂的排列方式存储。

例如,前 4 个值是纹素 0,0; 0,1; 1,0;和 1,1。所以一个 2x2 的纹素块存储在一个连续的内存数组中。这是 swizzled 纹理存储工作原理的一个示例。

但这都是一个实现细节;您无法做任何事情来影响或影响这一点,甚至像 Vulkan 这样的低级 API 也不允许您直接加载预混合的纹素数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多