On Thu, 2017-10-12 at 17:33 +0200, Maarten Lankhorst wrote: > Now that we can set individual properties through the igt_kms api, > we no longer need to duplicate functionality from igt_kms. Set > invalid > properties directly, and rewrite kms_atomic.c to use igt_display. > This will allow us to remove a lot of code in kms_atomic.c, > and benefit from how igt_kms can set up a valid configuration, > instead of having to inherit it from fbcon. > > Changes since v1: > - Fix test failure when atomic_invalid_params is run standalone. > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@xxxxxxxxxxxxxxx> > Cc: Daniel Stone <daniels@xxxxxxxxxxxxx> > --- > tests/kms_atomic.c | 1668 ++++++++++++++++------------------------ > ------------ > 1 file changed, 512 insertions(+), 1156 deletions(-) > > diff --git a/tests/kms_atomic.c b/tests/kms_atomic.c > index 042a7c263aab..e0fc324eab61 100644 > --- a/tests/kms_atomic.c > +++ b/tests/kms_atomic.c > @@ -46,10 +46,6 @@ > #include "igt_aux.h" > #include "sw_sync.h" > > -#ifndef DRM_CLIENT_CAP_ATOMIC > -#define DRM_CLIENT_CAP_ATOMIC 3 > -#endif > - > #ifndef DRM_CAP_CURSOR_WIDTH > #define DRM_CAP_CURSOR_WIDTH 0x8 > #endif > @@ -58,23 +54,6 @@ > #define DRM_CAP_CURSOR_HEIGHT 0x9 > #endif > > -#ifndef DRM_MODE_ATOMIC_TEST_ONLY > -#define DRM_MODE_ATOMIC_TEST_ONLY 0x0100 > -#define DRM_MODE_ATOMIC_NONBLOCK 0x0200 > -#define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400 > - > -struct drm_mode_atomic { > - __u32 flags; > - __u32 count_objs; > - __u64 objs_ptr; > - __u64 count_props_ptr; > - __u64 props_ptr; > - __u64 prop_values_ptr; > - __u64 reserved; > - __u64 user_data; > -}; > -#endif > - > IGT_TEST_DESCRIPTION("Test atomic modesetting API"); > > enum kms_atomic_check_relax { > @@ -83,1259 +62,652 @@ enum kms_atomic_check_relax { > PLANE_RELAX_FB = (1 << 1) > }; > > -/** > - * KMS plane type enum > - * > - * KMS plane types are represented by enums, which do not have > stable numeric > - * values, but must be looked up by their string value each time. > - * > - * To make the code more simple, we define a plane_type enum which > maps to > - * each KMS enum value. These values must be looked up through the > map, and > - * cannot be passed directly to KMS functions. > - */ > -enum plane_type { > - PLANE_TYPE_PRIMARY = 0, > - PLANE_TYPE_OVERLAY, > - PLANE_TYPE_CURSOR, > - NUM_PLANE_TYPE_PROPS > -}; > - > -static const char *plane_type_prop_names[NUM_PLANE_TYPE_PROPS] = { > - "Primary", > - "Overlay", > - "Cursor" > -}; > - > -struct kms_atomic_blob { > - uint32_t id; /* 0 if not already allocated */ > - size_t len; > - void *data; > -}; > - > -struct kms_atomic_connector_state { > - struct kms_atomic_state *state; > - uint32_t obj; > - uint32_t crtc_id; > -}; > - > -struct kms_atomic_plane_state { > - struct kms_atomic_state *state; > - uint32_t obj; > - enum plane_type type; > - uint32_t crtc_mask; > - uint32_t crtc_id; /* 0 to disable */ > - uint32_t fb_id; /* 0 to disable */ > - uint32_t src_x, src_y, src_w, src_h; /* 16.16 fixed-point */ > - uint32_t crtc_x, crtc_y, crtc_w, crtc_h; /* normal integers > */ > - int32_t fence_fd; > -}; > - > -struct kms_atomic_crtc_state { > - struct kms_atomic_state *state; > - uint32_t obj; > - int idx; > - bool active; > - int32_t *out_fence_ptr; > - struct kms_atomic_blob mode; > -}; > - > -struct kms_atomic_state { > - struct kms_atomic_connector_state *connectors; > - int num_connectors; > - struct kms_atomic_crtc_state *crtcs; > - int num_crtcs; > - struct kms_atomic_plane_state *planes; > - int num_planes; > - struct kms_atomic_desc *desc; > -}; > - > -struct kms_atomic_desc { > - int fd; > - uint32_t props_connector[IGT_NUM_CONNECTOR_PROPS]; > - uint32_t props_crtc[IGT_NUM_CRTC_PROPS]; > - uint32_t props_plane[IGT_NUM_PLANE_PROPS]; > - uint64_t props_plane_type[NUM_PLANE_TYPE_PROPS]; > -}; > - > -static uint32_t blob_duplicate(int fd, uint32_t id_orig) > +static bool plane_filter(enum igt_atomic_plane_properties prop) > { > - drmModePropertyBlobPtr orig = drmModeGetPropertyBlob(fd, > id_orig); > - uint32_t id_new; > - > - igt_assert(orig); > - do_or_die(drmModeCreatePropertyBlob(fd, orig->data, orig- > >length, > - &id_new)); > - drmModeFreePropertyBlob(orig); > + if ((1 << prop) & IGT_PLANE_COORD_CHANGED_MASK) > + return false; > > - return id_new; > -} > - > -#define crtc_set_prop(req, crtc, prop, value) \ > - igt_assert_lt(0, drmModeAtomicAddProperty(req, crtc->obj, \ > - crtc->state->desc- > >props_crtc[prop], \ > - value)); > - > -#define plane_set_prop(req, plane, prop, value) \ > - igt_assert_lt(0, drmModeAtomicAddProperty(req, plane->obj, \ > - plane->state- > >desc->props_plane[prop], \ > - value)); > - > -#define do_atomic_commit(fd, req, flags) \ > - do_or_die(drmModeAtomicCommit(fd, req, flags, NULL)); > + if (prop == IGT_PLANE_CRTC_ID || prop == IGT_PLANE_FB_ID) > + return false; > > -#define do_atomic_commit_err(fd, req, flags, err) { \ > - igt_assert_neq(drmModeAtomicCommit(fd, req, flags, NULL), > 0); \ > - igt_assert_eq(errno, err); \ > -} > - > -#define crtc_commit_atomic(crtc, plane, req, relax, flags) { \ > - drmModeAtomicSetCursor(req, 0); \ > - crtc_populate_req(crtc, req); \ > - plane_populate_req(plane, req); \ > - do_atomic_commit((crtc)->state->desc->fd, req, flags); \ > - if (!(flags & DRM_MODE_ATOMIC_TEST_ONLY)) { \ > - crtc_check_current_state(crtc, plane, relax); \ > - plane_check_current_state(plane, relax); \ > - } \ > -} > + if (prop == IGT_PLANE_IN_FENCE_FD) > + return false; > > -#define crtc_commit_atomic_err(crtc, plane, crtc_old, plane_old, > req, flags, relax, e) { \ > - drmModeAtomicSetCursor(req, 0); \ > - crtc_populate_req(crtc, req); \ > - plane_populate_req(plane, req); \ > - do_atomic_commit_err((crtc)->state->desc->fd, req, flags, > e); \ > - crtc_check_current_state(crtc_old, plane_old, relax); \ > - plane_check_current_state(plane_old, relax); \ > + /* Don't care about other properties */ > + return true; > } > > -#define plane_commit_atomic(plane, req, relax) { \ > - drmModeAtomicSetCursor(req, 0); \ > - plane_populate_req(plane, req); \ > - do_atomic_commit((plane)->state->desc->fd, req, 0); \ > - plane_check_current_state(plane, relax); \ > -} > - > -#define plane_commit_atomic_err(plane, plane_old, req, relax, e) { \ > - drmModeAtomicSetCursor(req, 0); \ > - plane_populate_req(plane, req); \ > - do_atomic_commit_err((plane)->state->desc->fd, req, 0, e); \ > - plane_check_current_state(plane_old, relax); \ > -} > - > -static void > -connector_get_current_state(struct kms_atomic_connector_state > *connector) > -{ > - drmModeObjectPropertiesPtr props; > - int i; > - > - props = drmModeObjectGetProperties(connector->state->desc- > >fd, > - connector->obj, > - DRM_MODE_OBJECT_CONNECTOR > ); > - igt_assert(props); > - > - for (i = 0; i < props->count_props; i++) { > - uint32_t *prop_ids = connector->state->desc- > >props_connector; > - > - if (props->props[i] == > prop_ids[IGT_CONNECTOR_CRTC_ID]) > - connector->crtc_id = props->prop_values[i]; > - } > - drmModeFreeObjectProperties(props); > -} > - > -#if 0 > -/* XXX: Checking this repeatedly actually hangs the GPU. I have > literally no > - * idea why. */ > -static void > -connector_check_current_state(struct kms_atomic_connector_state > *connector) > -{ > - struct kms_atomic_connector_state connector_kernel; > - drmModeConnectorPtr legacy; > - uint32_t crtc_id; > - > - legacy = drmModeGetConnectorCurrent(connector->state->desc- > >fd, > - connector->obj); > - igt_assert(legacy); > - > - if (legacy->encoder_id) { > - drmModeEncoderPtr legacy_enc; > - > - legacy_enc = drmModeGetEncoder(connector->state- > >desc->fd, > - legacy->encoder_id); > - igt_assert(legacy_enc); > - > - crtc_id = legacy_enc->crtc_id; > - drmModeFreeEncoder(legacy_enc); > - } else { > - crtc_id = 0; > - } > - > - igt_assert_eq_u32(crtc_id, connector->crtc_id); > - > - memcpy(&connector_kernel, connector, > sizeof(connector_kernel)); > - connector_get_current_state(&connector_kernel); > - do_or_die(memcmp(&connector_kernel, connector, > - sizeof(connector_kernel))); > - > - drmModeFreeConnector(legacy); > -} > -#endif > - > -static struct kms_atomic_connector_state * > -find_connector(struct kms_atomic_state *state, > - struct kms_atomic_crtc_state *crtc) > +static void plane_get_current_state(igt_plane_t *plane, uint64_t > *values) > { > int i; > > - for (i = 0; i < state->num_connectors; i++) { > - struct kms_atomic_connector_state *connector = > - &state->connectors[i]; > - > - if (!connector->obj) > + for (i = 0; i < IGT_NUM_PLANE_PROPS; i++) { > + if (plane_filter(i)) { > + values[i] = 0; > continue; > - if (crtc && connector->crtc_id != crtc->obj) > - continue; > - > - return connector; > - } > - > - return NULL; > -} > - > -static void plane_populate_req(struct kms_atomic_plane_state *plane, > - drmModeAtomicReq *req) > -{ > - if (plane->fence_fd) > - plane_set_prop(req, plane, IGT_PLANE_IN_FENCE_FD, > plane->fence_fd); > - > - plane_set_prop(req, plane, IGT_PLANE_CRTC_ID, plane- > >crtc_id); > - plane_set_prop(req, plane, IGT_PLANE_FB_ID, plane->fb_id); > - plane_set_prop(req, plane, IGT_PLANE_SRC_X, plane->src_x); > - plane_set_prop(req, plane, IGT_PLANE_SRC_Y, plane->src_y); > - plane_set_prop(req, plane, IGT_PLANE_SRC_W, plane->src_w); > - plane_set_prop(req, plane, IGT_PLANE_SRC_H, plane->src_h); > - plane_set_prop(req, plane, IGT_PLANE_CRTC_X, plane->crtc_x); > - plane_set_prop(req, plane, IGT_PLANE_CRTC_Y, plane->crtc_y); > - plane_set_prop(req, plane, IGT_PLANE_CRTC_W, plane->crtc_w); > - plane_set_prop(req, plane, IGT_PLANE_CRTC_H, plane->crtc_h); > -} > - > -static void plane_get_current_state(struct kms_atomic_plane_state > *plane) > -{ > - struct kms_atomic_desc *desc = plane->state->desc; > - drmModeObjectPropertiesPtr props; > - int i; > - > - props = drmModeObjectGetProperties(desc->fd, plane->obj, > - DRM_MODE_OBJECT_PLANE); > - igt_assert(props); > - > - for (i = 0; i < props->count_props; i++) { > - uint32_t *prop_ids = desc->props_plane; > - > - if (props->props[i] == prop_ids[IGT_PLANE_CRTC_ID]) > - plane->crtc_id = props->prop_values[i]; > - else if (props->props[i] == > prop_ids[IGT_PLANE_FB_ID]) > - plane->fb_id = props->prop_values[i]; > - else if (props->props[i] == > prop_ids[IGT_PLANE_CRTC_X]) > - plane->crtc_x = props->prop_values[i]; > - else if (props->props[i] == > prop_ids[IGT_PLANE_CRTC_Y]) > - plane->crtc_y = props->prop_values[i]; > - else if (props->props[i] == > prop_ids[IGT_PLANE_CRTC_W]) > - plane->crtc_w = props->prop_values[i]; > - else if (props->props[i] == > prop_ids[IGT_PLANE_CRTC_H]) > - plane->crtc_h = props->prop_values[i]; > - else if (props->props[i] == > prop_ids[IGT_PLANE_SRC_X]) > - plane->src_x = props->prop_values[i]; > - else if (props->props[i] == > prop_ids[IGT_PLANE_SRC_Y]) > - plane->src_y = props->prop_values[i]; > - else if (props->props[i] == > prop_ids[IGT_PLANE_SRC_W]) > - plane->src_w = props->prop_values[i]; > - else if (props->props[i] == > prop_ids[IGT_PLANE_SRC_H]) > - plane->src_h = props->prop_values[i]; > - else if (props->props[i] == > prop_ids[IGT_PLANE_TYPE]) { > - int j; > - > - for (j = 0; j < ARRAY_SIZE(desc- > >props_plane_type); j++) { > - if (props->prop_values[i] == desc- > >props_plane_type[j]) { > - plane->type = j; > - break; > - } > - } > } > - } > > - drmModeFreeObjectProperties(props); > + values[i] = igt_plane_get_prop(plane, i); > + } > } > > -static void plane_check_current_state(struct kms_atomic_plane_state > *plane, > +static void plane_check_current_state(igt_plane_t *plane, const > uint64_t *values, > enum kms_atomic_check_relax > relax) > { > drmModePlanePtr legacy; > - struct kms_atomic_plane_state plane_kernel; > + uint64_t current_values[IGT_NUM_PLANE_PROPS]; > + int i; > > - legacy = drmModeGetPlane(plane->state->desc->fd, plane- > >obj); > + legacy = drmModeGetPlane(plane->pipe->display->drm_fd, > plane->drm_plane->plane_id); > igt_assert(legacy); > > - igt_assert_eq_u32(legacy->crtc_id, plane->crtc_id); > + igt_assert_eq_u32(legacy->crtc_id, > values[IGT_PLANE_CRTC_ID]); > > if (!(relax & PLANE_RELAX_FB)) > - igt_assert_eq_u32(legacy->fb_id, plane->fb_id); > + igt_assert_eq_u32(legacy->fb_id, > values[IGT_PLANE_FB_ID]); > > - memcpy(&plane_kernel, plane, sizeof(plane_kernel)); > - plane_get_current_state(&plane_kernel); > + plane_get_current_state(plane, current_values); > > /* Legacy cursor ioctls create their own, unknowable, > internal > * framebuffer which we can't reason about. */ > if (relax & PLANE_RELAX_FB) > - plane_kernel.fb_id = plane->fb_id; > - do_or_die(memcmp(&plane_kernel, plane, > sizeof(plane_kernel))); > + current_values[IGT_PLANE_FB_ID] = > values[IGT_PLANE_FB_ID]; > + > + for (i = 0; i < IGT_NUM_PLANE_PROPS; i++) > + if (!plane_filter(i)) > + igt_assert_eq_u64(current_values[i], > values[i]); > > drmModeFreePlane(legacy); > } > > -static void plane_commit_legacy(struct kms_atomic_plane_state > *plane, > +static void plane_commit(igt_plane_t *plane, enum igt_commit_style > s, > enum kms_atomic_check_relax relax) > { > - do_or_die(drmModeSetPlane(plane->state->desc->fd, plane- > >obj, > - plane->crtc_id, > - plane->fb_id, 0, > - plane->crtc_x, plane->crtc_y, > - plane->crtc_w, plane->crtc_h, > - plane->src_x, plane->src_y, > - plane->src_w, plane->src_h)); > - plane_check_current_state(plane, relax); > + igt_display_commit2(plane->pipe->display, s); > + plane_check_current_state(plane, plane->values, relax); > } > > -static struct kms_atomic_plane_state * > -find_plane(struct kms_atomic_state *state, enum plane_type type, > - struct kms_atomic_crtc_state *crtc) > +static void plane_commit_atomic_err(igt_plane_t *plane, > + enum kms_atomic_check_relax > relax, > + int err) > { > - struct kms_atomic_plane_state *ret = NULL; > - int i; > - > - for (i = 0; i < state->num_planes; i++) { > - struct kms_atomic_plane_state *plane = &state- > >planes[i]; > - > - if (!plane->obj) > - continue; > - if (type != NUM_PLANE_TYPE_PROPS && plane->type != > type) > - continue; > - if (crtc && !(plane->crtc_mask & (1 << crtc->idx))) > - continue; > + uint64_t current_values[IGT_NUM_PLANE_PROPS]; > > - plane_get_current_state(plane); > + plane_get_current_state(plane, current_values); > > - /* Try to find a plane that's already on this CRTC. > In > - * particular, this ensures that for special > (primary/cursor) > - * planes that can be on multiple CRTCs, we find the > same > - * one that the legacy ioctls will. */ > - if (!crtc || plane->crtc_id == crtc->obj) > - return plane; > - > - ret = plane; > - } > + igt_assert_eq(-err, igt_display_try_commit2(plane->pipe- > >display, COMMIT_ATOMIC)); > > - return ret; > + plane_check_current_state(plane, current_values, relax); > } > > -static void crtc_populate_req(struct kms_atomic_crtc_state *crtc, > - drmModeAtomicReq *req) > +static bool crtc_filter(enum igt_atomic_crtc_properties prop) > { > - if (crtc->out_fence_ptr) > - crtc_set_prop(req, crtc, IGT_CRTC_OUT_FENCE_PTR, > - to_user_pointer(crtc->out_fence_ptr)); > + if (prop == IGT_CRTC_MODE_ID || prop == IGT_CRTC_ACTIVE) > + return false; > > - crtc_set_prop(req, crtc, IGT_CRTC_MODE_ID, crtc->mode.id); > - crtc_set_prop(req, crtc, IGT_CRTC_ACTIVE, crtc->active); > + return true; > } > > -static void crtc_get_current_state(struct kms_atomic_crtc_state > *crtc) > +static void crtc_get_current_state(igt_pipe_t *pipe, uint64_t > *values) > { > - drmModeObjectPropertiesPtr props; > int i; > > - props = drmModeObjectGetProperties(crtc->state->desc->fd, > crtc->obj, > - DRM_MODE_OBJECT_CRTC); > - igt_assert(props); > - > - for (i = 0; i < props->count_props; i++) { > - uint32_t *prop_ids = crtc->state->desc->props_crtc; > - > - if (props->props[i] == prop_ids[IGT_CRTC_MODE_ID]) { > - drmModePropertyBlobPtr blob; > - > - crtc->mode.id = props->prop_values[i]; > - if (!crtc->mode.id) { > - crtc->mode.len = 0; > - continue; > - } > - > - blob = drmModeGetPropertyBlob(crtc->state- > >desc->fd, > - crtc- > >mode.id); > - igt_assert(blob); > - igt_assert_eq_u32(blob->length, > - sizeof(struct > drm_mode_modeinfo)); > - > - if (!crtc->mode.data || > - memcmp(crtc->mode.data, blob->data, > blob->length) != 0) > - crtc->mode.data = blob->data; > - crtc->mode.len = blob->length; > - } > - else if (props->props[i] == > prop_ids[IGT_CRTC_ACTIVE]) { > - crtc->active = props->prop_values[i]; > + for (i = 0; i < IGT_NUM_CRTC_PROPS; i++) { > + if (crtc_filter(i)) { > + values[i] = 0; > + continue; > } > - } > > - drmModeFreeObjectProperties(props); > + values[i] = igt_pipe_obj_get_prop(pipe, i); > + } > } > > -static void crtc_check_current_state(struct kms_atomic_crtc_state > *crtc, > - struct kms_atomic_plane_state > *primary, > +static void crtc_check_current_state(igt_pipe_t *pipe, > + const uint64_t *pipe_values, > + const uint64_t *primary_values, > enum kms_atomic_check_relax > relax) > { > - struct kms_atomic_crtc_state crtc_kernel; > + uint64_t current_pipe_values[IGT_NUM_CRTC_PROPS]; > drmModeCrtcPtr legacy; > + drmModePropertyBlobRes *mode_prop = NULL; > + struct drm_mode_modeinfo *mode = NULL; > > - legacy = drmModeGetCrtc(crtc->state->desc->fd, crtc->obj); > - igt_assert(legacy); > - > - igt_assert_eq_u32(legacy->crtc_id, crtc->obj); > - igt_assert_eq_u32(legacy->x, primary->src_x >> 16); > - igt_assert_eq_u32(legacy->y, primary->src_y >> 16); > - > - if (crtc->active) > - igt_assert_eq_u32(legacy->buffer_id, primary- > >fb_id); > - else > - igt_assert_eq_u32(legacy->buffer_id, 0); > + if (pipe_values[IGT_CRTC_MODE_ID]) { > + mode_prop = drmModeGetPropertyBlob(pipe->display- > >drm_fd, > + pipe_values[IGT_C > RTC_MODE_ID]); > > - if (legacy->mode_valid) { > - igt_assert_neq(legacy->mode_valid, 0); > - igt_assert_eq(crtc->mode.len, > - sizeof(struct drm_mode_modeinfo)); > - do_or_die(memcmp(&legacy->mode, crtc->mode.data, > - crtc->mode.len)); > - igt_assert_eq(legacy->width, legacy->mode.hdisplay); > - igt_assert_eq(legacy->height, legacy- > >mode.vdisplay); > - } else { > - igt_assert_eq(legacy->mode_valid, 0); > - } > + igt_assert(mode_prop); > > - memcpy(&crtc_kernel, crtc, sizeof(crtc_kernel)); > - crtc_get_current_state(&crtc_kernel); > - > - if (crtc_kernel.mode.id != 0) > - igt_assert_eq(crtc_kernel.mode.len, > + igt_assert_eq(mode_prop->length, > sizeof(struct drm_mode_modeinfo)); > - > - /* Optionally relax the check for MODE_ID: using the legacy > SetCrtc > - * API can potentially change MODE_ID even if the mode > itself remains > - * unchanged. */ > - if (((relax & CRTC_RELAX_MODE) && > - (crtc_kernel.mode.id != crtc->mode.id && > - crtc_kernel.mode.id != 0 && crtc->mode.id != 0)) && > - memcmp(crtc_kernel.mode.data, crtc->mode.data, > - sizeof(struct drm_mode_modeinfo)) == 0) { > - crtc_kernel.mode.id = crtc->mode.id; > - crtc_kernel.mode.data = crtc->mode.data; > - } > - > - do_or_die(memcmp(&crtc_kernel, crtc, sizeof(crtc_kernel))); > - > - drmModeFreeCrtc(legacy); > -} > - > -static void crtc_commit_legacy(struct kms_atomic_crtc_state *crtc, > - struct kms_atomic_plane_state *plane, > - enum kms_atomic_check_relax relax) > -{ > - drmModeObjectPropertiesPtr props; > - uint32_t *connectors; > - int num_connectors = 0; > - int i; > - > - if (!crtc->active) { > - do_or_die(drmModeSetCrtc(crtc->state->desc->fd, > - crtc->obj, 0, 0, 0, NULL, > 0, NULL)); > - return; > - } > - > - connectors = calloc(crtc->state->num_connectors, > - sizeof(*connectors)); > - igt_assert(connectors); > - > - igt_assert_neq_u32(crtc->mode.id, 0); > - > - for (i = 0; i < crtc->state->num_connectors; i++) { > - struct kms_atomic_connector_state *connector = > - &crtc->state->connectors[i]; > - > - if (connector->crtc_id != crtc->obj) > - continue; > - > - connectors[num_connectors++] = connector->obj; > + mode = mode_prop->data; > } > > - do_or_die(drmModeSetCrtc(crtc->state->desc->fd, crtc->obj, > - plane->fb_id, > - plane->src_x >> 16, plane->src_y >> > 16, > - (num_connectors) ? connectors : > NULL, > - num_connectors, > - crtc->mode.data)); > - /* When doing a legacy commit, the core may update MODE_ID > to be a new > - * blob implicitly created by the legacy request. Hence we > backfill > - * the value in the state object to ensure they match. */ > - props = drmModeObjectGetProperties(crtc->state->desc->fd, > crtc->obj, > - DRM_MODE_OBJECT_CRTC); > - igt_assert(props); > - > - for (i = 0; i < props->count_props; i++) { > - if (props->props[i] != > - crtc->state->desc->props_crtc[IGT_CRTC_MODE_ID]) > - continue; > - crtc->mode.id = props->prop_values[i]; > - break; > - } > + legacy = drmModeGetCrtc(pipe->display->drm_fd, pipe- > >crtc_id); > + igt_assert(legacy); > > - drmModeFreeObjectProperties(props); > + igt_assert_eq_u32(legacy->crtc_id, pipe->crtc_id); > + igt_assert_eq_u32(legacy->x, primary_values[IGT_PLANE_SRC_X] > >> 16); > + igt_assert_eq_u32(legacy->y, primary_values[IGT_PLANE_SRC_Y] > >> 16); > > - crtc_check_current_state(crtc, plane, relax); > - plane_check_current_state(plane, relax); > -} > + igt_assert_eq_u32(legacy->buffer_id, > primary_values[IGT_PLANE_FB_ID]); > > -static struct kms_atomic_crtc_state *find_crtc(struct > kms_atomic_state *state, > - bool must_be_enabled) > -{ > - int i; > + if (legacy->mode_valid) { > + igt_assert(mode_prop); > > - for (i = 0; i < state->num_crtcs; i++) { > - struct kms_atomic_crtc_state *crtc = &state- > >crtcs[i]; > + do_or_die(memcmp(&legacy->mode, mode, > sizeof(*mode))); > > - if (!crtc->obj) > - continue; > - if (must_be_enabled && !crtc->active) > - continue; > + igt_assert_eq(legacy->width, legacy->mode.hdisplay); > + igt_assert_eq(legacy->height, legacy- > >mode.vdisplay); > > - crtc_get_current_state(crtc); > - return crtc; > + igt_assert_neq(pipe_values[IGT_CRTC_MODE_ID], 0); > + } else { > + igt_assert(!mode_prop); > } > > - return NULL; > -} > + crtc_get_current_state(pipe, current_pipe_values); > > -static void fill_obj_props(int fd, uint32_t id, int type, int > num_props, > - const char **prop_names, uint32_t > *prop_ids) > -{ > - drmModeObjectPropertiesPtr props; > - int i, j; > - > - props = drmModeObjectGetProperties(fd, id, type); > - igt_assert(props); > + /* Optionally relax the check for MODE_ID: using the legacy > SetCrtc > + * API can potentially change MODE_ID even if the mode > itself remains > + * unchanged. */ > + if (relax & CRTC_RELAX_MODE && mode && > current_pipe_values[IGT_CRTC_MODE_ID] && > + current_pipe_values[IGT_CRTC_MODE_ID] != > pipe_values[IGT_CRTC_MODE_ID]) { > + drmModePropertyBlobRes *cur_prop = > + drmModeGetPropertyBlob(pipe->display- > >drm_fd, > + current_pipe_values[I > GT_CRTC_MODE_ID]); > > - for (i = 0; i < props->count_props; i++) { > - drmModePropertyPtr prop = > - drmModeGetProperty(fd, props->props[i]); > + igt_assert(cur_prop); > + igt_assert_eq(cur_prop->length, sizeof(struct > drm_mode_modeinfo)); > > - for (j = 0; j < num_props; j++) { > - if (strcmp(prop->name, prop_names[j]) != 0) > - continue; > - prop_ids[j] = props->props[i]; > - break; > - } > + if (!memcmp(cur_prop->data, mode, sizeof(*mode))) > + current_pipe_values[IGT_CRTC_MODE_ID] = > pipe_values[IGT_CRTC_MODE_ID]; > > - drmModeFreeProperty(prop); > + drmModeFreePropertyBlob(cur_prop); > } > > - drmModeFreeObjectProperties(props); > -} > + do_or_die(memcmp(pipe_values, current_pipe_values, > sizeof(current_pipe_values))); > > -static void fill_obj_prop_map(int fd, uint32_t id, int type, const > char *name, > - int num_enums, const char > **enum_names, > - uint64_t *enum_ids) > -{ > - drmModeObjectPropertiesPtr props; > - int i, j, k; > - > - props = drmModeObjectGetProperties(fd, id, type); > - igt_assert(props); > - > - for (i = 0; i < props->count_props; i++) { > - drmModePropertyPtr prop = > - drmModeGetProperty(fd, props->props[i]); > - > - igt_assert(prop); > - > - if (strcmp(prop->name, name) != 0) { > - drmModeFreeProperty(prop); > - continue; > - } > - > - for (j = 0; j < prop->count_enums; j++) { > - struct drm_mode_property_enum *e = &prop- > >enums[j]; > - > - for (k = 0; k < num_enums; k++) { > - if (strcmp(e->name, enum_names[k]) > != 0) > - continue; > - > - enum_ids[k] = e->value; > - break; > - } > - } > - > - drmModeFreeProperty(prop); > - } > + drmModeFreeCrtc(legacy); > + drmModeFreePropertyBlob(mode_prop); > } > > -static void atomic_setup(struct kms_atomic_state *state) > +static void crtc_commit(igt_pipe_t *pipe, igt_plane_t *plane, > + enum igt_commit_style s, > + enum kms_atomic_check_relax relax) > { > - struct kms_atomic_desc *desc = state->desc; > - drmModeResPtr res; > - drmModePlaneResPtr res_plane; > - int i; > - > - desc->fd = drm_open_driver_master(DRIVER_ANY); > - igt_assert_fd(desc->fd); > - > - igt_skip_on(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, IGT_NUM_CRTC_PROPS, > - igt_crtc_prop_names, desc->props_crtc); > - > - fill_obj_props(desc->fd, res_plane->planes[0], > - DRM_MODE_OBJECT_PLANE, IGT_NUM_PLANE_PROPS, > - igt_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, > IGT_NUM_CONNECTOR_PROPS, > - igt_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); > - } > + igt_display_commit2(pipe->display, s); > > - 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); > + crtc_check_current_state(pipe, pipe->values, plane->values, > relax); > + plane_check_current_state(plane, plane->values, relax); > } > > -static struct kms_atomic_state * > -atomic_state_dup(const struct kms_atomic_state *state) > +static void crtc_commit_atomic_flags_err(igt_pipe_t *pipe, > igt_plane_t *plane, > + unsigned flags, > + enum kms_atomic_check_relax > relax, > + int err) > { > - struct kms_atomic_state *ret = calloc(1, sizeof(*ret)); > - > - igt_assert(ret); > - *ret = *state; > + uint64_t current_pipe_values[IGT_NUM_CRTC_PROPS]; > + uint64_t current_plane_values[IGT_NUM_PLANE_PROPS]; > > - ret->crtcs = calloc(ret->num_crtcs, sizeof(*ret->crtcs)); > - igt_assert(ret->crtcs); > - memcpy(ret->crtcs, state->crtcs, ret->num_crtcs * > sizeof(*ret->crtcs)); > + crtc_get_current_state(pipe, current_pipe_values); > + plane_get_current_state(plane, current_plane_values); > > - ret->planes = calloc(ret->num_planes, sizeof(*ret->planes)); > - igt_assert(ret->planes); > - memcpy(ret->planes, state->planes, > - ret->num_planes * sizeof(*ret->planes)); > + igt_assert_eq(-err, igt_display_try_commit_atomic(pipe- > >display, flags, NULL)); > > - ret->connectors = calloc(ret->num_connectors, sizeof(*ret- > >connectors)); > - igt_assert(ret->connectors); > - memcpy(ret->connectors, state->connectors, > - ret->num_connectors * sizeof(*ret->connectors)); > - > - return ret; > + crtc_check_current_state(pipe, current_pipe_values, > current_plane_values, relax); > + plane_check_current_state(plane, current_plane_values, > relax); > } > > -static void atomic_state_free(struct kms_atomic_state *state) > -{ > - free(state->crtcs); > - free(state->planes); > - free(state->connectors); > - free(state); > -} > +#define crtc_commit_atomic_err(pipe, plane, relax, err) \ > + crtc_commit_atomic_flags_err(pipe, plane, > DRM_MODE_ATOMIC_ALLOW_MODESET, relax, err) > > -static uint32_t plane_get_igt_format(struct kms_atomic_plane_state > *plane) > +static uint32_t plane_get_igt_format(igt_plane_t *plane) > { > drmModePlanePtr plane_kms; > const uint32_t *igt_formats; > - uint32_t ret = 0; > int num_igt_formats; > int i; > > - plane_kms = drmModeGetPlane(plane->state->desc->fd, plane- > >obj); > - igt_assert(plane_kms); > + plane_kms = plane->drm_plane; > > igt_get_all_cairo_formats(&igt_formats, &num_igt_formats); > for (i = 0; i < num_igt_formats; i++) { > int j; > > for (j = 0; j < plane_kms->count_formats; j++) { > - if (plane_kms->formats[j] == igt_formats[i]) > { > - ret = plane_kms->formats[j]; > - break; > - } > + if (plane_kms->formats[j] == igt_formats[i]) > + return plane_kms->formats[j]; > } > } > > - drmModeFreePlane(plane_kms); > - return ret; > + return 0; > } > > static void > -set_dpms(int fd, int mode) > +set_dpms(igt_output_t *output, int mode) > { > - int i; > - drmModeConnector *connector; > - uint32_t id; > - drmModeRes *resources = drmModeGetResources(fd); > - > - for (i = 0; i < resources->count_connectors; i++) { > - id = resources->connectors[i]; > - > - connector = drmModeGetConnectorCurrent(fd, id); > - > - kmstest_set_connector_dpms(fd, connector, mode); > - > - drmModeFreeConnector(connector); > - } > + do_or_die(drmModeConnectorSetProperty(output->display- > >drm_fd, output->id, > + output- > >props[IGT_CONNECTOR_DPMS], mode)); > } > > -static void plane_overlay(struct kms_atomic_crtc_state *crtc, > - struct kms_atomic_plane_state *plane_old) > +static void plane_overlay(igt_pipe_t *pipe, igt_output_t *output, > igt_plane_t *plane) > { > - 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(); > + drmModeModeInfo *mode = igt_output_get_mode(output); > + uint32_t format = plane_get_igt_format(plane); > struct igt_fb fb; > + uint32_t w = mode->hdisplay / 2; > + uint32_t h = mode->vdisplay / 2; > > - 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); > + igt_create_pattern_fb(pipe->display->drm_fd, w, h, > + format, I915_TILING_NONE, &fb); > + > + igt_plane_set_fb(plane, &fb); > + igt_plane_set_position(plane, w/2, h/2); > > /* 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); > + plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE); > > /* Disable the plane and check the state matches the old. */ > - plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE); > + igt_plane_set_fb(plane, NULL); > + igt_plane_set_position(plane, 0, 0); > + plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE); > > /* Re-enable the plane through the legacy plane API, and > verify through > * atomic. */ > - plane_commit_legacy(&plane, ATOMIC_RELAX_NONE); > + igt_plane_set_fb(plane, &fb); > + igt_plane_set_position(plane, w/2, h/2); > + plane_commit(plane, COMMIT_LEGACY, 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); > + igt_plane_set_fb(plane, NULL); > + igt_plane_set_position(plane, 0, 0); > + plane_commit(plane, COMMIT_LEGACY, ATOMIC_RELAX_NONE); > > - drmModeAtomicFree(req); > + igt_remove_fb(pipe->display->drm_fd, &fb); > } > > -static void plane_primary(struct kms_atomic_crtc_state *crtc, > - struct kms_atomic_plane_state *plane_old) > +static void plane_primary(igt_pipe_t *pipe, igt_plane_t *plane, > struct igt_fb *fb) > { > - 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; > - uint32_t flags = 0; > - int ret; > - > - igt_require(format != 0); > + struct igt_fb fb2; > > - 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); > - > - drmModeAtomicSetCursor(req, 0); > - crtc_populate_req(crtc, req); > - plane_populate_req(&plane, req); > - ret = drmModeAtomicCommit(crtc->state->desc->fd, req, > - DRM_MODE_ATOMIC_TEST_ONLY, NULL); > - /* Try harder in case the failure is caused by disallowing > modeset. */ > - if (ret == -EINVAL) > - flags |= DRM_MODE_ATOMIC_ALLOW_MODESET; > + igt_create_color_pattern_fb(pipe->display->drm_fd, > + fb->width, fb->height, > + fb->drm_format, > I915_TILING_NONE, > + 0.2, 0.2, 0.2, &fb2); > > /* 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, > flags); > + igt_plane_set_fb(plane, &fb2); > + crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE); > > /* Restore the primary plane and check the state matches the > old. */ > - crtc_commit_atomic(crtc, plane_old, req, ATOMIC_RELAX_NONE, > flags); > + igt_plane_set_fb(plane, fb); > + crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE); > > - /* Re-enable the plane through the legacy CRTC/primary-plane > API, and > + /* Set the plane through the legacy CRTC/primary-plane API, > and > * verify through atomic. */ > - crtc_commit_legacy(crtc, &plane, CRTC_RELAX_MODE); > + igt_plane_set_fb(plane, &fb2); > + crtc_commit(pipe, plane, COMMIT_LEGACY, 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, > flags); > + igt_plane_set_fb(plane, fb); > + crtc_commit(pipe, plane, COMMIT_LEGACY, CRTC_RELAX_MODE); > > - drmModeAtomicFree(req); > + /* Set the plane through the universal setplane API, and > + * verify through atomic. */ > + igt_plane_set_fb(plane, &fb2); > + plane_commit(plane, COMMIT_UNIVERSAL, ATOMIC_RELAX_NONE); > } > > /* test to ensure that DRM_MODE_ATOMIC_TEST_ONLY really only touches > the > * free-standing state objects and nothing else. > */ > -static void test_only(struct kms_atomic_crtc_state *crtc, > - struct kms_atomic_plane_state *plane_old) > +static void test_only(igt_pipe_t *pipe_obj, > + igt_plane_t *primary, > + igt_output_t *output) > { > - 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(); > + drmModeModeInfo *mode = igt_output_get_mode(output); > + uint32_t format = plane_get_igt_format(primary); > struct igt_fb fb; > - int ret; > + uint64_t old_plane_values[IGT_NUM_PLANE_PROPS], > old_crtc_values[IGT_NUM_CRTC_PROPS]; > > 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); > - > - drmModeAtomicSetCursor(req, 0); > - crtc_populate_req(crtc, req); > - plane_populate_req(&plane, req); > - ret = drmModeAtomicCommit(crtc->state->desc->fd, req, > - DRM_MODE_ATOMIC_TEST_ONLY, NULL); > - > - igt_assert_eq(ret, 0); > - > - /* go through dpms off/on cycle */ > - set_dpms(crtc->state->desc->fd, DRM_MODE_DPMS_OFF); > - set_dpms(crtc->state->desc->fd, DRM_MODE_DPMS_ON); > - > - /* check the state */ > - crtc_check_current_state(crtc, plane_old, > ATOMIC_RELAX_NONE); > - plane_check_current_state(plane_old, ATOMIC_RELAX_NONE); > - > - /* Re-enable the plane through the legacy CRTC/primary-plane > API, and > - * verify through atomic. */ > - crtc_commit_legacy(crtc, plane_old, CRTC_RELAX_MODE); > + plane_get_current_state(primary, old_plane_values); > + crtc_get_current_state(pipe_obj, old_crtc_values); > + > + igt_assert(!old_crtc_values[IGT_CRTC_MODE_ID]); > + > + igt_create_pattern_fb(pipe_obj->display->drm_fd, > + mode->hdisplay, mode->vdisplay, > + format, I915_TILING_NONE, &fb); > + igt_plane_set_fb(primary, &fb); > + igt_output_set_pipe(output, pipe_obj->pipe); > + > + igt_display_commit_atomic(pipe_obj->display, > DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL); > + > + /* check the state, should still be old state */ > + crtc_check_current_state(pipe_obj, old_crtc_values, > old_plane_values, ATOMIC_RELAX_NONE); > + plane_check_current_state(primary, old_plane_values, > ATOMIC_RELAX_NONE); > + > + /* > + * Enable the plane through the legacy CRTC/primary-plane > API, and > + * verify through atomic. > + */ > + crtc_commit(pipe_obj, primary, COMMIT_LEGACY, > CRTC_RELAX_MODE); > + > + /* Same for disable.. */ > + plane_get_current_state(primary, old_plane_values); > + crtc_get_current_state(pipe_obj, old_crtc_values); > + > + igt_plane_set_fb(primary, NULL); > + igt_output_set_pipe(output, PIPE_NONE); > + > + igt_display_commit_atomic(pipe_obj->display, > DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL); > > - drmModeAtomicFree(req); > + /* for extra stress, go through dpms off/on cycle */ > + set_dpms(output, DRM_MODE_DPMS_OFF); > + set_dpms(output, DRM_MODE_DPMS_ON); There is this library function 'kmstest_set_connector_dpms()'. Could we utilize this function here instead? > + > + /* check the state, should still be old state */ > + crtc_check_current_state(pipe_obj, old_crtc_values, > old_plane_values, ATOMIC_RELAX_NONE); > + plane_check_current_state(primary, old_plane_values, > ATOMIC_RELAX_NONE); > + > + /* And disable the pipe and remove fb, test complete */ > + crtc_commit(pipe_obj, primary, COMMIT_ATOMIC, > ATOMIC_RELAX_NONE); > + igt_remove_fb(pipe_obj->display->drm_fd, &fb); > } > > -static void plane_cursor(struct kms_atomic_crtc_state *crtc, > - struct kms_atomic_plane_state *plane_old) > +static void plane_cursor(igt_pipe_t *pipe_obj, > + igt_output_t *output, > + igt_plane_t *cursor) > { > - struct drm_mode_modeinfo *mode = crtc->mode.data; > - struct kms_atomic_plane_state plane = *plane_old; > - drmModeAtomicReq *req = drmModeAtomicAlloc(); > + drmModeModeInfo *mode = igt_output_get_mode(output); > struct igt_fb fb; > uint64_t width, height; > - > - igt_assert(req); > + int x = mode->hdisplay / 2; > + int y = mode->vdisplay / 2; > > /* Any kernel new enough for atomic, also has the cursor > size caps. */ > - do_or_die(drmGetCap(plane.state->desc->fd, > + do_or_die(drmGetCap(pipe_obj->display->drm_fd, > DRM_CAP_CURSOR_WIDTH, &width)); > - do_or_die(drmGetCap(plane.state->desc->fd, > + do_or_die(drmGetCap(pipe_obj->display->drm_fd, > DRM_CAP_CURSOR_HEIGHT, &height)); > > - plane.src_x = 0; > - plane.src_y = 0; > - plane.src_w = width << 16; > - plane.src_h = height << 16; > - plane.crtc_x = mode->hdisplay / 2; > - plane.crtc_y = mode->vdisplay / 2; > - plane.crtc_w = width; > - plane.crtc_h = height; > - plane.crtc_id = crtc->obj; > - plane.fb_id = igt_create_color_fb(plane.state->desc->fd, > - width, height, > - DRM_FORMAT_ARGB8888, > - LOCAL_DRM_FORMAT_MOD_NONE, > - 0.0, 0.0, 0.0, > - &fb); > - igt_assert_neq_u32(plane.fb_id, 0); > + igt_create_color_fb(pipe_obj->display->drm_fd, > + width, height, DRM_FORMAT_ARGB8888, > + LOCAL_DRM_FORMAT_MOD_NONE, > + 0.0, 0.0, 0.0, &fb); > > /* Flip the cursor plane using the atomic API, and double- > check > * state is what we think it should be. */ > - plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE); > + igt_plane_set_fb(cursor, &fb); > + igt_plane_set_position(cursor, x, y); > + plane_commit(cursor, COMMIT_ATOMIC, ATOMIC_RELAX_NONE); > > /* Restore the cursor plane and check the state matches the > old. */ > - plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE); > + igt_plane_set_fb(cursor, NULL); > + igt_plane_set_position(cursor, 0, 0); > + plane_commit(cursor, COMMIT_ATOMIC, ATOMIC_RELAX_NONE); > > /* Re-enable the plane through the legacy cursor API, and > verify > * through atomic. */ > - do_or_die(drmModeMoveCursor(plane.state->desc->fd, > plane.crtc_id, > - plane.crtc_x, plane.crtc_y)); > - do_or_die(drmModeSetCursor(plane.state->desc->fd, > plane.crtc_id, > - fb.gem_handle, width, height)); > - plane_check_current_state(&plane, PLANE_RELAX_FB); > + igt_plane_set_fb(cursor, &fb); > + igt_plane_set_position(cursor, x, y); > + plane_commit(cursor, COMMIT_LEGACY, PLANE_RELAX_FB); > > /* Wiggle. */ > - plane.crtc_x -= 16; > - plane.crtc_y -= 16; > - do_or_die(drmModeMoveCursor(plane.state->desc->fd, > plane.crtc_id, > - plane.crtc_x, plane.crtc_y)); > - plane_check_current_state(&plane, PLANE_RELAX_FB); > + igt_plane_set_position(cursor, x - 16, y - 16); > + plane_commit(cursor, COMMIT_LEGACY, PLANE_RELAX_FB); > > /* Restore the plane to its original settings through the > legacy cursor > * API, and verify through atomic. */ > - do_or_die(drmModeSetCursor2(plane.state->desc->fd, > plane.crtc_id, > - 0, 0, 0, 0, 0)); > - plane_check_current_state(plane_old, ATOMIC_RELAX_NONE); > - > - /* Finally, restore to the original state. */ > - plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE); > - > - drmModeAtomicFree(req); > + igt_plane_set_fb(cursor, NULL); > + igt_plane_set_position(cursor, 0, 0); > + plane_commit(cursor, COMMIT_LEGACY, ATOMIC_RELAX_NONE); > } > > -static void plane_invalid_params(struct kms_atomic_crtc_state *crtc, > - struct kms_atomic_plane_state > *plane_old, > - struct kms_atomic_connector_state > *conn) > +static void plane_invalid_params(igt_pipe_t *pipe, > + igt_output_t *output, > + igt_plane_t *plane, > + struct igt_fb *fb) > { > - 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; > + struct igt_fb fb2; > > /* 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); > + igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, plane- > >drm_plane->plane_id); > + plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL); > > - plane.fb_id = crtc->obj; > - plane_commit_atomic_err(&plane, plane_old, req, > - ATOMIC_RELAX_NONE, EINVAL); > + igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, pipe- > >crtc_id); > + plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL); > > - plane.fb_id = conn->obj; > - plane_commit_atomic_err(&plane, plane_old, req, > - ATOMIC_RELAX_NONE, EINVAL); > + igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, output- > >id); > + plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL); > > - plane.fb_id = crtc->mode.id; > - plane_commit_atomic_err(&plane, plane_old, req, > - ATOMIC_RELAX_NONE, EINVAL); > + igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, pipe- > >values[IGT_CRTC_MODE_ID]); > + plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL); > > - plane.fb_id = plane_old->fb_id; > - plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE); > + igt_plane_set_fb(plane, fb); > + plane_commit(plane, COMMIT_ATOMIC, 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); > + igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, plane- > >drm_plane->plane_id); > + plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL); > > - plane.crtc_id = plane.fb_id; > - plane_commit_atomic_err(&plane, plane_old, req, > - ATOMIC_RELAX_NONE, EINVAL); > + igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, fb- > >fb_id); > + plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL); > > - plane.crtc_id = conn->obj; > - plane_commit_atomic_err(&plane, plane_old, req, > - ATOMIC_RELAX_NONE, EINVAL); > + igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, output- > >id); > + plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL); > > - plane.crtc_id = crtc->mode.id; > - plane_commit_atomic_err(&plane, plane_old, req, > - ATOMIC_RELAX_NONE, EINVAL); > + igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, pipe- > >values[IGT_CRTC_MODE_ID]); > + plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL); > > - plane.crtc_id = plane_old->crtc_id; > - plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE); > + igt_plane_set_fb(plane, fb); > + plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE); > > /* Create a framebuffer too small for the plane > configuration. */ > - igt_require(format != 0); > + igt_create_pattern_fb(pipe->display->drm_fd, > + fb->width - 1, fb->height - 1, > + fb->drm_format, I915_TILING_NONE, > &fb2); > > - 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); > + igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, fb2.fb_id); > + plane_commit_atomic_err(plane, 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); > + igt_plane_set_fb(plane, fb); > + plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE); > } > > -static void plane_invalid_params_fence(struct kms_atomic_crtc_state > *crtc, > - struct kms_atomic_plane_state > *plane_old, > - struct kms_atomic_connector_state > *conn) > +static void plane_invalid_params_fence(igt_pipe_t *pipe, > + igt_output_t *output, > + igt_plane_t *plane) > { > - struct kms_atomic_plane_state plane = *plane_old; > - drmModeAtomicReq *req = drmModeAtomicAlloc(); > int timeline, fence_fd; > > igt_require_sw_sync(); > > + timeline = sw_sync_timeline_create(); > + > /* invalid fence fd */ > - plane.fence_fd = plane.state->desc->fd; > - plane.crtc_id = plane_old->crtc_id; > - plane_commit_atomic_err(&plane, plane_old, req, > - ATOMIC_RELAX_NONE, EINVAL); > + igt_plane_set_fence_fd(plane, pipe->display->drm_fd); > + plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL); > > /* Valid fence_fd but invalid CRTC */ > - timeline = sw_sync_timeline_create(); > - fence_fd = sw_sync_timeline_create_fence(timeline, 1); > - plane.fence_fd = fence_fd; > - plane.crtc_id = ~0U; > - plane_commit_atomic_err(&plane, plane_old, req, > - ATOMIC_RELAX_NONE, EINVAL); > + fence_fd = sw_sync_timeline_create_fence(timeline, 1); > + > + igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, ~0); > + igt_plane_set_fence_fd(plane, fence_fd); > + plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL); > + > + sw_sync_timeline_inc(timeline, 1); > + igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, pipe- > >crtc_id); > + plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE); > > - plane.fence_fd = -1; > close(fence_fd); > close(timeline); > - > - drmModeAtomicFree(req); > } > > -static void crtc_invalid_params(struct kms_atomic_crtc_state > *crtc_old, > - struct kms_atomic_plane_state > *plane, > - struct kms_atomic_connector_state > *conn) > +static void crtc_invalid_params(igt_pipe_t *pipe, > + igt_output_t *output, > + igt_plane_t *plane, > + struct igt_fb *fb) > { > - struct kms_atomic_crtc_state crtc = *crtc_old; > - drmModeAtomicReq *req = drmModeAtomicAlloc(); > - > - igt_assert(req); > + uint64_t old_mode_id = pipe->values[IGT_CRTC_MODE_ID]; > + drmModeModeInfo *mode = igt_output_get_mode(output); > > /* Pass a series of invalid object IDs for the mode ID. */ > - crtc.mode.id = plane->obj; > - crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, > 0, > - ATOMIC_RELAX_NONE, EINVAL); > + igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, plane- > >drm_plane->plane_id); > + crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, > EINVAL); > > - crtc.mode.id = crtc.obj; > - crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, > 0, > - ATOMIC_RELAX_NONE, EINVAL); > + igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, pipe- > >crtc_id); > + crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, > EINVAL); > > - crtc.mode.id = conn->obj; > - crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, > 0, > - ATOMIC_RELAX_NONE, EINVAL); > + igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, output- > >id); > + crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, > EINVAL); > > - crtc.mode.id = plane->fb_id; > - crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, > 0, > - ATOMIC_RELAX_NONE, EINVAL); > + igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, fb- > >fb_id); > + crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, > EINVAL); > > - /* successful TEST_ONLY with fences set */ > - crtc.mode.id = crtc_old->mode.id; > - crtc_commit_atomic(&crtc, plane, req, ATOMIC_RELAX_NONE, > - DRM_MODE_ATOMIC_TEST_ONLY); > + /* Can we restore mode? */ > + igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, > old_mode_id); > + crtc_commit_atomic_flags_err(pipe, plane, > DRM_MODE_ATOMIC_TEST_ONLY, ATOMIC_RELAX_NONE, 0); > > /* > * TEST_ONLY cannot be combined with > DRM_MODE_PAGE_FLIP_EVENT, > * but DRM_MODE_PAGE_FLIP_EVENT will always generate EINVAL > * without valid crtc, so test it here. > */ > - crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, > - DRM_MODE_ATOMIC_TEST_ONLY | > DRM_MODE_PAGE_FLIP_EVENT, > - ATOMIC_RELAX_NONE, EINVAL); > + crtc_commit_atomic_flags_err(pipe, plane, > + DRM_MODE_ATOMIC_TEST_ONLY | > DRM_MODE_PAGE_FLIP_EVENT, > + ATOMIC_RELAX_NONE, EINVAL); > > /* Create a blob which is the wrong size to be a valid mode. > */ > - do_or_die(drmModeCreatePropertyBlob(crtc.state->desc->fd, > - crtc.mode.data, > - sizeof(struct > drm_mode_modeinfo) - 1, > - &crtc.mode.id)); > - crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, > 0, > - ATOMIC_RELAX_NONE, EINVAL); > + igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, mode, > sizeof(*mode) - 1); > + crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, > EINVAL); > > - > - do_or_die(drmModeCreatePropertyBlob(crtc.state->desc->fd, > - crtc.mode.data, > - sizeof(struct > drm_mode_modeinfo) + 1, > - &crtc.mode.id)); > - crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, > 0, > - ATOMIC_RELAX_NONE, EINVAL); > + igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, mode, > sizeof(*mode) + 1); > + crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, > EINVAL); > > > /* Restore the CRTC and check the state matches the old. */ > - crtc_commit_atomic(crtc_old, plane, req, ATOMIC_RELAX_NONE, > 0); > - > - drmModeAtomicFree(req); > + igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, mode, > sizeof(*mode)); > + crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE); > } > > -static void crtc_invalid_params_fence(struct kms_atomic_crtc_state > *crtc_old, > - struct kms_atomic_plane_state > *plane, > - struct kms_atomic_connector_state > *conn) > +static void crtc_invalid_params_fence(igt_pipe_t *pipe, > + igt_output_t *output, > + igt_plane_t *plane, > + struct igt_fb *fb) > { > - struct kms_atomic_crtc_state crtc = *crtc_old; > - drmModeAtomicReq *req = drmModeAtomicAlloc(); > - int timeline, fence_fd, *out_fence; > + int timeline, fence_fd; > + void *map; > + const ptrdiff_t PAGE_SIZE = sysconf(_SC_PAGE_SIZE); > + uint64_t old_mode_id = pipe->values[IGT_CRTC_MODE_ID]; > > igt_require_sw_sync(); > > + timeline = sw_sync_timeline_create(); > + > + /* invalid out_fence_ptr */ > + map = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_ANONYMOUS | > MAP_PRIVATE, -1, 0); > + igt_assert(map != MAP_FAILED); > + > + igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, > (ptrdiff_t)map); > + crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, > EFAULT); > + munmap(map, PAGE_SIZE); > + > /* invalid out_fence_ptr */ > - crtc.mode.id = crtc_old->mode.id; > - crtc.out_fence_ptr = (int32_t *) crtc_invalid_params; > - crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, > 0, > - ATOMIC_RELAX_NONE, EFAULT); > + map = mmap(NULL, PAGE_SIZE, PROT_EXEC, MAP_ANONYMOUS | > MAP_PRIVATE, -1, 0); > + igt_assert(map != MAP_FAILED); > + > + igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, > (ptrdiff_t)map); > + crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, > EFAULT); > + munmap(map, PAGE_SIZE); > > /* invalid out_fence_ptr */ > - crtc.mode.id = crtc_old->mode.id; > - crtc.out_fence_ptr = (int32_t *) 0x8; > - crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, > 0, > - ATOMIC_RELAX_NONE, EFAULT); > - crtc.out_fence_ptr = (int32_t *) 0; > + map = mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_ANONYMOUS | > MAP_PRIVATE, -1, 0); > + igt_assert(map != MAP_FAILED); > + > + igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, > (ptrdiff_t)map); > + crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, > EFAULT); > + munmap(map, PAGE_SIZE); > > /* valid in fence but not allowed prop on crtc */ > - timeline = sw_sync_timeline_create(); > - fence_fd = sw_sync_timeline_create_fence(timeline, 1); > - plane->fence_fd = fence_fd; > - crtc.active = false; > - crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, > 0, > - ATOMIC_RELAX_NONE, EINVAL); > + fence_fd = sw_sync_timeline_create_fence(timeline, 1); > + igt_plane_set_fence_fd(plane, fence_fd); > > - out_fence = malloc(sizeof(uint64_t)); > - igt_assert(out_fence); > + igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_ACTIVE, 0); > + igt_pipe_obj_clear_prop_changed(pipe, > IGT_CRTC_OUT_FENCE_PTR); > > + crtc_commit_atomic_flags_err(pipe, plane, 0, > ATOMIC_RELAX_NONE, EINVAL); > > /* valid out fence ptr and flip event but not allowed prop > on crtc */ > - crtc.out_fence_ptr = (int32_t *) out_fence; > - crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, > 0, > - ATOMIC_RELAX_NONE, EINVAL); > + igt_pipe_request_out_fence(pipe); > + crtc_commit_atomic_flags_err(pipe, plane, > DRM_MODE_PAGE_FLIP_EVENT, > + ATOMIC_RELAX_NONE, EINVAL); > > - /* valid out fence ptr and flip event but not allowed prop > on crtc */ > - crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, > - DRM_MODE_PAGE_FLIP_EVENT, > - ATOMIC_RELAX_NONE, EINVAL); > - > - /* valid page flip event but not allowed prop on crtc */ > - crtc.out_fence_ptr = (int32_t *) 0; > - crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, > - DRM_MODE_PAGE_FLIP_EVENT, > - ATOMIC_RELAX_NONE, EINVAL); > - crtc.active = true; > - > - /* valid out fence ptr and flip event but invalid prop on > crtc */ > - crtc.out_fence_ptr = (int32_t *) out_fence; > - crtc.mode.id = plane->fb_id; > - crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, > 0, > - ATOMIC_RELAX_NONE, EINVAL); > + /* valid flip event but not allowed prop on crtc */ > + igt_pipe_obj_clear_prop_changed(pipe, > IGT_CRTC_OUT_FENCE_PTR); > + crtc_commit_atomic_flags_err(pipe, plane, > DRM_MODE_PAGE_FLIP_EVENT, > + ATOMIC_RELAX_NONE, EINVAL); > + > + igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_ACTIVE, 1); > + > + /* Configuration should be valid again */ > + crtc_commit_atomic_flags_err(pipe, plane, > DRM_MODE_ATOMIC_TEST_ONLY, > + ATOMIC_RELAX_NONE, 0); > + > + /* Set invalid prop */ > + igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, fb- > >fb_id); > + > + /* valid out fence but invalid prop on crtc */ > + igt_pipe_request_out_fence(pipe); > + crtc_commit_atomic_flags_err(pipe, plane, 0, > + ATOMIC_RELAX_NONE, EINVAL); > > /* valid out fence ptr and flip event but invalid prop on > crtc */ > - crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, > - DRM_MODE_PAGE_FLIP_EVENT, > - ATOMIC_RELAX_NONE, EINVAL); > + crtc_commit_atomic_flags_err(pipe, plane, > DRM_MODE_PAGE_FLIP_EVENT, > + ATOMIC_RELAX_NONE, EINVAL); > > /* valid page flip event but invalid prop on crtc */ > - crtc.out_fence_ptr = (int32_t *) 0; > - crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, > - DRM_MODE_PAGE_FLIP_EVENT, > - ATOMIC_RELAX_NONE, EINVAL); > + crtc_commit_atomic_flags_err(pipe, plane, > DRM_MODE_PAGE_FLIP_EVENT, > + ATOMIC_RELAX_NONE, EINVAL); > > /* successful TEST_ONLY with fences set */ > - plane->fence_fd = fence_fd; > - crtc.mode.id = crtc_old->mode.id; > - crtc_commit_atomic(&crtc, plane, req, ATOMIC_RELAX_NONE, > - DRM_MODE_ATOMIC_TEST_ONLY); > - igt_assert(*out_fence == -1); > + igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, > old_mode_id); > + crtc_commit_atomic_flags_err(pipe, plane, > DRM_MODE_ATOMIC_TEST_ONLY, > + ATOMIC_RELAX_NONE, 0); > + igt_assert(pipe->out_fence_fd == -1); > close(fence_fd); > close(timeline); > > /* reset fences */ > - plane->fence_fd = -1; > - crtc.out_fence_ptr = (int32_t *) 0; > - crtc_commit_atomic(&crtc, plane, req, ATOMIC_RELAX_NONE, 0); > + igt_plane_set_fence_fd(plane, -1); > + igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, > 0); > + igt_pipe_obj_clear_prop_changed(pipe, > IGT_CRTC_OUT_FENCE_PTR); > + crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE); > > /* out fence ptr but not page flip event */ > - crtc.out_fence_ptr = (int32_t *) out_fence; > - crtc_commit_atomic(crtc_old, plane, req, ATOMIC_RELAX_NONE, > 0); > + igt_pipe_request_out_fence(pipe); > + crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE); > > - close(*out_fence); > - free(out_fence); > - drmModeAtomicFree(req); > + igt_assert(pipe->out_fence_fd != -1); > } > > /* Abuse the atomic ioctl directly in order to test various invalid > conditions, > * which the libdrm wrapper won't allow us to create. */ > -static void atomic_invalid_params(struct kms_atomic_crtc_state > *crtc, > - struct kms_atomic_plane_state > *plane, > - struct kms_atomic_connector_state > *connector) > +static void atomic_invalid_params(igt_pipe_t *pipe, > + igt_plane_t *plane, > + igt_output_t *output, > + struct igt_fb *fb) > { > - struct kms_atomic_desc *desc = crtc->state->desc; > + igt_display_t *display = pipe->display; > struct drm_mode_atomic ioc; > uint32_t obj_raw[16]; /* array of objects (sized by > count_objs) */ > uint32_t num_props_raw[16]; /* array of num props per obj > (ditto) */ > @@ -1346,7 +718,7 @@ static void atomic_invalid_params(struct > kms_atomic_crtc_state *crtc, > memset(&ioc, 0, sizeof(ioc)); > > /* An empty request should do nothing. */ > - do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc); > + do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc); > > for (i = 0; i < ARRAY_SIZE(obj_raw); i++) > obj_raw[i] = 0; > @@ -1363,248 +735,232 @@ static void atomic_invalid_params(struct > kms_atomic_crtc_state *crtc, > ioc.prop_values_ptr = (uintptr_t) values_raw; > > /* Valid pointers, but still should copy nothing. */ > - do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc); > + do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc); > > /* Valid noop, but with event set should fail. */ > ioc.flags = DRM_MODE_PAGE_FLIP_EVENT; > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EINVAL); > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > EINVAL); > > /* Nonsense flags. */ > ioc.flags = 0xdeadbeef; > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EINVAL); > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > EINVAL); > > ioc.flags = 0; > /* Safety check that flags is reset properly. */ > - do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc); > + do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc); > > /* Reserved/MBZ. */ > ioc.reserved = 1; > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EINVAL); > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > EINVAL); > ioc.reserved = 0; > - do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc); > + do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc); > > /* Zero is not a valid object ID. */ > ioc.count_objs = ARRAY_SIZE(obj_raw); > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT); > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > ENOENT); > > /* Invalid object type (not a thing we can set properties > on). */ > ioc.count_objs = 1; > - obj_raw[0] = crtc->mode.id; > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT); > - obj_raw[0] = plane->fb_id; > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT); > + obj_raw[0] = pipe->values[IGT_CRTC_MODE_ID]; > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > ENOENT); > + obj_raw[0] = fb->fb_id; > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > ENOENT); > > /* Filled object but with no properties; no-op. */ > for (i = 0; i < ARRAY_SIZE(obj_raw); i++) > - obj_raw[i] = crtc->obj; > - do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc); > + obj_raw[i] = pipe->crtc_id; > + do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc); > > /* Pass in all sorts of things other than the property ID. > */ > num_props_raw[0] = 1; > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT); > - props_raw[0] = crtc->obj; > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT); > - props_raw[0] = plane->obj; > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT); > - props_raw[0] = connector->obj; > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT); > - props_raw[0] = crtc->mode.id; > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT); > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > ENOENT); > + props_raw[0] = pipe->crtc_id; > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > ENOENT); > + props_raw[0] = plane->drm_plane->plane_id; > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > ENOENT); > + props_raw[0] = output->id; > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > ENOENT); > + props_raw[0] = pipe->values[IGT_CRTC_MODE_ID]; > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > ENOENT); > > /* Valid property, valid value. */ > + > for (i = 0; i < ARRAY_SIZE(props_raw); i++) { > - props_raw[i] = desc->props_crtc[IGT_CRTC_MODE_ID]; > - values_raw[i] = crtc->mode.id; > + props_raw[i] = pipe->props[IGT_CRTC_MODE_ID]; > + values_raw[i] = pipe->values[IGT_CRTC_MODE_ID]; > } > - do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc); > + do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc); > > /* Setting the same thing multiple times is OK. */ > for (i = 0; i < ARRAY_SIZE(obj_raw); i++) > num_props_raw[i] = ARRAY_SIZE(props_raw) / > ARRAY_SIZE(obj_raw); > - do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc); > + do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc); > ioc.count_objs = ARRAY_SIZE(obj_raw); > - do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc); > + do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc); > > /* Pass a series of outlandish addresses. */ > ioc.objs_ptr = 0; > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT); > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > EFAULT); > > ioc.objs_ptr = (uintptr_t) obj_raw; > ioc.count_props_ptr = 0; > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT); > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > EFAULT); > > ioc.count_props_ptr = (uintptr_t) num_props_raw; > ioc.props_ptr = 0; > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT); > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > EFAULT); > > ioc.props_ptr = (uintptr_t) props_raw; > ioc.prop_values_ptr = 0; > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT); > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > EFAULT); > > ioc.prop_values_ptr = (uintptr_t) values_raw; > - do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc); > + do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc); > > /* Attempt to overflow and/or trip various boundary > conditions. */ > ioc.count_objs = UINT32_MAX / sizeof(uint32_t); > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT); > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > ENOENT); > > ioc.count_objs = ARRAY_SIZE(obj_raw); > ioc.objs_ptr = UINT64_MAX - sizeof(uint32_t); > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT); > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > EFAULT); > ioc.count_objs = 1; > ioc.objs_ptr = UINT64_MAX - sizeof(uint32_t); > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT); > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > EFAULT); > > num_props_raw[0] = UINT32_MAX / sizeof(uint32_t); > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT); > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > EFAULT); > num_props_raw[0] = UINT32_MAX - 1; > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT); > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > EFAULT); > > for (i = 0; i < ARRAY_SIZE(obj_raw); i++) > num_props_raw[i] = (UINT32_MAX / > ARRAY_SIZE(obj_raw)) + 1; > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT); > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > EFAULT); > for (i = 0; i < ARRAY_SIZE(obj_raw); i++) > num_props_raw[i] = ARRAY_SIZE(props_raw) / > ARRAY_SIZE(obj_raw); > - do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT); > + do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, > EFAULT); > +} > + > +static void atomic_setup(igt_display_t *display, enum pipe pipe, > igt_output_t *output, igt_plane_t *primary, struct igt_fb *fb) > +{ > + igt_output_set_pipe(output, pipe); > + igt_plane_set_fb(primary, fb); > + > + crtc_commit(primary->pipe, primary, COMMIT_ATOMIC, > ATOMIC_RELAX_NONE); > +} > + > +static void atomic_clear(igt_display_t *display, enum pipe pipe, > igt_plane_t *primary, igt_output_t *output) > +{ > + igt_plane_t *plane; > + > + for_each_plane_on_pipe(display, pipe, plane) { > + igt_plane_set_fb(plane, NULL); > + igt_plane_set_position(plane, 0, 0); > + } > + > + igt_output_set_pipe(output, PIPE_NONE); > + crtc_commit(primary->pipe, primary, COMMIT_ATOMIC, > ATOMIC_RELAX_NONE); > } > > igt_main > { > - struct kms_atomic_desc desc; > - struct kms_atomic_state *current; > + igt_display_t display; > + enum pipe pipe = PIPE_NONE; > + igt_pipe_t *pipe_obj; > + igt_output_t *output = NULL; > + igt_plane_t *primary = NULL; > + drmModeModeInfo *mode; > + struct igt_fb fb; > + > + igt_fixture { > + display.drm_fd = drm_open_driver_master(DRIVER_ANY); > + > + kmstest_set_vt_graphics_mode(); > + > + igt_display_init(&display, display.drm_fd); > + > + igt_require(display.is_atomic); > + igt_display_require_output(&display); > > - memset(&desc, 0, sizeof(desc)); > + for_each_pipe_with_valid_output(&display, pipe, > output) > + break; > + > + pipe_obj = &display.pipes[pipe]; > + primary = igt_pipe_get_plane_type(pipe_obj, > DRM_PLANE_TYPE_PRIMARY); > > - current = calloc(1, sizeof(*current)); > - igt_assert(current); > - current->desc = &desc; > + mode = igt_output_get_mode(output); > > - igt_fixture > - atomic_setup(current); > + igt_create_pattern_fb(display.drm_fd, > + mode->hdisplay, mode- > >vdisplay, > + plane_get_igt_format(primary), > + LOCAL_DRM_FORMAT_MOD_NONE, > &fb); > + } > > igt_subtest("plane_overlay_legacy") { > - struct kms_atomic_state *scratch = > atomic_state_dup(current); > - struct kms_atomic_crtc_state *crtc = > find_crtc(scratch, true); > - struct kms_atomic_plane_state *plane = > - find_plane(scratch, PLANE_TYPE_OVERLAY, > crtc); > - > - igt_require(crtc); > - igt_require(plane); > - plane_overlay(crtc, plane); > - atomic_state_free(scratch); > + igt_plane_t *overlay = > + igt_pipe_get_plane_type(pipe_obj, > DRM_PLANE_TYPE_OVERLAY); > + > + igt_require(overlay); > + > + atomic_setup(&display, pipe, output, primary, &fb); > + plane_overlay(pipe_obj, output, overlay); > } > > igt_subtest("plane_primary_legacy") { > - struct kms_atomic_state *scratch = > atomic_state_dup(current); > - struct kms_atomic_crtc_state *crtc = > find_crtc(scratch, true); > - struct kms_atomic_plane_state *plane = > - find_plane(scratch, PLANE_TYPE_PRIMARY, > crtc); > - > - igt_require(crtc); > - igt_require(plane); > - plane_primary(crtc, plane); > - atomic_state_free(scratch); > + atomic_setup(&display, pipe, output, primary, &fb); > + > + plane_primary(pipe_obj, primary, &fb); > } > > igt_subtest("test_only") { > - struct kms_atomic_state *scratch = > atomic_state_dup(current); > - struct kms_atomic_crtc_state *crtc = > find_crtc(scratch, true); > - struct kms_atomic_plane_state *plane = > - find_plane(scratch, PLANE_TYPE_PRIMARY, > crtc); > - > - igt_require(crtc); > - igt_require(plane); > - test_only(crtc, plane); > - atomic_state_free(scratch); > - } > + atomic_clear(&display, pipe, primary, output); > > + test_only(pipe_obj, primary, output); > + } > igt_subtest("plane_cursor_legacy") { > - struct kms_atomic_state *scratch = > atomic_state_dup(current); > - struct kms_atomic_crtc_state *crtc = > find_crtc(scratch, true); > - struct kms_atomic_plane_state *plane = > - find_plane(scratch, PLANE_TYPE_CURSOR, > crtc); > - > - igt_require(crtc); > - igt_require(plane); > - plane_cursor(crtc, plane); > - atomic_state_free(scratch); > + igt_plane_t *cursor = > + igt_pipe_get_plane_type(pipe_obj, > DRM_PLANE_TYPE_CURSOR); > + > + igt_require(cursor); > + > + atomic_setup(&display, pipe, output, primary, &fb); > + plane_cursor(pipe_obj, output, cursor); > } > > igt_subtest("plane_invalid_params") { > - struct kms_atomic_state *scratch = > atomic_state_dup(current); > - struct kms_atomic_crtc_state *crtc = > find_crtc(scratch, true); > - struct kms_atomic_plane_state *plane = > - find_plane(current, PLANE_TYPE_PRIMARY, > crtc); > - struct kms_atomic_connector_state *conn = > - find_connector(scratch, crtc); > - > - igt_require(crtc); > - igt_require(plane); > - plane_invalid_params(crtc, plane, conn); > - atomic_state_free(scratch); > + atomic_setup(&display, pipe, output, primary, &fb); > + > + plane_invalid_params(pipe_obj, output, primary, > &fb); > } > > igt_subtest("plane_invalid_params_fence") { > - struct kms_atomic_state *scratch = > atomic_state_dup(current); > - struct kms_atomic_crtc_state *crtc = > find_crtc(scratch, true); > - struct kms_atomic_plane_state *plane = > - find_plane(current, PLANE_TYPE_PRIMARY, > crtc); > - struct kms_atomic_connector_state *conn = > - find_connector(scratch, crtc); > - > - igt_require(crtc); > - igt_require(plane); > - plane_invalid_params_fence(crtc, plane, conn); > - atomic_state_free(scratch); > + atomic_setup(&display, pipe, output, primary, &fb); > + > + plane_invalid_params_fence(pipe_obj, output, > primary); > } > > igt_subtest("crtc_invalid_params") { > - struct kms_atomic_state *scratch = > atomic_state_dup(current); > - struct kms_atomic_crtc_state *crtc = > find_crtc(scratch, true); > - struct kms_atomic_plane_state *plane = > - find_plane(scratch, NUM_PLANE_TYPE_PROPS, > crtc); > - struct kms_atomic_connector_state *conn = > - find_connector(scratch, crtc); > - > - igt_require(crtc); > - igt_require(plane); > - igt_require(conn); > - crtc_invalid_params(crtc, plane, conn); > - atomic_state_free(scratch); > + atomic_setup(&display, pipe, output, primary, &fb); > + > + crtc_invalid_params(pipe_obj, output, primary, &fb); > } > > igt_subtest("crtc_invalid_params_fence") { > - struct kms_atomic_state *scratch = > atomic_state_dup(current); > - struct kms_atomic_crtc_state *crtc = > find_crtc(scratch, true); > - struct kms_atomic_plane_state *plane = > - find_plane(scratch, NUM_PLANE_TYPE_PROPS, > crtc); > - struct kms_atomic_connector_state *conn = > - find_connector(scratch, crtc); > - > - igt_require(crtc); > - igt_require(plane); > - igt_require(conn); > - crtc_invalid_params_fence(crtc, plane, conn); > - atomic_state_free(scratch); > + atomic_setup(&display, pipe, output, primary, &fb); > + > + crtc_invalid_params_fence(pipe_obj, output, primary, > &fb); > } > > igt_subtest("atomic_invalid_params") { > - struct kms_atomic_state *scratch = > atomic_state_dup(current); > - struct kms_atomic_crtc_state *crtc = > find_crtc(scratch, true); > - struct kms_atomic_plane_state *plane = > - find_plane(scratch, NUM_PLANE_TYPE_PROPS, > crtc); > - struct kms_atomic_connector_state *conn = > - find_connector(scratch, crtc); > - > - igt_require(crtc); > - igt_require(plane); > - igt_require(conn); > - atomic_invalid_params(crtc, plane, conn); > - atomic_state_free(scratch); > + atomic_setup(&display, pipe, output, primary, &fb); > + > + atomic_invalid_params(pipe_obj, primary, output, > &fb); > } > > - atomic_state_free(current); > + igt_fixture { > + atomic_clear(&display, pipe, primary, output); > + igt_remove_fb(display.drm_fd, &fb); > > - igt_fixture > - close(desc.fd); > + igt_display_fini(&display); > + } > } -- Mika Kahola - Intel OTC _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx