summaryrefslogtreecommitdiff
path: root/tests/hlsl/dxsdk/NBodyGravityCS11
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/NBodyGravityCS11
parent52e8d4b9a27ab0060f874c3a63ab531847be35c0 (diff)
Initial import of code.
Diffstat (limited to 'tests/hlsl/dxsdk/NBodyGravityCS11')
-rw-r--r--tests/hlsl/dxsdk/NBodyGravityCS11/NBodyGravityCS11.hlsl103
-rw-r--r--tests/hlsl/dxsdk/NBodyGravityCS11/ParticleDraw.hlsl128
2 files changed, 231 insertions, 0 deletions
diff --git a/tests/hlsl/dxsdk/NBodyGravityCS11/NBodyGravityCS11.hlsl b/tests/hlsl/dxsdk/NBodyGravityCS11/NBodyGravityCS11.hlsl
new file mode 100644
index 000000000..0a694450c
--- /dev/null
+++ b/tests/hlsl/dxsdk/NBodyGravityCS11/NBodyGravityCS11.hlsl
@@ -0,0 +1,103 @@
+//TEST_IGNORE_FILE: Currently failing due to Spire compiler issues.
+//TEST:COMPARE_HLSL: -target dxbc-assembly -profile cs_4_0 -entry CSMain
+//--------------------------------------------------------------------------------------
+// File: NBodyGravityCS11.hlsl
+//
+// Demonstrates how to use Compute Shader to do n-body gravity computation
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//--------------------------------------------------------------------------------------
+
+static float softeningSquared = 0.0012500000*0.0012500000;
+static float g_fG = 6.67300e-11f * 10000.0f;
+static float g_fParticleMass = g_fG*10000.0f * 10000.0f;
+
+#define blocksize 128
+groupshared float4 sharedPos[blocksize];
+
+// Body to body interaction, acceleration of the particle at position bi is updated
+void bodyBodyInteraction(inout float3 ai, float4 bj, float4 bi, float mass, int particles )
+{
+ float3 r = bj.xyz - bi.xyz;
+
+ float distSqr = dot(r, r);
+ distSqr += softeningSquared;
+
+ float invDist = 1.0f / sqrt(distSqr);
+ float invDistCube = invDist * invDist * invDist;
+
+ float s = mass * invDistCube * particles;
+
+ ai += r * s;
+}
+
+cbuffer cbCS : register( b0 )
+{
+ uint4 g_param; // pcbCS->param[0] = MAX_PARTICLES;
+ // pcbCS->param[1] = dimx;
+ float4 g_paramf; // pcbCS->paramf[0] = 0.1f;
+ // pcbCS->paramf[1] = 1;
+};
+
+struct PosVelo
+{
+ float4 pos;
+ float4 velo;
+};
+
+StructuredBuffer<PosVelo> oldPosVelo;
+RWStructuredBuffer<PosVelo> newPosVelo;
+
+[numthreads(blocksize, 1, 1)]
+void CSMain( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
+{
+ // Each thread of the CS updates one of the particles
+
+ float4 pos = oldPosVelo[DTid.x].pos;
+ float4 vel = oldPosVelo[DTid.x].velo;
+ float3 accel = 0;
+ float mass = g_fParticleMass;
+
+ // Update current particle using all other particles
+ [loop]
+ for (uint tile = 0; tile < g_param.y; tile++)
+ {
+ // Cache a tile of particles unto shared memory to increase IO efficiency
+ sharedPos[GI] = oldPosVelo[tile * blocksize + GI].pos;
+
+ GroupMemoryBarrierWithGroupSync();
+
+ [unroll]
+ for (uint counter = 0; counter < blocksize; counter+=8 )
+ {
+ bodyBodyInteraction(accel, sharedPos[counter], pos, mass, 1);
+ bodyBodyInteraction(accel, sharedPos[counter+1], pos, mass, 1);
+ bodyBodyInteraction(accel, sharedPos[counter+2], pos, mass, 1);
+ bodyBodyInteraction(accel, sharedPos[counter+3], pos, mass, 1);
+ bodyBodyInteraction(accel, sharedPos[counter+4], pos, mass, 1);
+ bodyBodyInteraction(accel, sharedPos[counter+5], pos, mass, 1);
+ bodyBodyInteraction(accel, sharedPos[counter+6], pos, mass, 1);
+ bodyBodyInteraction(accel, sharedPos[counter+7], pos, mass, 1);
+ }
+
+ GroupMemoryBarrierWithGroupSync();
+ }
+
+ // g_param.x is the number of our particles, however this number might not be an exact multiple of the tile size.
+ // In such cases, out of bound reads occur in the process above, which means there will be
+ // tooManyParticles "phantom" particles generating false gravity at position (0, 0, 0), so we have to substract them here.
+ // NOTE, out of bound reads always return 0 in CS
+ const uint tooManyParticles = g_param.y * blocksize - g_param.x;
+ bodyBodyInteraction(accel, float4(0, 0, 0, 0), pos, mass, -tooManyParticles);
+
+ // Update the velocity and position of current particle using the acceleration computed above
+ vel.xyz += accel.xyz * g_paramf.x; //deltaTime;
+ vel.xyz *= g_paramf.y; //damping;
+ pos.xyz += vel.xyz * g_paramf.x; //deltaTime;
+
+ if ( DTid.x < g_param.x )
+ {
+ newPosVelo[DTid.x].pos = pos;
+ newPosVelo[DTid.x].velo = float4(vel.xyz, length(accel));
+ }
+}
diff --git a/tests/hlsl/dxsdk/NBodyGravityCS11/ParticleDraw.hlsl b/tests/hlsl/dxsdk/NBodyGravityCS11/ParticleDraw.hlsl
new file mode 100644
index 000000000..ea56e20e9
--- /dev/null
+++ b/tests/hlsl/dxsdk/NBodyGravityCS11/ParticleDraw.hlsl
@@ -0,0 +1,128 @@
+//TEST_IGNORE_FILE: Currently failing due to Spire compiler issues.
+//TEST:COMPARE_HLSL: -target dxbc-assembly -profile vs_4_0 -entry VSParticleDraw -profile gs_4_0 -entry GSParticleDraw -profile ps_4_0 -entry PSParticleDraw
+//--------------------------------------------------------------------------------------
+// File: ParticleDraw.hlsl
+//
+// Shaders for rendering the particle as point sprite
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//--------------------------------------------------------------------------------------
+
+struct VSParticleIn
+{
+ float4 color : COLOR;
+ uint id : SV_VERTEXID;
+};
+
+struct VSParticleDrawOut
+{
+ float3 pos : POSITION;
+ float4 color : COLOR;
+};
+
+struct GSParticleDrawOut
+{
+ float2 tex : TEXCOORD0;
+ float4 color : COLOR;
+ float4 pos : SV_POSITION;
+};
+
+struct PSParticleDrawIn
+{
+ float2 tex : TEXCOORD0;
+ float4 color : COLOR;
+};
+
+struct PosVelo
+{
+ float4 pos;
+ float4 velo;
+};
+
+Texture2D g_txDiffuse;
+StructuredBuffer<PosVelo> g_bufPosVelo;
+
+
+SamplerState g_samLinear
+{
+ Filter = MIN_MAG_MIP_LINEAR;
+ AddressU = Clamp;
+ AddressV = Clamp;
+};
+
+cbuffer cb0
+{
+ row_major float4x4 g_mWorldViewProj;
+ row_major float4x4 g_mInvView;
+};
+
+cbuffer cb1
+{
+ static float g_fParticleRad = 10.0f;
+};
+
+cbuffer cbImmutable
+{
+ static float3 g_positions[4] =
+ {
+ float3( -1, 1, 0 ),
+ float3( 1, 1, 0 ),
+ float3( -1, -1, 0 ),
+ float3( 1, -1, 0 ),
+ };
+
+ static float2 g_texcoords[4] =
+ {
+ float2(0,0),
+ float2(1,0),
+ float2(0,1),
+ float2(1,1),
+ };
+};
+
+//
+// Vertex shader for drawing the point-sprite particles
+//
+VSParticleDrawOut VSParticleDraw(VSParticleIn input)
+{
+ VSParticleDrawOut output;
+
+ output.pos = g_bufPosVelo[input.id].pos;
+
+ float mag = g_bufPosVelo[input.id].velo.w/9;
+ output.color = lerp( float4(1,0.1,0.1,1), input.color, mag );
+
+ return output;
+}
+
+//
+// GS for rendering point sprite particles. Takes a point and turns it into 2 tris.
+//
+[maxvertexcount(4)]
+void GSParticleDraw(point VSParticleDrawOut input[1], inout TriangleStream<GSParticleDrawOut> SpriteStream)
+{
+ GSParticleDrawOut output;
+
+ //
+ // Emit two new triangles
+ //
+ for(int i=0; i<4; i++)
+ {
+ float3 position = g_positions[i] * g_fParticleRad;
+ position = mul( position, (float3x3)g_mInvView ) + input[0].pos;
+ output.pos = mul( float4(position,1.0), g_mWorldViewProj );
+
+ output.color = input[0].color;
+ output.tex = g_texcoords[i];
+ SpriteStream.Append(output);
+ }
+ SpriteStream.RestartStrip();
+}
+
+//
+// PS for drawing particles
+//
+float4 PSParticleDraw(PSParticleDrawIn input) : SV_Target
+{
+ return g_txDiffuse.Sample( g_samLinear, input.tex ) * input.color;
+} \ No newline at end of file