diff --git a/src/platform/linux/kmsgrab.cpp b/src/platform/linux/kmsgrab.cpp index f608d950c4e..bfbe3935c1d 100644 --- a/src/platform/linux/kmsgrab.cpp +++ b/src/platform/linux/kmsgrab.cpp @@ -242,6 +242,23 @@ namespace platf { return -1; } + // Open the render node for this card to share with libva. + // If it fails, we'll just share the primary node instead. + char *rendernode_path = drmGetRenderDeviceNameFromFd(fd.el); + if (rendernode_path) { + BOOST_LOG(debug) << "Opening render node: "sv << rendernode_path; + render_fd.el = open(rendernode_path, O_RDWR); + if (render_fd.el < 0) { + BOOST_LOG(warning) << "Couldn't open render node: "sv << rendernode_path << ": "sv << strerror(errno); + render_fd.el = dup(fd.el); + } + free(rendernode_path); + } + else { + BOOST_LOG(warning) << "No render device name for: "sv << path; + render_fd.el = dup(fd.el); + } + if (drmSetClientCap(fd.el, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1)) { BOOST_LOG(error) << "Couldn't expose some/all drm planes for card: "sv << path; return -1; @@ -423,6 +440,7 @@ namespace platf { } file_t fd; + file_t render_fd; plane_res_t plane_res; }; @@ -846,7 +864,7 @@ namespace platf { std::unique_ptr make_avcodec_encode_device(pix_fmt_e pix_fmt) override { if (mem_type == mem_type_e::vaapi) { - return va::make_avcodec_encode_device(width, height, dup(card.fd.el), img_offset_x, img_offset_y, true); + return va::make_avcodec_encode_device(width, height, dup(card.render_fd.el), img_offset_x, img_offset_y, true); } BOOST_LOG(error) << "Unsupported pixel format for egl::display_vram_t: "sv << platf::from_pix_fmt(pix_fmt); @@ -966,7 +984,7 @@ namespace platf { return -1; } - if (!va::validate(card.fd.el)) { + if (!va::validate(card.render_fd.el)) { BOOST_LOG(warning) << "Monitor "sv << display_name << " doesn't support hardware encoding. Reverting back to GPU -> RAM -> GPU"sv; return -1; }