Пример #1
0
static void
test_pipeline_caching(TestState *state)
{
    cg_pipeline_t *pipeline;
    cg_snippet_t *snippet;

    /* Check that the pipeline caching works when unrelated pipelines
       share snippets state. It's too hard to actually assert this in
       the conformance test but at least it should be possible to see by
       setting CG_DEBUG=show-source to check whether this shader gets
       generated twice */
    snippet = cg_snippet_new(CG_SNIPPET_HOOK_FRAGMENT,
                             "/* This comment should only be seen ONCE\n"
                             "   when CG_DEBUG=show-source is true\n"
                             "   even though it is used in two different\n"
                             "   unrelated pipelines */",
                             "cg_color_out = vec4(0.0, 1.0, 0.0, 1.0);\n");

    pipeline = cg_pipeline_new(test_dev);
    cg_pipeline_add_snippet(pipeline, snippet);
    cg_framebuffer_draw_rectangle(test_fb, pipeline, 50, 0, 60, 10);
    cg_object_unref(pipeline);

    pipeline = cg_pipeline_new(test_dev);
    cg_pipeline_add_snippet(pipeline, snippet);
    cg_framebuffer_draw_rectangle(test_fb, pipeline, 60, 0, 70, 10);
    cg_object_unref(pipeline);

    cg_object_unref(snippet);

    test_cg_check_pixel(test_fb, 55, 5, 0x00ff00ff);
    test_cg_check_pixel(test_fb, 65, 5, 0x00ff00ff);
}
Пример #2
0
static void
test_replace_string(TestState *state)
{
    cg_pipeline_t *pipeline;
    cg_snippet_t *snippet;

    /* Check the replace string */
    snippet = cg_snippet_new(CG_SNIPPET_HOOK_FRAGMENT, NULL, NULL);
    cg_snippet_set_pre(snippet,
                       "cg_color_out = vec4(0.0, 0.5, 0.0, 1.0);");
    /* Remove the generated output. If the replace string isn't working
       then the code from the pre string would get overwritten with
       white */
    cg_snippet_set_replace(snippet, "/* do nothing */");
    cg_snippet_set_post(snippet,
                        "cg_color_out += vec4(0.5, 0.0, 0.0, 1.0);");

    pipeline = cg_pipeline_new(test_dev);
    cg_pipeline_add_snippet(pipeline, snippet);
    cg_framebuffer_draw_rectangle(test_fb, pipeline, 70, 0, 80, 10);
    cg_object_unref(pipeline);

    cg_object_unref(snippet);

    test_cg_check_pixel(test_fb, 75, 5, 0x808000ff);
}
Пример #3
0
static void
shared_uniform(TestState *state)
{
    cg_pipeline_t *pipeline;
    cg_snippet_t *snippet;
    int location;

    /* Snippets sharing a uniform across the vertex and fragment
       hooks */
    pipeline = cg_pipeline_new(test_dev);

    location = cg_pipeline_get_uniform_location(pipeline, "a_value");
    cg_pipeline_set_uniform_1f(pipeline, location, 0.25f);

    cg_pipeline_set_color4ub(pipeline, 255, 0, 0, 255);

    snippet = cg_snippet_new(CG_SNIPPET_HOOK_VERTEX,
                             "uniform float a_value;",
                             "cg_color_out.b += a_value;");
    cg_pipeline_add_snippet(pipeline, snippet);
    cg_object_unref(snippet);
    snippet = cg_snippet_new(CG_SNIPPET_HOOK_FRAGMENT,
                             "uniform float a_value;",
                             "cg_color_out.b += a_value;");
    cg_pipeline_add_snippet(pipeline, snippet);
    cg_object_unref(snippet);

    cg_framebuffer_draw_rectangle(test_fb,
                                  pipeline,
                                  20, 0, 30, 10);

    cg_object_unref(pipeline);

    test_cg_check_pixel(test_fb, 25, 5, 0xff0080ff);
}
Пример #4
0
static void
test_multiple_samples(TestState *state)
{
    cg_pipeline_t *pipeline;
    cg_snippet_t *snippet;

    /* Check that we can use the passed in sampler in the texture lookup
       to sample multiple times */
    snippet = cg_snippet_new(CG_SNIPPET_HOOK_TEXTURE_LOOKUP,
                             NULL,
                             NULL);
    cg_snippet_set_replace(snippet,
                           "cg_texel = "
                           "texture2D(cg_sampler, vec2(0.25, 0.25)) + "
                           "texture2D(cg_sampler, vec2(0.75, 0.25));");

    pipeline = create_texture_pipeline(state);
    cg_pipeline_add_layer_snippet(pipeline, 0, snippet);
    cg_framebuffer_draw_rectangle(test_fb, pipeline, 0, 0, 10, 10);
    cg_object_unref(pipeline);

    cg_object_unref(snippet);

    test_cg_check_pixel(test_fb, 5, 5, 0xffff00ff);
}
Пример #5
0
static void
shared_variable_pre_post(TestState *state)
{
    cg_pipeline_t *pipeline;
    cg_snippet_t *snippet;

    /* Test that the pre string can declare variables used by the post
       string */
    pipeline = cg_pipeline_new(test_dev);

    cg_pipeline_set_color4ub(pipeline, 255, 255, 255, 255);

    snippet = cg_snippet_new(CG_SNIPPET_HOOK_FRAGMENT,
                             NULL, /* declarations */
                             "cg_color_out = redvec;");
    cg_snippet_set_pre(snippet, "vec4 redvec = vec4(1.0, 0.0, 0.0, 1.0);");
    cg_pipeline_add_snippet(pipeline, snippet);
    cg_object_unref(snippet);

    cg_framebuffer_draw_rectangle(test_fb, pipeline, 40, 0, 50, 10);

    cg_object_unref(pipeline);

    test_cg_check_pixel(test_fb, 45, 5, 0xff0000ff);
}
Пример #6
0
static void
create_pipelines(cg_pipeline_t **pipelines, int n_pipelines)
{
    int i;

    for (i = 0; i < n_pipelines; i++) {
        char *source = c_strdup_printf("  cg_color_out = "
                                       "vec4 (%f, 0.0, 0.0, 1.0);\n",
                                       i / 255.0f);
        cg_snippet_t *snippet = cg_snippet_new(CG_SNIPPET_HOOK_FRAGMENT,
                                               NULL, /* declarations */
                                               source);

        c_free(source);

        pipelines[i] = cg_pipeline_new(test_dev);
        cg_pipeline_add_snippet(pipelines[i], snippet);
        cg_object_unref(snippet);
    }

    /* Test that drawing with them works. This should create the entries
     * in the cache */
    for (i = 0; i < n_pipelines; i++) {
        cg_framebuffer_draw_rectangle(test_fb, pipelines[i], i, 0, i + 1, 1);
        test_cg_check_pixel_rgb(test_fb, i, 0, i, 0, 0);
    }
}
Пример #7
0
void
test_primitive_and_journal (void)
{
  cg_primitive_t *primitives[2];
  cg_pipeline_t *pipeline;

  setup_orthographic_modelview ();
  create_primitives (primitives);
  pipeline = create_pipeline ();

  /* Set a clip to clip all three rectangles to just the bottom half.
   * The journal flushes its own clip state so this verifies that the
   * clip state is correctly restored for the second primitive. */
  cg_framebuffer_push_rectangle_clip (test_fb,
                                        0, 50, 300, 100);

  cg_primitive_draw (primitives[0], test_fb, pipeline);

  /* Draw a rectangle using the journal in-between the two primitives.
   * This should test that the journal gets flushed correctly and that
   * the modelview matrix is restored. Half of the rectangle should be
   * overriden by the second primitive */
  cg_framebuffer_draw_rectangle (test_fb,
                                   pipeline,
                                   100, 0, /* x1/y1 */
                                   300, 100 /* x2/y2 */);

  cg_primitive_draw (primitives[1], test_fb, pipeline);

  /* Check the three rectangles */
  test_cg_check_region (test_fb,
                           1, 51,
                           98, 48,
                           0xff0000ff);
  test_cg_check_region (test_fb,
                           101, 51,
                           98, 48,
                           0x00ff00ff);
  test_cg_check_region (test_fb,
                           201, 51,
                           98, 48,
                           0x0000ffff);

  /* Check that the top half of all of the rectangles was clipped */
  test_cg_check_region (test_fb,
                           1, 1,
                           298, 48,
                           0x000000ff);

  cg_framebuffer_pop_clip (test_fb);

  if (test_verbose ())
    c_print ("OK\n");
}
Пример #8
0
static void
test_global_vertex_hook(TestState *state)
{
    cg_pipeline_t *pipeline;
    cg_snippet_t *snippet;

    pipeline = cg_pipeline_new(test_dev);

    /* Creates a function in the global declarations hook which is used
     * by a subsequent snippet. The subsequent snippets replace any
     * previous snippets but this shouldn't prevent the global
     * declarations from being generated */

    snippet = cg_snippet_new(CG_SNIPPET_HOOK_VERTEX_GLOBALS,
                             /* declarations */
                             "float\n"
                             "multiply_by_two(float number)\n"
                             "{\n"
                             "  return number * 2.0;\n"
                             "}\n",
                             /* post */
                             "This string shouldn't be used so "
                             "we can safely put garbage in here.");
    cg_snippet_set_pre(snippet,
                       "This string shouldn't be used so "
                       "we can safely put garbage in here.");
    cg_snippet_set_replace(snippet,
                           "This string shouldn't be used so "
                           "we can safely put garbage in here.");
    cg_pipeline_add_snippet(pipeline, snippet);
    cg_object_unref(snippet);

    snippet = cg_snippet_new(CG_SNIPPET_HOOK_VERTEX,
                             NULL, /* declarations */
                             NULL /* replace */);
    cg_snippet_set_replace(snippet,
                           "cg_color_out.r = multiply_by_two(0.5);\n"
                           "cg_color_out.gba = vec3(0.0, 0.0, 1.0);\n"
                           "cg_position_out = cg_position_in;\n");
    cg_pipeline_add_snippet(pipeline, snippet);
    cg_object_unref(snippet);

    cg_framebuffer_draw_rectangle(test_fb,
                                  pipeline,
                                  -1, 1,
                                  10.0f * 2.0f / state->fb_width - 1.0f,
                                  10.0f * 2.0f / state->fb_height - 1.0f);

    cg_object_unref(pipeline);

    test_cg_check_pixel(test_fb, 5, 5, 0xff0000ff);
}
Пример #9
0
static void
_rut_rectangle_paint(rut_object_t *object,
                     rut_paint_context_t *paint_ctx)
{
    rut_rectangle_t *rectangle = object;
    rut_object_t *camera = paint_ctx->camera;

    cg_framebuffer_draw_rectangle(rut_camera_get_framebuffer(camera),
                                  rectangle->pipeline,
                                  0,
                                  0,
                                  rectangle->width,
                                  rectangle->height);
}
Пример #10
0
static void
paint (cg_texture_t *texture)
{
  cg_pipeline_t *pipeline = cg_pipeline_new (test_dev);
  int x = 0, y = 0, size = TEXTURE_SIZE;

  cg_pipeline_set_layer_texture (pipeline, 0, texture);
  cg_pipeline_set_layer_filters (pipeline, 0,
                                   CG_PIPELINE_FILTER_NEAREST_MIPMAP_NEAREST,
                                   CG_PIPELINE_FILTER_NEAREST);

  cg_framebuffer_draw_rectangle (test_fb,
                                   pipeline,
                                   x, y,
                                   x + size,
                                   y + size);

  x += size;
  size /= 2;
  cg_framebuffer_draw_rectangle (test_fb,
                                   pipeline,
                                   x, y,
                                   x + size,
                                   y + size);

  x += size;
  size /= 2;
  cg_framebuffer_draw_rectangle (test_fb,
                                   pipeline,
                                   x, y,
                                   x + size,
                                   y + size);

  cg_object_unref (pipeline);
  cg_object_unref (texture);
}
Пример #11
0
static void
test_vertex_transform_hook(TestState *state)
{
    cg_pipeline_t *pipeline;
    cg_snippet_t *snippet;
    c_matrix_t identity_matrix;
    c_matrix_t matrix;
    int location;

    /* Test the vertex transform hook */

    c_matrix_init_identity(&identity_matrix);

    pipeline = cg_pipeline_new(test_dev);

    cg_pipeline_set_color4ub(pipeline, 255, 0, 255, 255);

    snippet = cg_snippet_new(CG_SNIPPET_HOOK_VERTEX_TRANSFORM,
                             "uniform mat4 pmat;",
                             NULL);
    cg_snippet_set_replace(snippet, "cg_position_out = "
                           "pmat * cg_position_in;");
    cg_pipeline_add_snippet(pipeline, snippet);
    cg_object_unref(snippet);

    /* Copy the current projection matrix to a uniform */
    cg_framebuffer_get_projection_matrix(test_fb, &matrix);
    location = cg_pipeline_get_uniform_location(pipeline, "pmat");
    cg_pipeline_set_uniform_matrix(pipeline,
                                   location,
                                   4, /* dimensions */
                                   1, /* count */
                                   false, /* don't transpose */
                                   c_matrix_get_array(&matrix));

    /* Replace the real projection matrix with the identity. This should
       mess up the drawing unless the snippet replacement is working */
    cg_framebuffer_set_projection_matrix(test_fb, &identity_matrix);

    cg_framebuffer_draw_rectangle(test_fb, pipeline, 150, 0, 160, 10);
    cg_object_unref(pipeline);

    /* Restore the projection matrix */
    cg_framebuffer_set_projection_matrix(test_fb, &matrix);

    test_cg_check_pixel(test_fb, 155, 5, 0xff00ffff);
}
Пример #12
0
static bool
draw_rectangle (TestState *state,
                int x,
                int y,
                TestDepthState *rect_state)
{
  uint8_t Cr = MASK_RED (rect_state->color);
  uint8_t Cg = MASK_GREEN (rect_state->color);
  uint8_t Cb = MASK_BLUE (rect_state->color);
  uint8_t Ca = MASK_ALPHA (rect_state->color);
  cg_pipeline_t *pipeline;
  cg_depth_state_t depth_state;

  cg_depth_state_init (&depth_state);
  cg_depth_state_set_test_enabled (&depth_state, rect_state->test_enable);
  cg_depth_state_set_test_function (&depth_state, rect_state->test_function);
  cg_depth_state_set_write_enabled (&depth_state, rect_state->write_enable);
  cg_depth_state_set_range (&depth_state,
                              rect_state->range_near,
                              rect_state->range_far);

  pipeline = cg_pipeline_new (test_dev);
  if (!cg_pipeline_set_depth_state (pipeline, &depth_state, NULL))
    {
      cg_object_unref (pipeline);
      return false;
    }

  cg_pipeline_set_color4ub (pipeline, Cr, Cg, Cb, Ca);

  cg_framebuffer_set_depth_write_enabled (test_fb, rect_state->fb_write_enable);
  cg_framebuffer_push_matrix (test_fb);
  cg_framebuffer_translate (test_fb, 0, 0, rect_state->depth);
  cg_framebuffer_draw_rectangle (test_fb,
                                   pipeline,
                                   x * QUAD_WIDTH,
                                   y * QUAD_WIDTH,
                                   x * QUAD_WIDTH + QUAD_WIDTH,
                                   y * QUAD_WIDTH + QUAD_WIDTH);
  cg_framebuffer_pop_matrix (test_fb);

  cg_object_unref (pipeline);

  return true;
}
Пример #13
0
static void
lots_snippets(TestState *state)
{
    cg_pipeline_t *pipeline;
    cg_snippet_t *snippet;
    int location;
    int i;

    /* Lots of snippets on one pipeline */
    pipeline = cg_pipeline_new(test_dev);

    cg_pipeline_set_color4ub(pipeline, 0, 0, 0, 255);

    for(i = 0; i < 3; i++) {
        char letter = 'x' + i;
        char *uniform_name = c_strdup_printf("%c_value", letter);
        char *declarations = c_strdup_printf("uniform float %s;\n",
                                             uniform_name);
        char *code = c_strdup_printf("cg_color_out.%c = %s;\n",
                                     letter,
                                     uniform_name);

        location = cg_pipeline_get_uniform_location(pipeline, uniform_name);
        cg_pipeline_set_uniform_1f(pipeline, location,(i + 1) * 0.1f);

        snippet = cg_snippet_new(CG_SNIPPET_HOOK_FRAGMENT,
                                 declarations,
                                 code);
        cg_pipeline_add_snippet(pipeline, snippet);
        cg_object_unref(snippet);

        c_free(code);
        c_free(uniform_name);
        c_free(declarations);
    }

    cg_framebuffer_draw_rectangle(test_fb, pipeline, 30, 0, 40, 10);

    cg_object_unref(pipeline);

    test_cg_check_pixel(test_fb, 35, 5, 0x19334cff);
}
Пример #14
0
static void
simple_vertex_snippet(TestState *state)
{
    cg_pipeline_t *pipeline;
    cg_snippet_t *snippet;

    /* Simple vertex snippet */
    pipeline = cg_pipeline_new(test_dev);

    cg_pipeline_set_color4ub(pipeline, 255, 0, 0, 255);

    snippet = cg_snippet_new(CG_SNIPPET_HOOK_VERTEX,
                             NULL,
                             "cg_color_out.b += 1.0;");
    cg_pipeline_add_snippet(pipeline, snippet);
    cg_object_unref(snippet);

    cg_framebuffer_draw_rectangle(test_fb, pipeline, 10, 0, 20, 10);

    cg_object_unref(pipeline);

    test_cg_check_pixel(test_fb, 15, 5, 0xff00ffff);
}
Пример #15
0
static void
simple_fragment_snippet(TestState *state)
{
    cg_pipeline_t *pipeline;
    cg_snippet_t *snippet;

    /* Simple fragment snippet */
    pipeline = cg_pipeline_new(test_dev);

    cg_pipeline_set_color4ub(pipeline, 255, 0, 0, 255);

    snippet = cg_snippet_new(CG_SNIPPET_HOOK_FRAGMENT,
                             NULL, /* declarations */
                             "cg_color_out.g += 1.0;");
    cg_pipeline_add_snippet(pipeline, snippet);
    cg_object_unref(snippet);

    cg_framebuffer_draw_rectangle(test_fb, pipeline, 0, 0, 10, 10);

    cg_object_unref(pipeline);

    test_cg_check_pixel(test_fb, 5, 5, 0xffff00ff);
}
Пример #16
0
static void
test_naming_texture_units(TestState *state)
{
    cg_pipeline_t *pipeline;
    cg_snippet_t *snippet;
    cg_texture_t *tex1, *tex2;

    /* Test that we can sample from an arbitrary texture unit by naming
       its layer number */

    snippet = cg_snippet_new(CG_SNIPPET_HOOK_FRAGMENT,
                             NULL,
                             NULL);
    cg_snippet_set_replace(snippet,
                           "cg_color_out = "
                           "texture2D(cg_sampler100, vec2(0.0, 0.0)) + "
                           "texture2D(cg_sampler200, vec2(0.0, 0.0));");

    tex1 = test_cg_create_color_texture(test_dev, 0xff0000ff);
    tex2 = test_cg_create_color_texture(test_dev, 0x00ff00ff);

    pipeline = cg_pipeline_new(test_dev);

    cg_pipeline_set_layer_texture(pipeline, 100, tex1);
    cg_pipeline_set_layer_texture(pipeline, 200, tex2);

    cg_pipeline_add_snippet(pipeline, snippet);

    cg_framebuffer_draw_rectangle(test_fb, pipeline, 0, 0, 10, 10);

    cg_object_unref(pipeline);
    cg_object_unref(snippet);
    cg_object_unref(tex1);
    cg_object_unref(tex2);

    test_cg_check_pixel(test_fb, 5, 5, 0xffff00ff);
}
Пример #17
0
static void
test_snippet_order(TestState *state)
{
    cg_pipeline_t *pipeline;
    cg_snippet_t *snippet;

    /* Verify that the snippets are executed in the right order. We'll
       replace the r component of the color in the pre sections of the
       snippets and the g component in the post. The pre sections should
       be executed in the reverse order they were added and the post
       sections in the same order as they were added. Therefore the r
       component should be taken from the the second snippet and the g
       component from the first */
    pipeline = cg_pipeline_new(test_dev);

    cg_pipeline_set_color4ub(pipeline, 0, 0, 0, 255);

    snippet = cg_snippet_new(CG_SNIPPET_HOOK_FRAGMENT,
                             NULL,
                             "cg_color_out.g = 0.5;\n");
    cg_snippet_set_pre(snippet, "cg_color_out.r = 0.5;\n");
    cg_snippet_set_replace(snippet, "cg_color_out.ba = vec2(0.0, 1.0);");
    cg_pipeline_add_snippet(pipeline, snippet);
    cg_object_unref(snippet);

    snippet = cg_snippet_new(CG_SNIPPET_HOOK_FRAGMENT,
                             NULL,
                             "cg_color_out.g = 1.0;\n");
    cg_snippet_set_pre(snippet, "cg_color_out.r = 1.0;\n");
    cg_pipeline_add_snippet(pipeline, snippet);
    cg_object_unref(snippet);

    cg_framebuffer_draw_rectangle(test_fb, pipeline, 160, 0, 170, 10);
    cg_object_unref(pipeline);

    test_cg_check_pixel(test_fb, 165, 5, 0x80ff00ff);
}
Пример #18
0
cg_texture_t *
rig_downsampler_downsample(rig_downsampler_t *downsampler,
                           cg_texture_t *source,
                           int scale_factor_x,
                           int scale_factor_y)
{
    cg_texture_components_t components;
    int src_w, src_h;
    int dest_width, dest_height;
    cg_pipeline_t *pipeline;

    /* validation */
    src_w = cg_texture_get_width(source);
    src_h = cg_texture_get_height(source);

    if (src_w % scale_factor_x != 0) {
        c_warning("downsample: the width of the texture (%d) is not a "
                  "multiple of the scale factor (%d)",
                  src_w,
                  scale_factor_x);
    }
    if (src_h % scale_factor_y != 0) {
        c_warning("downsample: the height of the texture (%d) is not a "
                  "multiple of the scale factor (%d)",
                  src_h,
                  scale_factor_y);
    }

    /* create the destination texture up front */
    dest_width = src_w / scale_factor_x;
    dest_height = src_h / scale_factor_y;
    components = cg_texture_get_components(source);

    if (downsampler->dest == NULL ||
        cg_texture_get_width(downsampler->dest) != dest_width ||
        cg_texture_get_height(downsampler->dest) != dest_height ||
        cg_texture_get_components(downsampler->dest) != components) {
        cg_offscreen_t *offscreen;
        cg_texture_2d_t *texture_2d = cg_texture_2d_new_with_size(
            downsampler->engine->shell->cg_device, dest_width, dest_height);

        cg_texture_set_components(texture_2d, components);

        _rig_downsampler_reset(downsampler);

        downsampler->dest = texture_2d;

        /* create the FBO to render the downsampled texture */
        offscreen = cg_offscreen_new_with_texture(downsampler->dest);
        downsampler->fb = offscreen;

        /* create the camera that will setup the scene for the render */
        downsampler->camera = rig_camera_new(downsampler->engine,
                                             dest_width, /* ortho width */
                                             dest_height, /* ortho height */
                                             downsampler->fb);
        rut_camera_set_near_plane(downsampler->camera, -1.f);
        rut_camera_set_far_plane(downsampler->camera, 1.f);
    }

    pipeline = cg_pipeline_copy(downsampler->pipeline);
    cg_pipeline_set_layer_texture(pipeline, 0, source);

    rut_camera_flush(downsampler->camera);

    cg_framebuffer_draw_rectangle(
        downsampler->fb, pipeline, 0, 0, dest_width, dest_height);

    rut_camera_end_frame(downsampler->camera);

    cg_object_unref(pipeline);

    return cg_object_ref(downsampler->dest);
}