在使用纹理内存时,我遇到了以下代码:-
uint f = (blockIdx.x * blockDim.x) + threadIdx.x;
uint c = (blockIdx.y * blockDim.y) + threadIdx.y;
uint read = tex2D( refTex, c+0.5f, f+0.5f);
我的问题是为什么我们0.5f
要同时添加c
and f
?这让我很困惑..谢谢
在图形中,纹理是一组描述表面视觉外观的样本。一个样本就是一个点。也就是说,它没有大小(与具有物理大小的像素相反)。当使用样本来确定像素的颜色时,每个样本都位于其对应像素的确切中心。当使用整数坐标寻址像素时,给定像素的精确中心变为其整数坐标加上 0.5 的偏移量(在每个维度中)。
换句话说,将 0.5 添加到纹理坐标可确保从这些坐标读取时,返回该像素的准确样本值。
然而,只有当filterMode
纹理被设置为时cudaFilterModeLinear
,从纹理中读取的值才会在一个像素内变化。在该模式下,从不在像素精确中心的坐标读取返回值,这些值在给定像素的样本和相邻像素的样本之间进行插值。因此,将 0.5 添加到整数坐标可以有效地否定cudaFilterModeLinear
模式。但是,由于向纹理坐标添加 0.5 会占用内核中的周期,因此最好通过设置为 来简单地关闭filterMode
插值cudaFilterModePoint
。然后,从像素内的任何坐标读取会返回该像素的确切纹理样本值,因此,可以使用整数直接读取纹理样本。
使用 时cudaFilterModePoint
,如果在计算纹理坐标时涉及任何浮点数学运算,则必须注意确保浮点不准确不会导致纹理坐标超出预期目标像素的范围。
此外,正如评论所提到的,您的代码中可能存在问题。将 0.5f 添加到纹理坐标意味着cudaFilterModeLinear
正在使用该模式,但该模式返回一个浮点数,而不是一个整数。
根据纹理属性,返回的值tex2D
可能是线性插值的。在那种情况下,“索引”f
不c
应该是整数,而是每个维度的界限之间的连续值。
在这个例子中有点奇怪的是返回值是一个整数,无论如何这将使任何线性插值分段常数。
有关更多详细信息,请参阅 CUDA 编程指南的第 3.2.10 节。