diff options
author | Adrian Kummerlaender | 2019-02-25 19:57:11 +0100 |
---|---|---|
committer | Adrian Kummerlaender | 2019-02-25 19:57:11 +0100 |
commit | 26c1cf58f483e64d80703fe37c4bd3923d1ff5b7 (patch) | |
tree | 7cfd9a7a6a919d0879a096ff1f9b27200800ec56 | |
parent | dbac2c0b8722e17ea211fc47a6fd92f8db48402e (diff) | |
download | compustream-26c1cf58f483e64d80703fe37c4bd3923d1ff5b7.tar compustream-26c1cf58f483e64d80703fe37c4bd3923d1ff5b7.tar.gz compustream-26c1cf58f483e64d80703fe37c4bd3923d1ff5b7.tar.bz2 compustream-26c1cf58f483e64d80703fe37c4bd3923d1ff5b7.tar.lz compustream-26c1cf58f483e64d80703fe37c4bd3923d1ff5b7.tar.xz compustream-26c1cf58f483e64d80703fe37c4bd3923d1ff5b7.tar.zst compustream-26c1cf58f483e64d80703fe37c4bd3923d1ff5b7.zip |
Merge streaming into collide shaderpattern/ab
i.e. implement the A-B pattern.
Dispatching only one compute shader per interaction-less simulation step
already yields very noticeable performance gains. All cell types are now
fully handled by the collide shader which further simplifies the code.
-rw-r--r-- | src/main.cc | 15 | ||||
-rw-r--r-- | src/shader/code/collide.glsl | 36 | ||||
-rw-r--r-- | src/shader/code/stream.glsl | 82 |
3 files changed, 31 insertions, 102 deletions
diff --git a/src/main.cc b/src/main.cc index 71fbc88..fb3bfd0 100644 --- a/src/main.cc +++ b/src/main.cc @@ -20,7 +20,6 @@ #include "shader/code/interact.glsl" #include "shader/code/collide.glsl" -#include "shader/code/stream.glsl" #include "timer.h" @@ -100,7 +99,6 @@ int render(bool open_boundaries) { std::unique_ptr<ComputeShader> interact_shader; std::unique_ptr<ComputeShader> collide_shader; - std::unique_ptr<ComputeShader> stream_shader; window.init([&]() { scene_shader = std::make_unique<GraphicShader>( @@ -112,10 +110,9 @@ int render(bool open_boundaries) { interact_shader = std::make_unique<ComputeShader>(INTERACT_SHADER_CODE); collide_shader = std::make_unique<ComputeShader>(COLLIDE_SHADER_CODE); - stream_shader = std::make_unique<ComputeShader>(STREAM_SHADER_CODE); }); - if ( !interact_shader->isGood() || !collide_shader->isGood() || !stream_shader->isGood() ) { + if ( !interact_shader->isGood() || !collide_shader->isGood() ) { std::cerr << "Compute shader error." << std::endl; return -1; } @@ -151,14 +148,12 @@ int render(bool open_boundaries) { if ( update_lattice ) { if ( timer::millisecondsSince(last_frame) >= 1000/lups ) { if ( tick ) { - collide_shader->workOn(tick_buffers); - stream_shader->workOn(tick_buffers); interact_shader->workOn(tick_buffers); + collide_shader->workOn(tick_buffers); tick = false; } else { - collide_shader->workOn(tock_buffers); - stream_shader->workOn(tock_buffers); interact_shader->workOn(tock_buffers); + collide_shader->workOn(tock_buffers); tick = true; } @@ -193,10 +188,6 @@ int render(bool open_boundaries) { auto guard = collide_shader->use(); collide_shader->dispatch(nX, nY); } - { - auto guard = stream_shader->use(); - stream_shader->dispatch(nX, nY); - } last_frame = timer::now(); } diff --git a/src/shader/code/collide.glsl b/src/shader/code/collide.glsl index 673a285..4efd7fb 100644 --- a/src/shader/code/collide.glsl +++ b/src/shader/code/collide.glsl @@ -61,7 +61,7 @@ float get(uint x, uint y, int i, int j) { } void set(uint x, uint y, int i, int j, float v) { - collideCells[indexOfLatticeCell(x,y) + indexOfDirection(i,j)] = v; + streamCells[indexOfLatticeCell(x,y) + indexOfDirection(i,j)] = v; } void setFluid(uint x, uint y, vec2 v) { @@ -105,6 +105,18 @@ bool isBulkFluidCell(int material) { return material == 1 || material == 4 || material == 5 || material == 6; } +bool isBounceBackCell(int material) { + return material == 2 || material == 3; +} + +bool isInflowCell(int material) { + return material == 5; +} + +bool isOutflowCell(int material) { + return material == 6; +} + float getExternalMassInflux(int material) { if ( material == 4 ) { return 1.5; @@ -113,7 +125,7 @@ float getExternalMassInflux(int material) { } }; -/// Actual collide kernel +/// Actual collide&stream kernel void main() { const uint x = gl_GlobalInvocationID.x; @@ -125,14 +137,14 @@ void main() { const int material = getMaterial(x,y); - if ( isBulkFluidCell(material) ) { - float d = max(density(x,y), getExternalMassInflux(material)); - vec2 v = velocity(x,y,d); + float d = max(density(x,y), getExternalMassInflux(material)); + vec2 v = velocity(x,y,d); - if ( material == 5 ) { + if ( isBulkFluidCell(material) ) { + if ( isInflowCell(material) ) { v = vec2(0.1,0.0); } - if ( material == 6 ) { + if ( isOutflowCell(material) ) { d = 1.0; } @@ -140,7 +152,15 @@ void main() { for ( int i = -1; i <= 1; ++i ) { for ( int j = -1; j <= 1; ++j ) { - set(x,y,i,j, get(x,y,i,j) + omega * (equilibrium(d,v,i,j) - get(x,y,i,j))); + set(x+i,y+j,i,j, get(x,y,i,j) + omega * (equilibrium(d,v,i,j) - get(x,y,i,j))); + } + } + } + + if ( isBounceBackCell(material) ) { + for ( int i = -1; i <= 1; ++i ) { + for ( int j = -1; j <= 1; ++j ) { + set(x+(-1)*i,y+(-1)*j,(-1)*i,(-1)*j, get(x,y,i,j) + omega * (equilibrium(d,v,i,j) - get(x,y,i,j))); } } } diff --git a/src/shader/code/stream.glsl b/src/shader/code/stream.glsl deleted file mode 100644 index 59aed98..0000000 --- a/src/shader/code/stream.glsl +++ /dev/null @@ -1,82 +0,0 @@ -static const std::string STREAM_SHADER_CODE = R"( -#version 430 - -layout (local_size_x = 1, local_size_y = 1) in; - -layout (std430, binding=1) buffer bufferCollide { float collideCells[]; }; -layout (std430, binding=2) buffer bufferStream { float streamCells[]; }; -layout (std430, binding=3) buffer bufferFluid { float fluidCells[]; }; - -/// LBM constants - -uniform uint nX; -uniform uint nY; - -const uint q = 9; - -// Array indexing - -uint indexOfDirection(int i, int j) { - return 3*(i+1) + (j+1); -} - -uint indexOfLatticeCell(uint x, uint y) { - return q*nX*y + q*x; -} - -uint indexOfFluidVertex(uint x, uint y) { - return 3*nX*y + 3*x; -} - -/// Data access - -float get(uint x, uint y, int i, int j) { - return collideCells[indexOfLatticeCell(x,y) + indexOfDirection(i,j)]; -} - -void set(uint x, uint y, int i, int j, float v) { - streamCells[indexOfLatticeCell(x,y) + indexOfDirection(i,j)] = v; -} - -int getMaterial(uint x, uint y) { - const uint idx = indexOfFluidVertex(x, y); - return int(fluidCells[idx + 2]); -} - -/// Boundary conditions - -void bounceBack(uint x, uint y) { - for ( int i = -1; i <= 1; ++i ) { - for ( int j = -1; j <= 1; ++j ) { - set(x,y,i,j, get(x,y,(-1)*i,(-1)*j)); - } - } -} - -/// Actual stream kernel - -void main() { - const uint x = gl_GlobalInvocationID.x; - const uint y = gl_GlobalInvocationID.y; - - if ( !(x < nX && y < nY) ) { - return; - } - - const int material = getMaterial(x,y); - - if ( material == 0 ) { - return; - } - - if ( material == 2 || material == 3 ) { - bounceBack(x,y); - } - - for ( int i = -1; i <= 1; ++i ) { - for ( int j = -1; j <= 1; ++j ) { - set(x+i,y+j,i,j, get(x,y,i,j)); - } - } -} -)"; |