diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-06-09 11:34:21 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-06-09 13:44:59 -0700 |
| commit | fcf83dbf9effab3bd98bad2b83b2468b7eb05cfd (patch) | |
| tree | 41047c94883b86ec085a81597391ce3ef557cd43 /tests/hlsl/dxsdk/AdaptiveTessellationCS40/ScanCS.hlsl | |
| parent | 52e8d4b9a27ab0060f874c3a63ab531847be35c0 (diff) | |
Initial import of code.
Diffstat (limited to 'tests/hlsl/dxsdk/AdaptiveTessellationCS40/ScanCS.hlsl')
| -rw-r--r-- | tests/hlsl/dxsdk/AdaptiveTessellationCS40/ScanCS.hlsl | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/tests/hlsl/dxsdk/AdaptiveTessellationCS40/ScanCS.hlsl b/tests/hlsl/dxsdk/AdaptiveTessellationCS40/ScanCS.hlsl new file mode 100644 index 000000000..46cdc1ed9 --- /dev/null +++ b/tests/hlsl/dxsdk/AdaptiveTessellationCS40/ScanCS.hlsl @@ -0,0 +1,109 @@ +//TEST:COMPARE_HLSL: -target dxbc-assembly -profile cs_4_0 -entry CSScanInBucket -entry CSScanBucketResult -entry CSScanAddBucketResult +//-------------------------------------------------------------------------------------- +// File: ScanCS.hlsl +// +// A simple inclusive prefix sum(scan) implemented in CS4.0, +// using a typical up sweep and down sweep scheme +// +// Copyright (c) Microsoft Corporation. All rights reserved. +//-------------------------------------------------------------------------------------- +StructuredBuffer<uint2> Input : register( t0 ); // Change uint2 here if scan other types, and +RWStructuredBuffer<uint2> Result : register( u0 ); // also here + +#define groupthreads 128 +groupshared uint4 bucket[groupthreads]; // Change uint4 to the "type x2" if scan other types, e.g. + // if scan uint2, then put uint4 here, + // if scan float, then put float2 here + +void CSScan( uint3 DTid, uint GI, uint2 x ) // Change the type of x here if scan other types +{ + // since CS40 can only support one shared memory for one shader, we use .xy and .zw as ping-ponging buffers + // if scan a single element type like int, search and replace all .xy to .x and .zw to .y below + bucket[GI].xy = x; + bucket[GI].zw = 0; + + // Up sweep + [unroll] + for ( uint stride = 2; stride <= groupthreads; stride <<= 1 ) + { + GroupMemoryBarrierWithGroupSync(); + + if ( (GI & (stride - 1)) == (stride - 1) ) + { + bucket[GI].xy += bucket[GI - stride/2].xy; + } + } + + if ( GI == (groupthreads - 1) ) + { + bucket[GI].xy = 0; + } + + // Down sweep + bool n = true; + [unroll] + for ( stride = groupthreads / 2; stride >= 1; stride >>= 1 ) + { + GroupMemoryBarrierWithGroupSync(); + + uint a = stride - 1; + uint b = stride | a; + + if ( n ) // ping-pong between passes + { + if ( ( GI & b) == b ) + { + bucket[GI].zw = bucket[GI-stride].xy + bucket[GI].xy; + } else + if ( (GI & a) == a ) + { + bucket[GI].zw = bucket[GI+stride].xy; + } else + { + bucket[GI].zw = bucket[GI].xy; + } + } else + { + if ( ( GI & b) == b ) + { + bucket[GI].xy = bucket[GI-stride].zw + bucket[GI].zw; + } else + if ( (GI & a) == a ) + { + bucket[GI].xy = bucket[GI+stride].zw; + } else + { + bucket[GI].xy = bucket[GI].zw; + } + } + + n = !n; + } + + Result[DTid.x] = bucket[GI].zw + x; +} + +// scan in each bucket +[numthreads( groupthreads, 1, 1 )] +void CSScanInBucket( uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI: SV_GroupIndex ) +{ + uint2 x = Input[DTid.x]; // Change the type of x here if scan other types + CSScan( DTid, GI, x ); +} + +// record and scan the sum of each bucket +[numthreads( groupthreads, 1, 1 )] +void CSScanBucketResult( uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI: SV_GroupIndex ) +{ + uint2 x = Input[DTid.x*groupthreads - 1]; // Change the type of x here if scan other types + CSScan( DTid, GI, x ); +} + +StructuredBuffer<uint2> Input1 : register( t1 ); + +// add the bucket scanned result to each bucket to get the final result +[numthreads( groupthreads, 1, 1 )] +void CSScanAddBucketResult( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI: SV_GroupIndex ) +{ + Result[DTid.x] = Input[DTid.x] + Input1[Gid.x]; +} |
