mirror of
https://github.com/tiagovignatti/intel-gpu-tools.git
synced 2025-06-10 17:36:11 +00:00
lib/igt_kms: Add COMMIT_ATOMIC to igt_display_commit2()
Co-Author : Marius Vlad <marius.c.vlad@intel.com> Co-Author : Pratik Vishwakarma <pratik.vishwakarma@intel.com> So far we have had only two commit styles, COMMIT_LEGACY and COMMIT_UNIVERSAL. This patch adds another commit style COMMIT_ATOMIC which makes use of drmModeAtomicCommit() v2: (Marius) i)Set CRTC_ID to zero while disabling plane ii)Modified the log message in igt_atomic_prepare_plane_commit https://patchwork.freedesktop.org/patch/71945/ v3: (Marius)Set FB_ID to zero while disabling plane https://patchwork.freedesktop.org/patch/72179/ v4: (Maarten) Corrected the typo in commit message https://patchwork.freedesktop.org/patch/72598/ v5: Added check for DRM_CLIENT_CAP_ATOMIC in igt_display_init (Marius) i)Removed unused props from igt_display_init ii)Removed unused ret. Changed function to void iii)Declare the variable before checking if we have DRM_CLIENT_CAP_ATOMIC. https://patchwork.freedesktop.org/patch/73505/ v6: (Jani) Corrected typo in commit message v7: Added is_atomic check for DRM_CLIENT_CAP_ATOMIC in igt_display_init and igt_atomic_commit v8: (Matthew Auld) Replaced for loops by for_each_connected_output and for_each_plane_on_pipe (Lionel) Populate properties only if the value has changed Remove the resetting of values in disable case Note : I've used Maarten's diff patch v9: (Lionel) Added resetting of rotation property v10: (Marius) Modified the macro declaration to avoid shadow declaration warning, also removed one unused variable Signed-off-by: Mayuresh Gharpure <mayuresh.s.gharpure@intel.com> Signed-off-by: Pratik Vishwakarma <pratik.vishwakarma@intel.com> Signed-off-by: Mayuresh Gharpure <mayuresh.s.gharpure@intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
This commit is contained in:
parent
314fa179c8
commit
0e2e880e04
289
lib/igt_kms.c
289
lib/igt_kms.c
@ -145,6 +145,120 @@ const unsigned char* igt_kms_get_base_edid(void)
|
||||
*
|
||||
* Returns: an alternate edid block
|
||||
*/
|
||||
static const char *igt_plane_prop_names[IGT_NUM_PLANE_PROPS] = {
|
||||
"SRC_X",
|
||||
"SRC_Y",
|
||||
"SRC_W",
|
||||
"SRC_H",
|
||||
"CRTC_X",
|
||||
"CRTC_Y",
|
||||
"CRTC_W",
|
||||
"CRTC_H",
|
||||
"FB_ID",
|
||||
"CRTC_ID",
|
||||
"type",
|
||||
"rotation"
|
||||
};
|
||||
|
||||
static const char *igt_crtc_prop_names[IGT_NUM_CRTC_PROPS] = {
|
||||
"background_color"
|
||||
};
|
||||
|
||||
static const char *igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
|
||||
"scaling mode",
|
||||
"DPMS"
|
||||
};
|
||||
|
||||
/*
|
||||
* Retrieve all the properies specified in props_name and store them into
|
||||
* plane->atomic_props_plane.
|
||||
*/
|
||||
static void
|
||||
igt_atomic_fill_plane_props(igt_display_t *display, igt_plane_t *plane,
|
||||
int num_props, const char **prop_names)
|
||||
{
|
||||
drmModeObjectPropertiesPtr props;
|
||||
int i, j, fd;
|
||||
|
||||
fd = display->drm_fd;
|
||||
|
||||
props = drmModeObjectGetProperties(fd, plane->drm_plane->plane_id, DRM_MODE_OBJECT_PLANE);
|
||||
igt_assert(props);
|
||||
|
||||
for (i = 0; i < props->count_props; i++) {
|
||||
drmModePropertyPtr prop =
|
||||
drmModeGetProperty(fd, props->props[i]);
|
||||
|
||||
for (j = 0; j < num_props; j++) {
|
||||
if (strcmp(prop->name, prop_names[j]) != 0)
|
||||
continue;
|
||||
|
||||
plane->atomic_props_plane[j] = props->props[i];
|
||||
break;
|
||||
}
|
||||
|
||||
drmModeFreeProperty(prop);
|
||||
}
|
||||
|
||||
drmModeFreeObjectProperties(props);
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve all the properies specified in props_name and store them into
|
||||
* config->atomic_props_crtc and config->atomic_props_connector.
|
||||
*/
|
||||
static void
|
||||
igt_atomic_fill_props(igt_display_t *display, igt_output_t *output,
|
||||
int num_crtc_props, const char **crtc_prop_names,
|
||||
int num_connector_props, const char **conn_prop_names)
|
||||
{
|
||||
drmModeObjectPropertiesPtr props;
|
||||
int i, j, fd;
|
||||
|
||||
fd = display->drm_fd;
|
||||
|
||||
props = drmModeObjectGetProperties(fd, output->config.crtc->crtc_id, DRM_MODE_OBJECT_CRTC);
|
||||
igt_assert(props);
|
||||
|
||||
for (i = 0; i < props->count_props; i++) {
|
||||
drmModePropertyPtr prop =
|
||||
drmModeGetProperty(fd, props->props[i]);
|
||||
|
||||
for (j = 0; j < num_crtc_props; j++) {
|
||||
if (strcmp(prop->name, crtc_prop_names[j]) != 0)
|
||||
continue;
|
||||
|
||||
output->config.atomic_props_crtc[j] = props->props[i];
|
||||
break;
|
||||
}
|
||||
|
||||
drmModeFreeProperty(prop);
|
||||
}
|
||||
|
||||
drmModeFreeObjectProperties(props);
|
||||
props = NULL;
|
||||
props = drmModeObjectGetProperties(fd, output->config.connector->connector_id, DRM_MODE_OBJECT_CONNECTOR);
|
||||
igt_assert(props);
|
||||
|
||||
for (i = 0; i < props->count_props; i++) {
|
||||
drmModePropertyPtr prop =
|
||||
drmModeGetProperty(fd, props->props[i]);
|
||||
|
||||
for (j = 0; j < num_connector_props; j++) {
|
||||
if (strcmp(prop->name, conn_prop_names[j]) != 0)
|
||||
continue;
|
||||
|
||||
output->config.atomic_props_connector[j] = props->props[i];
|
||||
break;
|
||||
}
|
||||
|
||||
drmModeFreeProperty(prop);
|
||||
}
|
||||
|
||||
drmModeFreeObjectProperties(props);
|
||||
|
||||
}
|
||||
|
||||
const unsigned char* igt_kms_get_alt_edid(void)
|
||||
{
|
||||
update_edid_csum(alt_edid);
|
||||
@ -1000,6 +1114,8 @@ static void igt_output_refresh(igt_output_t *output)
|
||||
kmstest_pipe_name(output->config.pipe));
|
||||
|
||||
display->pipes_in_use |= 1 << output->config.pipe;
|
||||
igt_atomic_fill_props(display, output, IGT_NUM_CRTC_PROPS, igt_crtc_prop_names,
|
||||
IGT_NUM_CONNECTOR_PROPS, igt_connector_prop_names);
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -1069,6 +1185,7 @@ void igt_display_init(igt_display_t *display, int drm_fd)
|
||||
drmModeRes *resources;
|
||||
drmModePlaneRes *plane_resources;
|
||||
int i;
|
||||
int is_atomic = 0;
|
||||
|
||||
memset(display, 0, sizeof(igt_display_t));
|
||||
|
||||
@ -1086,6 +1203,7 @@ void igt_display_init(igt_display_t *display, int drm_fd)
|
||||
display->n_pipes = resources->count_crtcs;
|
||||
|
||||
drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
|
||||
is_atomic = drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1);
|
||||
plane_resources = drmModeGetPlaneResources(display->drm_fd);
|
||||
igt_assert(plane_resources);
|
||||
|
||||
@ -1142,6 +1260,10 @@ void igt_display_init(igt_display_t *display, int drm_fd)
|
||||
|
||||
plane->pipe = pipe;
|
||||
plane->drm_plane = drm_plane;
|
||||
if (is_atomic == 0) {
|
||||
display->is_atomic = 1;
|
||||
igt_atomic_fill_plane_props(display, plane, IGT_NUM_PLANE_PROPS, igt_plane_prop_names);
|
||||
}
|
||||
|
||||
get_plane_property(display->drm_fd, drm_plane->plane_id,
|
||||
"rotation",
|
||||
@ -1397,6 +1519,80 @@ static uint32_t igt_plane_get_fb_gem_handle(igt_plane_t *plane)
|
||||
igt_assert(r == 0); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Add position and fb changes of a plane to the atomic property set
|
||||
*/
|
||||
static void
|
||||
igt_atomic_prepare_plane_commit(igt_plane_t *plane, igt_output_t *output,
|
||||
drmModeAtomicReq *req)
|
||||
{
|
||||
|
||||
igt_display_t *display = output->display;
|
||||
uint32_t fb_id, crtc_id;
|
||||
|
||||
igt_assert(plane->drm_plane);
|
||||
|
||||
/* it's an error to try an unsupported feature */
|
||||
igt_assert(igt_plane_supports_rotation(plane) ||
|
||||
!plane->rotation_changed);
|
||||
|
||||
fb_id = igt_plane_get_fb_id(plane);
|
||||
crtc_id = output->config.crtc->crtc_id;
|
||||
|
||||
LOG(display,
|
||||
"%s: populating plane data: %s.%d, fb %u\n",
|
||||
igt_output_name(output),
|
||||
kmstest_pipe_name(output->config.pipe),
|
||||
plane->index,
|
||||
fb_id);
|
||||
|
||||
if (plane->fb_changed) {
|
||||
igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_ID, fb_id ? crtc_id : 0);
|
||||
igt_atomic_populate_plane_req(req, plane, IGT_PLANE_FB_ID, fb_id);
|
||||
}
|
||||
|
||||
if (plane->position_changed || plane->size_changed) {
|
||||
uint32_t src_x = IGT_FIXED(plane->fb->src_x, 0); /* src_x */
|
||||
uint32_t src_y = IGT_FIXED(plane->fb->src_y, 0); /* src_y */
|
||||
uint32_t src_w = IGT_FIXED(plane->fb->src_w, 0); /* src_w */
|
||||
uint32_t src_h = IGT_FIXED(plane->fb->src_h, 0); /* src_h */
|
||||
int32_t crtc_x = plane->crtc_x;
|
||||
int32_t crtc_y = plane->crtc_y;
|
||||
uint32_t crtc_w = plane->crtc_w;
|
||||
uint32_t crtc_h = plane->crtc_h;
|
||||
|
||||
LOG(display,
|
||||
"src = (%d, %d) %u x %u "
|
||||
"dst = (%d, %d) %u x %u\n",
|
||||
src_x >> 16, src_y >> 16, src_w >> 16, src_h >> 16,
|
||||
crtc_x, crtc_y, crtc_w, crtc_h);
|
||||
|
||||
igt_atomic_populate_plane_req(req, plane, IGT_PLANE_SRC_X, src_x);
|
||||
igt_atomic_populate_plane_req(req, plane, IGT_PLANE_SRC_Y, src_y);
|
||||
igt_atomic_populate_plane_req(req, plane, IGT_PLANE_SRC_W, src_w);
|
||||
igt_atomic_populate_plane_req(req, plane, IGT_PLANE_SRC_H, src_h);
|
||||
|
||||
igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_X, crtc_x);
|
||||
igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_Y, crtc_y);
|
||||
igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_W, crtc_w);
|
||||
igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_H, crtc_h);
|
||||
}
|
||||
|
||||
if (plane->rotation_changed)
|
||||
igt_atomic_populate_plane_req(req, plane,
|
||||
IGT_PLANE_ROTATION, plane->rotation);
|
||||
|
||||
plane->fb_changed = false;
|
||||
plane->position_changed = false;
|
||||
plane->size_changed = false;
|
||||
plane->rotation_changed = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Commit position and fb changes to a DRM plane via the SetPlane ioctl; if the
|
||||
* DRM call to program the plane fails, we'll either fail immediately (for
|
||||
@ -1649,7 +1845,7 @@ static int igt_plane_commit(igt_plane_t *plane,
|
||||
return igt_primary_plane_commit_legacy(plane, output,
|
||||
fail_on_error);
|
||||
} else {
|
||||
return igt_drm_plane_commit(plane, output, fail_on_error);
|
||||
return igt_drm_plane_commit(plane, output, fail_on_error);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1703,6 +1899,89 @@ static int igt_output_commit(igt_output_t *output,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Add crtc property changes to the atomic property set
|
||||
*/
|
||||
static void igt_atomic_prepare_crtc_commit(igt_output_t *output, drmModeAtomicReq *req)
|
||||
{
|
||||
|
||||
igt_pipe_t *pipe_obj = igt_output_get_driving_pipe(output);
|
||||
|
||||
if (pipe_obj->background_changed)
|
||||
igt_atomic_populate_crtc_req(req, output, IGT_CRTC_BACKGROUND, pipe_obj->background);
|
||||
|
||||
/*
|
||||
* TODO: Add all crtc level properties here
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Add connector property changes to the atomic property set
|
||||
*/
|
||||
static void igt_atomic_prepare_connector_commit(igt_output_t *output, drmModeAtomicReq *req)
|
||||
{
|
||||
|
||||
struct kmstest_connector_config *config = &output->config;
|
||||
|
||||
if (config->connector_scaling_mode_changed)
|
||||
igt_atomic_populate_connector_req(req, output, IGT_CONNECTOR_SCALING_MODE, config->connector_scaling_mode);
|
||||
|
||||
if (config->connector_dpms_changed)
|
||||
igt_atomic_populate_connector_req(req, output, IGT_CONNECTOR_DPMS, config->connector_dpms);
|
||||
/*
|
||||
* TODO: Add all other connector level properties here
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Commit all the changes of all the planes,crtcs, connectors
|
||||
* atomically using drmModeAtomicCommit()
|
||||
*/
|
||||
static int igt_atomic_commit(igt_display_t *display)
|
||||
{
|
||||
|
||||
int ret = 0;
|
||||
drmModeAtomicReq *req;
|
||||
igt_output_t *output;
|
||||
if (display->is_atomic != 1)
|
||||
return -1;
|
||||
req = drmModeAtomicAlloc();
|
||||
drmModeAtomicSetCursor(req, 0);
|
||||
|
||||
for_each_connected_output(display, output) {
|
||||
igt_pipe_t *pipe_obj;
|
||||
igt_plane_t *plane;
|
||||
enum pipe pipe;
|
||||
|
||||
/*
|
||||
* Add CRTC Properties to the property set
|
||||
*/
|
||||
igt_atomic_prepare_crtc_commit(output, req);
|
||||
|
||||
/*
|
||||
* Add Connector Properties to the property set
|
||||
*/
|
||||
igt_atomic_prepare_connector_commit(output, req);
|
||||
|
||||
|
||||
pipe_obj = igt_output_get_driving_pipe(output);
|
||||
|
||||
pipe = pipe_obj->pipe;
|
||||
|
||||
for_each_plane_on_pipe(display, pipe, plane) {
|
||||
igt_atomic_prepare_plane_commit(plane, output, req);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ret = drmModeAtomicCommit(display->drm_fd, req, 0, NULL);
|
||||
drmModeAtomicFree(req);
|
||||
return ret;
|
||||
|
||||
}
|
||||
/*
|
||||
* Commit all plane changes across all outputs of the display.
|
||||
*
|
||||
@ -1722,6 +2001,14 @@ static int do_display_commit(igt_display_t *display,
|
||||
|
||||
igt_display_refresh(display);
|
||||
|
||||
if (s == COMMIT_ATOMIC) {
|
||||
|
||||
ret = igt_atomic_commit(display);
|
||||
CHECK_RETURN(ret, fail_on_error);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
for (i = 0; i < display->n_outputs; i++) {
|
||||
igt_output_t *output = &display->outputs[i];
|
||||
|
||||
|
@ -106,11 +106,28 @@ int kmstest_get_pipe_from_crtc_id(int fd, int crtc_id);
|
||||
void kmstest_set_vt_graphics_mode(void);
|
||||
void kmstest_restore_vt_mode(void);
|
||||
|
||||
enum igt_atomic_crtc_properties {
|
||||
IGT_CRTC_BACKGROUND = 0,
|
||||
IGT_NUM_CRTC_PROPS
|
||||
};
|
||||
|
||||
enum igt_atomic_connector_properties {
|
||||
IGT_CONNECTOR_SCALING_MODE = 0,
|
||||
IGT_CONNECTOR_DPMS,
|
||||
IGT_NUM_CONNECTOR_PROPS
|
||||
};
|
||||
|
||||
struct kmstest_connector_config {
|
||||
drmModeCrtc *crtc;
|
||||
drmModeConnector *connector;
|
||||
drmModeEncoder *encoder;
|
||||
drmModeModeInfo default_mode;
|
||||
uint64_t connector_scaling_mode;
|
||||
bool connector_scaling_mode_changed;
|
||||
uint64_t connector_dpms;
|
||||
bool connector_dpms_changed;
|
||||
uint32_t atomic_props_crtc[IGT_NUM_CRTC_PROPS];
|
||||
uint32_t atomic_props_connector[IGT_NUM_CONNECTOR_PROPS];
|
||||
int crtc_idx;
|
||||
int pipe;
|
||||
};
|
||||
@ -163,9 +180,28 @@ uint32_t kmstest_find_crtc_for_connector(int fd, drmModeRes *res,
|
||||
enum igt_commit_style {
|
||||
COMMIT_LEGACY = 0,
|
||||
COMMIT_UNIVERSAL,
|
||||
/* We'll add atomic here eventually. */
|
||||
COMMIT_ATOMIC,
|
||||
};
|
||||
|
||||
enum igt_atomic_plane_properties {
|
||||
IGT_PLANE_SRC_X = 0,
|
||||
IGT_PLANE_SRC_Y,
|
||||
IGT_PLANE_SRC_W,
|
||||
IGT_PLANE_SRC_H,
|
||||
|
||||
IGT_PLANE_CRTC_X,
|
||||
IGT_PLANE_CRTC_Y,
|
||||
IGT_PLANE_CRTC_W,
|
||||
IGT_PLANE_CRTC_H,
|
||||
|
||||
IGT_PLANE_FB_ID,
|
||||
IGT_PLANE_CRTC_ID,
|
||||
IGT_PLANE_TYPE,
|
||||
IGT_PLANE_ROTATION,
|
||||
IGT_NUM_PLANE_PROPS
|
||||
};
|
||||
|
||||
|
||||
typedef struct igt_display igt_display_t;
|
||||
typedef struct igt_pipe igt_pipe_t;
|
||||
typedef uint32_t igt_fixed_t; /* 16.16 fixed point */
|
||||
@ -207,6 +243,7 @@ typedef struct {
|
||||
/* panning offset within the fb */
|
||||
unsigned int pan_x, pan_y;
|
||||
igt_rotation_t rotation;
|
||||
uint32_t atomic_props_plane[IGT_NUM_PLANE_PROPS];
|
||||
} igt_plane_t;
|
||||
|
||||
struct igt_pipe {
|
||||
@ -242,6 +279,7 @@ struct igt_display {
|
||||
igt_output_t *outputs;
|
||||
igt_pipe_t pipes[I915_MAX_PIPES];
|
||||
bool has_universal_planes;
|
||||
bool is_atomic;
|
||||
};
|
||||
|
||||
void igt_display_init(igt_display_t *display, int drm_fd);
|
||||
@ -283,11 +321,43 @@ void igt_wait_for_vblank(int drm_fd, enum pipe pipe);
|
||||
for (pipe = 0; pipe < igt_display_get_n_pipes(display); pipe++) \
|
||||
|
||||
#define for_each_plane_on_pipe(display, pipe, plane) \
|
||||
for (int i__ = 0; (plane) = &(display)->pipes[(pipe)].planes[i__], \
|
||||
i__ < (display)->pipes[(pipe)].n_planes; i__++)
|
||||
for (int j__ = 0; (plane) = &(display)->pipes[(pipe)].planes[j__], \
|
||||
j__ < (display)->pipes[(pipe)].n_planes; j__++)
|
||||
|
||||
#define IGT_FIXED(i,f) ((i) << 16 | (f))
|
||||
|
||||
/**
|
||||
* igt_atomic_populate_plane_req:
|
||||
* @req: A pointer to drmModeAtomicReq
|
||||
* @plane: A pointer igt_plane_t
|
||||
* @prop: one of igt_atomic_plane_properties
|
||||
* @value: the value to add
|
||||
*/
|
||||
#define igt_atomic_populate_plane_req(req, plane, prop, value) \
|
||||
igt_assert_lt(0, drmModeAtomicAddProperty(req, plane->drm_plane->plane_id,\
|
||||
plane->atomic_props_plane[prop], value))
|
||||
|
||||
/**
|
||||
* igt_atomic_populate_crtc_req:
|
||||
* @req: A pointer to drmModeAtomicReq
|
||||
* @output: A pointer igt_output_t
|
||||
* @prop: one of igt_atomic_crtc_properties
|
||||
* @value: the value to add
|
||||
*/
|
||||
#define igt_atomic_populate_crtc_req(req, output, prop, value) \
|
||||
igt_assert_lt(0, drmModeAtomicAddProperty(req, output->config.crtc->crtc_id,\
|
||||
output->config.atomic_props_crtc[prop], value))
|
||||
/**
|
||||
* igt_atomic_populate_connector_req:
|
||||
* @req: A pointer to drmModeAtomicReq
|
||||
* @output: A pointer igt_output_t
|
||||
* @prop: one of igt_atomic_connector_properties
|
||||
* @value: the value to add
|
||||
*/
|
||||
#define igt_atomic_populate_connector_req(req, output, prop, value) \
|
||||
igt_assert_lt(0, drmModeAtomicAddProperty(req, output->config.connector->connector_id,\
|
||||
output->config.atomic_props_connector[prop], value))
|
||||
|
||||
void igt_enable_connectors(void);
|
||||
void igt_reset_connectors(void);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user