mirror of
https://github.com/tiagovignatti/intel-gpu-tools.git
synced 2025-06-23 07:46:15 +00:00
lib/display: Add support for the cursor plane
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
This commit is contained in:
parent
c4823ce9a4
commit
5ec399b4a6
148
lib/igt_kms.c
148
lib/igt_kms.c
@ -890,16 +890,29 @@ void igt_display_init(igt_display_t *display, int drm_fd)
|
|||||||
for (i = 0; i < display->n_pipes; i++) {
|
for (i = 0; i < display->n_pipes; i++) {
|
||||||
igt_pipe_t *pipe = &display->pipes[i];
|
igt_pipe_t *pipe = &display->pipes[i];
|
||||||
igt_plane_t *plane;
|
igt_plane_t *plane;
|
||||||
|
int p;
|
||||||
|
|
||||||
pipe->display = display;
|
pipe->display = display;
|
||||||
pipe->pipe = i;
|
pipe->pipe = i;
|
||||||
pipe->n_planes = 1;
|
|
||||||
|
|
||||||
/* primary plane */
|
/* primary plane */
|
||||||
plane = &pipe->planes[0];
|
p = IGT_PLANE_PRIMARY;
|
||||||
|
plane = &pipe->planes[p];
|
||||||
plane->pipe = pipe;
|
plane->pipe = pipe;
|
||||||
plane->index = 0;
|
plane->index = p;
|
||||||
plane->is_primary = true;
|
plane->is_primary = true;
|
||||||
|
|
||||||
|
/* cursor plane */
|
||||||
|
p++;
|
||||||
|
plane = &pipe->planes[p];
|
||||||
|
plane->pipe = pipe;
|
||||||
|
plane->index = p;
|
||||||
|
plane->is_cursor = true;
|
||||||
|
|
||||||
|
pipe->n_planes = ++p;
|
||||||
|
|
||||||
|
/* make sure we don't overflow the plane array */
|
||||||
|
igt_assert(pipe->n_planes <= IGT_MAX_PLANES);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1010,6 +1023,22 @@ static igt_pipe_t *igt_output_get_driving_pipe(igt_output_t *output)
|
|||||||
return &display->pipes[pipe];
|
return &display->pipes[pipe];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static igt_plane_t *igt_pipe_get_plane(igt_pipe_t *pipe, enum igt_plane plane)
|
||||||
|
{
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
/* Cursor plane is always the upper plane */
|
||||||
|
if (plane == IGT_PLANE_CURSOR)
|
||||||
|
idx = pipe->n_planes - 1;
|
||||||
|
else {
|
||||||
|
igt_assert_f(plane >= 0 && plane < (pipe->n_planes - 1),
|
||||||
|
"plane=%d\n", plane);
|
||||||
|
idx = plane;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pipe->planes[idx];
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t igt_plane_get_fd_id(igt_plane_t *plane)
|
static uint32_t igt_plane_get_fd_id(igt_plane_t *plane)
|
||||||
{
|
{
|
||||||
if (plane->fb)
|
if (plane->fb)
|
||||||
@ -1018,10 +1047,53 @@ static uint32_t igt_plane_get_fd_id(igt_plane_t *plane)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t igt_plane_get_fb_gem_handle(igt_plane_t *plane)
|
||||||
|
{
|
||||||
|
if (plane->fb)
|
||||||
|
return plane->fb->gem_handle;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int igt_cursor_commit(igt_plane_t *plane, igt_output_t *output)
|
||||||
|
{
|
||||||
|
igt_display_t *display = output->display;
|
||||||
|
uint32_t crtc_id = output->config.crtc->crtc_id;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (plane->position_changed) {
|
||||||
|
int x = plane->crtc_x;
|
||||||
|
int y = plane->crtc_y;
|
||||||
|
|
||||||
|
LOG(display,
|
||||||
|
"%s: MoveCursor pipe %c, (%d, %d)\n",
|
||||||
|
igt_output_name(output),
|
||||||
|
pipe_name(output->config.pipe),
|
||||||
|
x, y);
|
||||||
|
|
||||||
|
ret = drmModeMoveCursor(display->drm_fd, crtc_id, x, y);
|
||||||
|
|
||||||
|
igt_assert(ret == 0);
|
||||||
|
|
||||||
|
plane->position_changed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int igt_plane_commit(igt_plane_t *plane, igt_output_t *output)
|
||||||
|
{
|
||||||
|
if (plane->is_cursor)
|
||||||
|
igt_cursor_commit(plane, output);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int igt_output_commit(igt_output_t *output)
|
static int igt_output_commit(igt_output_t *output)
|
||||||
{
|
{
|
||||||
igt_display_t *display = output->display;
|
igt_display_t *display = output->display;
|
||||||
igt_pipe_t *pipe;
|
igt_pipe_t *pipe;
|
||||||
|
int i;
|
||||||
|
|
||||||
pipe = igt_output_get_driving_pipe(output);
|
pipe = igt_output_get_driving_pipe(output);
|
||||||
if (pipe->need_set_crtc) {
|
if (pipe->need_set_crtc) {
|
||||||
@ -1074,6 +1146,48 @@ static int igt_output_commit(igt_output_t *output)
|
|||||||
pipe->need_set_crtc = false;
|
pipe->need_set_crtc = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pipe->need_set_cursor) {
|
||||||
|
igt_plane_t *cursor;
|
||||||
|
uint32_t gem_handle, crtc_id;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
cursor = igt_pipe_get_plane(pipe, IGT_PLANE_CURSOR);
|
||||||
|
crtc_id = output->config.crtc->crtc_id;
|
||||||
|
gem_handle = igt_plane_get_fb_gem_handle(cursor);
|
||||||
|
|
||||||
|
if (gem_handle) {
|
||||||
|
LOG(display,
|
||||||
|
"%s: SetCursor pipe %c, fb %u %dx%d\n",
|
||||||
|
igt_output_name(output),
|
||||||
|
pipe_name(output->config.pipe),
|
||||||
|
gem_handle,
|
||||||
|
cursor->fb->width, cursor->fb->height);
|
||||||
|
|
||||||
|
ret = drmModeSetCursor(display->drm_fd, crtc_id,
|
||||||
|
gem_handle,
|
||||||
|
cursor->fb->width,
|
||||||
|
cursor->fb->height);
|
||||||
|
} else {
|
||||||
|
LOG(display,
|
||||||
|
"%s: SetCursor pipe %c, disabling\n",
|
||||||
|
igt_output_name(output),
|
||||||
|
pipe_name(output->config.pipe));
|
||||||
|
|
||||||
|
ret = drmModeSetCursor(display->drm_fd, crtc_id,
|
||||||
|
0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
igt_assert(ret == 0);
|
||||||
|
|
||||||
|
pipe->need_set_cursor = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < pipe->n_planes; i++) {
|
||||||
|
igt_plane_t *plane = &pipe->planes[i];
|
||||||
|
|
||||||
|
igt_plane_commit(plane, output);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1119,12 +1233,6 @@ void igt_output_set_pipe(igt_output_t *output, enum pipe pipe)
|
|||||||
output->pending_crtc_idx_mask = 1 << pipe;
|
output->pending_crtc_idx_mask = 1 << pipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
static igt_plane_t *igt_pipe_get_plane(igt_pipe_t *pipe, int index)
|
|
||||||
{
|
|
||||||
igt_assert(index >= 0 && index < pipe->n_planes);
|
|
||||||
return &pipe->planes[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
igt_plane_t *igt_ouput_get_plane(igt_output_t *output, enum igt_plane plane)
|
igt_plane_t *igt_ouput_get_plane(igt_output_t *output, enum igt_plane plane)
|
||||||
{
|
{
|
||||||
igt_pipe_t *pipe;
|
igt_pipe_t *pipe;
|
||||||
@ -1145,4 +1253,26 @@ void igt_plane_set_fb(igt_plane_t *plane, struct kmstest_fb *fb)
|
|||||||
|
|
||||||
if (plane->is_primary)
|
if (plane->is_primary)
|
||||||
pipe->need_set_crtc = true;
|
pipe->need_set_crtc = true;
|
||||||
|
else if (plane->is_cursor)
|
||||||
|
pipe->need_set_cursor = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void igt_plane_set_position(igt_plane_t *plane, int x, int y)
|
||||||
|
{
|
||||||
|
igt_pipe_t *pipe = plane->pipe;
|
||||||
|
igt_display_t *display = pipe->display;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX: Some platforms don't need the primary plane to cover the
|
||||||
|
* whole pipe. Of course this test becomes wrong when we support that.
|
||||||
|
*/
|
||||||
|
igt_assert(!plane->is_primary || (x == 0 && y == 0));
|
||||||
|
|
||||||
|
LOG(display, "%c.%d: plane_set_position(%d,%d)\n",
|
||||||
|
pipe_name(pipe->pipe), plane->index, x, y);
|
||||||
|
|
||||||
|
plane->crtc_x = x;
|
||||||
|
plane->crtc_y = y;
|
||||||
|
|
||||||
|
plane->position_changed = true;
|
||||||
}
|
}
|
||||||
|
@ -109,18 +109,24 @@ uint32_t drm_format_to_bpp(uint32_t drm_format);
|
|||||||
|
|
||||||
typedef struct igt_display igt_display_t;
|
typedef struct igt_display igt_display_t;
|
||||||
typedef struct igt_pipe igt_pipe_t;
|
typedef struct igt_pipe igt_pipe_t;
|
||||||
|
typedef uint32_t igt_fixed_t; /* 16.16 fixed point */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
igt_pipe_t *pipe;
|
igt_pipe_t *pipe;
|
||||||
int index;
|
int index;
|
||||||
unsigned int is_primary : 1;
|
unsigned int is_primary : 1;
|
||||||
|
unsigned int is_cursor : 1;
|
||||||
|
unsigned int position_changed : 1;
|
||||||
struct kmstest_fb *fb;
|
struct kmstest_fb *fb;
|
||||||
|
/* position within pipe_src_w x pipe_src_h */
|
||||||
|
int crtc_x, crtc_y;
|
||||||
} igt_plane_t;
|
} igt_plane_t;
|
||||||
|
|
||||||
struct igt_pipe {
|
struct igt_pipe {
|
||||||
igt_display_t *display;
|
igt_display_t *display;
|
||||||
enum pipe pipe;
|
enum pipe pipe;
|
||||||
unsigned int need_set_crtc : 1;
|
unsigned int need_set_crtc : 1;
|
||||||
|
unsigned int need_set_cursor : 1;
|
||||||
#define IGT_MAX_PLANES 4
|
#define IGT_MAX_PLANES 4
|
||||||
int n_planes;
|
int n_planes;
|
||||||
igt_plane_t planes[IGT_MAX_PLANES];
|
igt_plane_t planes[IGT_MAX_PLANES];
|
||||||
@ -158,10 +164,13 @@ void igt_output_set_pipe(igt_output_t *output, enum pipe pipe);
|
|||||||
igt_plane_t *igt_ouput_get_plane(igt_output_t *output, enum igt_plane plane);
|
igt_plane_t *igt_ouput_get_plane(igt_output_t *output, enum igt_plane plane);
|
||||||
|
|
||||||
void igt_plane_set_fb(igt_plane_t *plane, struct kmstest_fb *fb);
|
void igt_plane_set_fb(igt_plane_t *plane, struct kmstest_fb *fb);
|
||||||
|
void igt_plane_set_position(igt_plane_t *plane, int x, int y);
|
||||||
|
|
||||||
#define for_each_connected_output(display, output) \
|
#define for_each_connected_output(display, output) \
|
||||||
for (int i__ = 0; i__ < (display)->n_outputs; i__++) \
|
for (int i__ = 0; i__ < (display)->n_outputs; i__++) \
|
||||||
if ((output = &(display)->outputs[i__]), output->valid)
|
if ((output = &(display)->outputs[i__]), output->valid)
|
||||||
|
|
||||||
|
#define IGT_FIXED(i,f) ((i) << 16 | (f))
|
||||||
|
|
||||||
#endif /* __IGT_KMS_H__ */
|
#endif /* __IGT_KMS_H__ */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user