From: Steinar H. Gunderson Date: Wed, 22 Nov 2017 19:13:46 +0000 (+0100) Subject: Support sqrt-transformed intermediates with compute shaders. X-Git-Tag: 1.6.0~42 X-Git-Url: https://git.sesse.net/?p=movit;a=commitdiff_plain;h=beef8c4b242dd9e073f04b80539a10295417ced5;ds=sidebyside Support sqrt-transformed intermediates with compute shaders. --- diff --git a/effect_chain_test.cpp b/effect_chain_test.cpp index 2140354..63f574b 100644 --- a/effect_chain_test.cpp +++ b/effect_chain_test.cpp @@ -1304,6 +1304,21 @@ TEST(EffectChainTest, StringStreamLocalesWork) { free(saved_locale); } +// An effect that does nothing, but as a compute shader. +class IdentityComputeEffect : public Effect { +public: + IdentityComputeEffect() {} + virtual string effect_type_id() const { return "IdentityComputeEffect"; } + virtual bool is_compute_shader() const { return true; } + string output_fragment_shader() { return read_file("identity.comp"); } +}; + +class WithAndWithoutComputeShaderTest : public testing::TestWithParam { +}; +INSTANTIATE_TEST_CASE_P(WithAndWithoutComputeShaderTest, + WithAndWithoutComputeShaderTest, + testing::Values("fragment", "compute")); + TEST(EffectChainTest, sRGBIntermediate) { float data[] = { 0.0f, 0.5f, 0.0f, 1.0f, @@ -1371,7 +1386,7 @@ TEST(EffectChainTest, Linear10bitIntermediateAccuracy) { expect_equal(linear_data, out_data, size, 1, 7.5e-3, 2e-5); } -TEST(EffectChainTest, SquareRoot10bitIntermediateAccuracy) { +TEST_P(WithAndWithoutComputeShaderTest, SquareRoot10bitIntermediateAccuracy) { // Note that we do the comparison in sRGB space, which is what we // typically would want; however, we do the sRGB conversion ourself // to avoid compounding errors from shader conversions into the @@ -1386,7 +1401,11 @@ TEST(EffectChainTest, SquareRoot10bitIntermediateAccuracy) { EffectChainTester tester(data, size, 1, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR, GL_RGBA32F); tester.get_chain()->set_intermediate_format(GL_RGB10_A2, SQUARE_ROOT_FRAMEBUFFER_TRANSFORMATION); - tester.get_chain()->add_effect(new IdentityEffect()); + if (GetParam() == "compute") { + tester.get_chain()->add_effect(new IdentityComputeEffect()); + } else { + tester.get_chain()->add_effect(new IdentityEffect()); + } tester.get_chain()->add_effect(new BouncingIdentityEffect()); tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR); @@ -1467,15 +1486,6 @@ TEST(EffectChainTest, ProgramsAreClonedForMultipleThreads) { expect_equal(data, out_data, 3, 2); } -// An effect that does nothing, but as a compute shader. -class IdentityComputeEffect : public Effect { -public: - IdentityComputeEffect() {} - virtual string effect_type_id() const { return "IdentityComputeEffect"; } - virtual bool is_compute_shader() const { return true; } - string output_fragment_shader() { return read_file("identity.comp"); } -}; - TEST(ComputeShaderTest, Identity) { float data[] = { 0.0f, 0.25f, 0.3f, diff --git a/footer.comp b/footer.comp index 3ece901..16197a6 100644 --- a/footer.comp +++ b/footer.comp @@ -1,3 +1,10 @@ +// GLSL is pickier than the C++ preprocessor in if-testing for undefined +// tokens; do some fixups here to keep it happy. + +#ifndef SQUARE_ROOT_TRANSFORMATION +#define SQUARE_ROOT_TRANSFORMATION 0 +#endif + void main() { INPUT(); @@ -10,10 +17,14 @@ vec4 tex2D(sampler2D s, vec2 coord) void cs_output(uvec2 coord, vec4 val) { - imageStore(outbuf, ivec2(coord), val); + cs_output(ivec2(coord), val); } void cs_output(ivec2 coord, vec4 val) { +#if SQUARE_ROOT_TRANSFORMATION + // Make sure we don't give negative values to sqrt. + val.rgb = sqrt(max(val.rgb, 0.0)); +#endif imageStore(outbuf, coord, val); }