[Compute Shader] Dispatch problem

Started by
2 comments, last by Alundra 10 years, 1 month ago

Hi all,

I have a structured buffer who contains a linear data, its size is large enought to contains a max of data, it's a pool.

The not-used memory is here to avoid problem of sync, maybe a better solution exist, but for now it's ok.

The problem is using Dispatch(1,1,1) all works ok but using thread group I have problem.

I used thread group of 8 on x-y-z axis, so I just do ceil(SizeX/8),ceil(SizeY/8),ceil(SizeZ/8) and set that on the dispatch function.

The compute shader code :


[numthreads(8, 8, 8)]
void GenerateLightGrid(uint3 dispatchThreadID : SV_DispatchThreadID)
{
  // Get the x/y/Z values.
  uint x = dispatchThreadID.x;
  uint y = dispatchThreadID.y;
  uint z = dispatchThreadID.z;
  
  // Compute the start offset.
  uint StartOffset = (x*MAX_LIGHT) + (y*(Width*MAX_LIGHT)) + (z*Width*Height*MAX_LIGHT);
  
  // Offset used to store indices.
  uint Offset = StartOffset;
  
  // Each point light.
  uint NumPointLight = 0;
  for( uint pl = 0; pl < PointLightCount; ++pl )
  {
    // Get the screen rect.
    SCREEN_RECT ScreenRect = PointLightRectsReadOnly[ pl ];
    
    // Check for invalid bounds.
    if( ( int( z ) > ScreenRect.MaxZ || int( z ) < ScreenRect.MinZ ) ||
        ( int( x ) > ScreenRect.MaxX || int( x ) < ScreenRect.MinX ) ||
        ( int( y ) > ScreenRect.MaxY || int( y ) < ScreenRect.MinY ) )
        continue;
        
    // Set the light index and add offset.
    LightIndices[ Offset++ ] = pl;

    // Add a point light.
    ++NumPointLight;
  }
  // Set the light count.
  LightLookup[ dispatchThreadID ] = uint4( StartOffset, NumPointLight, 0, 0 );
}

Using :


[numthreads(1, 1, 1)]

There is no problem, only when using thread group I have bad result.

Since the array is linear normally there should not have problems.

Thanks for the help

Advertisement

You must take into account the group id? http://msdn.microsoft.com/en-us/library/windows/desktop/ff471566(v=vs.85).aspx

What is the value of MAX_LIGHT, and how does that relate to the size of the StartOffset that you are calculating? If you are working on a structured buffer, wouldn't your index just be x + width*y + width*height*z ?

MAX_LIGHT is defined like that on the compute shader :


#define MAX_LIGHT 1024

It's the max light on a cluster allowed, it's to avoid sync problem of compute shader because offset of light must be linear.

The structured buffer size = Width*Height*Depth*1024.


LightLookup[ dispatchThreadID ] = uint4( StartOffset, NumPointLight, 0, 0 );

StartOffset is the index to start to lookup and y,z,w are number of light of each type for this cluster.

On the pixel shader it's a for loop of each type using linear data stored :


offset = LightLookup.x
for each point light
  pointlights[LightIndices[offset]]
  compute light using data
  offset++
for each spot light
  spotlights[LightIndices[offset]]
  compute light using data
  offset++

This topic is closed to new replies.

Advertisement