// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved // // Author: James Stanard (jstanard@microsoft.com) // // Used with FXAA to resolve the lengths of the two work queues and to generate DispatchIndirect parameters. // The work queues are also padded out to a multiple of 64 with dummy work items. // #include "Common.usf" RWStructuredBuffer WorkQueueH : register( u0 ); RWStructuredBuffer WorkQueueV : register( u1 ); RWByteAddressBuffer IndirectParams : register( u2 ); groupshared uint PixelCountH; groupshared uint PixelCountV; [numthreads( 64, 1, 1 )] void main( uint3 Gid : SV_GroupID, uint GI : SV_GroupIndex, uint3 GTid : SV_GroupThreadID, uint3 DTid : SV_DispatchThreadID ) { if (GI == 0) { // Increment the counter so we can read the current value. #if ORBIS PixelCountH = WorkQueueH.IncrementCount(); PixelCountV = WorkQueueV.IncrementCount(); #else PixelCountH = WorkQueueH.IncrementCounter(); PixelCountV = WorkQueueV.IncrementCounter(); #endif } GroupMemoryBarrierWithGroupSync(); uint PaddedCountH = max( (( PixelCountH + 63 ) & ~63), 1 ); uint PaddedCountV = max( (( PixelCountV + 63 ) & ~63), 1 ); // Write out padding to the buffer if ( GI + PixelCountH < PaddedCountH ) WorkQueueH[ PixelCountH + GI ] = uint4( 0xffffffff, 0xffffffff, 0, 0xffffffff ); // Write out padding to the buffer if ( GI + PixelCountV < PaddedCountV ) WorkQueueV[ PixelCountV + GI ] = uint4( 0xffffffff, 0xffffffff, 0, 0xffffffff ); if ( GI == 0 ) { IndirectParams.Store( 0, PaddedCountH >> 6); IndirectParams.Store( 4, 1); IndirectParams.Store( 8, 1); IndirectParams.Store( 12, PaddedCountV >> 6); IndirectParams.Store( 16, 1); IndirectParams.Store( 20, 1); } }