Handle texture non-bounce a bit better.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Mon, 10 Mar 2014 21:09:18 +0000 (22:09 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Mon, 10 Mar 2014 21:09:18 +0000 (22:09 +0100)
This allows us to ignore the texture bounce flag when reading from a
FlatInput, and also handles better the case where an YCbCrInput is read
from multiple times (it's now bounced, which should be better for speed,
I think).

The main motivation, however, is to be able to control sampler state
a bit less hackish in the future.

effect.h
effect_chain.cpp
flat_input.h

index 16b6cbb..9d95705 100644 (file)
--- a/effect.h
+++ b/effect.h
@@ -167,6 +167,15 @@ public:
        // next effect set needs_texture_bounce()).
        virtual bool changes_output_size() const { return false; }
 
+       // Whether this effect is effectively sampling from a a single texture.
+       // If so, it will override needs_texture_bounce(); however, there are also
+       // two demands it needs to fulfill:
+       //
+       //  1. It needs to be an Input, ie. num_inputs() == 0.
+       //  2. It needs to allocate exactly one sampler in set_gl_state(),
+       //     and allow dependent effects to change that sampler state.
+       virtual bool is_single_texture() const { return false; }
+
        // If changes_output_size() is true, you must implement this to tell
        // the framework what output size you want. Also, you can set a
        // virtual width/height, which is the size the next effect (if any)
index 41e026d..0cd4802 100644 (file)
@@ -359,13 +359,13 @@ void EffectChain::construct_glsl_programs(Node *output)
                        for (unsigned i = 0; i < deps.size(); ++i) {
                                bool start_new_phase = false;
 
-                               // FIXME: If we sample directly from a texture, we won't need this.
-                               if (node->effect->needs_texture_bounce()) {
+                               if (node->effect->needs_texture_bounce() &&
+                                   !deps[i]->effect->is_single_texture()) {
                                        start_new_phase = true;
                                }
 
                                if (deps[i]->outgoing_links.size() > 1) {
-                                       if (deps[i]->effect->num_inputs() > 0) {
+                                       if (!deps[i]->effect->is_single_texture()) {
                                                // More than one effect uses this as the input,
                                                // and it is not a texture itself.
                                                // The easiest thing to do (and probably also the safest
@@ -373,6 +373,8 @@ void EffectChain::construct_glsl_programs(Node *output)
                                                // and then let the next passes read from that.
                                                start_new_phase = true;
                                        } else {
+                                               assert(deps[i]->effect->num_inputs() == 0);
+
                                                // For textures, we try to be slightly more clever;
                                                // if none of our outputs need a bounce, we don't bounce
                                                // but instead simply use the effect many times.
index caa68b7..5f3faed 100644 (file)
@@ -58,6 +58,7 @@ public:
        unsigned get_height() const { return height; }
        Colorspace get_color_space() const { return image_format.color_space; }
        GammaCurve get_gamma_curve() const { return image_format.gamma_curve; }
+       virtual bool is_single_texture() const { return true; }
 
        // Tells the input where to fetch the actual pixel data. Note that if you change
        // this data, you must either call set_pixel_data() again (using the same pointer