X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=effect.h;h=a1852fc12e09f9a1abf454d0167241b26c7d3e1a;hb=d7def3f9e42e72566d7aedd52ffdeb5851da8314;hp=e10fab80759fd2359571fb6ff48d71a56d894aca;hpb=24164d4eb7654cbcde8dfc2f0d7fad2e698e3ff0;p=movit diff --git a/effect.h b/effect.h index e10fab8..a1852fc 100644 --- a/effect.h +++ b/effect.h @@ -196,7 +196,16 @@ public: // set sets_virtual_output_size(), though. // // Does not make a lot of sense together with needs_texture_bounce(). - virtual bool one_to_one_sampling() const { return false; } + // Cannot be set for compute shaders. + virtual bool one_to_one_sampling() const { return strong_one_to_one_sampling(); } + + // Similar in use to one_to_one_sampling(), but even stricter: + // The effect must not use texture coordinate in any way beyond + // giving it unmodified to its (single) input. This allows it to + // also be used after a compute shader, in the same phase. + // + // An effect that it strong one-to-one must also be one-to-one. + virtual bool strong_one_to_one_sampling() const { return false; } // Whether this effect wants to output to a different size than // its input(s) (see inform_input_size(), below). See also @@ -245,6 +254,45 @@ public: assert(false); } + // Whether this effect uses a compute shader instead of a regular fragment shader. + // Compute shaders are more flexible in that they can have multiple outputs + // for each invocation and also communicate between instances (by using shared + // memory within each group), but are not universally supported. The typical + // pattern would be to check movit_compute_shaders_supported and rewrite the + // graph to use a compute shader effect instead of a regular effect if it is + // available, in order to get better performance. Since compute shaders can reuse + // loads (again typically through shared memory), using needs_texture_bounce() + // is usually not needed, although it is allowed; the best candidates for compute + // shaders are typically those that sample many times from their input + // but can reuse those loads across neighboring instances. + // + // Compute shaders commonly work with unnormalized texture coordinates + // (where coordinates are integers [0..W) and [0..H)), whereas the rest + // of Movit, including any inputs you may want to sample from, works + // with normalized coordinates ([0..1)). Movit gives you uniforms + // PREFIX(inv_output_size) and PREFIX(output_texcoord_adjust) that you + // can use to transform unnormalized to normalized, as well as a macro + // NORMALIZE_TEXTURE_COORDS(vec2) that does it for you. + // + // Since compute shaders have flexible output, it is difficult to chain other + // effects after them in the same phase, and thus, they will always be last. + // (This limitation may be lifted for the special case of one-to-one effects + // in the future.) Furthermore, they cannot write to the framebuffer, just to + // textures, so Movit may have to insert an extra phase just to do the output + // from a texture to the screen in some cases. However, this is transparent + // to both the effect and the user. + virtual bool is_compute_shader() const { return false; } + + // For a compute shader (see the previous member function), what dimensions + // it should be invoked over. Called every frame, before uniforms are set + // (so you are allowed to update uniforms based from this call). + virtual void get_compute_dimensions(unsigned output_width, unsigned output_height, + unsigned *x, unsigned *y, unsigned *z) const { + *x = output_width; + *y = output_height; + *z = 1; + } + // Tells the effect the resolution of each of its input. // This will be called every frame, and always before get_output_size(), // so you can change your output size based on the input if so desired. @@ -301,7 +349,8 @@ public: // Set a parameter; intended to be called from user code. // Neither of these take ownership of the pointer. - virtual bool set_int(const std::string&, int value) MUST_CHECK_RESULT; + virtual bool set_int(const std::string &key, int value) MUST_CHECK_RESULT; + virtual bool set_ivec2(const std::string &key, const int *values) MUST_CHECK_RESULT; virtual bool set_float(const std::string &key, float value) MUST_CHECK_RESULT; virtual bool set_vec2(const std::string &key, const float *values) MUST_CHECK_RESULT; virtual bool set_vec3(const std::string &key, const float *values) MUST_CHECK_RESULT; @@ -318,6 +367,7 @@ protected: // These correspond directly to int/float/vec2/vec3/vec4 in GLSL. void register_int(const std::string &key, int *value); + void register_ivec2(const std::string &key, int *values); void register_float(const std::string &key, float *value); void register_vec2(const std::string &key, float *values); void register_vec3(const std::string &key, float *values); @@ -345,7 +395,8 @@ protected: // except for register_int as noted above. void register_uniform_sampler2d(const std::string &key, const int *value); void register_uniform_bool(const std::string &key, const bool *value); - void register_uniform_int(const std::string &key, const int *value); // Note: Requires GLSL 1.30 or newer. + void register_uniform_int(const std::string &key, const int *value); + void register_uniform_ivec2(const std::string &key, const int *values); void register_uniform_float(const std::string &key, const float *value); void register_uniform_vec2(const std::string &key, const float *values); void register_uniform_vec3(const std::string &key, const float *values); @@ -358,24 +409,27 @@ protected: private: std::map params_int; + std::map params_ivec2; std::map params_float; std::map params_vec2; std::map params_vec3; std::map params_vec4; // Picked out by EffectChain during finalization. - std::vector > uniforms_sampler2d; - std::vector > uniforms_bool; - std::vector > uniforms_int; - std::vector > uniforms_float; - std::vector > uniforms_vec2; - std::vector > uniforms_vec3; - std::vector > uniforms_vec4; - std::vector > uniforms_float_array; - std::vector > uniforms_vec2_array; - std::vector > uniforms_vec3_array; - std::vector > uniforms_vec4_array; - std::vector > uniforms_mat3; + std::vector> uniforms_image2d; + std::vector> uniforms_sampler2d; + std::vector> uniforms_bool; + std::vector> uniforms_int; + std::vector> uniforms_ivec2; + std::vector> uniforms_float; + std::vector> uniforms_vec2; + std::vector> uniforms_vec3; + std::vector> uniforms_vec4; + std::vector> uniforms_float_array; + std::vector> uniforms_vec2_array; + std::vector> uniforms_vec3_array; + std::vector> uniforms_vec4_array; + std::vector> uniforms_mat3; friend class EffectChain; };