summaryrefslogtreecommitdiff
path: root/tests/hlsl/dxsdk/AdaptiveTessellationCS40/ScanCS.hlsl
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-06-09 11:34:21 -0700
committerTim Foley <tfoley@nvidia.com>2017-06-09 13:44:59 -0700
commitfcf83dbf9effab3bd98bad2b83b2468b7eb05cfd (patch)
tree41047c94883b86ec085a81597391ce3ef557cd43 /tests/hlsl/dxsdk/AdaptiveTessellationCS40/ScanCS.hlsl
parent52e8d4b9a27ab0060f874c3a63ab531847be35c0 (diff)
Initial import of code.
Diffstat (limited to 'tests/hlsl/dxsdk/AdaptiveTessellationCS40/ScanCS.hlsl')
-rw-r--r--tests/hlsl/dxsdk/AdaptiveTessellationCS40/ScanCS.hlsl109
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];
+}