X-Git-Url: https://git.ti.com/gitweb?p=android%2Fexternal-libkmsxx.git;a=blobdiff_plain;f=utils%2Fkmstest.cpp;h=cfec7804bc2184ba88e5c8ff7607ea7de945605f;hp=cc895e3dde9496bec8c9ff47fa01e45b4421c582;hb=40b807f6d16562edc261414a39353471c006a331;hpb=84d3338b761ad6c58cc0f06291ece6ba6a3e962c diff --git a/utils/kmstest.cpp b/utils/kmstest.cpp index cc895e3..cfec780 100644 --- a/utils/kmstest.cpp +++ b/utils/kmstest.cpp @@ -9,6 +9,7 @@ #include #include +#include #include @@ -45,6 +46,9 @@ static bool s_use_cea; static unsigned s_num_buffers = 1; static bool s_flip_mode; static bool s_flip_sync; +static bool s_cvt; +static bool s_cvt_v2; +static bool s_cvt_vid_opt; static set s_used_crtcs; static set s_used_planes; @@ -101,67 +105,127 @@ static void get_default_crtc(Card& card, OutputInfo& output) static void parse_crtc(Card& card, const string& crtc_str, OutputInfo& output) { - // @12:1920x1200@60 - const regex mode_re("(?:(@?)(\\d+):)?" // @12: - "(?:(\\d+)x(\\d+)(i)?)" // 1920x1200i - "(?:@([\\d\\.]+))?"); // @60 + // @12:1920x1200i@60 + // @12:33000000,800/210/30/16/-,480/22/13/10/-,i + + const regex modename_re("(?:(@?)(\\d+):)?" // @12: + "(?:(\\d+)x(\\d+)(i)?)" // 1920x1200i + "(?:@([\\d\\.]+))?"); // @60 + + const regex modeline_re("(?:(@?)(\\d+):)?" // @12: + "(\\d+)," // 33000000, + "(\\d+)/(\\d+)/(\\d+)/(\\d+)/([+-])," // 800/210/30/16/-, + "(\\d+)/(\\d+)/(\\d+)/(\\d+)/([+-])" // 480/22/13/10/- + "(?:,([i]+))?" // ,i + ); smatch sm; - if (!regex_match(crtc_str, sm, mode_re)) - EXIT("Failed to parse crtc option '%s'", crtc_str.c_str()); + if (regex_match(crtc_str, sm, modename_re)) { + if (sm[2].matched) { + bool use_id = sm[1].length() == 1; + unsigned num = stoul(sm[2].str()); - if (sm[2].matched) { - bool use_id = sm[1].length() == 1; - unsigned num = stoul(sm[2].str()); + if (use_id) { + Crtc* c = card.get_crtc(num); + if (!c) + EXIT("Bad crtc id '%u'", num); - if (use_id) { - Crtc* c = card.get_crtc(num); - if (!c) - EXIT("Bad crtc id '%u'", num); + output.crtc = c; + } else { + auto crtcs = card.get_crtcs(); - output.crtc = c; - } else { - auto crtcs = card.get_crtcs(); + if (num >= crtcs.size()) + EXIT("Bad crtc number '%u'", num); - if (num >= crtcs.size()) - EXIT("Bad crtc number '%u'", num); + output.crtc = crtcs[num]; + } + } else { + output.crtc = output.connector->get_current_crtc(); + } - output.crtc = crtcs[num]; + unsigned w = stoul(sm[3]); + unsigned h = stoul(sm[4]); + bool ilace = sm[5].matched ? true : false; + float refresh = sm[6].matched ? stof(sm[6]) : 0; + + if (s_cvt) { + output.mode = videomode_from_cvt(w, h, refresh, ilace, s_cvt_v2, s_cvt_vid_opt); + } else if (s_use_dmt) { + try { + output.mode = find_dmt(w, h, refresh, ilace); + } catch (exception& e) { + EXIT("Mode not found from DMT tables\n"); + } + } else if (s_use_cea) { + try { + output.mode = find_cea(w, h, refresh, ilace); + } catch (exception& e) { + EXIT("Mode not found from CEA tables\n"); + } + } else { + try { + output.mode = output.connector->get_mode(w, h, refresh, ilace); + } catch (exception& e) { + EXIT("Mode not found from the connector\n"); + } } - } else { - output.crtc = output.connector->get_current_crtc(); - } + } else if (regex_match(crtc_str, sm, modeline_re)) { + if (sm[2].matched) { + bool use_id = sm[1].length() == 1; + unsigned num = stoul(sm[2].str()); - unsigned w = stoul(sm[3]); - unsigned h = stoul(sm[4]); - bool ilace = sm[5].matched ? true : false; - float refresh = sm[6].matched ? stof(sm[6]) : 0; + if (use_id) { + Crtc* c = card.get_crtc(num); + if (!c) + EXIT("Bad crtc id '%u'", num); - bool found_mode = false; + output.crtc = c; + } else { + auto crtcs = card.get_crtcs(); - try { - output.mode = output.connector->get_mode(w, h, refresh, ilace); - found_mode = true; - } catch (exception& e) { } + if (num >= crtcs.size()) + EXIT("Bad crtc number '%u'", num); - if (!found_mode && s_use_dmt) { - try { - output.mode = find_dmt(w, h, refresh, ilace); - found_mode = true; - printf("Found mode from DMT\n"); - } catch (exception& e) { } - } + output.crtc = crtcs[num]; + } + } else { + output.crtc = output.connector->get_current_crtc(); + } - if (!found_mode && s_use_cea) { - try { - output.mode = find_cea(w, h, refresh, ilace); - found_mode = true; - printf("Found mode from CEA\n"); - } catch (exception& e) { } + unsigned clock = stoul(sm[3]); + + unsigned hact = stoul(sm[4]); + unsigned hfp = stoul(sm[5]); + unsigned hsw = stoul(sm[6]); + unsigned hbp = stoul(sm[7]); + bool h_pos_sync = sm[8] == "+" ? true : false; + + unsigned vact = stoul(sm[9]); + unsigned vfp = stoul(sm[10]); + unsigned vsw = stoul(sm[11]); + unsigned vbp = stoul(sm[12]); + bool v_pos_sync = sm[13] == "+" ? true : false; + + output.mode = videomode_from_timings(clock / 1000, hact, hfp, hsw, hbp, vact, vfp, vsw, vbp); + output.mode.set_hsync(h_pos_sync ? SyncPolarity::Positive : SyncPolarity::Negative); + output.mode.set_vsync(v_pos_sync ? SyncPolarity::Positive : SyncPolarity::Negative); + + if (sm[14].matched) { + for (int i = 0; i < sm[14].length(); ++i) { + char f = string(sm[14])[i]; + + switch (f) { + case 'i': + output.mode.set_interlace(true); + break; + default: + EXIT("Bad mode flag %c", f); + } + } + } + } else { + EXIT("Failed to parse crtc option '%s'", crtc_str.c_str()); } - - if (!found_mode) - throw invalid_argument("Mode not found"); } static void parse_plane(Card& card, const string& plane_str, const OutputInfo& output, PlaneInfo& pinfo) @@ -274,10 +338,13 @@ static const char* usage_str = " --device=DEVICE DEVICE is the path to DRM card to open\n" " -c, --connector=CONN CONN is \n" " -r, --crtc=CRTC CRTC is [:]x[@]\n" + " or\n" + " [:],////,////[,i]\n" " -p, --plane=PLANE PLANE is [:][,-]x\n" " -f, --fb=FB FB is [x][-][<4cc>]\n" " --dmt Search for the given mode from DMT tables\n" " --cea Search for the given mode from CEA tables\n" + " --cvt=CVT Create videomode with CVT. CVT is 'v1', 'v2' or 'v2o'\n" " --flip Do page flipping for each output\n" " --sync Synchronize page flipping\n" "\n" @@ -366,6 +433,19 @@ static vector parse_cmdline(int argc, char **argv) { s_flip_sync = true; }), + Option("|cvt=", [&](string s) + { + if (s == "v1") + s_cvt = true; + else if (s == "v2") + s_cvt = s_cvt_v2 = true; + else if (s == "v2o") + s_cvt = s_cvt_v2 = s_cvt_vid_opt = true; + else { + usage(); + exit(-1); + } + }), Option("h|help", [&]() { usage(); @@ -604,20 +684,20 @@ static void set_crtcs_n_planes(Card& card, const vector& outputs) auto conn = o.connector; auto crtc = o.crtc; - if (!o.fbs.empty()) { - auto fb = o.fbs[0]; + blobs.emplace_back(o.mode.to_blob(card)); + Blob* mode_blob = blobs.back().get(); - blobs.emplace_back(o.mode.to_blob(card)); - Blob* mode_blob = blobs.back().get(); + req.add(conn, { + { "CRTC_ID", crtc->id() }, + }); - req.add(conn, { - { "CRTC_ID", crtc->id() }, - }); + req.add(crtc, { + { "ACTIVE", 1 }, + { "MODE_ID", mode_blob->id() }, + }); - req.add(crtc, { - { "ACTIVE", 1 }, - { "MODE_ID", mode_blob->id() }, - }); + if (!o.fbs.empty()) { + auto fb = o.fbs[0]; req.add(o.primary_plane, { { "FB_ID", fb->id() },