3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Windowsで50ms以下の低遅延を実現:ゲーミングリモートデスクトップソフトの開発

Posted at

低遅延なゲーミングリモートデスクトップを実現するまで

概要

Windows 環境で CUDA / DirectX / NVENC を組み合わせ、ゲーム用途でも使える超低遅延リモートデスクトップを自作(現在はテスト機段階)。
エンドツーエンドの体感遅延は 非ゲーム時で約 40ms、ゲーム実行時で約 50–60ms を確認。

開発するに至った経緯

「カフェでお茶しながら、自宅以外でもPCゲームを遊びたい」。
しかしゲーミングノートは高価・重い・盗難リスクもある。ならば自宅のゲーミングPCをサーバー化して、外から軽量クライアントで快適に遊べば良い――。市販の一般的なリモートデスクトップは遅延が大きくゲームに不向き。ほとんどが“業務用・汎用”設計で、ゲームのような映像変化の激しい負荷を前提としていない。
そこで、ゲーム対応を最初から目的化したリモートデスクトップの自作に着手。

目標と設計方針

遅延目標:人が違和感を覚えにくい100msを基準に、**総遅延50ms以下(LAN前提)**を狙う。
サーバー側(ゲーム実行機):キャプチャ→処理→送出まで ~15ms を目標。処理はCPUを極力使わずGPUで完結。
クライアント側:一般的なPC/iGPUでも動く軽量描画。現状はNVIDIA前提だが、Intel iGPU(Quick Sync / D3D)対応に改修中。
前提:ゲームPCという高性能GPUがあることを活かし、重めでも低遅延を優先する構成。

技術スタックと全体像

OS:Windows
GPU計算:CUDA
表示/共有:DirectX(主にD3D11/12)
エンコード:NVENC(CUDA モード採用)
狙い:GPUメモリ内でキャプチャ→処理→圧縮までを閉じる(CPU往復を避ける)

処理の流れ

サーバー

1.画面キャプチャ(GPU)
2.CUDAで必要な画像処理(色空間変換・スケーリング等)
3.CUDAモードのNVENCでエンコード
4.ネットワーク送出

クライアント

デコード+描画(現状はNVIDIA向け、iGPU対応を進行中)

サーバー側:低遅延を生むアーキテクチャ

GPU完結主義:キャプチャからNVENC投入までをGPUメモリ内で完結。CPUコピーを極力ゼロに。
CUDA×DirectX インターオペラビリティ(interop):CUDAカーネルが出した結果をCPUに戻さずDirectXへ引き渡し。
同期設計:CPU待ちを発生させないキューイングとタイムライン制御。GPUの処理列を乱さない。

たとえ話
「CUDA=絵の具職人、CPU=絵の具チューブ、DirectX=絵師」。
職人が作った絵の具を毎回チューブ(CPU)に詰め替えて渡すと時間がかかる。
同じパレット(GPUメモリ)上で職人が絵の具を作り、絵師がそのまま描けば高速――これが interop の価値。

クライアント側:軽さと互換性

方針:外出先のノートPCやiGPUでも動くこと。
現状:開発初期は1台でサーバー/クライアントを作った事情もありNVIDIA前提。
進行中:Intel iGPUでもデコード+レンダリングできるよう設計変更中。

実証:サーバー(RTX 4070)で FF14 4K/最高画質を実行し、クライアント(GTX 1650)でレンダリング成功。
※GTX1650単体では4K最高画質のFF14は困難だが、リモート経由なら描画可能。

開発でハマったポイント(詳細)

1. CUDA×DirectX interop

情報の少なさ:NVIDIAの公式サンプルや書籍・Webに実用レベルのサンプルがほぼ皆無。
実装難度:AIを活用したバイブコーディングで実装にチャレンジするも、誤ったコード例も多く、安定稼働までに約3か月。
肝:CPUに戻さないこと。GPUメモリ上での共有と同期(フェンス/バリア/所有権移譲の正確さ)が成否を分ける。

2. NVENC の“罠”と回避策

当初は DirectX(D3D)モードで NVENC を使う方針だったが、以下の壁に直面:

D3D12→D3D11変換の必要:CUDA→D3D12→NVENC という流れを取ると、NVENC投入のためにD3D11へ変換が要るケースが発生。
NV12のUAV化が不可:一般的な NV12 を UAV(Unordered Access View) にする運用は、コンシューマ向けRTXでは不可という制約に当たり実質NG。このためエンタープライズGPUが前提になり得ると判断し、DirectXモードは断念。

CUDAモードへ転換:NVENC を CUDA モードで運用する方針に切り替え。

さらに CUDA モードにも落とし穴:
「線形バッファに NV12 直書き → NVENC 拒否」問題:
CUDAカーネルで NV12 を1本の線形バッファに直接出力して渡すと NVENC が受理しない事象に遭遇。

動いた解:
Y面とUV面を別個に生成
計算済みの正確なピッチで、GPU上で線形バッファへ面ごとにコピー
その線形バッファを NVENC へ投入
→ この手順で安定動作。仕様として明文化されておらず、解明に約2か月。

3. 同期と安定化

CPU待ちゼロ設計:GPUキューの詰まりや無駄な同期を避け、“進められるものは進め続ける”。
フレームパイプライン:キャプチャ→処理→エンコード→送出の多段を深すぎず浅すぎず。遅延と安定性の最適点を探る。
結果:体感スムーズかつ破綻しないレンダリングを実現。

こだわり機能:マルチモニター

最大4モニター同時キャプチャ、即時切替に対応。
ゲーム片方+ブラウジング/攻略情報/配信ツールなどを同時に扱えるのは、ゲーム用途の強い差別化。
市販品でのマルチモニター対応は限定的なため、実用上の価値が高い。

使ってみてわかったこと・学び

“GPUで完結”の威力:CPU往復を消すだけで遅延と安定性が段違い。
ドキュメント化されない挙動に出会う:現場で動く“正解”は公式サンプル通りとは限らない。
AIは良い相棒だが、鵜呑みは危険:最終的には自分の検証。誤りを潰し切る粘りが必要。

今後の展望

Intel iGPU対応:デコード&レンダリングの広い互換性を確保。多数のノートPCで動作へ。
さらなる遅延短縮:
キャプチャ経路・メモリレイアウト最適化
フレームパイプラインの深さ調整
レンダリングパスの簡素化/ゼロコピー化の徹底
ネットワーク耐性:可変ビットレート・ジッタ吸収・フロー制御の洗練。
ユーザー機能:画質/遅延プリセット、ホットキー、配信モード、録画など。

まとめ

目的:外から軽量PCでも“快適にゲーム”。
手段:CUDA×DirectX×NVENCでGPU完結のパイプラインを構築。
成果:~40–60msの体感遅延、4画面キャプチャ/瞬時切替を実現。
苦労:interopとNVENCまわりは情報が少なく仕様も曲者。だが検証で突破口を発見。
次:iGPU対応とさらなる遅延削減で、実用域から“快適域”へ。

動作環境

実演動画の動作環境は以下の通り

サーバー

CPU:Ryzen5 4500 6Core CPU
Memory: 32GB
GPU: NVIDIA RTX 4070 12GB
SSD: 1TB

クライアント

CPU:Core i5 11400H
Memory: 16GB
GPU: GTX1650
SSD: 500GB

動作動画

動作動画

3
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?