sync with OpenBSD -current

This commit is contained in:
purplerain 2024-01-31 02:14:33 +00:00
parent abc24a81d1
commit 921461fcd8
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
53 changed files with 2169 additions and 443 deletions

View file

@ -124,16 +124,36 @@ bo_create(int fd, unsigned int format,
int ret;
switch (format) {
case DRM_FORMAT_C1:
bpp = 1;
break;
case DRM_FORMAT_C2:
bpp = 2;
break;
case DRM_FORMAT_C4:
bpp = 4;
break;
case DRM_FORMAT_C8:
case DRM_FORMAT_NV12:
case DRM_FORMAT_NV21:
case DRM_FORMAT_NV16:
case DRM_FORMAT_NV61:
case DRM_FORMAT_NV24:
case DRM_FORMAT_NV42:
case DRM_FORMAT_YUV420:
case DRM_FORMAT_YVU420:
bpp = 8;
break;
case DRM_FORMAT_NV15:
case DRM_FORMAT_NV20:
case DRM_FORMAT_NV30:
bpp = 10;
break;
case DRM_FORMAT_ARGB4444:
case DRM_FORMAT_XRGB4444:
case DRM_FORMAT_ABGR4444:
@ -144,6 +164,7 @@ bo_create(int fd, unsigned int format,
case DRM_FORMAT_BGRX4444:
case DRM_FORMAT_ARGB1555:
case DRM_FORMAT_XRGB1555:
case DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN:
case DRM_FORMAT_ABGR1555:
case DRM_FORMAT_XBGR1555:
case DRM_FORMAT_RGBA5551:
@ -151,6 +172,7 @@ bo_create(int fd, unsigned int format,
case DRM_FORMAT_BGRA5551:
case DRM_FORMAT_BGRX5551:
case DRM_FORMAT_RGB565:
case DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN:
case DRM_FORMAT_BGR565:
case DRM_FORMAT_UYVY:
case DRM_FORMAT_VYUY:
@ -198,6 +220,7 @@ bo_create(int fd, unsigned int format,
switch (format) {
case DRM_FORMAT_NV12:
case DRM_FORMAT_NV21:
case DRM_FORMAT_NV15:
case DRM_FORMAT_YUV420:
case DRM_FORMAT_YVU420:
virtual_height = height * 3 / 2;
@ -205,9 +228,16 @@ bo_create(int fd, unsigned int format,
case DRM_FORMAT_NV16:
case DRM_FORMAT_NV61:
case DRM_FORMAT_NV20:
virtual_height = height * 2;
break;
case DRM_FORMAT_NV24:
case DRM_FORMAT_NV42:
case DRM_FORMAT_NV30:
virtual_height = height * 3;
break;
default:
virtual_height = height;
break;
@ -244,6 +274,8 @@ bo_create(int fd, unsigned int format,
case DRM_FORMAT_NV21:
case DRM_FORMAT_NV16:
case DRM_FORMAT_NV61:
case DRM_FORMAT_NV15:
case DRM_FORMAT_NV20:
offsets[0] = 0;
handles[0] = bo->handle;
pitches[0] = bo->pitch;
@ -255,6 +287,20 @@ bo_create(int fd, unsigned int format,
planes[1] = virtual + offsets[1];
break;
case DRM_FORMAT_NV24:
case DRM_FORMAT_NV42:
case DRM_FORMAT_NV30:
offsets[0] = 0;
handles[0] = bo->handle;
pitches[0] = bo->pitch;
pitches[1] = pitches[0] * 2;
offsets[1] = pitches[0] * height;
handles[1] = bo->handle;
planes[0] = virtual;
planes[1] = virtual + offsets[1];
break;
case DRM_FORMAT_YUV420:
case DRM_FORMAT_YVU420:
offsets[0] = 0;
@ -272,6 +318,9 @@ bo_create(int fd, unsigned int format,
planes[2] = virtual + offsets[2];
break;
case DRM_FORMAT_C1:
case DRM_FORMAT_C2:
case DRM_FORMAT_C4:
case DRM_FORMAT_C8:
case DRM_FORMAT_ARGB4444:
case DRM_FORMAT_XRGB4444:
@ -283,6 +332,7 @@ bo_create(int fd, unsigned int format,
case DRM_FORMAT_BGRX4444:
case DRM_FORMAT_ARGB1555:
case DRM_FORMAT_XRGB1555:
case DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN:
case DRM_FORMAT_ABGR1555:
case DRM_FORMAT_XBGR1555:
case DRM_FORMAT_RGBA5551:
@ -290,6 +340,7 @@ bo_create(int fd, unsigned int format,
case DRM_FORMAT_BGRA5551:
case DRM_FORMAT_BGRX5551:
case DRM_FORMAT_RGB565:
case DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN:
case DRM_FORMAT_BGR565:
case DRM_FORMAT_BGR888:
case DRM_FORMAT_RGB888:
@ -338,3 +389,22 @@ void bo_destroy(struct bo *bo)
free(bo);
}
void bo_dump(struct bo *bo, const char *filename)
{
FILE *fp;
if (!bo || !filename)
return;
fp = fopen(filename, "wb");
if (fp) {
void *addr;
bo_map(bo, &addr);
printf("Dumping buffer %p to file %s.\n", bo->ptr, filename);
fwrite(bo->ptr, 1, bo->size, fp);
bo_unmap(bo);
fclose(fp);
}
}

View file

@ -36,5 +36,6 @@ struct bo *bo_create(int fd, unsigned int format,
unsigned int handles[4], unsigned int pitches[4],
unsigned int offsets[4], enum util_fill_pattern pattern);
void bo_destroy(struct bo *bo);
void bo_dump(struct bo *bo, const char *filename);
#endif

View file

@ -25,5 +25,6 @@ modetest = executable(
include_directories : [inc_root, inc_tests, inc_drm],
dependencies : [dep_threads, dep_cairo],
link_with : [libdrm, libutil],
link_args: '-lm',
install : with_install_tests,
)

View file

@ -70,6 +70,7 @@
static enum util_fill_pattern primary_fill = UTIL_PATTERN_SMPTE;
static enum util_fill_pattern secondary_fill = UTIL_PATTERN_TILES;
static drmModeModeInfo user_mode;
struct crtc {
drmModeCrtc *crtc;
@ -128,6 +129,7 @@ struct device {
int use_atomic;
drmModeAtomicReq *req;
int32_t writeback_fence_fd;
};
static inline int64_t U642I64(uint64_t val)
@ -137,8 +139,19 @@ static inline int64_t U642I64(uint64_t val)
static float mode_vrefresh(drmModeModeInfo *mode)
{
return mode->clock * 1000.00
/ (mode->htotal * mode->vtotal);
unsigned int num, den;
num = mode->clock;
den = mode->htotal * mode->vtotal;
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
num *= 2;
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
den *= 2;
if (mode->vscan > 1)
den *= mode->vscan;
return num * 1000.00 / den;
}
#define bit_name_fn(res) \
@ -317,7 +330,7 @@ static void dump_in_formats(struct device *dev, uint32_t blob_id)
printf(": ");
}
printf(" %s", modifier_to_string(iter.mod));
printf(" %s(0x%"PRIx64")", modifier_to_string(iter.mod), iter.mod);
}
printf("\n");
@ -804,13 +817,15 @@ struct pipe_arg {
unsigned int num_cons;
uint32_t crtc_id;
char mode_str[64];
char format_str[5];
char format_str[8]; /* need to leave room for "_BE" and terminating \0 */
float vrefresh;
unsigned int fourcc;
drmModeModeInfo *mode;
struct crtc *crtc;
unsigned int fb_id[2], current_fb_id;
struct timeval start;
unsigned int out_fb_id;
struct bo *out_bo;
int swap_count;
};
@ -826,7 +841,7 @@ struct plane_arg {
unsigned int old_fb_id;
struct bo *bo;
struct bo *old_bo;
char format_str[5]; /* need to leave room for terminating \0 */
char format_str[8]; /* need to leave room for "_BE" and terminating \0 */
unsigned int fourcc;
};
@ -839,7 +854,25 @@ connector_find_mode(struct device *dev, uint32_t con_id, const char *mode_str,
int i;
connector = get_connector_by_id(dev, con_id);
if (!connector || !connector->count_modes)
if (!connector)
return NULL;
if (strchr(mode_str, ',')) {
i = sscanf(mode_str, "%hu,%hu,%hu,%hu,%hu,%hu,%hu,%hu",
&user_mode.hdisplay, &user_mode.hsync_start,
&user_mode.hsync_end, &user_mode.htotal,
&user_mode.vdisplay, &user_mode.vsync_start,
&user_mode.vsync_end, &user_mode.vtotal);
if (i == 8) {
user_mode.clock = roundf(user_mode.htotal * user_mode.vtotal * vrefresh / 1000);
user_mode.vrefresh = roundf(vrefresh);
snprintf(user_mode.name, sizeof(user_mode.name), "custom%dx%d", user_mode.hdisplay, user_mode.vdisplay);
return &user_mode;
}
}
if (!connector->count_modes)
return NULL;
/* Pick by Index */
@ -1040,7 +1073,7 @@ static bool set_property(struct device *dev, struct property_arg *p)
if (ret < 0)
fprintf(stderr, "failed to set %s %i property %s to %" PRIu64 ": %s\n",
obj_type, p->obj_id, p->name, p->value, strerror(errno));
obj_type, p->obj_id, p->name, p->value, strerror(-ret));
return true;
}
@ -1116,15 +1149,23 @@ static bool add_property_optional(struct device *dev, uint32_t obj_id,
static void set_gamma(struct device *dev, unsigned crtc_id, unsigned fourcc)
{
unsigned blob_id = 0;
const struct util_format_info *info;
/* TODO: support 1024-sized LUTs, when the use-case arises */
struct drm_color_lut gamma_lut[256];
int i, ret;
if (fourcc == DRM_FORMAT_C8) {
/* TODO: Add C8 support for more patterns */
util_smpte_c8_gamma(256, gamma_lut);
info = util_format_info_find(fourcc);
if (info->ncolors) {
memset(gamma_lut, 0, sizeof(gamma_lut));
/* TODO: Add index support for more patterns */
util_smpte_fill_lut(info->ncolors, gamma_lut);
drmModeCreatePropertyBlob(dev->fd, gamma_lut, sizeof(gamma_lut), &blob_id);
} else {
/*
* Initialize gamma_lut to a linear table for the legacy API below.
* The modern property API resets to a linear/pass-thru table if blob_id
* is 0, hence no PropertyBlob is created here.
*/
for (i = 0; i < 256; i++) {
gamma_lut[i].red =
gamma_lut[i].green =
@ -1135,6 +1176,7 @@ static void set_gamma(struct device *dev, unsigned crtc_id, unsigned fourcc)
add_property_optional(dev, crtc_id, "DEGAMMA_LUT", 0);
add_property_optional(dev, crtc_id, "CTM", 0);
if (!add_property_optional(dev, crtc_id, "GAMMA_LUT", blob_id)) {
/* If we can't add the GAMMA_LUT property, try the legacy API. */
uint16_t r[256], g[256], b[256];
for (i = 0; i < 256; i++) {
@ -1144,7 +1186,7 @@ static void set_gamma(struct device *dev, unsigned crtc_id, unsigned fourcc)
}
ret = drmModeCrtcSetGamma(dev->fd, crtc_id, 256, r, g, b);
if (ret)
if (ret && errno != ENOSYS)
fprintf(stderr, "failed to set gamma: %s\n", strerror(errno));
}
}
@ -1441,6 +1483,24 @@ static int pipe_resolve_connectors(struct device *dev, struct pipe_arg *pipe)
return 0;
}
static bool pipe_has_writeback_connector(struct device *dev, struct pipe_arg *pipes,
unsigned int count)
{
drmModeConnector *connector;
unsigned int i, j;
for (j = 0; j < count; j++) {
struct pipe_arg *pipe = &pipes[j];
for (i = 0; i < pipe->num_cons; i++) {
connector = get_connector_by_id(dev, pipe->con_ids[i]);
if (connector && connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
return true;
}
}
return false;
}
static int pipe_attempt_connector(struct device *dev, drmModeConnector *con,
struct pipe_arg *pipe)
{
@ -1503,7 +1563,8 @@ static int pipe_find_preferred(struct device *dev, struct pipe_arg **out_pipes)
for (i = 0; i < res->count_connectors; i++) {
con = res->connectors[i].connector;
if (!con || con->connection != DRM_MODE_CONNECTED)
if (!con || con->connection != DRM_MODE_CONNECTED ||
con->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
continue;
connected++;
}
@ -1550,32 +1611,35 @@ static struct plane *get_primary_plane_by_crtc(struct device *dev, struct crtc *
return NULL;
}
static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count)
static unsigned int set_mode(struct device *dev, struct pipe_arg **pipe_args, unsigned int count)
{
unsigned int i, j;
int ret, x = 0;
int preferred = count == 0;
struct pipe_arg *pipes;
for (i = 0; i < count; i++) {
struct pipe_arg *pipe = &pipes[i];
ret = pipe_resolve_connectors(dev, pipe);
if (ret < 0)
return;
ret = pipe_find_crtc_and_mode(dev, pipe);
if (ret < 0)
continue;
}
if (preferred) {
struct pipe_arg *pipe_args;
count = pipe_find_preferred(dev, &pipe_args);
count = pipe_find_preferred(dev, pipe_args);
if (!count) {
fprintf(stderr, "can't find any preferred connector/mode.\n");
return;
return 0;
}
pipes = *pipe_args;
} else {
pipes = *pipe_args;
for (i = 0; i < count; i++) {
struct pipe_arg *pipe = &pipes[i];
ret = pipe_resolve_connectors(dev, pipe);
if (ret < 0)
return 0;
ret = pipe_find_crtc_and_mode(dev, pipe);
if (ret < 0)
continue;
}
pipes = pipe_args;
}
if (!dev->use_atomic) {
@ -1602,7 +1666,7 @@ static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int co
if (bo_fb_create(dev->fd, pipes[0].fourcc, dev->mode.width, dev->mode.height,
primary_fill, &dev->mode.bo, &dev->mode.fb_id))
return;
return 0;
}
for (i = 0; i < count; i++) {
@ -1634,7 +1698,7 @@ static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int co
if (ret) {
fprintf(stderr, "failed to set mode: %s\n", strerror(errno));
return;
return 0;
}
set_gamma(dev, pipe->crtc_id, pipe->fourcc);
@ -1660,6 +1724,77 @@ static void set_mode(struct device *dev, struct pipe_arg *pipes, unsigned int co
}
}
}
return count;
}
static void writeback_config(struct device *dev, struct pipe_arg *pipes, unsigned int count)
{
drmModeConnector *connector;
unsigned int i, j;
for (j = 0; j < count; j++) {
struct pipe_arg *pipe = &pipes[j];
for (i = 0; i < pipe->num_cons; i++) {
connector = get_connector_by_id(dev, pipe->con_ids[i]);
if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) {
if (!pipe->mode) {
fprintf(stderr, "no mode for writeback\n");
return;
}
bo_fb_create(dev->fd, pipes[j].fourcc,
pipe->mode->hdisplay, pipe->mode->vdisplay,
UTIL_PATTERN_PLAIN,
&pipe->out_bo, &pipe->out_fb_id);
add_property(dev, pipe->con_ids[i], "WRITEBACK_FB_ID",
pipe->out_fb_id);
add_property(dev, pipe->con_ids[i], "WRITEBACK_OUT_FENCE_PTR",
(uintptr_t)(&dev->writeback_fence_fd));
}
}
}
}
static int poll_writeback_fence(int fd, int timeout)
{
struct pollfd fds = { fd, POLLIN };
int ret;
do {
ret = poll(&fds, 1, timeout);
if (ret > 0) {
if (fds.revents & (POLLERR | POLLNVAL))
return -EINVAL;
return 0;
} else if (ret == 0) {
return -ETIMEDOUT;
} else {
ret = -errno;
if (ret == -EINTR || ret == -EAGAIN)
continue;
return ret;
}
} while (1);
}
static void dump_output_fb(struct device *dev, struct pipe_arg *pipes, char *dump_path,
unsigned int count)
{
drmModeConnector *connector;
unsigned int i, j;
for (j = 0; j < count; j++) {
struct pipe_arg *pipe = &pipes[j];
for (i = 0; i < pipe->num_cons; i++) {
connector = get_connector_by_id(dev, pipe->con_ids[i]);
if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
bo_dump(pipe->out_bo, dump_path);
}
}
}
static void atomic_clear_mode(struct device *dev, struct pipe_arg *pipes, unsigned int count)
@ -1897,8 +2032,9 @@ static int parse_connector(struct pipe_arg *pipe, const char *arg)
}
if (*p == '@') {
strncpy(pipe->format_str, p + 1, 4);
pipe->format_str[4] = '\0';
len = sizeof(pipe->format_str) - 1;
strncpy(pipe->format_str, p + 1, len);
pipe->format_str[len] = '\0';
}
pipe->fourcc = util_format_fourcc(pipe->format_str);
@ -1912,6 +2048,7 @@ static int parse_connector(struct pipe_arg *pipe, const char *arg)
static int parse_plane(struct plane_arg *plane, const char *p)
{
unsigned int len;
char *end;
plane->plane_id = strtoul(p, &end, 10);
@ -1950,8 +2087,9 @@ static int parse_plane(struct plane_arg *plane, const char *p)
}
if (*end == '@') {
strncpy(plane->format_str, end + 1, 4);
plane->format_str[4] = '\0';
len = sizeof(plane->format_str) - 1;
strncpy(plane->format_str, end + 1, len);
plane->format_str[len] = '\0';
} else {
strcpy(plane->format_str, "XR24");
}
@ -1990,7 +2128,7 @@ static void parse_fill_patterns(char *arg)
static void usage(char *name)
{
fprintf(stderr, "usage: %s [-acDdefMPpsCvrw]\n", name);
fprintf(stderr, "usage: %s [-acDdefMoPpsCvrw]\n", name);
fprintf(stderr, "\n Query options:\n\n");
fprintf(stderr, "\t-c\tlist connectors\n");
@ -1999,14 +2137,19 @@ static void usage(char *name)
fprintf(stderr, "\t-p\tlist CRTCs and planes (pipes)\n");
fprintf(stderr, "\n Test options:\n\n");
fprintf(stderr, "\t-P <plane_id>@<crtc_id>:<w>x<h>[+<x>+<y>][*<scale>][@<format>]\tset a plane\n");
fprintf(stderr, "\t-s <connector_id>[,<connector_id>][@<crtc_id>]:[#<mode index>]<mode>[-<vrefresh>][@<format>]\tset a mode\n");
fprintf(stderr, "\t-P <plane_id>@<crtc_id>:<w>x<h>[+<x>+<y>][*<scale>][@<format>]\tset a plane, see 'plane-topology'\n");
fprintf(stderr, "\t-s <connector_id>[,<connector_id>][@<crtc_id>]:mode[@<format>]\tset a mode, see 'mode-topology'\n");
fprintf(stderr, "\t\twhere mode can be specified as:\n");
fprintf(stderr, "\t\t<hdisp>x<vdisp>[-<vrefresh>]\n");
fprintf(stderr, "\t\t<hdisp>,<hss>,<hse>,<htot>,<vdisp>,<vss>,<vse>,<vtot>-<vrefresh>\n");
fprintf(stderr, "\t\t#<mode index>\n");
fprintf(stderr, "\t-C\ttest hw cursor\n");
fprintf(stderr, "\t-v\ttest vsynced page flipping\n");
fprintf(stderr, "\t-r\tset the preferred mode for all connectors\n");
fprintf(stderr, "\t-w <obj_id>:<prop_name>:<value>\tset property\n");
fprintf(stderr, "\t-w <obj_id>:<prop_name>:<value>\tset property, see 'property'\n");
fprintf(stderr, "\t-a \tuse atomic API\n");
fprintf(stderr, "\t-F pattern1,pattern2\tspecify fill patterns\n");
fprintf(stderr, "\t-o <desired file path> \t Dump writeback output buffer to file\n");
fprintf(stderr, "\n Generic options:\n\n");
fprintf(stderr, "\t-d\tdrop master after mode set\n");
@ -2014,10 +2157,29 @@ static void usage(char *name)
fprintf(stderr, "\t-D device\tuse the given device\n");
fprintf(stderr, "\n\tDefault is to dump all info.\n");
fprintf(stderr, "\n");
fprintf(stderr, "Plane Topology is defined as:\n");
fprintf(stderr, "\tplane-topology\t::= plane-id '@' crtc-id ':' width 'x' height ( <plane-offsets> )? ;\n");
fprintf(stderr, "\tplane-offsets\t::= '+' x-offset '+' y-offset ( <plane-scale> )? ;\n");
fprintf(stderr, "\tplane-scale\t::= '*' scale ( <plane-format> )? ;\n");
fprintf(stderr, "\tplane-format\t::= '@' format ;\n");
fprintf(stderr, "\n");
fprintf(stderr, "Mode Topology is defined as:\n");
fprintf(stderr, "\tmode-topology\t::= connector-id ( ',' connector-id )* ( '@' crtc-id )? ':' <mode-selection> ( '@' format )? ;\n");
fprintf(stderr, "\tmode-selection\t::= <indexed-mode> | <named-mode> | <custom-mode> ;\n");
fprintf(stderr, "\tindexed-mode\t::= '#' mode-index ;\n");
fprintf(stderr, "\tnamed-mode\t::= width 'x' height ( '-' vrefresh )? ;\n");
fprintf(stderr, "\tcustom-mode\t::= hdisplay ',' hsyncstart ',' hsyncend ',' htotal ',' vdisplay ',' vsyncstart ',' vsyncend ',' vtotal '-' vrefresh ;\n");
fprintf(stderr, "\n");
fprintf(stderr, "Property is defined as:\n");
fprintf(stderr, "\tproperty\t::= object-id ':' property-name ':' value ;\n");
exit(0);
}
static char optstr[] = "acdD:efF:M:P:ps:Cvrw:";
static char optstr[] = "acdD:efF:M:P:ps:Cvrw:o:";
int main(int argc, char **argv)
{
@ -2040,6 +2202,7 @@ int main(int argc, char **argv)
struct property_arg *prop_args = NULL;
unsigned int args = 0;
int ret;
char *dump_path = NULL;
memset(&dev, 0, sizeof dev);
@ -2078,6 +2241,9 @@ int main(int argc, char **argv)
/* Preserve the default behaviour of dumping all information. */
args--;
break;
case 'o':
dump_path = optarg;
break;
case 'P':
plane_args = realloc(plane_args,
(plane_count + 1) * sizeof *plane_args);
@ -2143,8 +2309,8 @@ int main(int argc, char **argv)
if (!args)
encoders = connectors = crtcs = planes = framebuffers = 1;
if (test_vsync && !count) {
fprintf(stderr, "page flipping requires at least one -s option.\n");
if (test_vsync && !count && !set_preferred) {
fprintf(stderr, "page flipping requires at least one -s or -r option.\n");
return -1;
}
if (set_preferred && count) {
@ -2152,17 +2318,13 @@ int main(int argc, char **argv)
return -1;
}
if (set_preferred && plane_count) {
fprintf(stderr, "cannot use -r (preferred) when -P (plane) is set\n");
return -1;
}
dev.fd = util_open(device, module);
if (dev.fd < 0)
return -1;
if (use_atomic) {
ret = drmSetClientCap(dev.fd, DRM_CLIENT_CAP_ATOMIC, 1);
drmSetClientCap(dev.fd, DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
if (ret) {
fprintf(stderr, "no atomic modesetting support: %s\n", strerror(errno));
drmClose(dev.fd);
@ -2186,12 +2348,13 @@ int main(int argc, char **argv)
dump_resource(&dev, planes);
dump_resource(&dev, framebuffers);
if (dev.use_atomic)
dev.req = drmModeAtomicAlloc();
for (i = 0; i < prop_count; ++i)
set_property(&dev, &prop_args[i]);
if (dev.use_atomic) {
dev.req = drmModeAtomicAlloc();
if (set_preferred || (count && plane_count)) {
uint64_t cap = 0;
@ -2202,7 +2365,16 @@ int main(int argc, char **argv)
}
if (set_preferred || count)
set_mode(&dev, pipe_args, count);
count = set_mode(&dev, &pipe_args, count);
if (dump_path) {
if (!pipe_has_writeback_connector(&dev, pipe_args, count)) {
fprintf(stderr, "No writeback connector found, can not dump.\n");
return 1;
}
writeback_config(&dev, pipe_args, count);
}
if (plane_count)
atomic_set_planes(&dev, plane_args, plane_count, false);
@ -2213,6 +2385,18 @@ int main(int argc, char **argv)
return 1;
}
/*
* Since only writeback connectors have an output fb, this should only be
* called for writeback.
*/
if (dump_path) {
ret = poll_writeback_fence(dev.writeback_fence_fd, 1000);
if (ret)
fprintf(stderr, "Poll for writeback error: %d. Skipping Dump.\n",
ret);
dump_output_fb(&dev, pipe_args, dump_path, count);
}
if (test_vsync)
atomic_test_page_flip(&dev, pipe_args, plane_args, plane_count);
@ -2230,17 +2414,22 @@ int main(int argc, char **argv)
if (count)
atomic_clear_mode(&dev, pipe_args, count);
ret = drmModeAtomicCommit(dev.fd, dev.req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
if (ret)
fprintf(stderr, "Atomic Commit failed\n");
if (plane_count)
atomic_clear_FB(&dev, plane_args, plane_count);
}
ret = drmModeAtomicCommit(dev.fd, dev.req, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
if (ret)
fprintf(stderr, "Atomic Commit failed\n");
if (count && plane_count)
atomic_clear_FB(&dev, plane_args, plane_count);
drmModeAtomicFree(dev.req);
} else {
if (dump_path) {
fprintf(stderr, "writeback / dump is only supported in atomic mode\n");
return 1;
}
if (set_preferred || count || plane_count) {
uint64_t cap = 0;
@ -2251,7 +2440,7 @@ int main(int argc, char **argv)
}
if (set_preferred || count)
set_mode(&dev, pipe_args, count);
count = set_mode(&dev, &pipe_args, count);
if (plane_count)
set_planes(&dev, plane_args, plane_count);