diff --git a/drmu/drmu_output.c b/drmu/drmu_output.c index c6a9eaf..7797e29 100644 --- a/drmu/drmu_output.c +++ b/drmu/drmu_output.c @@ -472,13 +472,12 @@ try_conn_crtc(drmu_env_t * du, drmu_conn_t * dn, drmu_crtc_t * dc) } int -drmu_atomic_output_add_writeback_fb(drmu_atomic_t * const da_out, drmu_output_t * const dout, - drmu_fb_t * const dfb) +drmu_atomic_output_add_writeback_fb_mode(drmu_atomic_t * const da_out, drmu_output_t * const dout, + drmu_fb_t * const dfb, const struct drm_mode_modeinfo *mode) { drmu_env_t * const du = dout->du; drmu_atomic_t * da = drmu_atomic_new(drmu_atomic_env(da_out)); int rv = -ENOMEM; - struct drm_mode_modeinfo mode = modeinfo_fake(drmu_fb_width(dfb), drmu_fb_height(dfb)); drmu_conn_t * const dn = dout->dns[0]; if (da == NULL) @@ -488,7 +487,7 @@ drmu_atomic_output_add_writeback_fb(drmu_atomic_t * const da_out, drmu_output_t drmu_err(du, "Failed to add FB to conn"); goto fail; } - if ((rv = drmu_atomic_crtc_add_modeinfo(da, dout->dc, &mode)) != 0) { + if ((rv = drmu_atomic_crtc_add_modeinfo(da, dout->dc, mode)) != 0) { drmu_err(du, "Failed to add modeinfo to CRTC"); goto fail; } @@ -508,6 +507,15 @@ drmu_atomic_output_add_writeback_fb(drmu_atomic_t * const da_out, drmu_output_t return rv; } +int +drmu_atomic_output_add_writeback_fb(drmu_atomic_t * const da_out, drmu_output_t * const dout, + drmu_fb_t * const dfb) +{ + struct drm_mode_modeinfo mode = modeinfo_fake(drmu_fb_width(dfb), drmu_fb_height(dfb)); + + return drmu_atomic_output_add_writeback_fb_mode(da_out, dout, dfb, &mode); +} + int drmu_output_add_writeback(drmu_output_t * const dout) { diff --git a/drmu/drmu_output.h b/drmu/drmu_output.h index 5ec2d71..96fe2ff 100644 --- a/drmu/drmu_output.h +++ b/drmu/drmu_output.h @@ -55,6 +55,9 @@ int drmu_output_modeset_allow(drmu_output_t * const dout, const bool allow); // If != NULL then 1st conn with prefix-matching name is used int drmu_output_add_output(drmu_output_t * const dout, const char * const conn_name); +// Set writeback fb on output with user specified mode +int drmu_atomic_output_add_writeback_fb_mode(drmu_atomic_t * const da_req, drmu_output_t * const dout, + drmu_fb_t * const dfb, const struct drm_mode_modeinfo *mode); // Set writeback fb on output int drmu_atomic_output_add_writeback_fb(drmu_atomic_t * const da_req, drmu_output_t * const dout, drmu_fb_t * const dfb); diff --git a/test/10bittest.c b/test/10bittest.c index 93b29fd..fbb6a11 100644 --- a/test/10bittest.c +++ b/test/10bittest.c @@ -301,6 +301,7 @@ usage() "-M drm module name, default: " DRM_MODULE "\n" "-v verbose\n" "-w write to writeback rather than screen, then writen to wb.rgb\n" + "-t transpose writeback output\n" "\n" "Hit return to exit\n" "\n" @@ -311,6 +312,25 @@ usage() exit(1); } +static void create_drm_mode(struct drm_mode_modeinfo * mode, int width, int height) +{ + mode->clock = width * height * 60; + mode->hdisplay = width; + mode->hsync_start = width; + mode->hsync_end = width; + mode->htotal = width; + mode->hskew = 0; + mode->vdisplay = height; + mode->vsync_start = height; + mode->vsync_end = height; + mode->vtotal = height; + mode->vscan = 0; + mode->vrefresh = 60; + mode->type = DRM_MODE_TYPE_USERDEF; + mode->flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC; + strcpy(mode->name, "fake"); +} + int main(int argc, char *argv[]) { drmu_env_t * du = NULL; @@ -338,7 +358,7 @@ int main(int argc, char *argv[]) bool mode_req = false; bool hi_bpc = true; bool dofrac = false; - bool try_writeback = false; + bool try_writeback = false, try_transpose = false; int verbose = 0; int c; uint64_t fillval = p16val(~0U, 0x8000, 0x8000, 0x8000); @@ -346,7 +366,7 @@ int main(int argc, char *argv[]) unsigned int p16_stride = 0; int rv; - while ((c = getopt(argc, argv, "8c:e:f:FgpM:P:r:R:svwy")) != -1) { + while ((c = getopt(argc, argv, "8c:e:f:FgpM:P:r:R:stvwy")) != -1) { switch (c) { case 'c': colorspace = optarg; @@ -431,6 +451,9 @@ int main(int argc, char *argv[]) case 'w': try_writeback = true; break; + case 't': + try_transpose = true; + break; case 'v': ++verbose; break; @@ -498,17 +521,22 @@ int main(int argc, char *argv[]) drmu_output_max_bpc_allow(dout, hi_bpc); if (try_writeback) { + struct drm_mode_modeinfo mode = { 0 }; + if (!mp.width || !mp.height) { mp.width = 1920; mp.height = 1080; } + printf("Try writeback %dx%d\n", mp.width, mp.height); - if ((fb_out = drmu_fb_new_dumb(du, mp.width, mp.height, DRM_FORMAT_ARGB8888)) == NULL) { + if ((fb_out = drmu_fb_new_dumb(du, try_transpose ? mp.height : mp.width, + try_transpose ? mp.width : mp.height, DRM_FORMAT_ARGB8888)) == NULL) { printf("Failed to create fb-out\n"); goto fail; } - if (drmu_atomic_output_add_writeback_fb(da, dout, fb_out) != 0) { + create_drm_mode(&mode , mp.width, (mp.height + 15) & ~15); + if (drmu_atomic_output_add_writeback_fb_mode(da, dout, fb_out, &mode) != 0) { printf("Failed to add writeback fb\n"); goto fail; }