kmscon: replace gpu selection modes with new --gpu option

Instead of using one option for each selection mode, we now provide a new
option --gpus. It takes as argument the selection mode to use.

We also remove the --video-devices option as it doesn't fit into the big
picture. Instead, we should provide a blacklist and users would then use
--gpu=all --blacklist-video=<blacklist> instead.

However, blacklisting is also required for input devices and until we
figure it out, we will provide no blacklisting at all.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
David Herrmann 2012-12-06 11:36:46 +01:00
parent b18cf69663
commit b972ebb102
4 changed files with 80 additions and 56 deletions

View File

@ -126,14 +126,10 @@ static void print_help()
"\t Create new terminal session\n"
"\n"
"Video Options:\n"
"\t --video-devices <d1,d2> [all] List of video devices to be used\n"
"\t by kmscon. This can be a list of\n"
"\t paths to /dev/* or \"all\"\n"
"\t --drm [on] Use DRM if available\n"
"\t --hwaccel [off] Use 3D hardware-acceleration if\n"
"\t available\n"
"\t --primary-gpu-only [off] Use primary GPU only\n"
"\t --all-gpus [on] Use all GPUs unconditionally\n"
"\t --gpus={all,aux,primary}[all] GPU selection mode\n"
"\t --render-engine <eng> [-] Console renderer\n"
"\t --render-timing [off] Print renderer timing information\n"
"\n"
@ -350,6 +346,56 @@ static int file_login(struct conf_option *opt, bool on, const char *arg)
return 0;
}
/*
* GPU selection type
* The GPU selection mode is a simple string to enum parser.
*/
static void conf_default_gpus(struct conf_option *opt)
{
conf_uint.set_default(opt);
}
static void conf_free_gpus(struct conf_option *opt)
{
conf_uint.free(opt);
}
static int conf_parse_gpus(struct conf_option *opt, bool on, const char *arg)
{
struct kmscon_conf_t *conf = KMSCON_CONF_FROM_FIELD(opt->mem, gpus);
unsigned int mode;
if (!strcmp(arg, "all")) {
mode = KMSCON_GPU_ALL;
} else if (!strcmp(arg, "aux") || !strcmp(arg, "auxiliary")) {
mode = KMSCON_GPU_AUX;
} else if (!strcmp(arg, "primary") || !strcmp(arg, "single")) {
mode = KMSCON_GPU_PRIMARY;
} else {
log_error("invalid GPU selection mode --gpus='%s'", arg);
return -EFAULT;
}
opt->type->free(opt);
conf->gpus = mode;
return 0;
}
static int conf_copy_gpus(struct conf_option *opt,
const struct conf_option *src)
{
return conf_uint.copy(opt, src);
}
static const struct conf_type conf_gpus = {
.flags = CONF_HAS_ARG,
.set_default = conf_default_gpus,
.free = conf_free_gpus,
.parse = conf_parse_gpus,
.copy = conf_copy_gpus,
};
/*
* Custom Afterchecks
* Several other options have side-effects on other options. We use afterchecks
@ -423,8 +469,6 @@ static int aftercheck_vt(struct conf_option *opt, int argc, char **argv,
static char *def_seats[] = { "seat0", NULL };
static char *def_video_devices[] = { "all", NULL };
static struct conf_grab def_grab_scroll_up =
CONF_SINGLE_GRAB(SHL_SHIFT_MASK, XKB_KEY_Up);
@ -510,11 +554,9 @@ int kmscon_conf_new(struct conf_ctx **out)
CONF_OPTION_GRAB(0, "grab-terminal-new", &conf->grab_terminal_new, &def_grab_terminal_new),
/* Video Options */
CONF_OPTION_STRING_LIST(0, "video-devices", &conf->video_devices, def_video_devices),
CONF_OPTION_BOOL_FULL(0, "drm", aftercheck_drm, NULL, NULL, &conf->drm, true),
CONF_OPTION_BOOL(0, "hwaccel", &conf->hwaccel, false),
CONF_OPTION_BOOL(0, "primary-gpu-only", &conf->primary_gpu_only, false),
CONF_OPTION_BOOL(0, "all-gpus", &conf->all_gpus, true),
CONF_OPTION(0, 0, "gpus", &conf_gpus, NULL, NULL, NULL, &conf->gpus, KMSCON_GPU_ALL),
CONF_OPTION_STRING(0, "render-engine", &conf->render_engine, NULL),
CONF_OPTION_BOOL(0, "render-timing", &conf->render_timing, false),

View File

@ -37,6 +37,12 @@
#include "conf.h"
#include "shl_dlist.h"
enum kmscon_conf_gpu_selection {
KMSCON_GPU_ALL,
KMSCON_GPU_AUX,
KMSCON_GPU_PRIMARY,
};
struct kmscon_conf_t {
/* General Options */
/* show help/usage information */
@ -115,19 +121,15 @@ struct kmscon_conf_t {
struct conf_grab *grab_terminal_new;
/* Video Options */
/* whitelist of usable video devices or "all" */
char **video_devices;
/* use DRM if available */
bool drm;
/* use 3D hardware-acceleration if available */
bool hwaccel;
/* use only primary GPU */
bool primary_gpu_only;
/* use all GPUs unconditionally */
bool all_gpus;
/* gpu selection mode */
unsigned int gpus;
/* render engine */
char *render_engine;
/* print rendering engine timing information */
/* print render-engine timing information */
bool render_timing;
/* Font Options */

View File

@ -216,26 +216,13 @@ static void app_seat_video_event(struct uterm_video *video,
}
}
static bool app_seat_is_ignored(struct app_seat *seat,
unsigned int type,
bool drm_backed,
bool primary,
bool aux,
const char *node)
static bool app_seat_gpu_is_ignored(struct app_seat *seat,
unsigned int type,
bool drm_backed,
bool primary,
bool aux,
const char *node)
{
unsigned int i;
if (!shl_string_list_is(seat->conf->video_devices, "all")) {
for (i = 0; seat->conf->video_devices[i]; ++i) {
if (!strcmp(seat->conf->video_devices[i], node))
return false;
}
log_info("ignoring video device %s on seat %s as it is not in the whitelist",
node, seat->name);
return true;
}
switch (type) {
case UTERM_MONITOR_FBDEV:
if (seat->conf->drm) {
@ -244,11 +231,6 @@ static bool app_seat_is_ignored(struct app_seat *seat,
node, seat->name);
return true;
}
if (primary) {
log_info("ignoring video device %s on seat %s as it is a primary fbdev device",
node, seat->name);
return true;
}
}
break;
case UTERM_MONITOR_DRM:
@ -264,13 +246,13 @@ static bool app_seat_is_ignored(struct app_seat *seat,
return true;
}
if (seat->conf->primary_gpu_only && !primary) {
if (seat->conf->gpus == KMSCON_GPU_PRIMARY && !primary) {
log_info("ignoring video device %s on seat %s as it is no primary GPU",
node, seat->name);
return true;
}
if (!seat->conf->all_gpus && !primary && !aux) {
if (seat->conf->gpus == KMSCON_GPU_AUX && !primary && !aux) {
log_info("ignoring video device %s on seat %s as it is neither a primary nor auxiliary GPU",
node, seat->name);
return true;
@ -289,11 +271,11 @@ static int app_seat_add_video(struct app_seat *seat,
unsigned int mode;
struct app_video *vid;
if (app_seat_is_ignored(seat, type,
flags & UTERM_MONITOR_DRM_BACKED,
flags & UTERM_MONITOR_PRIMARY,
flags & UTERM_MONITOR_AUX,
node))
if (app_seat_gpu_is_ignored(seat, type,
flags & UTERM_MONITOR_DRM_BACKED,
flags & UTERM_MONITOR_PRIMARY,
flags & UTERM_MONITOR_AUX,
node))
return -ERANGE;
log_debug("new video device %s on seat %s", node, seat->name);

View File

@ -401,14 +401,12 @@ static int get_fb_id(struct udev_device *dev)
* used as additional GPU together with but also independent of the primary GPU.
*
* UTERM_MONITOR_PRIMARY:
* A primary GPU is a GPU that can be used independently. An application
* can always use such CPUs without getting into troubles. For instance, under
* dual-GPU systems, there is often only one display controller but both DRM
* devices advertice modesetting capability. The application can now rely on
* this flag to mark the GPU that actually should be used for modesetting. The
* other GPU is neither PRIMARY nor AUX and shouldn't be used by the application
* except for offloading rendering-work or similar.
* Note, that multiple GPUs can be marked primary (including fbdev devices).
* A primary GPU is the main GPU in the system which is used to display boot
* graphics. Older systems used to have them hardwired, but especially embedded
* systems tend to no longer have primary GPUs so this flag cannot be guaranteed
* to be set for all systems.
* Hence, this flag shouldn't be used by default but rather as fallback if the
* user selects "primary GPU only" flag or similar.
*/
static unsigned int get_fbdev_flags(struct uterm_monitor *mon, const char *node)