// just immediately throws away half of the warp, but it helps convergence
// a _lot_ (rough testing indicates that five iterations of SOR is as good
// as ~50 iterations of Jacobi). We could probably do better by reorganizing
- // the data into two-values-per-pixel, so-called “twinning buffering”,
- // but it makes for rather annoying code in the rest of the pipeline.
+ // the data into two-values-per-pixel, so-called “twinned buffering”;
+ // seemingly, it helps Haswell by ~15% on the SOR code, but GTX 950 not at all
+ // (at least not on 720p). Presumably the latter is already bandwidth bound.
int color = int(round(element_sum_idx)) & 1;
if (color != phase) discard;
float inv_A22 = uintBitsToFloat(equation.z);
vec2 b = unpack_floats_shared(equation.w);
+ const float omega = 1.8; // Marginally better than 1.6, it seems.
+
if (zero_diff_flow) {
- diff_flow = vec2(0.0f);
+ // Simplified version of the code below, assuming diff_flow == 0.0f everywhere.
+ diff_flow.x = omega * b.x * inv_A11;
+ diff_flow.y = omega * b.y * inv_A22;
} else {
// Subtract the missing terms from the right-hand side
// (it couldn't be done earlier, because we didn't know
b += smooth_d * textureOffset(diff_flow_tex, tc, ivec2( 0, -1)).xy;
b += smooth_u * textureOffset(diff_flow_tex, tc, ivec2( 0, 1)).xy;
diff_flow = texture(diff_flow_tex, tc).xy;
- }
- const float omega = 1.8; // Marginally better than 1.6, it seems.
-
- // From https://en.wikipedia.org/wiki/Successive_over-relaxation.
- float sigma_u = A12 * diff_flow.y;
- diff_flow.x += omega * ((b.x - sigma_u) * inv_A11 - diff_flow.x);
- float sigma_v = A12 * diff_flow.x;
- diff_flow.y += omega * ((b.y - sigma_v) * inv_A22 - diff_flow.y);
+ // From https://en.wikipedia.org/wiki/Successive_over-relaxation.
+ float sigma_u = A12 * diff_flow.y;
+ diff_flow.x += omega * ((b.x - sigma_u) * inv_A11 - diff_flow.x);
+ float sigma_v = A12 * diff_flow.x;
+ diff_flow.y += omega * ((b.y - sigma_v) * inv_A22 - diff_flow.y);
+ }
}