From 8ee9712bae3cff206b3e3205748633edb33cbbcf Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sat, 25 Nov 2017 01:58:08 +0100 Subject: [PATCH] Fix a bug where the wrong effect would be asked for compute shaders dimensions. --- effect_chain.cpp | 2 +- effect_chain_test.cpp | 33 +++++++++++++++++++++++++++++++++ mirror.comp | 14 ++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 mirror.comp diff --git a/effect_chain.cpp b/effect_chain.cpp index c6bac80..a4d9c86 100644 --- a/effect_chain.cpp +++ b/effect_chain.cpp @@ -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. diff --git a/effect_chain_test.cpp b/effect_chain_test.cpp index 551cdbc..b7877f5 100644 --- a/effect_chain_test.cpp +++ b/effect_chain_test.cpp @@ -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 index 0000000..d402136 --- /dev/null +++ b/mirror.comp @@ -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)))); +} -- 2.39.2