Add output size as a uniform to compute shaders, as an integer; not just the inverse...
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 29 Dec 2017 21:10:14 +0000 (22:10 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 29 Dec 2017 21:10:14 +0000 (22:10 +0100)
effect.cpp
effect.h
effect_chain.cpp
effect_chain.h

index 3446b42..805138f 100644 (file)
@@ -21,6 +21,15 @@ bool Effect::set_int(const string &key, int value)
        return true;
 }
 
+bool Effect::set_ivec2(const string &key, const int *values)
+{
+       if (params_ivec2.count(key) == 0) {
+               return false;
+       }
+       memcpy(params_ivec2[key], values, sizeof(int) * 2);
+       return true;
+}
+
 bool Effect::set_float(const string &key, float value)
 {
        if (params_float.count(key) == 0) {
@@ -64,6 +73,13 @@ void Effect::register_int(const string &key, int *value)
        register_uniform_int(key, value);
 }
 
+void Effect::register_ivec2(const string &key, int *values)
+{
+       assert(params_ivec2.count(key) == 0);
+       params_ivec2[key] = values;
+       register_uniform_ivec2(key, values);
+}
+
 void Effect::register_float(const string &key, float *value)
 {
        assert(params_float.count(key) == 0);
@@ -126,6 +142,16 @@ void Effect::register_uniform_int(const std::string &key, const int *value)
        uniforms_int.push_back(uniform);
 }
 
+void Effect::register_uniform_ivec2(const std::string &key, const int *values)
+{
+       Uniform<int> uniform;
+       uniform.name = key;
+       uniform.value = values;
+       uniform.num_values = 1;
+       uniform.location = -1;
+       uniforms_ivec2.push_back(uniform);
+}
+
 void Effect::register_uniform_float(const std::string &key, const float *value)
 {
        Uniform<float> uniform;
index ba39d6a..a1852fc 100644 (file)
--- a/effect.h
+++ b/effect.h
@@ -349,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;
@@ -366,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);
@@ -393,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);
@@ -406,6 +409,7 @@ protected:
 
 private:
        std::map<std::string, int *> params_int;
+       std::map<std::string, int *> params_ivec2;
        std::map<std::string, float *> params_float;
        std::map<std::string, float *> params_vec2;
        std::map<std::string, float *> params_vec3;
@@ -416,6 +420,7 @@ private:
        std::vector<Uniform<int>> uniforms_sampler2d;
        std::vector<Uniform<bool>> uniforms_bool;
        std::vector<Uniform<int>> uniforms_int;
+       std::vector<Uniform<int>> uniforms_ivec2;
        std::vector<Uniform<float>> uniforms_float;
        std::vector<Uniform<float>> uniforms_vec2;
        std::vector<Uniform<float>> uniforms_vec3;
index aefae8f..3084930 100644 (file)
@@ -523,6 +523,7 @@ void EffectChain::compile_glsl_program(Phase *phase)
 
        if (phase->is_compute_shader) {
                frag_shader.append(read_file("footer.comp"));
+               phase->compute_shader_node->effect->register_uniform_ivec2("output_size", phase->uniform_output_size);
                phase->compute_shader_node->effect->register_uniform_vec2("inv_output_size", (float *)&phase->inv_output_size);
                phase->compute_shader_node->effect->register_uniform_vec2("output_texcoord_adjust", (float *)&phase->output_texcoord_adjust);
        } else {
@@ -544,6 +545,7 @@ void EffectChain::compile_glsl_program(Phase *phase)
                extract_uniform_declarations(effect->uniforms_sampler2d, "sampler2D", effect_id, &phase->uniforms_sampler2d, &frag_shader_uniforms);
                extract_uniform_declarations(effect->uniforms_bool, "bool", effect_id, &phase->uniforms_bool, &frag_shader_uniforms);
                extract_uniform_declarations(effect->uniforms_int, "int", effect_id, &phase->uniforms_int, &frag_shader_uniforms);
+               extract_uniform_declarations(effect->uniforms_ivec2, "ivec2", effect_id, &phase->uniforms_ivec2, &frag_shader_uniforms);
                extract_uniform_declarations(effect->uniforms_float, "float", effect_id, &phase->uniforms_float, &frag_shader_uniforms);
                extract_uniform_declarations(effect->uniforms_vec2, "vec2", effect_id, &phase->uniforms_vec2, &frag_shader_uniforms);
                extract_uniform_declarations(effect->uniforms_vec3, "vec3", effect_id, &phase->uniforms_vec3, &frag_shader_uniforms);
@@ -607,6 +609,7 @@ void EffectChain::compile_glsl_program(Phase *phase)
        collect_uniform_locations(phase->glsl_program_num, &phase->uniforms_sampler2d);
        collect_uniform_locations(phase->glsl_program_num, &phase->uniforms_bool);
        collect_uniform_locations(phase->glsl_program_num, &phase->uniforms_int);
+       collect_uniform_locations(phase->glsl_program_num, &phase->uniforms_ivec2);
        collect_uniform_locations(phase->glsl_program_num, &phase->uniforms_float);
        collect_uniform_locations(phase->glsl_program_num, &phase->uniforms_vec2);
        collect_uniform_locations(phase->glsl_program_num, &phase->uniforms_vec3);
@@ -2154,6 +2157,8 @@ void EffectChain::execute_phase(Phase *phase,
                phase->outbuf_image_unit = 0;
                glBindImageTexture(phase->outbuf_image_unit, destinations[0].texnum, 0, GL_FALSE, 0, GL_WRITE_ONLY, destinations[0].format);
                check_error();
+               phase->uniform_output_size[0] = phase->output_width;
+               phase->uniform_output_size[1] = phase->output_height;
                phase->inv_output_size.x = 1.0f / phase->output_width;
                phase->inv_output_size.y = 1.0f / phase->output_height;
                phase->output_texcoord_adjust.x = 0.5f / phase->output_width;
@@ -2247,6 +2252,12 @@ void EffectChain::setup_uniforms(Phase *phase)
                        glUniform1iv(uniform.location, uniform.num_values, uniform.value);
                }
        }
+       for (size_t i = 0; i < phase->uniforms_ivec2.size(); ++i) {
+               const Uniform<int> &uniform = phase->uniforms_ivec2[i];
+               if (uniform.location != -1) {
+                       glUniform2iv(uniform.location, uniform.num_values, uniform.value);
+               }
+       }
        for (size_t i = 0; i < phase->uniforms_float.size(); ++i) {
                const Uniform<float> &uniform = phase->uniforms_float[i];
                if (uniform.location != -1) {
index 793bf7b..a36840d 100644 (file)
@@ -192,6 +192,7 @@ struct Phase {
 
        // These are used in transforming from unnormalized to normalized coordinates
        // in compute shaders.
+       int uniform_output_size[2];
        Point2D inv_output_size, output_texcoord_adjust;
 
        // Identifier used to create unique variables in GLSL.
@@ -203,6 +204,7 @@ struct Phase {
        std::vector<Uniform<int>> uniforms_sampler2d;
        std::vector<Uniform<bool>> uniforms_bool;
        std::vector<Uniform<int>> uniforms_int;
+       std::vector<Uniform<int>> uniforms_ivec2;
        std::vector<Uniform<float>> uniforms_float;
        std::vector<Uniform<float>> uniforms_vec2;
        std::vector<Uniform<float>> uniforms_vec3;