示例#1
0
static void plane_primary(struct kms_atomic_crtc_state *crtc,
			  struct kms_atomic_plane_state *plane_old)
{
	struct drm_mode_modeinfo *mode = crtc->mode.data;
	struct kms_atomic_plane_state plane = *plane_old;
	uint32_t format = plane_get_igt_format(&plane);
	drmModeAtomicReq *req = drmModeAtomicAlloc();
	uint32_t *connectors;
	int num_connectors;
	struct igt_fb fb;
	int i;

	connectors = calloc(crtc->state->num_connectors, sizeof(*connectors));
	igt_assert(connectors);

	for (i = 0; i < crtc->state->num_connectors; i++) {
		if (crtc->state->connectors[i].crtc_id == crtc->obj)
			connectors[num_connectors++] =
				crtc->state->connectors[i].obj;
	}

	igt_require(format != 0);

	plane.src_x = 0;
	plane.src_y = 0;
	plane.src_w = mode->hdisplay << 16;
	plane.src_h = mode->vdisplay << 16;
	plane.crtc_x = 0;
	plane.crtc_y = 0;
	plane.crtc_w = mode->hdisplay;
	plane.crtc_h = mode->vdisplay;
	plane.crtc_id = crtc->obj;
	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
					    plane.crtc_w, plane.crtc_h,
					    format, I915_TILING_NONE, &fb);

	/* Flip the primary plane using the atomic API, and double-check
	 * state is what we think it should be. */
	crtc_commit_atomic(crtc, &plane, req, ATOMIC_RELAX_NONE);

	/* Restore the primary plane and check the state matches the old. */
	crtc_commit_atomic(crtc, plane_old, req, ATOMIC_RELAX_NONE);

	/* Re-enable the plane through the legacy CRTC/primary-plane API, and
	 * verify through atomic. */
	crtc_commit_legacy(crtc, &plane, CRTC_RELAX_MODE);

	/* Restore the plane to its original settings through the legacy CRTC
	 * API, and verify through atomic. */
	crtc_commit_legacy(crtc, plane_old, CRTC_RELAX_MODE);

	/* Finally, restore to the original state. */
	crtc_commit_atomic(crtc, plane_old, req, ATOMIC_RELAX_NONE);

	drmModeAtomicFree(req);
}
示例#2
0
static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
                         igt_plane_t *plane, drmModeModeInfo *mode, enum igt_commit_style s)
{
    igt_display_t *display = &data->display;

    igt_output_set_pipe(output, pipe);

    /* create the pipe_crc object for this pipe */
    igt_pipe_crc_free(data->pipe_crc);
    data->pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO);

    /* before allocating, free if any older fb */
    if (data->fb_id1) {
        igt_remove_fb(data->drm_fd, &data->fb1);
        data->fb_id1 = 0;
    }

    /* allocate fb for plane 1 */
    data->fb_id1 = igt_create_pattern_fb(data->drm_fd,
                                         mode->hdisplay, mode->vdisplay,
                                         DRM_FORMAT_XRGB8888,
                                         LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
                                         &data->fb1);
    igt_assert(data->fb_id1);

    /*
     * We always set the primary plane to actually enable the pipe as
     * there's no way (that works) to light up a pipe with only a sprite
     * plane enabled at the moment.
     */
    if (!plane->is_primary) {
        igt_plane_t *primary;

        primary = igt_output_get_plane(output, IGT_PLANE_PRIMARY);
        igt_plane_set_fb(primary, &data->fb1);
    }

    igt_plane_set_fb(plane, &data->fb1);
    if (s == COMMIT_LEGACY) {
        int ret;
        ret = drmModeSetCrtc(data->drm_fd,
                             output->config.crtc->crtc_id,
                             data->fb_id1,
                             plane->pan_x, plane->pan_y,
                             &output->id,
                             1,
                             mode);
        igt_assert_eq(ret, 0);
    } else {
        igt_display_commit2(display, s);
    }
}
示例#3
0
static void plane_overlay(struct kms_atomic_crtc_state *crtc,
			  struct kms_atomic_plane_state *plane_old)
{
	struct drm_mode_modeinfo *mode = crtc->mode.data;
	struct kms_atomic_plane_state plane = *plane_old;
	uint32_t format = plane_get_igt_format(&plane);
	drmModeAtomicReq *req = drmModeAtomicAlloc();
	struct igt_fb fb;

	igt_require(req);
	igt_require(format != 0);

	plane.src_x = 0;
	plane.src_y = 0;
	plane.src_w = (mode->hdisplay / 2) << 16;
	plane.src_h = (mode->vdisplay / 2) << 16;
	plane.crtc_x = mode->hdisplay / 4;
	plane.crtc_y = mode->vdisplay / 4;
	plane.crtc_w = mode->hdisplay / 2;
	plane.crtc_h = mode->vdisplay / 2;
	plane.crtc_id = crtc->obj;
	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
					    plane.crtc_w, plane.crtc_h,
					    format, I915_TILING_NONE, &fb);

	/* Enable the overlay plane using the atomic API, and double-check
	 * state is what we think it should be. */
	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);

	/* Disable the plane and check the state matches the old. */
	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);

	/* Re-enable the plane through the legacy plane API, and verify through
	 * atomic. */
	plane_commit_legacy(&plane, ATOMIC_RELAX_NONE);

	/* Restore the plane to its original settings through the legacy plane
	 * API, and verify through atomic. */
	plane_commit_legacy(plane_old, ATOMIC_RELAX_NONE);

	drmModeAtomicFree(req);
}
示例#4
0
static void plane_invalid_params(struct kms_atomic_crtc_state *crtc,
				 struct kms_atomic_plane_state *plane_old,
				 struct kms_atomic_connector_state *conn)
{
	struct drm_mode_modeinfo *mode = crtc->mode.data;
	struct kms_atomic_plane_state plane = *plane_old;
	uint32_t format = plane_get_igt_format(&plane);
	drmModeAtomicReq *req = drmModeAtomicAlloc();
	struct igt_fb fb;

	/* Pass a series of invalid object IDs for the FB ID. */
	plane.fb_id = plane.obj;
	plane_commit_atomic_err(&plane, plane_old, req,
	                        ATOMIC_RELAX_NONE, EINVAL);

	plane.fb_id = crtc->obj;
	plane_commit_atomic_err(&plane, plane_old, req,
	                        ATOMIC_RELAX_NONE, EINVAL);

	plane.fb_id = conn->obj;
	plane_commit_atomic_err(&plane, plane_old, req,
	                        ATOMIC_RELAX_NONE, EINVAL);

	plane.fb_id = crtc->mode.id;
	plane_commit_atomic_err(&plane, plane_old, req,
	                        ATOMIC_RELAX_NONE, EINVAL);

	plane.fb_id = plane_old->fb_id;
	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);

	/* Pass a series of invalid object IDs for the CRTC ID. */
	plane.crtc_id = plane.obj;
	plane_commit_atomic_err(&plane, plane_old, req,
	                        ATOMIC_RELAX_NONE, EINVAL);

	plane.crtc_id = plane.fb_id;
	plane_commit_atomic_err(&plane, plane_old, req,
	                        ATOMIC_RELAX_NONE, EINVAL);

	plane.crtc_id = conn->obj;
	plane_commit_atomic_err(&plane, plane_old, req,
	                        ATOMIC_RELAX_NONE, EINVAL);

	plane.crtc_id = crtc->mode.id;
	plane_commit_atomic_err(&plane, plane_old, req,
	                        ATOMIC_RELAX_NONE, EINVAL);

	plane.crtc_id = plane_old->crtc_id;
	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);

	/* Create a framebuffer too small for the plane configuration. */
	igt_require(format != 0);

	plane.src_x = 0;
	plane.src_y = 0;
	plane.src_w = mode->hdisplay << 16;
	plane.src_h = mode->vdisplay << 16;
	plane.crtc_x = 0;
	plane.crtc_y = 0;
	plane.crtc_w = mode->hdisplay;
	plane.crtc_h = mode->vdisplay;
	plane.crtc_id = crtc->obj;
	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
					    plane.crtc_w - 1, plane.crtc_h - 1,
					    format, I915_TILING_NONE, &fb);

	plane_commit_atomic_err(&plane, plane_old, req,
	                        ATOMIC_RELAX_NONE, ENOSPC);

	/* Restore the primary plane and check the state matches the old. */
	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);

	drmModeAtomicFree(req);
}
示例#5
0
static void
set_mode(struct connector *c)
{
	unsigned int fb_id = 0;
	struct igt_fb fb_info[2] = { };
	int j, test_mode_num, current_fb = 0, old_fb = -1;

	test_mode_num = 1;
	if (force_mode){
		memcpy( &c->mode, &force_timing, sizeof(force_timing));
		c->mode.vrefresh =(force_timing.clock*1e3)/(force_timing.htotal*force_timing.vtotal);
		c->mode_valid = 1;
		sprintf(c->mode.name, "%dx%d", force_timing.hdisplay, force_timing.vdisplay);
	} else if (test_all_modes)
		test_mode_num = c->connector->count_modes;

	for (j = 0; j < test_mode_num; j++) {

		if (test_all_modes)
			c->mode = c->connector->modes[j];

		/* set_mode() only tests 2D modes */
		if (c->mode.flags & DRM_MODE_FLAG_3D_MASK)
			continue;

		if (!c->mode_valid)
			continue;

		width = c->mode.hdisplay;
		height = c->mode.vdisplay;

		fb_id = igt_create_pattern_fb(drm_fd, width, height,
					      igt_bpp_depth_to_drm_format(bpp, depth),
					      tiling, &fb_info[current_fb]);
		paint_output_info(c, &fb_info[current_fb]);
		paint_color_key(&fb_info[current_fb]);

		igt_info("CRTC(%u):[%d]", c->crtc, j);
		kmstest_dump_mode(&c->mode);
		if (drmModeSetCrtc(drm_fd, c->crtc, fb_id, 0, 0,
				   &c->id, 1, &c->mode)) {
			igt_warn("failed to set mode (%dx%d@%dHz): %s\n", width, height, c->mode.vrefresh, strerror(errno));
			igt_remove_fb(drm_fd, &fb_info[current_fb]);
			continue;
		}

		if (old_fb != -1)
			igt_remove_fb(drm_fd, &fb_info[old_fb]);
		old_fb = current_fb;
		current_fb = 1 - current_fb;

		if (sleep_between_modes && test_all_modes && !qr_code)
			sleep(sleep_between_modes);

		if (do_dpms) {
			kmstest_set_connector_dpms(drm_fd, c->connector, do_dpms);
			sleep(sleep_between_modes);
			kmstest_set_connector_dpms(drm_fd, c->connector, DRM_MODE_DPMS_ON);
		}

		if (qr_code){
			set_single();
			pause();
		}
	}

	if (test_all_modes && old_fb != -1)
		igt_remove_fb(drm_fd, &fb_info[old_fb]);

	drmModeFreeEncoder(c->encoder);
	drmModeFreeConnector(c->connector);
}
示例#6
0
static void test_plane_scaling(data_t *d)
{
    igt_display_t *display = &d->display;
    igt_output_t *output;
    enum pipe pipe;
    int valid_tests = 0;
    int primary_plane_scaling = 0; /* For now */

    igt_require(d->display.has_universal_planes);
    igt_require(d->num_scalers);

    for_each_connected_output(display, output) {
        drmModeModeInfo *mode;

        pipe = output->config.pipe;
        igt_output_set_pipe(output, pipe);

        mode = igt_output_get_mode(output);

        /* allocate fb2 with image size */
        d->fb_id2 = igt_create_image_fb(d->drm_fd, 0, 0,
                                        DRM_FORMAT_XRGB8888,
                                        LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
                                        FILE_NAME, &d->fb2);
        igt_assert(d->fb_id2);

        d->fb_id3 = igt_create_pattern_fb(d->drm_fd,
                                          mode->hdisplay, mode->vdisplay,
                                          DRM_FORMAT_XRGB8888,
                                          LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */
                                          &d->fb3);
        igt_assert(d->fb_id3);

        /* Set up display with plane 1 */
        d->plane1 = igt_output_get_plane(output, IGT_PLANE_PRIMARY);
        prepare_crtc(d, output, pipe, d->plane1, mode, COMMIT_UNIVERSAL);

        if (primary_plane_scaling) {
            /* Primary plane upscaling */
            igt_fb_set_position(&d->fb1, d->plane1, 100, 100);
            igt_fb_set_size(&d->fb1, d->plane1, 500, 500);
            igt_plane_set_position(d->plane1, 0, 0);
            igt_plane_set_size(d->plane1, mode->hdisplay, mode->vdisplay);
            igt_display_commit2(display, COMMIT_UNIVERSAL);

            /* Primary plane 1:1 no scaling */
            igt_fb_set_position(&d->fb1, d->plane1, 0, 0);
            igt_fb_set_size(&d->fb1, d->plane1, d->fb1.width, d->fb1.height);
            igt_plane_set_position(d->plane1, 0, 0);
            igt_plane_set_size(d->plane1, mode->hdisplay, mode->vdisplay);
            igt_display_commit2(display, COMMIT_UNIVERSAL);
        }

        /* Set up fb2->plane2 mapping. */
        d->plane2 = igt_output_get_plane(output, IGT_PLANE_2);
        igt_plane_set_fb(d->plane2, &d->fb2);

        /* 2nd plane windowed */
        igt_fb_set_position(&d->fb2, d->plane2, 100, 100);
        igt_fb_set_size(&d->fb2, d->plane2, d->fb2.width-200, d->fb2.height-200);
        igt_plane_set_position(d->plane2, 100, 100);
        igt_plane_set_size(d->plane2, mode->hdisplay-200, mode->vdisplay-200);
        igt_display_commit2(display, COMMIT_UNIVERSAL);

        iterate_plane_scaling(d, mode);

        /* 2nd plane up scaling */
        igt_fb_set_position(&d->fb2, d->plane2, 100, 100);
        igt_fb_set_size(&d->fb2, d->plane2, 500, 500);
        igt_plane_set_position(d->plane2, 10, 10);
        igt_plane_set_size(d->plane2, mode->hdisplay-20, mode->vdisplay-20);
        igt_display_commit2(display, COMMIT_UNIVERSAL);

        /* 2nd plane downscaling */
        igt_fb_set_position(&d->fb2, d->plane2, 0, 0);
        igt_fb_set_size(&d->fb2, d->plane2, d->fb2.width, d->fb2.height);
        igt_plane_set_position(d->plane2, 10, 10);
        igt_plane_set_size(d->plane2, 500, 500 * d->fb2.height/d->fb2.width);
        igt_display_commit2(display, COMMIT_UNIVERSAL);

        if (primary_plane_scaling) {
            /* Primary plane up scaling */
            igt_fb_set_position(&d->fb1, d->plane1, 100, 100);
            igt_fb_set_size(&d->fb1, d->plane1, 500, 500);
            igt_plane_set_position(d->plane1, 0, 0);
            igt_plane_set_size(d->plane1, mode->hdisplay, mode->vdisplay);
            igt_display_commit2(display, COMMIT_UNIVERSAL);
        }

        /* Set up fb3->plane3 mapping. */
        d->plane3 = igt_output_get_plane(output, IGT_PLANE_3);
        igt_plane_set_fb(d->plane3, &d->fb3);

        /* 3rd plane windowed - no scaling */
        igt_fb_set_position(&d->fb3, d->plane3, 100, 100);
        igt_fb_set_size(&d->fb3, d->plane3, d->fb3.width-300, d->fb3.height-300);
        igt_plane_set_position(d->plane3, 100, 100);
        igt_plane_set_size(d->plane3, mode->hdisplay-300, mode->vdisplay-300);
        igt_display_commit2(display, COMMIT_UNIVERSAL);

        /* Switch scaler from plane 2 to plane 3 */
        igt_fb_set_position(&d->fb2, d->plane2, 100, 100);
        igt_fb_set_size(&d->fb2, d->plane2, d->fb2.width-200, d->fb2.height-200);
        igt_plane_set_position(d->plane2, 100, 100);
        igt_plane_set_size(d->plane2, d->fb2.width-200, d->fb2.height-200);

        igt_fb_set_position(&d->fb3, d->plane3, 100, 100);
        igt_fb_set_size(&d->fb3, d->plane3, d->fb3.width-400, d->fb3.height-400);
        igt_plane_set_position(d->plane3, 10, 10);
        igt_plane_set_size(d->plane3, mode->hdisplay-300, mode->vdisplay-300);
        igt_display_commit2(display, COMMIT_UNIVERSAL);

        if (primary_plane_scaling) {
            /* Switch scaler from plane 1 to plane 2 */
            igt_fb_set_position(&d->fb1, d->plane1, 0, 0);
            igt_fb_set_size(&d->fb1, d->plane1, d->fb1.width, d->fb1.height);
            igt_plane_set_position(d->plane1, 0, 0);
            igt_plane_set_size(d->plane1, mode->hdisplay, mode->vdisplay);

            igt_fb_set_position(&d->fb2, d->plane2, 100, 100);
            igt_fb_set_size(&d->fb2, d->plane2, d->fb2.width-500,d->fb2.height-500);
            igt_plane_set_position(d->plane2, 100, 100);
            igt_plane_set_size(d->plane2, mode->hdisplay-200, mode->vdisplay-200);
            igt_display_commit2(display, COMMIT_UNIVERSAL);
        }

        /* back to single plane mode */
        igt_plane_set_fb(d->plane2, NULL);
        igt_plane_set_fb(d->plane3, NULL);
        igt_display_commit2(display, COMMIT_UNIVERSAL);

        valid_tests++;
        cleanup_crtc(d, output, d->plane1);
    }