10 #include <QOffscreenSurface>
11 #include <QOpenGLContext>
13 #include <QSurfaceFormat>
15 QGLWidget *global_share_widget = nullptr;
16 bool using_egl = false;
22 string get_pci_device_name(const char *node_name)
24 char vendor_path[256];
25 snprintf(vendor_path, sizeof(vendor_path), "/sys/class/drm/%s/device/vendor", node_name);
26 FILE *vendor_file = fopen(vendor_path, "r");
27 if (vendor_file == nullptr) {
28 return "could not look up vendor ID";
31 if (fscanf(vendor_file, "%i", &vendor) != 1) {
33 return "could not parse vendor ID";
37 char device_path[256];
38 snprintf(device_path, sizeof(device_path), "/sys/class/drm/%s/device/device", node_name);
39 FILE *device_file = fopen(device_path, "r");
40 if (device_file == nullptr) {
41 return "could not look up device ID";
44 if (fscanf(device_file, "%i", &device) != 1) {
46 return "could not parse device ID";
50 pci_access *pci = pci_alloc();
52 return "could not init libpci";
57 const char *name = pci_lookup_name(pci, buf, sizeof(buf), PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE, vendor, device);
60 if (name == nullptr) {
61 snprintf(buf, sizeof(buf), "%04x:%04x", vendor, device);
66 void print_available_drm_nodes()
69 int err = glob("/dev/dri/renderD*", 0, nullptr, &g); // TODO: Accept /dev/dri/card*, too?
71 fprintf(stderr, "Couldn't list render nodes (%s).\n", strerror(errno));
75 if (g.gl_pathc == 0) {
76 fprintf(stderr, "\n");
77 fprintf(stderr, "No render nodes found in /dev/dri.\n");
79 fprintf(stderr, "Available devices (these may or may not support VA-API encoding):\n\n");
80 for (size_t i = 0; i < g.gl_pathc; ++i) {
81 const char *node_name = basename(g.gl_pathv[i]);
82 fprintf(stderr, " %s (%s)\n", g.gl_pathv[i], get_pci_device_name(node_name).c_str());
91 QSurface *create_surface(const QSurfaceFormat &format)
93 QOffscreenSurface *surface = new QOffscreenSurface;
94 surface->setFormat(format);
96 if (!surface->isValid()) {
97 fprintf(stderr, "ERROR: surface not valid!\n");
99 fprintf(stderr, "\n\n");
100 fprintf(stderr, "OpenGL initialization failed. This is most likely because your driver does not\n");
101 fprintf(stderr, "support EGL (e.g. NVIDIA drivers). You can turn off EGL by specifying the\n");
102 fprintf(stderr, "VA-API path directly, assuming you have another GPU with VA-API support\n");
103 fprintf(stderr, "(typically an integrated Intel GPU -- note that it you might need to manually\n");
104 fprintf(stderr, "enable it in the BIOS, as it might be turned off when a discrete GPU is detected).\n");
105 fprintf(stderr, "\n");
106 fprintf(stderr, "Specify the VA-API device using “--va-display /dev/dri/<node>”.\n");
107 print_available_drm_nodes();
114 QSurface *create_surface_with_same_format(const QSurface *surface)
116 return create_surface(surface->format());
119 QOpenGLContext *create_context(const QSurface *surface)
121 QOpenGLContext *context = new QOpenGLContext;
122 context->setShareContext(global_share_widget->context()->contextHandle());
123 context->setFormat(surface->format());
128 bool make_current(QOpenGLContext *context, QSurface *surface)
130 return context->makeCurrent(surface);
133 void delete_context(QOpenGLContext *context)