内核中的像素坐标,纹理坐标和gid

时间:2017-01-05 21:14:37

标签: metal

假设我的宽度为100且高度为100的纹理,并将其分配给{10, 10, 1}线程组和大小的内核函数。

我无法理解thread_position_in_grid是从0 - 9还是0到99(因为我的纹理的大小是100 x 100)?

我正在使用float4 c = in.read(gid);来检索纹理的颜色,但我想知道gid如何将映射到纹理坐标以检索结果类型为float4(是否存在像素(纹理?)坐标之间的情况?)。

我想深入理解上述内容是如何工作的,因为我想要实现的是能够在内核函数中检索由纹理大小定义的确切位置;即:

调度大小:{10, 10, 1},纹理大小100 x 100;并检索内核函数中的值:

0,1,2,3,4,5 ...... 99。

总之,内核函数中gidtexture coordinatespixel coordinates如何相关?他们如何映射从一个到另一个?我过去4天一直在阅读文档和类似问题,但我没有成功获得具体和权威的答案。

谢谢。

1 个答案:

答案 0 :(得分:3)

在您的示例中,您将按照以下方式调度工作网格:

MTLSize threadsPerThreadgroup = { 10, 10, 1 };
MTLSize threadgroupCount = { 10, 10, 1 };
[computeEncoder dispatchThreadgroups:threadgroupCount
               threadsPerThreadgroup:threadsPerThreadgroup];

您的gid属性thread_position_in_grid可能属于uint2类型,因为网格的域是二维的。到目前为止,非常好。

gid的范围从(0,0)到(99,99)。如何将其映射到其他数量,包括纹理坐标完全取决于您

例如,假设您不是在100x100纹理上运行,而是在300x300纹理上运行,并且您想要在右下角执行某些操作。在这种情况下,您可以在读取/写入纹理之前将uint2(200, 200)添加到gid,以便使用坐标(200,200)到(299,299)来寻址像素区域。其他任意变换都是可能的。

基本上,指定网格尺寸是描述要执行的操作的逻辑形状的便捷方式,同时(通过threadsPerThreadgroup)允许您优化可以执行的工作量并行。

对于(规范化的)纹理坐标,在网格尺寸与纹理尺寸完全匹配的简单情况下,您可以通过除以{{1}限定的参数来获取与内核函数调用相对应的规范化坐标记住首先强制转换以避免截断:

[[threads_per_grid]]

其中float2 coords = gid / float2(tpg) 是内核函数的另一个参数,声明为tpg