低遅延なゲーミングリモートデスクトップを実現するまで
概要
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