Fix a bug where the wrong effect would be asked for compute shaders dimensions.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 25 Nov 2017 00:58:08 +0000 (01:58 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sat, 25 Nov 2017 01:02:24 +0000 (02:02 +0100)
effect_chain.cpp
effect_chain_test.cpp
mirror.comp [new file with mode: 0644]

index c6bac80..a4d9c86 100644 (file)
@@ -2172,7 +2172,7 @@ void EffectChain::execute_phase(Phase *phase,
 
        if (phase->is_compute_shader) {
                unsigned x, y, z;
-               phase->output_node->effect->get_compute_dimensions(phase->output_width, phase->output_height, &x, &y, &z);
+               phase->compute_shader_node->effect->get_compute_dimensions(phase->output_width, phase->output_height, &x, &y, &z);
 
                // Uniforms need to come after set_gl_state() _and_ get_compute_dimensions(),
                // since they can be updated from there.
index 551cdbc..b7877f5 100644 (file)
@@ -1547,4 +1547,37 @@ TEST(ComputeShaderTest, Render8BitTo8Bit) {
        expect_equal(data, out_data, 3, 2);
 }
 
+// A compute shader to mirror the inputs, in 2x2 blocks.
+class MirrorComputeEffect : public Effect {
+public:
+       MirrorComputeEffect() {}
+       string effect_type_id() const override { return "MirrorComputeEffect"; }
+       bool is_compute_shader() const override { return true; }
+       string output_fragment_shader() override { return read_file("mirror.comp"); }
+       void get_compute_dimensions(unsigned output_width, unsigned output_height,
+                                   unsigned *x, unsigned *y, unsigned *z) const override {
+               *x = output_width / 2;
+               *y = output_height / 2;
+               *z = 1;
+       }
+};
+
+TEST(ComputeShaderTest, Mirror) {
+       float data[] = {
+               0.0f, 0.25f, 0.3f, 0.8f,
+               0.75f, 1.0f, 1.0f, 0.2f,
+       };
+       float expected_data[] = {
+               0.8f, 0.3f, 0.25f, 0.0f,
+               0.2f, 1.0f, 1.0f, 0.75f,
+       };
+       float out_data[8];
+       EffectChainTester tester(data, 4, 2, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
+       tester.get_chain()->add_effect(new MirrorComputeEffect());
+       tester.get_chain()->add_effect(new OneToOneEffect());
+       tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
+
+       expect_equal(expected_data, out_data, 4, 2);
+}
+
 }  // namespace movit
diff --git a/mirror.comp b/mirror.comp
new file mode 100644 (file)
index 0000000..d402136
--- /dev/null
@@ -0,0 +1,14 @@
+// A compute shader to mirror the inputs, in 2x2 blocks. For testing only.
+
+layout(local_size_x = 1) in;
+
+void FUNCNAME()
+{
+       ivec2 tc = ivec2(gl_GlobalInvocationID.xy) * ivec2(2, 2);
+       int offs = int(gl_NumWorkGroups.x) * 2 - 1;
+
+       OUTPUT(ivec2(offs - tc.x,     tc.y),     INPUT(NORMALIZE_TEXTURE_COORDS(vec2(tc.x,     tc.y))));
+       OUTPUT(ivec2(offs - tc.x - 1, tc.y),     INPUT(NORMALIZE_TEXTURE_COORDS(vec2(tc.x + 1, tc.y))));
+       OUTPUT(ivec2(offs - tc.x,     tc.y + 1), INPUT(NORMALIZE_TEXTURE_COORDS(vec2(tc.x,     tc.y + 1))));
+       OUTPUT(ivec2(offs - tc.x - 1, tc.y + 1), INPUT(NORMALIZE_TEXTURE_COORDS(vec2(tc.x + 1, tc.y + 1))));
+}