5 #include "test-utils.h"
7 typedef struct _TestState
12 typedef void (* SnippetTestFunc) (TestState *state);
15 create_texture_pipeline (TestState *state)
17 CoglPipeline *pipeline;
19 static const guint8 tex_data[] =
21 0xff, 0x00, 0x00, 0xff, /* red */ 0x00, 0xff, 0x00, 0xff, /* green */
22 0x00, 0x00, 0xff, 0xff, /* blue */ 0xff, 0xff, 0x00, 0xff, /* yellow */
25 tex = cogl_texture_new_from_data (2, 2, /* width/height */
26 COGL_TEXTURE_NO_ATLAS,
27 COGL_PIXEL_FORMAT_RGBA_8888_PRE,
28 COGL_PIXEL_FORMAT_ANY,
32 pipeline = cogl_pipeline_new (ctx);
34 cogl_pipeline_set_layer_texture (pipeline, 0, tex);
36 cogl_pipeline_set_layer_filters (pipeline, 0,
37 COGL_PIPELINE_FILTER_NEAREST,
38 COGL_PIPELINE_FILTER_NEAREST);
40 cogl_object_unref (tex);
46 simple_fragment_snippet (TestState *state)
48 CoglPipeline *pipeline;
51 /* Simple fragment snippet */
52 pipeline = cogl_pipeline_new (ctx);
54 cogl_pipeline_set_color4ub (pipeline, 255, 0, 0, 255);
56 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
57 NULL, /* declarations */
58 "cogl_color_out.g += 1.0;");
59 cogl_pipeline_add_snippet (pipeline, snippet);
60 cogl_object_unref (snippet);
62 cogl_framebuffer_draw_rectangle (fb, pipeline, 0, 0, 10, 10);
64 cogl_object_unref (pipeline);
66 test_utils_check_pixel (fb, 5, 5, 0xffff00ff);
70 simple_vertex_snippet (TestState *state)
72 CoglPipeline *pipeline;
75 /* Simple vertex snippet */
76 pipeline = cogl_pipeline_new (ctx);
78 cogl_pipeline_set_color4ub (pipeline, 255, 0, 0, 255);
80 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
82 "cogl_color_out.b += 1.0;");
83 cogl_pipeline_add_snippet (pipeline, snippet);
84 cogl_object_unref (snippet);
86 cogl_framebuffer_draw_rectangle (fb, pipeline, 10, 0, 20, 10);
88 cogl_object_unref (pipeline);
90 test_utils_check_pixel (fb, 15, 5, 0xff00ffff);
94 shared_uniform (TestState *state)
96 CoglPipeline *pipeline;
100 /* Snippets sharing a uniform across the vertex and fragment
102 pipeline = cogl_pipeline_new (ctx);
104 location = cogl_pipeline_get_uniform_location (pipeline, "a_value");
105 cogl_pipeline_set_uniform_1f (pipeline, location, 0.25f);
107 cogl_pipeline_set_color4ub (pipeline, 255, 0, 0, 255);
109 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
110 "uniform float a_value;",
111 "cogl_color_out.b += a_value;");
112 cogl_pipeline_add_snippet (pipeline, snippet);
113 cogl_object_unref (snippet);
114 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
115 "uniform float a_value;",
116 "cogl_color_out.b += a_value;");
117 cogl_pipeline_add_snippet (pipeline, snippet);
118 cogl_object_unref (snippet);
120 cogl_framebuffer_draw_rectangle (fb,
124 cogl_object_unref (pipeline);
126 test_utils_check_pixel (fb, 25, 5, 0xff0080ff);
130 lots_snippets (TestState *state)
132 CoglPipeline *pipeline;
133 CoglSnippet *snippet;
137 /* Lots of snippets on one pipeline */
138 pipeline = cogl_pipeline_new (ctx);
140 cogl_pipeline_set_color4ub (pipeline, 0, 0, 0, 255);
142 for (i = 0; i < 3; i++)
144 char letter = 'x' + i;
145 char *uniform_name = g_strdup_printf ("%c_value", letter);
146 char *declarations = g_strdup_printf ("uniform float %s;\n",
148 char *code = g_strdup_printf ("cogl_color_out.%c = %s;\n",
152 location = cogl_pipeline_get_uniform_location (pipeline, uniform_name);
153 cogl_pipeline_set_uniform_1f (pipeline, location, (i + 1) * 0.1f);
155 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
158 cogl_pipeline_add_snippet (pipeline, snippet);
159 cogl_object_unref (snippet);
162 g_free (uniform_name);
163 g_free (declarations);
166 cogl_framebuffer_draw_rectangle (fb, pipeline, 30, 0, 40, 10);
168 cogl_object_unref (pipeline);
170 test_utils_check_pixel (fb, 35, 5, 0x19334cff);
174 shared_variable_pre_post (TestState *state)
176 CoglPipeline *pipeline;
177 CoglSnippet *snippet;
179 /* Test that the pre string can declare variables used by the post
181 pipeline = cogl_pipeline_new (ctx);
183 cogl_pipeline_set_color4ub (pipeline, 255, 255, 255, 255);
185 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
186 NULL, /* declarations */
187 "cogl_color_out = redvec;");
188 cogl_snippet_set_pre (snippet, "vec4 redvec = vec4 (1.0, 0.0, 0.0, 1.0);");
189 cogl_pipeline_add_snippet (pipeline, snippet);
190 cogl_object_unref (snippet);
192 cogl_framebuffer_draw_rectangle (fb, pipeline, 40, 0, 50, 10);
194 cogl_object_unref (pipeline);
196 test_utils_check_pixel (fb, 45, 5, 0xff0000ff);
200 test_pipeline_caching (TestState *state)
202 CoglPipeline *pipeline;
203 CoglSnippet *snippet;
205 /* Check that the pipeline caching works when unrelated pipelines
206 share snippets state. It's too hard to actually assert this in
207 the conformance test but at least it should be possible to see by
208 setting COGL_DEBUG=show-source to check whether this shader gets
210 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
211 "/* This comment should only be seen ONCE\n"
212 " when COGL_DEBUG=show-source is TRUE\n"
213 " even though it is used in two different\n"
214 " unrelated pipelines */",
215 "cogl_color_out = vec4 (0.0, 1.0, 0.0, 1.0);\n");
217 pipeline = cogl_pipeline_new (ctx);
218 cogl_pipeline_add_snippet (pipeline, snippet);
219 cogl_framebuffer_draw_rectangle (fb, pipeline, 50, 0, 60, 10);
220 cogl_object_unref (pipeline);
222 pipeline = cogl_pipeline_new (ctx);
223 cogl_pipeline_add_snippet (pipeline, snippet);
224 cogl_framebuffer_draw_rectangle (fb, pipeline, 60, 0, 70, 10);
225 cogl_object_unref (pipeline);
227 cogl_object_unref (snippet);
229 test_utils_check_pixel (fb, 55, 5, 0x00ff00ff);
230 test_utils_check_pixel (fb, 65, 5, 0x00ff00ff);
234 test_replace_string (TestState *state)
236 CoglPipeline *pipeline;
237 CoglSnippet *snippet;
239 /* Check the replace string */
240 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, NULL, NULL);
241 cogl_snippet_set_pre (snippet,
242 "cogl_color_out = vec4 (0.0, 0.5, 0.0, 1.0);");
243 /* Remove the generated output. If the replace string isn't working
244 then the code from the pre string would get overwritten with
246 cogl_snippet_set_replace (snippet, "/* do nothing */");
247 cogl_snippet_set_post (snippet,
248 "cogl_color_out += vec4 (0.5, 0.0, 0.0, 1.0);");
250 pipeline = cogl_pipeline_new (ctx);
251 cogl_pipeline_add_snippet (pipeline, snippet);
252 cogl_framebuffer_draw_rectangle (fb, pipeline, 70, 0, 80, 10);
253 cogl_object_unref (pipeline);
255 cogl_object_unref (snippet);
257 test_utils_check_pixel (fb, 75, 5, 0x808000ff);
261 test_texture_lookup_hook (TestState *state)
263 CoglPipeline *pipeline;
264 CoglSnippet *snippet;
266 /* Check the texture lookup hook */
267 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP,
269 "cogl_texel.b += 1.0;");
270 /* Flip the texture coordinates around the y axis so that it will
271 get the green texel */
272 cogl_snippet_set_pre (snippet, "cogl_tex_coord.x = 1.0 - cogl_tex_coord.x;");
274 pipeline = create_texture_pipeline (state);
275 cogl_pipeline_add_layer_snippet (pipeline, 0, snippet);
276 cogl_framebuffer_draw_textured_rectangle (fb,
280 cogl_object_unref (pipeline);
282 cogl_object_unref (snippet);
284 test_utils_check_pixel (fb, 85, 5, 0x00ffffff);
288 test_multiple_samples (TestState *state)
290 CoglPipeline *pipeline;
291 CoglSnippet *snippet;
293 /* Check that we can use the passed in sampler in the texture lookup
294 to sample multiple times */
295 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP,
298 cogl_snippet_set_replace (snippet,
300 "texture2D (cogl_sampler, vec2 (0.25, 0.25)) + "
301 "texture2D (cogl_sampler, vec2 (0.75, 0.25));");
303 pipeline = create_texture_pipeline (state);
304 cogl_pipeline_add_layer_snippet (pipeline, 0, snippet);
305 cogl_framebuffer_draw_rectangle (fb, pipeline, 0, 0, 10, 10);
306 cogl_object_unref (pipeline);
308 cogl_object_unref (snippet);
310 test_utils_check_pixel (fb, 5, 5, 0xffff00ff);
314 test_replace_lookup_hook (TestState *state)
316 CoglPipeline *pipeline;
317 CoglSnippet *snippet;
319 /* Check replacing the texture lookup hook */
320 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP, NULL, NULL);
321 cogl_snippet_set_replace (snippet, "cogl_texel = vec4 (0.0, 0.0, 1.0, 0.0);");
323 pipeline = create_texture_pipeline (state);
324 cogl_pipeline_add_layer_snippet (pipeline, 0, snippet);
325 cogl_framebuffer_draw_textured_rectangle (fb,
329 cogl_object_unref (pipeline);
331 cogl_object_unref (snippet);
333 test_utils_check_pixel (fb, 95, 5, 0x0000ffff);
337 test_replace_snippet (TestState *state)
339 CoglPipeline *pipeline;
340 CoglSnippet *snippet;
342 /* Test replacing a previous snippet */
343 pipeline = create_texture_pipeline (state);
345 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
347 "cogl_color_out = vec4 (0.5, 0.5, 0.5, 1.0);");
348 cogl_pipeline_add_snippet (pipeline, snippet);
349 cogl_object_unref (snippet);
351 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, NULL, NULL);
352 cogl_snippet_set_pre (snippet, "cogl_color_out = vec4 (1.0, 1.0, 1.0, 1.0);");
353 cogl_snippet_set_replace (snippet,
354 "cogl_color_out *= vec4 (1.0, 0.0, 0.0, 1.0);");
355 cogl_pipeline_add_snippet (pipeline, snippet);
356 cogl_object_unref (snippet);
358 cogl_framebuffer_draw_textured_rectangle (fb,
362 cogl_object_unref (pipeline);
364 test_utils_check_pixel (fb, 105, 5, 0xff0000ff);
368 test_replace_fragment_layer (TestState *state)
370 CoglPipeline *pipeline;
371 CoglSnippet *snippet;
373 /* Test replacing the fragment layer code */
374 pipeline = create_texture_pipeline (state);
376 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_LAYER_FRAGMENT, NULL, NULL);
377 cogl_snippet_set_replace (snippet, "cogl_layer = vec4 (0.0, 0.0, 1.0, 1.0);");
378 cogl_pipeline_add_layer_snippet (pipeline, 0, snippet);
379 cogl_object_unref (snippet);
381 /* Add a second layer which samples from the texture in the first
382 layer. The snippet override should cause the first layer not to
383 generate the code for the texture lookup but this second layer
384 should still be able to cause it to be generated */
385 cogl_pipeline_set_layer_combine (pipeline, 1,
386 "RGB = ADD(TEXTURE_0, PREVIOUS)"
387 "A = REPLACE(PREVIOUS)",
390 cogl_framebuffer_draw_textured_rectangle (fb,
394 cogl_object_unref (pipeline);
396 test_utils_check_pixel (fb, 115, 5, 0xff00ffff);
400 test_modify_fragment_layer (TestState *state)
402 CoglPipeline *pipeline;
403 CoglSnippet *snippet;
405 /* Test modifying the fragment layer code */
406 pipeline = cogl_pipeline_new (ctx);
408 cogl_pipeline_set_uniform_1f (pipeline,
409 cogl_pipeline_get_uniform_location (pipeline,
413 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_LAYER_FRAGMENT,
414 "uniform float a_value;",
415 "cogl_layer.g = a_value;");
416 cogl_pipeline_add_layer_snippet (pipeline, 0, snippet);
417 cogl_object_unref (snippet);
419 cogl_framebuffer_draw_textured_rectangle (fb,
423 cogl_object_unref (pipeline);
425 test_utils_check_pixel (fb, 125, 5, 0xff80ffff);
429 test_modify_vertex_layer (TestState *state)
431 CoglPipeline *pipeline;
432 CoglSnippet *snippet;
435 /* Test modifying the vertex layer code */
436 pipeline = create_texture_pipeline (state);
438 cogl_matrix_init_identity (&matrix);
439 cogl_matrix_translate (&matrix, 0.0f, 1.0f, 0.0f);
440 cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
442 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_COORD_TRANSFORM,
444 "cogl_tex_coord.x = 1.0;");
445 cogl_pipeline_add_layer_snippet (pipeline, 0, snippet);
446 cogl_object_unref (snippet);
448 cogl_framebuffer_draw_textured_rectangle (fb,
452 cogl_object_unref (pipeline);
454 test_utils_check_pixel (fb, 135, 5, 0xffff00ff);
458 test_replace_vertex_layer (TestState *state)
460 CoglPipeline *pipeline;
461 CoglSnippet *snippet;
464 /* Test replacing the vertex layer code */
465 pipeline = create_texture_pipeline (state);
467 cogl_matrix_init_identity (&matrix);
468 cogl_matrix_translate (&matrix, 0.0f, 1.0f, 0.0f);
469 cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
471 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_COORD_TRANSFORM,
474 cogl_snippet_set_replace (snippet, "cogl_tex_coord.x = 1.0;\n");
475 cogl_pipeline_add_layer_snippet (pipeline, 0, snippet);
476 cogl_object_unref (snippet);
478 cogl_framebuffer_draw_textured_rectangle (fb,
482 cogl_object_unref (pipeline);
484 test_utils_check_pixel (fb, 145, 5, 0x00ff00ff);
488 test_vertex_transform_hook (TestState *state)
490 CoglPipeline *pipeline;
491 CoglSnippet *snippet;
492 CoglMatrix identity_matrix;
496 /* Test the vertex transform hook */
498 cogl_matrix_init_identity (&identity_matrix);
500 pipeline = cogl_pipeline_new (ctx);
502 cogl_pipeline_set_color4ub (pipeline, 255, 0, 255, 255);
504 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX_TRANSFORM,
505 "uniform mat4 pmat;",
507 cogl_snippet_set_replace (snippet, "cogl_position_out = "
508 "pmat * cogl_position_in;");
509 cogl_pipeline_add_snippet (pipeline, snippet);
510 cogl_object_unref (snippet);
512 /* Copy the current projection matrix to a uniform */
513 cogl_framebuffer_get_projection_matrix (fb, &matrix);
514 location = cogl_pipeline_get_uniform_location (pipeline, "pmat");
515 cogl_pipeline_set_uniform_matrix (pipeline,
519 FALSE, /* don't transpose */
520 cogl_matrix_get_array (&matrix));
522 /* Replace the real projection matrix with the identity. This should
523 mess up the drawing unless the snippet replacement is working */
524 cogl_framebuffer_set_projection_matrix (fb, &identity_matrix);
526 cogl_framebuffer_draw_rectangle (fb, pipeline, 150, 0, 160, 10);
527 cogl_object_unref (pipeline);
529 /* Restore the projection matrix */
530 cogl_framebuffer_set_projection_matrix (fb, &matrix);
532 test_utils_check_pixel (fb, 155, 5, 0xff00ffff);
536 test_snippet_order (TestState *state)
538 CoglPipeline *pipeline;
539 CoglSnippet *snippet;
541 /* Verify that the snippets are executed in the right order. We'll
542 replace the r component of the color in the pre sections of the
543 snippets and the g component in the post. The pre sections should
544 be executed in the reverse order they were added and the post
545 sections in the same order as they were added. Therefore the r
546 component should be taken from the the second snippet and the g
547 component from the first */
548 pipeline = cogl_pipeline_new (ctx);
550 cogl_pipeline_set_color4ub (pipeline, 0, 0, 0, 255);
552 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
554 "cogl_color_out.g = 0.5;\n");
555 cogl_snippet_set_pre (snippet, "cogl_color_out.r = 0.5;\n");
556 cogl_snippet_set_replace (snippet, "cogl_color_out.ba = vec2 (0.0, 1.0);");
557 cogl_pipeline_add_snippet (pipeline, snippet);
558 cogl_object_unref (snippet);
560 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
562 "cogl_color_out.g = 1.0;\n");
563 cogl_snippet_set_pre (snippet, "cogl_color_out.r = 1.0;\n");
564 cogl_pipeline_add_snippet (pipeline, snippet);
565 cogl_object_unref (snippet);
567 cogl_framebuffer_draw_rectangle (fb, pipeline, 160, 0, 170, 10);
568 cogl_object_unref (pipeline);
570 test_utils_check_pixel (fb, 165, 5, 0x80ff00ff);
574 test_naming_texture_units (TestState *state)
576 CoglPipeline *pipeline;
577 CoglSnippet *snippet;
578 CoglTexture *tex1, *tex2;
580 /* Test that we can sample from an arbitrary texture unit by naming
583 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
586 cogl_snippet_set_replace (snippet,
588 "texture2D (cogl_sampler100, vec2 (0.0, 0.0)) + "
589 "texture2D (cogl_sampler200, vec2 (0.0, 0.0));");
591 tex1 = test_utils_create_color_texture (ctx, 0xff0000ff);
592 tex2 = test_utils_create_color_texture (ctx, 0x00ff00ff);
594 pipeline = cogl_pipeline_new (ctx);
596 cogl_pipeline_set_layer_texture (pipeline, 100, tex1);
597 cogl_pipeline_set_layer_texture (pipeline, 200, tex2);
599 cogl_pipeline_add_snippet (pipeline, snippet);
601 cogl_framebuffer_draw_rectangle (fb, pipeline, 0, 0, 10, 10);
603 cogl_object_unref (pipeline);
604 cogl_object_unref (snippet);
605 cogl_object_unref (tex1);
606 cogl_object_unref (tex2);
608 test_utils_check_pixel (fb, 5, 5, 0xffff00ff);
612 test_snippet_properties (TestState *state)
614 CoglSnippet *snippet;
616 /* Sanity check modifying the snippet */
617 snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, "foo", "bar");
618 g_assert_cmpstr (cogl_snippet_get_declarations (snippet), ==, "foo");
619 g_assert_cmpstr (cogl_snippet_get_post (snippet), ==, "bar");
620 g_assert_cmpstr (cogl_snippet_get_replace (snippet), ==, NULL);
621 g_assert_cmpstr (cogl_snippet_get_pre (snippet), ==, NULL);
623 cogl_snippet_set_declarations (snippet, "fu");
624 g_assert_cmpstr (cogl_snippet_get_declarations (snippet), ==, "fu");
625 g_assert_cmpstr (cogl_snippet_get_post (snippet), ==, "bar");
626 g_assert_cmpstr (cogl_snippet_get_replace (snippet), ==, NULL);
627 g_assert_cmpstr (cogl_snippet_get_pre (snippet), ==, NULL);
629 cogl_snippet_set_post (snippet, "ba");
630 g_assert_cmpstr (cogl_snippet_get_declarations (snippet), ==, "fu");
631 g_assert_cmpstr (cogl_snippet_get_post (snippet), ==, "ba");
632 g_assert_cmpstr (cogl_snippet_get_replace (snippet), ==, NULL);
633 g_assert_cmpstr (cogl_snippet_get_pre (snippet), ==, NULL);
635 cogl_snippet_set_pre (snippet, "fuba");
636 g_assert_cmpstr (cogl_snippet_get_declarations (snippet), ==, "fu");
637 g_assert_cmpstr (cogl_snippet_get_post (snippet), ==, "ba");
638 g_assert_cmpstr (cogl_snippet_get_replace (snippet), ==, NULL);
639 g_assert_cmpstr (cogl_snippet_get_pre (snippet), ==, "fuba");
641 cogl_snippet_set_replace (snippet, "baba");
642 g_assert_cmpstr (cogl_snippet_get_declarations (snippet), ==, "fu");
643 g_assert_cmpstr (cogl_snippet_get_post (snippet), ==, "ba");
644 g_assert_cmpstr (cogl_snippet_get_replace (snippet), ==, "baba");
645 g_assert_cmpstr (cogl_snippet_get_pre (snippet), ==, "fuba");
647 g_assert_cmpint (cogl_snippet_get_hook (snippet),
649 COGL_SNIPPET_HOOK_FRAGMENT);
652 static SnippetTestFunc
655 simple_fragment_snippet,
656 simple_vertex_snippet,
659 shared_variable_pre_post,
660 test_pipeline_caching,
662 test_texture_lookup_hook,
663 test_multiple_samples,
664 test_replace_lookup_hook,
665 test_replace_snippet,
666 test_replace_fragment_layer,
667 test_modify_fragment_layer,
668 test_modify_vertex_layer,
669 test_replace_vertex_layer,
670 test_vertex_transform_hook,
672 test_naming_texture_units,
673 test_snippet_properties
677 run_tests (TestState *state)
681 for (i = 0; i < G_N_ELEMENTS (tests); i++)
683 cogl_framebuffer_clear4f (fb,
684 COGL_BUFFER_BIT_COLOR,
694 /* If shaders aren't supported then we can't run the test */
695 if (cogl_features_available (COGL_FEATURE_SHADERS_GLSL))
699 cogl_framebuffer_orthographic (fb,
701 cogl_framebuffer_get_width (fb),
702 cogl_framebuffer_get_height (fb),
708 if (cogl_test_verbose ())
711 else if (cogl_test_verbose ())
712 g_print ("Skipping\n");