static void test_bad_brightness(int max) { int val; /* First write some sane value */ backlight_write(max / 2, "brightness"); /* Writing invalid values should fail and not change the value */ igt_assert_lt(backlight_write(-1, "brightness"), 0); backlight_read(&val, "brightness"); igt_assert_eq(val, max / 2); igt_assert_lt(backlight_write(max + 1, "brightness"), 0); backlight_read(&val, "brightness"); igt_assert_eq(val, max / 2); igt_assert_lt(backlight_write(INT_MAX, "brightness"), 0); backlight_read(&val, "brightness"); igt_assert_eq(val, max / 2); }
static int test_format(const char *test_name, struct kmstest_connector_config *cconf, drmModeModeInfo *mode, uint32_t format, enum test_flags flags) { int width; int height; struct igt_fb fb[2]; char *mode_format_str; char *cconf_str; int ret; ret = asprintf(&mode_format_str, "%s @ %dHz / %s", mode->name, mode->vrefresh, igt_format_str(format)); igt_assert_lt(0, ret); ret = asprintf(&cconf_str, "pipe %s, encoder %s, connector %s", kmstest_pipe_name(cconf->pipe), kmstest_encoder_type_str(cconf->encoder->encoder_type), kmstest_connector_type_str(cconf->connector->connector_type)); igt_assert_lt(0, ret); igt_info("Beginning test %s with %s on %s\n", test_name, mode_format_str, cconf_str); width = mode->hdisplay; height = mode->vdisplay; if (!igt_create_fb(drm_fd, width, height, format, LOCAL_DRM_FORMAT_MOD_NONE, &fb[0])) goto err1; if (!igt_create_fb(drm_fd, width, height, format, LOCAL_DRM_FORMAT_MOD_NONE, &fb[1])) goto err2; if (drmModeSetCrtc(drm_fd, cconf->crtc->crtc_id, fb[0].fb_id, 0, 0, &cconf->connector->connector_id, 1, mode)) goto err2; do_or_die(drmModePageFlip(drm_fd, cconf->crtc->crtc_id, fb[0].fb_id, 0, NULL)); sleep(2); if (flags & TEST_DIRECT_RENDER) { paint_fb(&fb[0], test_name, mode_format_str, cconf_str); } else if (flags & TEST_GPU_BLIT) { paint_fb(&fb[1], test_name, mode_format_str, cconf_str); gpu_blit(&fb[0], &fb[1]); } sleep(5); igt_info("Test %s with %s on %s: PASSED\n", test_name, mode_format_str, cconf_str); free(mode_format_str); free(cconf_str); igt_remove_fb(drm_fd, &fb[1]); igt_remove_fb(drm_fd, &fb[0]); return 0; err2: igt_remove_fb(drm_fd, &fb[0]); err1: igt_info("Test %s with %s on %s: SKIPPED\n", test_name, mode_format_str, cconf_str); free(mode_format_str); free(cconf_str); return -1; }
static void render_timeout(int fd) { drm_intel_bufmgr *bufmgr; struct intel_batchbuffer *batch; int64_t timeout = ENOUGH_WORK_IN_SECONDS * NSEC_PER_SEC; int64_t negative_timeout = -1; int ret; const bool do_signals = true; /* signals will seem to make the operation * use less process CPU time */ bool done = false; int i, iter = 1; igt_skip_on_simulation(); bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); drm_intel_bufmgr_gem_enable_reuse(bufmgr); batch = intel_batchbuffer_alloc(bufmgr, intel_get_drm_devid(fd)); dst = drm_intel_bo_alloc(bufmgr, "dst", BUF_SIZE, 4096); dst2 = drm_intel_bo_alloc(bufmgr, "dst2", BUF_SIZE, 4096); igt_skip_on_f(gem_bo_wait_timeout(fd, dst->handle, &timeout) == -EINVAL, "kernel doesn't support wait_timeout, skipping test\n"); timeout = ENOUGH_WORK_IN_SECONDS * NSEC_PER_SEC; /* Figure out a rough number of fills required to consume 1 second of * GPU work. */ do { struct timespec start, end; long diff; #ifndef CLOCK_MONOTONIC_RAW #define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC #endif igt_assert(clock_gettime(CLOCK_MONOTONIC_RAW, &start) == 0); for (i = 0; i < iter; i++) blt_color_fill(batch, dst, BUF_PAGES); intel_batchbuffer_flush(batch); drm_intel_bo_wait_rendering(dst); igt_assert(clock_gettime(CLOCK_MONOTONIC_RAW, &end) == 0); diff = do_time_diff(&end, &start); igt_assert(diff >= 0); if ((diff / MSEC_PER_SEC) > ENOUGH_WORK_IN_SECONDS) done = true; else iter <<= 1; } while (!done && iter < 1000000); igt_assert_lt(iter, 1000000); igt_info("%d iters is enough work\n", iter); gem_quiescent_gpu(fd); if (do_signals) igt_fork_signal_helper(); /* We should be able to do half as much work in the same amount of time, * but because we might schedule almost twice as much as required, we * might accidentally time out. Hence add some fudge. */ for (i = 0; i < iter/3; i++) blt_color_fill(batch, dst2, BUF_PAGES); intel_batchbuffer_flush(batch); igt_assert(gem_bo_busy(fd, dst2->handle) == true); igt_assert_eq(gem_bo_wait_timeout(fd, dst2->handle, &timeout), 0); igt_assert(gem_bo_busy(fd, dst2->handle) == false); igt_assert_neq(timeout, 0); if (timeout == (ENOUGH_WORK_IN_SECONDS * NSEC_PER_SEC)) igt_info("Buffer was already done!\n"); else { igt_info("Finished with %" PRIu64 " time remaining\n", timeout); } /* check that polling with timeout=0 works. */ timeout = 0; igt_assert_eq(gem_bo_wait_timeout(fd, dst2->handle, &timeout), 0); igt_assert_eq(timeout, 0); /* Now check that we correctly time out, twice the auto-tune load should * be good enough. */ timeout = ENOUGH_WORK_IN_SECONDS * NSEC_PER_SEC; for (i = 0; i < iter*2; i++) blt_color_fill(batch, dst2, BUF_PAGES); intel_batchbuffer_flush(batch); ret = gem_bo_wait_timeout(fd, dst2->handle, &timeout); igt_assert_eq(ret, -ETIME); igt_assert_eq(timeout, 0); igt_assert(gem_bo_busy(fd, dst2->handle) == true); /* check that polling with timeout=0 works. */ timeout = 0; igt_assert_eq(gem_bo_wait_timeout(fd, dst2->handle, &timeout), -ETIME); igt_assert_eq(timeout, 0); /* Now check that we can pass negative (infinite) timeouts. */ negative_timeout = -1; for (i = 0; i < iter; i++) blt_color_fill(batch, dst2, BUF_PAGES); intel_batchbuffer_flush(batch); igt_assert_eq(gem_bo_wait_timeout(fd, dst2->handle, &negative_timeout), 0); igt_assert_eq(negative_timeout, -1); /* infinity always remains */ igt_assert(gem_bo_busy(fd, dst2->handle) == false); if (do_signals) igt_stop_signal_helper(); drm_intel_bo_unreference(dst2); drm_intel_bo_unreference(dst); intel_batchbuffer_free(batch); drm_intel_bufmgr_destroy(bufmgr); }
static void atomic_setup(struct kms_atomic_state *state) { struct kms_atomic_desc *desc = state->desc; drmModeResPtr res; drmModePlaneResPtr res_plane; int i; desc->fd = drm_open_driver_master(DRIVER_INTEL); igt_assert_fd(desc->fd); do_or_die(drmSetClientCap(desc->fd, DRM_CLIENT_CAP_ATOMIC, 1)); res = drmModeGetResources(desc->fd); res_plane = drmModeGetPlaneResources(desc->fd); igt_assert(res); igt_assert(res_plane); igt_assert_lt(0, res->count_crtcs); state->num_crtcs = res->count_crtcs; state->crtcs = calloc(state->num_crtcs, sizeof(*state->crtcs)); igt_assert(state->crtcs); igt_assert_lt(0, res_plane->count_planes); state->num_planes = res_plane->count_planes; state->planes = calloc(state->num_planes, sizeof(*state->planes)); igt_assert(state->planes); igt_assert_lt(0, res->count_connectors); state->num_connectors = res->count_connectors; state->connectors = calloc(state->num_connectors, sizeof(*state->connectors)); igt_assert(state->connectors); fill_obj_props(desc->fd, res->crtcs[0], DRM_MODE_OBJECT_CRTC, NUM_CRTC_PROPS, crtc_prop_names, desc->props_crtc); fill_obj_props(desc->fd, res_plane->planes[0], DRM_MODE_OBJECT_PLANE, NUM_PLANE_PROPS, plane_prop_names, desc->props_plane); fill_obj_prop_map(desc->fd, res_plane->planes[0], DRM_MODE_OBJECT_PLANE, "type", NUM_PLANE_TYPE_PROPS, plane_type_prop_names, desc->props_plane_type); fill_obj_props(desc->fd, res->connectors[0], DRM_MODE_OBJECT_CONNECTOR, NUM_CONNECTOR_PROPS, connector_prop_names, desc->props_connector); for (i = 0; i < state->num_crtcs; i++) { struct kms_atomic_crtc_state *crtc = &state->crtcs[i]; crtc->state = state; crtc->obj = res->crtcs[i]; crtc->idx = i; crtc_get_current_state(crtc); /* The blob pointed to by MODE_ID could well be transient, * and lose its last reference as we switch away from it. * Duplicate the blob here so we have a reference we know we * own. */ if (crtc->mode.id != 0) crtc->mode.id = blob_duplicate(desc->fd, crtc->mode.id); } for (i = 0; i < state->num_planes; i++) { drmModePlanePtr plane = drmModeGetPlane(desc->fd, res_plane->planes[i]); igt_assert(plane); state->planes[i].state = state; state->planes[i].obj = res_plane->planes[i]; state->planes[i].crtc_mask = plane->possible_crtcs; plane_get_current_state(&state->planes[i]); } for (i = 0; i < state->num_connectors; i++) { state->connectors[i].state = state; state->connectors[i].obj = res->connectors[i]; connector_get_current_state(&state->connectors[i]); } drmModeFreePlaneResources(res_plane); drmModeFreeResources(res); }