今天看了 AMD_GpuAddress 模块文档,以前一直没有理解它的功能和原理。今天在网上一篇博客的指导下,终于明白了大概。
所以记录下来,以供日后参考。
通常纹理贴图数据按照线性方式排列,就如二维数组的样子。如果要访问纹理的某个元素,可以使用下面的公式。
Z = Y * stride + X
这里 Z 代表访问的结果,Y 代表行坐标,X 代表列坐标,stride 代表每行的固定跨度值。也就是说通过行,列的值可查找
所需的元素。但是因为GPU处理纹理时经常需要读取4x4, 8x8邻近元素的纹理值, 而以线性方式存储的大尺寸贴图,邻近
元素往往相距成千字节,所以很容易造成读取时的CacheMissing,以致执行效率低下。
如果数据以4x4, 8x8邻近元素块进行存贮,这样读取临近元素,就可以避免部分的CacheMissing,提高执行效率。当
然就不能以原来的线性方式进行元素访问了(它们是以非线性(non-linear)方式存放的)。如果还需要以X,Y的方式访问元素,
必须以对应的方式解算地址才行。(所以就会有GpuAddress这类的模块)例如下面代码表示的4X4Tile,
// per-texture constants uint tileW = 4; uint tileH = 4; uint widthInTiles = (width + tileW-1) / tileW; // actual addressing uint tileX = x / tileW; uint tileY = y / tileH; uint inTileX = x % tileW; uint inTileY = y % tileH; pixel = image[(tileY * widthInTiles + tileX) * (tileW * tileH) + inTileY * tileW + inTileX];
注意上面代码中,可以看到解算地址的代码不是很复杂的。
https://fgiesen.wordpress.com/2011/01/17/texture-tiling-and-swizzling/