内核中的像素坐标、纹理坐标和 gid
Pixel Coordinates, Texture Coordinates and gid within Kernel
假设我有一个宽度为 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.
综上所述,gid
、texture coordinates
和 pixel coordinates
在内核函数中是如何关联的?它们如何 映射 从一个到另一个?这4天我一直在看文档和类似的问题,但是一直没有成功得到具体权威的答案。
谢谢。
在您的示例中,您正在分派这样的工作网格:
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 的纹理上操作,并且您想在右下角执行一些操作。在这种情况下,您可以在 reading/writing 纹理之前添加 uint2(200, 200)
到 gid
,以便处理坐标为 (200, 200) 到 (299, 299) 的像素区域。其他的,任意变换也是可以的。
基本上,指定网格维度是您描述要执行的操作的逻辑形状的一种便捷方式,同时还(通过 threadsPerThreadgroup
)允许您优化可以执行的工作量并行执行。
至于(规范化)纹理坐标,在网格尺寸与纹理尺寸完全匹配的简单情况下,您可以通过除以符合 [[threads_per_grid]]
属性,记得先转换以避免截断:
float2 coords = gid / float2(tpg)
其中 tpg
是声明为 uint2 tpg [[threads_per_grid]]
.
的内核函数的另一个参数
假设我有一个宽度为 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.
综上所述,gid
、texture coordinates
和 pixel coordinates
在内核函数中是如何关联的?它们如何 映射 从一个到另一个?这4天我一直在看文档和类似的问题,但是一直没有成功得到具体权威的答案。
谢谢。
在您的示例中,您正在分派这样的工作网格:
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 的纹理上操作,并且您想在右下角执行一些操作。在这种情况下,您可以在 reading/writing 纹理之前添加 uint2(200, 200)
到 gid
,以便处理坐标为 (200, 200) 到 (299, 299) 的像素区域。其他的,任意变换也是可以的。
基本上,指定网格维度是您描述要执行的操作的逻辑形状的一种便捷方式,同时还(通过 threadsPerThreadgroup
)允许您优化可以执行的工作量并行执行。
至于(规范化)纹理坐标,在网格尺寸与纹理尺寸完全匹配的简单情况下,您可以通过除以符合 [[threads_per_grid]]
属性,记得先转换以避免截断:
float2 coords = gid / float2(tpg)
其中 tpg
是声明为 uint2 tpg [[threads_per_grid]]
.