aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdrian Kummerlaender2019-02-25 19:57:11 +0100
committerAdrian Kummerlaender2019-02-25 19:57:11 +0100
commit26c1cf58f483e64d80703fe37c4bd3923d1ff5b7 (patch)
tree7cfd9a7a6a919d0879a096ff1f9b27200800ec56 /src
parentdbac2c0b8722e17ea211fc47a6fd92f8db48402e (diff)
downloadcompustream-pattern/ab.tar
compustream-pattern/ab.tar.gz
compustream-pattern/ab.tar.bz2
compustream-pattern/ab.tar.lz
compustream-pattern/ab.tar.xz
compustream-pattern/ab.tar.zst
compustream-pattern/ab.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.
Diffstat (limited to 'src')
-rw-r--r--src/main.cc15
-rw-r--r--src/shader/code/collide.glsl36
-rw-r--r--src/shader/code/stream.glsl82
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));
- }
- }
-}
-)";