2
votes

I'm using Unity to launch an HLSL kernel on the GPU. The function I'm using is ComputeShader.Dispatch but if you're not familiar with Unity, this function only dispatches the shader on the GPU and it takes as parameters, the size x, y and z of the thread group you want.

Here is my problem, I sometimes want to run this kernel an odd amount of times.

I could call Dispatch with an odd size, but doing so would mean defining my kernel like so [numthreads(1,1,1)] which is known for being ineficient.

How do you manage your threads to treat odd textures, or other irregular shapes?

Many thanks

1
Wow - what a question!Fattie

1 Answers

1
votes

Standard way of performing this task is to ensure you're not performing out of bounds read/writes.

So let's say your group count is

[numthreads(8,8,1)]

In any case even if your texture size is not an odd number but also not a multiple of 8 (in each dimension), you can have this case to happen as well.

Let's say now you want to process a texture of 18*9

You need to dispatch enough thread in each dimension to cover at least the whole texture:

X = 18 / 8 (2.25), so you need 3 groups (which will process 24 pixels) Y = 9 / 8 (1.125), you need 2 groups

So you will call dispatch as context.Dispatch(3,2,1)

Inside the compute shader, the standard way to perform this is to do an early return in case you are out of bounds.

Texture2D texture2d <string uiname="Texture";>;

uint Width;
uint Height;

[numthreads(8,8,1)]
void CS(uint3 tid : SV_DispatchThreadID)
{
    if (tid.x >= Width || tid.y >= Height)
        return;

    //Perform your processing
}

You need to send the texture size into width/height parameters and shader will not process anything outside the texture that way.