Commit 66fb466e authored by Maarten Lankhorst's avatar Maarten Lankhorst

lib/igt_kms: Rework pipe properties to be more atomic, v7.

In the future I want to allow tests to commit more properties,
but for this to work I have to fix all properties to work better
with atomic commit. Instead of special casing each
property make a bitmask for all property changed flags, and try to
commit all properties.

This has been the most involved one, since legacy pipe commit still
handles a lot of the properties differently from the rest.

Changes since v1:
- Dump all changed properties on commit.
- Fix bug in igt_pipe_refresh().
Changes since v2:
- Set pipe ACTIVE property changed flag on init.
Changes since v3:
- Add a missing igt_pipe_refresh() to kms_atomic_interruptible.
Changes since v4:
- Perform error handling when setting custom crtc properties.
Changes since v5:
- Only attempt to commit changes properties.
Changes since v6:
- Clear OUT_FENCE_PTR on succesful commit.
Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: default avatarMika Kahola <mika.kahola@intel.com>
parent 5e42c623
This diff is collapsed.
......@@ -313,27 +313,13 @@ struct igt_pipe {
int plane_primary;
igt_plane_t *planes;
uint32_t atomic_props_crtc[IGT_NUM_CRTC_PROPS];
uint64_t background; /* Background color MSB BGR 16bpc LSB */
uint32_t background_changed : 1;
uint32_t background_property;
uint64_t degamma_blob;
uint32_t degamma_property;
uint64_t ctm_blob;
uint32_t ctm_property;
uint64_t gamma_blob;
uint32_t gamma_property;
uint32_t color_mgmt_changed : 1;
uint64_t changed;
uint32_t props[IGT_NUM_CRTC_PROPS];
uint64_t values[IGT_NUM_CRTC_PROPS];
uint32_t crtc_id;
uint64_t mode_blob;
bool mode_changed;
int32_t out_fence_fd;
bool out_fence_requested;
};
typedef struct {
......@@ -527,17 +513,6 @@ static inline bool igt_output_is_connected(igt_output_t *output)
igt_plane_set_prop_changed(plane, prop); \
} while (0)
/**
* igt_atomic_populate_crtc_req:
* @req: A pointer to drmModeAtomicReq
* @pipe: A pointer igt_pipe_t
* @prop: one of igt_atomic_crtc_properties
* @value: the value to add
*/
#define igt_atomic_populate_crtc_req(req, pipe, prop, value) \
igt_assert_lt(0, drmModeAtomicAddProperty(req, pipe->crtc_id,\
pipe->atomic_props_crtc[prop], value))
#define igt_output_is_prop_changed(output, prop) \
(!!((output)->changed & (1 << (prop))))
#define igt_output_set_prop_changed(output, prop) \
......@@ -552,26 +527,34 @@ static inline bool igt_output_is_connected(igt_output_t *output)
igt_output_set_prop_changed(output, prop); \
} while (0)
/*
* igt_pipe_refresh:
* @display: a pointer to an #igt_display_t structure
* @pipe: Pipe to refresh
* @force: Should be set to true if mode_blob is no longer considered
* to be valid, for example after doing an atomic commit during fork or closing display fd.
*
* Requests the pipe to be part of the state on next update.
* This is useful when state may have been out of sync after
* a fork, or we just want to be sure the pipe is included
* in the next commit.
*/
static inline void
igt_pipe_refresh(igt_display_t *display, enum pipe pipe, bool force)
{
if (force)
display->pipes[pipe].mode_blob = 0;
#define igt_pipe_obj_is_prop_changed(pipe_obj, prop) \
(!!((pipe_obj)->changed & (1 << (prop))))
display->pipes[pipe].mode_changed = true;
}
#define igt_pipe_is_prop_changed(display, pipe, prop) \
igt_pipe_obj_is_prop_changed(&(display)->pipes[(pipe)], prop)
#define igt_pipe_obj_set_prop_changed(pipe_obj, prop) \
(pipe_obj)->changed |= 1 << (prop)
#define igt_pipe_set_prop_changed(display, pipe, prop) \
igt_pipe_obj_set_prop_changed(&(display)->pipes[(pipe)], prop)
#define igt_pipe_obj_clear_prop_changed(pipe_obj, prop) \
(pipe_obj)->changed &= ~(1 << (prop))
#define igt_pipe_clear_prop_changed(display, pipe, prop) \
igt_pipe_obj_clear_prop_changed(&(display)->pipes[(pipe)], prop)
#define igt_pipe_obj_set_prop_value(pipe_obj, prop, value) \
do { \
(pipe_obj)->values[prop] = (value); \
igt_pipe_obj_set_prop_changed(pipe_obj, prop); \
} while (0)
#define igt_pipe_set_prop_value(display, pipe, prop, value) \
igt_pipe_obj_set_prop_value(&(display)->pipes[(pipe)], prop, value)
void igt_pipe_refresh(igt_display_t *display, enum pipe pipe, bool force);
void igt_enable_connectors(void);
void igt_reset_connectors(void);
......
......@@ -158,8 +158,8 @@ static void run_plane_test(igt_display_t *display, enum pipe pipe, igt_output_t
uint32_t count_props[3] = { 2, 1, 6 };
uint32_t props[] = {
/* crtc: 2 props */
plane->pipe->atomic_props_crtc[IGT_CRTC_MODE_ID],
plane->pipe->atomic_props_crtc[IGT_CRTC_ACTIVE],
plane->pipe->props[IGT_CRTC_MODE_ID],
plane->pipe->props[IGT_CRTC_ACTIVE],
/* connector: 1 prop */
output->props[IGT_CONNECTOR_CRTC_ID],
/* plane: remainder props */
......@@ -255,6 +255,10 @@ static void run_plane_test(igt_display_t *display, enum pipe pipe, igt_output_t
igt_waitchildren();
/* The mode is unset by the forked helper, force a refresh here */
if (test_type == test_legacy_modeset || test_type == test_atomic_modeset)
igt_pipe_refresh(display, pipe, true);
igt_plane_set_fb(plane, NULL);
igt_plane_set_fb(primary, NULL);
igt_output_set_pipe(output, PIPE_NONE);
......
......@@ -633,7 +633,7 @@ static unsigned set_combinations(igt_display_t *display, unsigned mask, struct i
drmModeModeInfo *mode = NULL;
if (!(mask & (1 << pipe))) {
if (display->pipes[pipe].mode_blob) {
if (igt_pipe_is_prop_changed(display, pipe, IGT_CRTC_ACTIVE)) {
event_mask |= 1 << pipe;
igt_plane_set_fb(plane, NULL);
}
......
......@@ -137,7 +137,7 @@ static void test_crtc_background(data_t *data)
igt_output_set_pipe(output, pipe);
plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
igt_require(plane->pipe->background_property);
igt_require(plane->pipe->props[IGT_CRTC_BACKGROUND]);
prepare_crtc(data, output, pipe, plane, 1, PURPLE, BLACK64);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment