Explicitly declare use of round() as an #extension.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 26 Jan 2014 23:03:36 +0000 (00:03 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 26 Jan 2014 23:03:36 +0000 (00:03 +0100)
round() is not part of GLSL 1.10, so we need to check explicitly for it
before we can use it.

Reported by Dan Dennedy.

demo.cpp
dither_effect.cpp
header.frag
init.cpp
init.h

index b401f05..81d3e50 100644 (file)
--- a/demo.cpp
+++ b/demo.cpp
@@ -181,6 +181,13 @@ int main(int argc, char **argv)
                log2(1.0f / movit_texel_subpixel_precision));
        printf("Wrongly rounded x+0.48 or x+0.52 values: %d/510\n",
                movit_num_wrongly_rounded);
+       if (movit_num_wrongly_rounded > 0) {
+               if (movit_shader_rounding_supported) {
+                       printf("Rounding off in the shader to compensate.\n");
+               } else {
+                       printf("No shader roundoff available; cannot compensate.\n");
+               }
+       }
        
        unsigned img_w, img_h;
        unsigned char *src_img = load_image(argc > 1 ? argv[1] : "blg_wheels_woman_1.jpg", &img_w, &img_h);
index 14132bd..6e1ddd8 100644 (file)
@@ -45,7 +45,7 @@ DitherEffect::~DitherEffect()
 string DitherEffect::output_fragment_shader()
 {
        char buf[256];
-       sprintf(buf, "#define NEED_EXPLICIT_ROUND %d\n", (movit_num_wrongly_rounded > 0));
+       sprintf(buf, "#define NEED_EXPLICIT_ROUND %d\n", (movit_num_wrongly_rounded > 0 && movit_shader_rounding_supported));
        return buf + read_file("dither_effect.frag");
 }
 
index 86c5730..af211fe 100644 (file)
@@ -1 +1,6 @@
+#ifdef GL_EXT_gpu_shader4
+// We sometimes want round().
+#extension GL_EXT_gpu_shader4 : enable
+#endif
+
 varying vec2 tc;
index df72832..d8d249f 100644 (file)
--- a/init.cpp
+++ b/init.cpp
@@ -14,6 +14,7 @@ MovitDebugLevel movit_debug_level = MOVIT_DEBUG_ON;
 float movit_texel_subpixel_precision;
 bool movit_srgb_textures_supported;
 int movit_num_wrongly_rounded;
+bool movit_shader_rounding_supported;
 
 // The rules for objects with nontrivial constructors in static scope
 // are somewhat convoluted, and easy to mess up. We simply have a
@@ -273,6 +274,12 @@ void check_extensions()
        // sRGB texture decode would be nice, but are not mandatory
        // (GammaExpansionEffect can do the same thing if needed).
        movit_srgb_textures_supported = glewIsSupported("GL_EXT_texture_sRGB");
+
+       // We may want to use round() at the end of the final shader,
+       // if supported. We need either GLSL 1.30 or this extension to do that,
+       // and 1.30 brings with it other things that we don't want to demand
+       // for now.
+       movit_shader_rounding_supported = glewIsSupported("GL_EXT_gpu_shader4");
 }
 
 }  // namespace
diff --git a/init.h b/init.h
index 9b4deff..398ddbe 100644 (file)
--- a/init.h
+++ b/init.h
@@ -51,9 +51,14 @@ extern float movit_texel_subpixel_precision;
 // round the right way (giving some leeway, but not a lot); the number
 // of errors are stored here.
 //
-// If this value is above 0, and you have enabled dithering, we will
-// round off explicitly at the very end of the shader.
+// If this value is above 0, the extension GL_EXT_gpu_shader4 is available
+// (giving round()) and you have enabled dithering, we will round off
+// explicitly at the very end of the shader.
+//
+// Note: I don't know of any cards that round off wrong (well, outside
+// our tolerance) and do not have this extension.
 extern int movit_num_wrongly_rounded;
+extern bool movit_shader_rounding_supported;
 
 // Whether the GPU in use supports GL_EXT_texture_sRGB.
 extern bool movit_srgb_textures_supported;