QtアプリケーションからのGPU(vivante)利用について

Torizon OS上でQtアプリケーションコンテナ(qtdemo-debug)を開発中です。
Qtアプリのグラフィック描画速度向上のため、GPU使用を検討していて、Qt6のGPUコンテナ(torizon/qt6-wayland-vivante:3)も起動するようにdocker-compose.ymlを修正して起動したところ、
qt6-wayland-vivanteコンテナが起動後、すぐに停止状態になり、GPUが使用できない状態です。
アプリケーション自体は、GPUを使用していない状態で起動できています。

試したこと:
docker-compose.ymlで、westonコンテナ(torizon/weston-vivante:3)を起動することで、QtアプリケーションがGPUを使用していない状態で起動できていました。
そこで、docker-compose.ymlファイルにtorizon/qt6-wayland-vivante:3を起動するように以下のように修正しました。

(修正前 docker-compose.yml)

version: "3.9"
services:
  qtdemo-debug:
    build:
      context: .
      dockerfile: Dockerfile.debug
    image: ${LOCAL_REGISTRY}:5002/pxtqtdemo-debug:${TAG}
    ports:
      # SSH debug
      - 2231:2231
      # gdbserver
      - 2232:2232
      # qml debug
      - 2233:2233
    devices:
      - "/dev/ttyRPMSG31:/dev/ttyRPMSG31" 
      - "/dev/snd"
    volumes:
      - type: bind
        source: /tmp
        target: /tmp
      - type: bind
        source: /dev
        target: /dev
        read_only: false
      - type: bind
        bind:
          propagation: shared
        source: /media
        target: /media

    device_cgroup_rules:
      # ... for tty0
      - "c 4:0 rmw"
      # ... for tty7
      - "c 4:7 rmw"
      # ... for /dev/input devices
      - "c 13:* rmw"
      - "c 199:* rmw"
      # ... for /dev/dri devices
      - "c 226:* rmw"
    depends_on: [
      weston
    ]

  weston:
    image: torizon/weston-vivante:3
    environment:
      - ACCEPT_FSL_EULA=1
    # Required to get udev events from host udevd via netlink
    network_mode: host
    volumes:
      - type: bind
        source: /tmp
        target: /tmp
      - type: bind
        source: /dev
        target: /dev
      - type: bind
        source: /run/udev
        target: /run/udev
      - type: bind
        source: /etc/xdg/weston/
        target: /etc/xdg/weston/
    cap_add:
      - CAP_SYS_TTY_CONFIG
    # Add device access rights through cgroup...
    device_cgroup_rules:
      # ... for tty0
      - "c 4:0 rmw"
      # ... for tty1
      - "c 4:1 rmw"
      # ... for tty7
      - "c 4:7 rmw"
      # ... for /dev/input devices
      - "c 13:* rmw"
      - "c 199:* rmw"
      # ... for /dev/dri devices
      - "c 226:* rmw"

(修正後 docker-compose.yml)

version: "3.9"
services:
  qtdemo-debug:
    build:
      context: .
      dockerfile: Dockerfile.debug
    image: ${LOCAL_REGISTRY}:5002/pxtqtdemo-debug:${TAG}
    ports:
      # SSH debug
      - 2231:2231
      # gdbserver
      - 2232:2232
      # qml debug
      - 2233:2233
    devices:
      - "/dev/ttyRPMSG31:/dev/ttyRPMSG31" 
      - "/dev/snd"
    volumes:
      - type: bind
        source: /tmp
        target: /tmp
      - type: bind
        source: /dev
        target: /dev
        read_only: false
      - type: bind
        bind:
          propagation: shared
        source: /media
        target: /media

    device_cgroup_rules:
      # ... for tty0
      - "c 4:0 rmw"
      # ... for tty7
      - "c 4:7 rmw"
      # ... for /dev/input devices
      - "c 13:* rmw"
      - "c 199:* rmw"
      # ... for /dev/dri devices
      - "c 226:* rmw"
    depends_on:
      qt6:
        condition: service_started

  weston:
    image: torizon/weston-vivante:3
    environment:
      - ACCEPT_FSL_EULA=1
    # Required to get udev events from host udevd via netlink
    network_mode: host
    volumes:
      - type: bind
        source: /tmp
        target: /tmp
      - type: bind
        source: /dev
        target: /dev
      - type: bind
        source: /run/udev
        target: /run/udev
      - type: bind
        source: /etc/xdg/weston/
        target: /etc/xdg/weston/
    cap_add:
      - CAP_SYS_TTY_CONFIG
    # Add device access rights through cgroup...
    device_cgroup_rules:
      # ... for tty0
      - "c 4:0 rmw"
      # ... for tty1
      - "c 4:1 rmw"
      # ... for tty7
      - "c 4:7 rmw"
      # ... for /dev/input devices
      - "c 13:* rmw"
      - "c 199:* rmw"
      # ... for /dev/dri devices
      - "c 226:* rmw"

  qt6:
    image: torizon/qt6-wayland${GPU}:3
    environment:
      - ACCEPT_FSL_EULA=1
      - QT_QPA_PLATFORM=wayland
    volumes:
      - /tmp:/tmp
      - /dev:/dev
    device_cgroup_rules:
      # ... for tty0
      - "c 4:0 rmw"
      # ... for tty1
      - "c 4:1 rmw"
      # ... for tty7
      - "c 4:7 rmw"
      # ... for /dev/input devices
      - "c 13:* rmw"
      - "c 199:* rmw"
      # ... for /dev/dri devices
      - "c 226:* rmw"
    depends_on:
      weston:
        condition: service_started

質問1:
Torizon OS上で動作するQtアプリケーションからGPU(vivante)を使用するには、weston-vivanteコンテナとqt6-wayland-vivanteコンテナを両方動作させる必要があるという認識であっていますか。

質問2:
質問1の認識が間違いない場合、qt6-wayland-vivanteコンテナを動作させ、QtアプリケーションからGPUを使用する方法を教えて欲しいです。

1 Like

Hi, I’m the Toradex AI Assistant.

I might make mistakes. Our support team will step in if needed. If I answered your question, please tick the “Solution” checkbox. For follow-up questions to me, please use @ToradexAI in your post.

Did you like my answer? :+1: :-1:


こんにちは、ご質問ありがとうございます。

質問1への回答

Qt6アプリケーションでGPUを使用するには、Westonコンテナ(torizon/weston-vivante:3)だけが必要です。
qt6-wayland-vivanteコンテナは、Qt6ベースライブラリを持つ「アプリ実行用のベース」コンテナです。
Qtアプリケーションは、Westonコンテナ(Waylandサーバ)経由でGPUアクセラレーションを利用できます。
つまり、Westonコンテナ+(自身の)Qt6アプリケーションコンテナ、の2つサービス構成が一般的です。

詳しくは下記公式ガイドを参照してください:

質問2への回答

Westonコンテナを正しく起動していれば、Qt6アプリケーションはGPUによる描画高速化が利用できます。
qt6-wayland-vivanteコンテナを「別で」動かす必要はありません。

正しいdocker-compose.yml構成例:

  • weston サービス: Waylandコンポジタ
  • qtdemo-debug サービス: Qtアプリケーション(この中にQt6が含まれる)

GPUアクセラレーションが有効な状態にするポイント

  • Qtアプリケーションのコンテナは /dev/galcore デバイスを利用できるようにマウントします。
  • 必要に応じて ACCEPT_FSL_EULA=1 環境変数も設定します。

docker-compose.yml設定例(一部抜粋):

services:
  qtdemo-debug:
    # ...その他の設定
    devices:
      - "/dev/galcore:/dev/galcore"
      - "/dev/snd"
      # ほかの必要デバイスがあれば追加
    environment:
      - ACCEPT_FSL_EULA=1
    depends_on:
      weston

  weston:
    image: torizon/weston-vivante:3
    environment:
      - ACCEPT_FSL_EULA=1
    network_mode: host
    # volumesやdevicesなど従来どおり

このように、Weston+自身でQtランタイム付きの(qtdemo-debugなど)アプリケーションコンテナのみで十分です。

参考ドキュメント:

もしご不明な点がありましたらご質問ください。

Best regards, Toradex AI Assistant.

指示されたようにdocker-compose.ymlを下記のように修正しました。

version: "3.9"
services:
  qtdemo-debug:
    build:
      context: .
      dockerfile: Dockerfile.debug
    image: ${LOCAL_REGISTRY}:5002/pxtqtdemo-debug:${TAG}
    ports:
      # SSH debug
      - 2231:2231
      # gdbserver
      - 2232:2232
      # qml debug
      - 2233:2233
    devices:
      - "/dev/ttyRPMSG31:/dev/ttyRPMSG31" 
      - "/dev/galcore:/dev/galcore"
      - "/dev/snd"
    environment:
      - ACCEPT_FSL_EULA=1
      - QT_QPA_PLATFORM=eglfs
    volumes:
      - type: bind
        source: /tmp
        target: /tmp
      - type: bind
        source: /dev
        target: /dev
        read_only: false
      - type: bind
        bind:
          propagation: shared
        source: /media
        target: /media

    device_cgroup_rules:
      # ... for tty0
      - "c 4:0 rmw"
      # ... for tty7
      - "c 4:7 rmw"
      # ... for /dev/input devices
      - "c 13:* rmw"
      - "c 199:* rmw"
      # ... for /dev/dri devices
      - "c 226:* rmw"
    depends_on: [
      weston
    ]


  weston:
    image: torizon/weston-vivante:3
    environment:
      - ACCEPT_FSL_EULA=1
    # Required to get udev events from host udevd via netlink
    network_mode: host
    volumes:
      - type: bind
        source: /tmp
        target: /tmp
      - type: bind
        source: /dev
        target: /dev
      - type: bind
        source: /run/udev
        target: /run/udev
      - type: bind
        source: /etc/xdg/weston/
        target: /etc/xdg/weston/
    cap_add:
      - CAP_SYS_TTY_CONFIG
    # Add device access rights through cgroup...
    device_cgroup_rules:
      # ... for tty0
      - "c 4:0 rmw"
      # ... for tty1
      - "c 4:1 rmw"
      # ... for tty7
      - "c 4:7 rmw"
      # ... for /dev/input devices
      - "c 13:* rmw"
      - "c 199:* rmw"
      # ... for /dev/dri devices
      - "c 226:* rmw"

そのうえで、下記のようなQtアプリケーションをqtdemo-debugコンテナで実行して、OpenGLが使用できることを確認しようとしましたが、例外が発生します。

#include <QGuiApplication>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QOffscreenSurface> // 追加
#include <QDebug>

int main(int argc, char *argv[]) {
    QGuiApplication app(argc, argv);

    QSurfaceFormat format;
    format.setVersion(3, 3); // Example: OpenGL 3.3
    format.setProfile(QSurfaceFormat::CoreProfile);
    QSurfaceFormat::setDefaultFormat(format);

    // Create a new OpenGL context
    QOpenGLContext context;
    context.setFormat(format);
    if (!context.create()) {
        qFatal("Failed to create OpenGL context");
        return -1;
    }

    // Create a dummy surface to make the context current
    QOffscreenSurface surface; // QOffscreenSurfaceの宣言
    surface.setFormat(format);
    surface.create();
    if (!context.makeCurrent(&surface)) {
        qFatal("Failed to make OpenGL context current");
        return -1;
    }

    // Get OpenGL functions
    QOpenGLFunctions *functions = context.functions();

    // Print OpenGL version information
    qDebug() << "OpenGL Vendor:" << reinterpret_cast<const char*>(functions->glGetString(GL_VENDOR));
    qDebug() << "OpenGL Renderer:" << reinterpret_cast<const char*>(functions->glGetString(GL_RENDERER));
    qDebug() << "OpenGL Version:" << reinterpret_cast<const char*>(functions->glGetString(GL_VERSION));

    return app.exec();
}

同じアプリケーションをLocalAMD64でビルド実行すると、OpenGLのバージョン等が表示されます。
qtdemo-debugコンテナでOpenGLが使用できるかを確認するにはどうすればよいですか?

1 Like

qtdemo-debugコンテナでOpenGLが使用できているかは、/sys/kernel/debug/gc/idleをモニターすることで確認できました。

1 Like