[cogl/wip/neil/pipeline-uniforms: 15/15] Add a conformance test for setting uniforms on a pipeline



commit bf4915e2963fe45d859119df6abb878fedfe0743
Author: Neil Roberts <neil linux intel com>
Date:   Thu Nov 3 17:28:01 2011 +0000

    Add a conformance test for setting uniforms on a pipeline
    
    The tests tries all of the various combinations of setting uniform
    values on a pipeline and verifies the expected results with a some
    example shaders.

 tests/conform/Makefile.am              |    1 +
 tests/conform/test-conform-main.c      |    1 +
 tests/conform/test-pipeline-uniforms.c |  353 ++++++++++++++++++++++++++++++++
 3 files changed, 355 insertions(+), 0 deletions(-)
---
diff --git a/tests/conform/Makefile.am b/tests/conform/Makefile.am
index 1f3fd01..440d849 100644
--- a/tests/conform/Makefile.am
+++ b/tests/conform/Makefile.am
@@ -42,6 +42,7 @@ test_sources = \
 	test-just-vertex-shader.c \
 	test-path.c \
 	test-pipeline-user-matrix.c \
+	test-pipeline-uniforms.c \
 	test-wrap-modes.c \
 	test-sub-texture.c \
 	$(NULL)
diff --git a/tests/conform/test-conform-main.c b/tests/conform/test-conform-main.c
index ecb4bb2..5be834b 100644
--- a/tests/conform/test-conform-main.c
+++ b/tests/conform/test-conform-main.c
@@ -161,6 +161,7 @@ main (int argc, char **argv)
   UNPORTED_TEST ("/cogl/vertex-array", test_cogl_primitive);
 
   ADD_TEST ("/cogl/shaders", test_cogl_just_vertex_shader);
+  ADD_TEST ("/cogl/shaders", test_cogl_pipeline_uniforms);
 
   ADD_TEST ("/cogl/internal/bitmask", test_cogl_bitmask);
 
diff --git a/tests/conform/test-pipeline-uniforms.c b/tests/conform/test-pipeline-uniforms.c
new file mode 100644
index 0000000..62084ea
--- /dev/null
+++ b/tests/conform/test-pipeline-uniforms.c
@@ -0,0 +1,353 @@
+#include <cogl/cogl.h>
+
+#include <string.h>
+
+#include "test-utils.h"
+
+typedef struct _TestState
+{
+  CoglPipeline *pipeline_red;
+  CoglPipeline *pipeline_green;
+  CoglPipeline *pipeline_blue;
+
+  CoglPipeline *matrix_pipeline;
+  CoglPipeline *vector_pipeline;
+  CoglPipeline *int_pipeline;
+} TestState;
+
+static const char
+color_source[] =
+  "uniform float red, green, blue;\n"
+  "\n"
+  "void\n"
+  "main ()\n"
+  "{\n"
+  "  cogl_color_out = vec4 (red, green, blue, 1.0);\n"
+  "}\n";
+
+static const char
+matrix_source[] =
+  "uniform mat4 matrix_array[4];\n"
+  "\n"
+  "void\n"
+  "main ()\n"
+  "{\n"
+  "  vec4 color = vec4 (0.0, 0.0, 0.0, 1.0);\n"
+  "  int i;\n"
+  "\n"
+  "  for (i = 0; i < 4; i++)\n"
+  "    color = matrix_array[i] * color;\n"
+  "\n"
+  "  cogl_color_out = color;\n"
+  "}\n";
+
+static const char
+vector_source[] =
+  "uniform vec4 vector_array[2];\n"
+  "uniform vec3 short_vector;\n"
+  "\n"
+  "void\n"
+  "main ()\n"
+  "{\n"
+  "  cogl_color_out = (vector_array[0] +\n"
+  "                    vector_array[1] +\n"
+  "                    vec4 (short_vector, 1.0));\n"
+  "}\n";
+
+static const char
+int_source[] =
+  "uniform ivec4 vector_array[2];\n"
+  "uniform int single_value;\n"
+  "\n"
+  "void\n"
+  "main ()\n"
+  "{\n"
+  "  cogl_color_out = (vec4 (vector_array[0]) +\n"
+  "                    vec4 (vector_array[1]) +\n"
+  "                    vec4 (float (single_value), 0.0, 0.0, 255.0)) / 255.0;\n"
+  "}\n";
+
+static CoglPipeline *
+create_pipeline_for_shader (const char *shader_source)
+{
+  CoglPipeline *pipeline;
+  CoglHandle shader;
+  CoglHandle program;
+
+  pipeline = cogl_pipeline_new ();
+
+  shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT);
+  cogl_shader_source (shader, shader_source);
+
+  program = cogl_create_program ();
+  cogl_program_attach_shader (program, shader);
+
+  cogl_pipeline_set_user_program (pipeline, program);
+
+  cogl_handle_unref (shader);
+  cogl_handle_unref (program);
+
+  return pipeline;
+}
+
+static void
+init_state (TestState *state)
+{
+  int uniform_location;
+
+  state->pipeline_red = create_pipeline_for_shader (color_source);
+
+  uniform_location =
+    cogl_pipeline_get_uniform_location (state->pipeline_red, "red");
+  cogl_pipeline_set_uniform_1f (state->pipeline_red, uniform_location, 1.0f);
+  uniform_location =
+    cogl_pipeline_get_uniform_location (state->pipeline_red, "green");
+  cogl_pipeline_set_uniform_1f (state->pipeline_red, uniform_location, 0.0f);
+  uniform_location =
+    cogl_pipeline_get_uniform_location (state->pipeline_red, "blue");
+  cogl_pipeline_set_uniform_1f (state->pipeline_red, uniform_location, 0.0f);
+
+  state->pipeline_green = cogl_pipeline_copy (state->pipeline_red);
+  uniform_location =
+    cogl_pipeline_get_uniform_location (state->pipeline_green, "green");
+  cogl_pipeline_set_uniform_1f (state->pipeline_green, uniform_location, 1.0f);
+
+  state->pipeline_blue = cogl_pipeline_copy (state->pipeline_red);
+  uniform_location =
+    cogl_pipeline_get_uniform_location (state->pipeline_blue, "blue");
+  cogl_pipeline_set_uniform_1f (state->pipeline_blue, uniform_location, 1.0f);
+
+  state->matrix_pipeline = create_pipeline_for_shader (matrix_source);
+  state->vector_pipeline = create_pipeline_for_shader (vector_source);
+  state->int_pipeline = create_pipeline_for_shader (int_source);
+}
+
+static void
+destroy_state (TestState *state)
+{
+  cogl_object_unref (state->pipeline_red);
+  cogl_object_unref (state->pipeline_green);
+  cogl_object_unref (state->pipeline_blue);
+  cogl_object_unref (state->matrix_pipeline);
+  cogl_object_unref (state->vector_pipeline);
+  cogl_object_unref (state->int_pipeline);
+}
+
+static void
+paint_pipeline (CoglPipeline *pipeline, int pos)
+{
+  cogl_push_source (pipeline);
+  cogl_rectangle (pos * 10, 0, pos * 10 + 10, 10);
+  cogl_pop_source ();
+}
+
+static void
+paint_color_pipelines (TestState *state)
+{
+  CoglPipeline *temp_pipeline;
+  int uniform_location;
+  int i;
+
+  /* Paint with the first pipeline that sets the uniforms to bright
+     red */
+  paint_pipeline (state->pipeline_red, 0);
+
+  /* Paint with the two other pipelines. These inherit from the red
+     pipeline and only override one other component. The values for
+     the two other components should be inherited from the red
+     pipeline. */
+  paint_pipeline (state->pipeline_green, 1);
+  paint_pipeline (state->pipeline_blue, 2);
+
+  /* Try modifying a single pipeline for multiple rectangles */
+  temp_pipeline = cogl_pipeline_copy (state->pipeline_green);
+  uniform_location = cogl_pipeline_get_uniform_location (temp_pipeline,
+                                                         "green");
+
+  for (i = 0; i <= 8; i++)
+    {
+      cogl_pipeline_set_uniform_1f (temp_pipeline, uniform_location,
+                                    i / 8.0f);
+      paint_pipeline (temp_pipeline, i + 3);
+    }
+
+  cogl_object_unref (temp_pipeline);
+}
+
+static void
+paint_matrix_pipeline (CoglPipeline *pipeline)
+{
+  CoglMatrix matrices[4];
+  float matrix_floats[16 * 4];
+  int uniform_location;
+  int i;
+
+  for (i = 0; i < 4; i++)
+    cogl_matrix_init_identity (matrices + i);
+
+  /* Use the first matrix to make the color red */
+  cogl_matrix_translate (matrices + 0, 1.0f, 0.0f, 0.0f);
+
+  /* Rotate the vertex so that it ends up green */
+  cogl_matrix_rotate (matrices + 1, 90.0f, 0.0f, 0.0f, 1.0f);
+
+  /* Scale the vertex so it ends up halved */
+  cogl_matrix_scale (matrices + 2, 0.5f, 0.5f, 0.5f);
+
+  /* Add a blue component in the final matrix. The final matrix is
+     uploaded as transposed so we need to transpose first to cancel
+     that out */
+  cogl_matrix_translate (matrices + 3, 0.0f, 0.0f, 1.0f);
+  cogl_matrix_transpose (matrices + 3);
+
+  for (i = 0; i < 4; i++)
+    memcpy (matrix_floats + i * 16,
+            cogl_matrix_get_array (matrices + i),
+            sizeof (float) * 16);
+
+  /* Set the first three matrices as transposed */
+  uniform_location =
+    cogl_pipeline_get_uniform_location (pipeline, "matrix_array");
+  cogl_pipeline_set_uniform_matrix (pipeline,
+                                    uniform_location,
+                                    4, /* dimensions */
+                                    3, /* count */
+                                    FALSE, /* not transposed */
+                                    matrix_floats);
+
+  /* Set the last matrix as untransposed */
+  uniform_location =
+    cogl_pipeline_get_uniform_location (pipeline, "matrix_array[3]");
+  cogl_pipeline_set_uniform_matrix (pipeline,
+                                    uniform_location,
+                                    4, /* dimensions */
+                                    1, /* count */
+                                    TRUE, /* transposed */
+                                    matrix_floats + 16 * 3);
+
+  paint_pipeline (pipeline, 12);
+}
+
+static void
+paint_vector_pipeline (CoglPipeline *pipeline)
+{
+  float vector_array_values[] = { 1.0f, 0.0f, 0.0f, 0.0f,
+                                  0.0f, 1.0f, 0.0f, 0.0f };
+  float short_vector_values[] = { 0.0f, 0.0f, 1.0f };
+  int uniform_location;
+
+  uniform_location =
+    cogl_pipeline_get_uniform_location (pipeline, "vector_array");
+  cogl_pipeline_set_uniform_float (pipeline,
+                                   uniform_location,
+                                   4, /* n_components */
+                                   2, /* count */
+                                   vector_array_values);
+
+  uniform_location =
+    cogl_pipeline_get_uniform_location (pipeline, "short_vector");
+  cogl_pipeline_set_uniform_float (pipeline,
+                                   uniform_location,
+                                   3, /* n_components */
+                                   1, /* count */
+                                   short_vector_values);
+
+  paint_pipeline (pipeline, 13);
+}
+
+static void
+paint_int_pipeline (CoglPipeline *pipeline)
+{
+  int vector_array_values[] = { 0x00, 0x00, 0xff, 0x00,
+                                0x00, 0xff, 0x00, 0x00 };
+  int single_value = 0x80;
+  int uniform_location;
+
+  uniform_location =
+    cogl_pipeline_get_uniform_location (pipeline, "vector_array");
+  cogl_pipeline_set_uniform_int (pipeline,
+                                 uniform_location,
+                                 4, /* n_components */
+                                 2, /* count */
+                                 vector_array_values);
+
+  uniform_location =
+    cogl_pipeline_get_uniform_location (pipeline, "single_value");
+  cogl_pipeline_set_uniform_1i (pipeline,
+                                uniform_location,
+                                single_value);
+
+  paint_pipeline (pipeline, 14);
+}
+
+static void
+paint (TestState *state)
+{
+  CoglColor color;
+
+  cogl_color_init_from_4ub (&color, 0, 0, 0, 255);
+  cogl_clear (&color, COGL_BUFFER_BIT_COLOR);
+
+  paint_color_pipelines (state);
+  paint_matrix_pipeline (state->matrix_pipeline);
+  paint_vector_pipeline (state->vector_pipeline);
+  paint_int_pipeline (state->int_pipeline);
+}
+
+static void
+check_pos (int pos, guint32 color)
+{
+  test_utils_check_pixel (pos * 10 + 5, 5, color);
+}
+
+static void
+validate_result (void)
+{
+  int i;
+
+  check_pos (0, 0xff0000ff);
+  check_pos (1, 0xffff00ff);
+  check_pos (2, 0xff00ffff);
+
+  for (i = 0; i <= 8; i++)
+    {
+      int green_value = i / 8.0f * 255.0f + 0.5f;
+      check_pos (i + 3, 0xff0000ff + (green_value << 16));
+    }
+
+  check_pos (12, 0x0080ffff);
+  check_pos (13, 0xffffffff);
+  check_pos (14, 0x80ffffff);
+}
+
+void
+test_cogl_pipeline_uniforms (TestUtilsGTestFixture *fixture,
+                             void *user_data)
+{
+  TestUtilsSharedState *shared_state = user_data;
+
+  /* If shaders aren't supported then we can't run the test */
+  if (cogl_features_available (COGL_FEATURE_SHADERS_GLSL))
+    {
+      TestState state;
+
+      init_state (&state);
+
+      cogl_ortho (/* left, right */
+                  0, cogl_framebuffer_get_width (shared_state->fb),
+                  /* bottom, top */
+                  cogl_framebuffer_get_height (shared_state->fb), 0,
+                  /* z near, far */
+                  -1, 100);
+
+      paint (&state);
+      validate_result ();
+
+      destroy_state (&state);
+
+      if (g_test_verbose ())
+        g_print ("OK\n");
+    }
+  else if (g_test_verbose ())
+    g_print ("Skipping\n");
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]