=== modified file 'src/canvas.h'
--- src/canvas.h	2011-11-01 16:49:42 +0000
+++ src/canvas.h	2011-11-10 10:21:27 +0000
@@ -31,6 +31,7 @@
 #include <sys/types.h>
 #include <string>
 #include <stdio.h>
+#include <cmath>
 
 /**
  * Abstraction for a GL rendering target.
@@ -61,6 +62,24 @@
                    (static_cast<uint32_t>(a) << 24);
 
         }
+
+        /** 
+         * Gets the euclidian distance from this pixel in 3D RGB space.
+         * 
+         * @param p the pixel to get the distance from
+         * 
+         * @return the euclidian distance
+         */
+        double distance_rgb(const Canvas::Pixel &p)
+        {
+            // These work without casts because of integer promotion rules
+            // (the uint8_ts are promoted to ints)
+            double d = (r - p.r) * (r - p.r) +
+                       (g - p.g) * (g - p.g) +
+                       (b - p.b) * (b - p.b);
+            return std::sqrt(d);
+        }
+
         uint8_t r;
         uint8_t g;
         uint8_t b;

=== modified file 'src/main.cpp'
--- src/main.cpp	2011-11-02 14:56:58 +0000
+++ src/main.cpp	2011-11-08 11:58:19 +0000
@@ -270,6 +270,15 @@
         return 0;
     }
 
+    /* Force 800x600 output for validation */
+    if (Options::validate &&
+        Options::size != std::pair<int,int>(800, 600))
+    {
+        Log::info("Ignoring custom size %dx%d for validation. Using 800x600.\n",
+                  Options::size.first, Options::size.second);
+        Options::size = std::pair<int,int>(800, 600);
+    }
+
     // Create the canvas
 #if USE_GL
     CanvasX11GLX canvas(Options::size.first, Options::size.second);

=== modified file 'src/scene-buffer.cpp'
--- src/scene-buffer.cpp	2011-11-01 16:46:08 +0000
+++ src/scene-buffer.cpp	2011-11-09 15:22:18 +0000
@@ -445,5 +445,20 @@
 Scene::ValidationResult
 SceneBuffer::validate()
 {
+    static const double radius_3d(std::sqrt(3.0 * 2.0 * 2.0));
+
+    Canvas::Pixel ref(0x34, 0x99, 0xd7, 0xff);
+    Canvas::Pixel pixel = canvas_.read_pixel(402, 189);
+
+    double dist = pixel.distance_rgb(ref);
+    if (dist < radius_3d + 0.01) {
+        return Scene::ValidationSuccess;
+    }
+    else {
+        Log::debug("Validation failed! Expected: 0x%x Actual: 0x%x Distance: %f\n",
+                    ref.to_le32(), pixel.to_le32(), dist);
+        return Scene::ValidationFailure;
+    }
+
     return Scene::ValidationUnknown;
 }

=== modified file 'src/scene-build.cpp'
--- src/scene-build.cpp	2011-10-26 14:09:17 +0000
+++ src/scene-build.cpp	2011-11-08 13:57:38 +0000
@@ -252,7 +252,7 @@
     Canvas::Pixel pixel = canvas_.read_pixel(canvas_.width() / 2,
                                              canvas_.height() / 2);
 
-    double dist = pixel_value_distance(pixel, ref);
+    double dist = pixel.distance_rgb(ref);
     if (dist < radius_3d + 0.01) {
         return Scene::ValidationSuccess;
     }

=== modified file 'src/scene-bump.cpp'
--- src/scene-bump.cpp	2011-10-26 14:09:17 +0000
+++ src/scene-bump.cpp	2011-11-08 13:57:38 +0000
@@ -262,7 +262,7 @@
     else
         return Scene::ValidationUnknown;
 
-    double dist = pixel_value_distance(pixel, ref);
+    double dist = pixel.distance_rgb(ref);
 
     if (dist < radius_3d + 0.01) {
         return Scene::ValidationSuccess;

=== modified file 'src/scene-conditionals.cpp'
--- src/scene-conditionals.cpp	2011-11-01 16:46:08 +0000
+++ src/scene-conditionals.cpp	2011-11-09 15:22:18 +0000
@@ -116,3 +116,38 @@
     startTime_ = Scene::get_timestamp_us() / 1000000.0;
     lastUpdateTime_ = startTime_;
 }
+
+Scene::ValidationResult
+SceneConditionals::validate()
+{
+    static const double radius_3d(std::sqrt(3.0 * 5.0 * 5.0));
+
+    bool frg_conditionals = options_["fragment-conditionals"].value == "true";
+    int frg_steps(Util::fromString<int>(options_["fragment-steps"].value));
+
+    if (!frg_conditionals)
+        return Scene::ValidationUnknown;
+
+    Canvas::Pixel ref;
+
+    if (frg_steps == 0)
+        ref = Canvas::Pixel(0xa0, 0xa0, 0xa0, 0xff);
+    else if (frg_steps == 5)
+        ref = Canvas::Pixel(0x25, 0x25, 0x25, 0xff);
+    else
+        return Scene::ValidationUnknown;
+
+    Canvas::Pixel pixel = canvas_.read_pixel(293, 89);
+
+    double dist = pixel.distance_rgb(ref);
+    if (dist < radius_3d + 0.01) {
+        return Scene::ValidationSuccess;
+    }
+    else {
+        Log::debug("Validation failed! Expected: 0x%x Actual: 0x%x Distance: %f\n",
+                    ref.to_le32(), pixel.to_le32(), dist);
+        return Scene::ValidationFailure;
+    }
+
+    return Scene::ValidationUnknown;
+}

=== modified file 'src/scene-desktop.cpp'
--- src/scene-desktop.cpp	2011-11-01 16:46:08 +0000
+++ src/scene-desktop.cpp	2011-11-09 15:22:18 +0000
@@ -935,5 +935,54 @@
 Scene::ValidationResult
 SceneDesktop::validate()
 {
-    return ValidationUnknown;
+    static const double radius_3d(std::sqrt(3.0 * 2.0 * 2.0));
+
+    Canvas::Pixel ref;
+
+    /* Parse the options */
+    unsigned int windows(0);
+    unsigned int passes(0);
+    unsigned int blur_radius(0);
+    float window_size_factor(0.0);
+    unsigned int shadow_size(0);
+
+    windows = Util::fromString<unsigned int>(options_["windows"].value);
+    window_size_factor = Util::fromString<float>(options_["window-size"].value);
+    passes = Util::fromString<unsigned int>(options_["passes"].value);
+    blur_radius = Util::fromString<unsigned int>(options_["blur-radius"].value);
+    shadow_size = Util::fromString<unsigned int>(options_["shadow-size"].value);
+
+    if (options_["effect"].value == "blur")
+    {
+        if (windows == 4 && passes == 1 && blur_radius == 5)
+            ref = Canvas::Pixel(0x89, 0xa3, 0x53, 0xff);
+        else
+            return Scene::ValidationUnknown;
+    }
+    else if (options_["effect"].value == "shadow")
+    {
+        if (windows == 4 && fabs(window_size_factor - 0.35) < 0.0001 &&
+            shadow_size == 20)
+        {
+            ref = Canvas::Pixel(0x1f, 0x27, 0x0d, 0xff);
+        }
+        else
+        {
+            return Scene::ValidationUnknown;
+        }
+    }
+
+    Canvas::Pixel pixel = canvas_.read_pixel(512, 209);
+
+    double dist = pixel.distance_rgb(ref);
+    if (dist < radius_3d + 0.01) {
+        return Scene::ValidationSuccess;
+    }
+    else {
+        Log::debug("Validation failed! Expected: 0x%x Actual: 0x%x Distance: %f\n",
+                    ref.to_le32(), pixel.to_le32(), dist);
+        return Scene::ValidationFailure;
+    }
+
+    return Scene::ValidationUnknown;
 }

=== modified file 'src/scene-effect-2d.cpp'
--- src/scene-effect-2d.cpp	2011-11-02 14:56:58 +0000
+++ src/scene-effect-2d.cpp	2011-11-08 13:57:38 +0000
@@ -186,7 +186,7 @@
  * @return whether parsing succeeded
  */
 static bool
-parse_matrix(std::string &str, std::vector<float> &matrix,
+parse_matrix(const std::string &str, std::vector<float> &matrix,
              unsigned int &width, unsigned int &height)
 {
     std::vector<std::string> rows;
@@ -392,5 +392,53 @@
 Scene::ValidationResult
 SceneEffect2D::validate()
 {
-    return ValidationUnknown;
+    static const double radius_3d(std::sqrt(3.0));
+
+    std::vector<float> kernel;
+    std::vector<float> kernel_edge;
+    std::vector<float> kernel_blur;
+    unsigned int kernel_width = 0;
+    unsigned int kernel_height = 0;
+
+    if (!parse_matrix("0,1,0;1,-4,1;0,1,0;", kernel_edge,
+                      kernel_width, kernel_height))
+    {
+        return Scene::ValidationUnknown;
+    }
+
+    if (!parse_matrix("1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;",
+                      kernel_blur,
+                      kernel_width, kernel_height))
+    {
+        return Scene::ValidationUnknown;
+    }
+
+    if (!parse_matrix(options_["kernel"].value, kernel,
+                      kernel_width, kernel_height))
+    {
+        return Scene::ValidationUnknown;
+    }
+
+    Canvas::Pixel ref;
+
+    if (kernel == kernel_edge)
+        ref = Canvas::Pixel(0x17, 0x0c, 0x2f, 0xff);
+    else if (kernel == kernel_blur)
+        ref = Canvas::Pixel(0xc7, 0xe1, 0x8d, 0xff);
+    else
+        return Scene::ValidationUnknown;
+
+    Canvas::Pixel pixel = canvas_.read_pixel(452, 237);
+
+    double dist = pixel.distance_rgb(ref);
+    if (dist < radius_3d + 0.01) {
+        return Scene::ValidationSuccess;
+    }
+    else {
+        Log::debug("Validation failed! Expected: 0x%x Actual: 0x%x Distance: %f\n",
+                   ref.to_le32(), pixel.to_le32(), dist);
+        return Scene::ValidationFailure;
+    }
+
+    return Scene::ValidationUnknown;
 }

=== modified file 'src/scene-function.cpp'
--- src/scene-function.cpp	2011-11-01 16:46:08 +0000
+++ src/scene-function.cpp	2011-11-09 15:22:18 +0000
@@ -19,6 +19,8 @@
  * Authors:
  *  Alexandros Frantzis (glmark2)
  */
+#include <cmath>
+
 #include "scene.h"
 #include "mat.h"
 #include "stack.h"
@@ -146,3 +148,32 @@
     startTime_ = Scene::get_timestamp_us() / 1000000.0;
     lastUpdateTime_ = startTime_;
 }
+
+Scene::ValidationResult
+SceneFunction::validate()
+{
+    static const double radius_3d(std::sqrt(3.0 * 15.0 * 15.0));
+
+    int frg_steps = Util::fromString<int>(options_["fragment-steps"].value);
+
+    Canvas::Pixel ref;
+
+    if (frg_steps == 5)
+        ref = Canvas::Pixel(0x5e, 0x5e, 0x5e, 0xff);
+    else
+        return Scene::ValidationUnknown;
+
+    Canvas::Pixel pixel = canvas_.read_pixel(293, 89);
+
+    double dist = pixel.distance_rgb(ref);
+    if (dist < radius_3d + 0.01) {
+        return Scene::ValidationSuccess;
+    }
+    else {
+        Log::debug("Validation failed! Expected: 0x%x Actual: 0x%x Distance: %f\n",
+                    ref.to_le32(), pixel.to_le32(), dist);
+        return Scene::ValidationFailure;
+    }
+
+    return Scene::ValidationUnknown;
+}

=== modified file 'src/scene-loop.cpp'
--- src/scene-loop.cpp	2011-11-01 16:46:08 +0000
+++ src/scene-loop.cpp	2011-11-09 15:22:18 +0000
@@ -19,6 +19,8 @@
  * Authors:
  *  Alexandros Frantzis (glmark2)
  */
+#include <cmath>
+
 #include "scene.h"
 #include "mat.h"
 #include "stack.h"
@@ -141,3 +143,32 @@
     startTime_ = Scene::get_timestamp_us() / 1000000.0;
     lastUpdateTime_ = startTime_;
 }
+
+Scene::ValidationResult
+SceneLoop::validate()
+{
+    static const double radius_3d(std::sqrt(3.0 * 15.0 * 15.0));
+
+    int frg_steps = Util::fromString<int>(options_["fragment-steps"].value);
+
+    Canvas::Pixel ref;
+
+    if (frg_steps == 5)
+        ref = Canvas::Pixel(0x5e, 0x5e, 0x5e, 0xff);
+    else
+        return Scene::ValidationUnknown;
+
+    Canvas::Pixel pixel = canvas_.read_pixel(293, 89);
+
+    double dist = pixel.distance_rgb(ref);
+    if (dist < radius_3d + 0.01) {
+        return Scene::ValidationSuccess;
+    }
+    else {
+        Log::debug("Validation failed! Expected: 0x%x Actual: 0x%x Distance: %f\n",
+                    ref.to_le32(), pixel.to_le32(), dist);
+        return Scene::ValidationFailure;
+    }
+
+    return Scene::ValidationUnknown;
+}

=== modified file 'src/scene-pulsar.cpp'
--- src/scene-pulsar.cpp	2011-11-01 16:50:07 +0000
+++ src/scene-pulsar.cpp	2011-11-08 13:57:38 +0000
@@ -224,7 +224,31 @@
 Scene::ValidationResult
 ScenePulsar::validate()
 {
-    return ValidationUnknown;
+    static const double radius_3d(std::sqrt(3.0));
+
+    int quads = Util::fromString<int>(options_["quads"].value);
+
+    if (options_["texture"].value != "false" ||
+        options_["light"].value != "false" ||
+        quads != 5)
+    {
+        return Scene::ValidationUnknown;
+    }
+
+    Canvas::Pixel ref(0x77, 0x02, 0x77, 0xff);
+    Canvas::Pixel pixel = canvas_.read_pixel(400, 299);
+
+    double dist = pixel.distance_rgb(ref);
+    if (dist < radius_3d + 0.01) {
+        return Scene::ValidationSuccess;
+    }
+    else {
+        Log::debug("Validation failed! Expected: 0x%x Actual: 0x%x Distance: %f\n",
+                    ref.to_le32(), pixel.to_le32(), dist);
+        return Scene::ValidationFailure;
+    }
+
+    return Scene::ValidationUnknown;
 }
 
 void

=== modified file 'src/scene-shading.cpp'
--- src/scene-shading.cpp	2011-10-31 20:42:52 +0000
+++ src/scene-shading.cpp	2011-11-08 13:57:38 +0000
@@ -331,7 +331,7 @@
     else
         return Scene::ValidationUnknown;
 
-    double dist = pixel_value_distance(pixel, ref);
+    double dist = pixel.distance_rgb(ref);
 
     if (dist < radius_3d + 0.01) {
         return Scene::ValidationSuccess;

=== modified file 'src/scene-texture.cpp'
--- src/scene-texture.cpp	2011-10-26 14:09:17 +0000
+++ src/scene-texture.cpp	2011-11-08 13:57:38 +0000
@@ -208,7 +208,7 @@
     else
         return Scene::ValidationUnknown;
 
-    double dist = pixel_value_distance(pixel, ref);
+    double dist = pixel.distance_rgb(ref);
 
     if (dist < radius_3d + 0.01) {
         return Scene::ValidationSuccess;

=== modified file 'src/scene.cpp'
--- src/scene.cpp	2011-11-01 16:46:08 +0000
+++ src/scene.cpp	2011-11-08 13:57:38 +0000
@@ -187,24 +187,6 @@
 
 }
 
-double
-Scene::pixel_value_distance(Canvas::Pixel p1, Canvas::Pixel p2,
-                            bool use_alpha)
-{
-    double s(0.0);
-
-    // These work without casts because of integer promotion rules
-    // (the Uint8s are promoted to ints)
-    s += (p1.r - p2.r) * (p1.r - p2.r);
-    s += (p1.g - p2.g) * (p1.g - p2.g);
-    s += (p1.b - p2.b) * (p1.b - p2.b);
-
-    if (use_alpha)
-        s += (p1.a - p2.a) * (p1.a - p2.a);
-
-    return std::sqrt(s);
-}
-
 bool
 Scene::load_shaders_from_strings(Program &program,
                                  const std::string &vtx_shader,

=== modified file 'src/scene.h'
--- src/scene.h	2011-10-25 18:05:37 +0000
+++ src/scene.h	2011-11-08 13:57:38 +0000
@@ -109,8 +109,6 @@
 protected:
     Scene(Canvas &pCanvas, const std::string &name);
     std::string construct_title(const std::string &title);
-    double pixel_value_distance(Canvas::Pixel p1, Canvas::Pixel p2,
-                                bool use_alpha=false);
 
     Canvas &canvas_;
     std::string name_;
@@ -240,6 +238,7 @@
 public:
     SceneConditionals(Canvas &pCanvas);
     void setup();
+    ValidationResult validate();
 
     ~SceneConditionals();
 };
@@ -249,6 +248,7 @@
 public:
     SceneFunction(Canvas &pCanvas);
     void setup();
+    ValidationResult validate();
 
     ~SceneFunction();
 };
@@ -258,6 +258,7 @@
 public:
     SceneLoop(Canvas &pCanvas);
     void setup();
+    ValidationResult validate();
 
     ~SceneLoop();
 };

