Reputation: 4229
In iOS or OS/X what texture coordinates are used in Metal Shader Language kernel function? For example, given an MTLTexture
and uint2 gid[[thread_position_in_grid]]
Is gid.x
and gid.y
between 0..1 (x and y are floats) or 0..inTexture.get_width()
(x and y are integers).
Thanks in Advance
Upvotes: 2
Views: 2446
Reputation: 1592
Each launch of a compute shader in Metal is accompanied by a dense rectangular 3D grid of thread IDs. The dimensions of the grid is set when you call [MTLComputeCommandEncoder dispatchThreadGroups:threadsPerThreadgroup:]
. You can for example have a threadgroup size of {16,16,1}
(256 threads in a threadgroup as a 16x16x1 square), and threadgroup count of {1,2,1}
, which will cause two threadgroups to be launched with a total area of 512 threads in the shape {16,32,1}
. These are the integers that appear at the top of your kernel as [[thread_position_in_grid]]
. The thread position is the way that you tell which thread you are, just like the threadID parameter passed to a block by dispatch_apply()
.
Metal specifies no mapping from [[thread_position_in_grid]]
to coordinates in a texture. This is done by you in software in your compute shader. If you want to read every other pixel in a region of a texture at some offset in the image, then you need to multiply the threadID by two and add an offset in your kernel before passing the new coordinate to texture2d.sample
. Since Metal can not launch partial threadgroups, it is up to you to make sure that unneeded threadgroups are not executed. For example, when applied to a smaller texture, the full size of your 32x64 launch might cause you to write off the end of your texture. In this case you must check the threadID to see if the thread will write off the end and then either return out of the shader or skip over the texture write call for that thread to avoid the problem.
Upvotes: 6
Reputation: 13462
thread_position_in_grid
is an index (an integer) in the grid that takes values in the ranges you specify in dispatchThreadgroups:threadsPerThreadgroup:
. It's up to you to decide how many thread groups you want, and how many threads per group.
In the following sample code you can see that threadsPerGroup.width * numThreadgroups.width == inputImage.width
and threadsPerGroup.height * numThreadgroups.height == inputImage.height
. In this case, a position in the grid will thus be a non-normalized (integer) pixel coordinate.
Upvotes: 6