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/NBodyGravityCS11 | |
| parent | 52e8d4b9a27ab0060f874c3a63ab531847be35c0 (diff) | |
Initial import of code.
Diffstat (limited to 'tests/hlsl/dxsdk/NBodyGravityCS11')
| -rw-r--r-- | tests/hlsl/dxsdk/NBodyGravityCS11/NBodyGravityCS11.hlsl | 103 | ||||
| -rw-r--r-- | tests/hlsl/dxsdk/NBodyGravityCS11/ParticleDraw.hlsl | 128 |
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 |
