# 機能設計書 266-imgui_impl_dx12

## 概要

本ドキュメントは、Dear ImGuiのDirectX12レンダラーバックエンド（imgui_impl_dx12）の機能設計を定義する。

### 本機能の処理概要

DirectX12レンダラーバックエンドは、Dear ImGuiのUI描画コマンドをDirectX12の明示的リソース管理APIに変換し、画面にUIを描画する機能を提供する。Shader Model 5.0を使用し、コマンドキュー、ルートシグネチャ、パイプラインステートオブジェクト（PSO）を通じてレンダリングを行う。

**業務上の目的・背景**：
DirectX12を使用するWindowsアプリケーションにDear ImGuiを統合する必要がある場合に本バックエンドを使用する。DirectX12はWindows 10以降でサポートされ、低レベルなリソース管理と明示的な同期により最高のパフォーマンスを実現できる。

**機能の利用シーン**：
- DirectX12アプリケーションへのImGuiデバッグUI追加
- Windows 10/11環境でのハイパフォーマンスレンダリング
- マルチGPU環境でのUI統合
- D3D12On7によるWindows 7対応

**主要な処理内容**：
1. バックエンドの初期化（`ImGui_ImplDX12_Init`）：InitInfo構造体による設定
2. デバイスオブジェクト作成（`ImGui_ImplDX12_CreateDeviceObjects`）：ルートシグネチャ、PSO作成
3. フレーム開始処理（`ImGui_ImplDX12_NewFrame`）：デバイスオブジェクト確認
4. 描画データのレンダリング（`ImGui_ImplDX12_RenderDrawData`）：リソース更新、描画実行
5. テクスチャ更新（`ImGui_ImplDX12_UpdateTexture`）：アップロードバッファ経由の転送
6. バックエンドの終了処理（`ImGui_ImplDX12_Shutdown`）：リソース解放

**関連システム・外部連携**：
- プラットフォームバックエンド（Win32）と組み合わせて使用
- DirectX12ランタイム、D3DCompiler
- SRVディスクリプタ管理はアプリケーション側で実施

**権限による制御**：
特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 全画面 | 主画面 | すべてのDear ImGuiウィジェットの描画出力先 |

## 機能種別

レンダリングバックエンド / グラフィックスAPI抽象化

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|-----------------|
| init_info | ImGui_ImplDX12_InitInfo* | Yes | 初期化設定構造体 | Device/CommandQueue必須 |
| draw_data | ImDrawData* | Yes | 描画コマンドリスト | DisplaySize > 0 |
| command_list | ID3D12GraphicsCommandList* | Yes | グラフィックスコマンドリスト | nullptr以外 |
| tex | ImTextureData* | Yes | テクスチャデータ | Status確認必須 |

### ImGui_ImplDX12_InitInfo構造体

| フィールド名 | 型 | 必須 | 説明 |
|-------------|-----|-----|------|
| Device | ID3D12Device* | Yes | Direct3D12デバイス |
| CommandQueue | ID3D12CommandQueue* | Yes | テクスチャアップロード用コマンドキュー |
| NumFramesInFlight | int | Yes | フライト中のフレーム数 |
| RTVFormat | DXGI_FORMAT | Yes | レンダーターゲット形式 |
| DSVFormat | DXGI_FORMAT | No | デプスステンシルビュー形式 |
| SrvDescriptorHeap | ID3D12DescriptorHeap* | Yes | SRVディスクリプタヒープ |
| SrvDescriptorAllocFn | function | Yes | SRVディスクリプタ割当コールバック |
| SrvDescriptorFreeFn | function | Yes | SRVディスクリプタ解放コールバック |

### 入力データソース

- ImGui_ImplDX12_InitInfo構造体
- ImDrawData構造体
- ImTextureData構造体

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 初期化結果 | bool | Init関数の成功/失敗 |
| テクスチャID | D3D12_GPU_DESCRIPTOR_HANDLE | GPUディスクリプタハンドル |
| 画面出力 | Direct3D12描画 | バックバッファへのUI描画結果 |

### 出力先

- Direct3D12バックバッファ
- io.BackendRendererUserData
- platform_io.Renderer_RenderState（コールバック用）

## 処理フロー

### 処理シーケンス

```
1. ImGui_ImplDX12_Init(init_info)
   ├─ InitInfo構造体のディープコピー
   ├─ フレームリソース配列の初期化
   └─ SrvDescriptor割当コールバックの設定

2. ImGui_ImplDX12_CreateDeviceObjects()
   ├─ CreateDXGIFactory1
   ├─ CheckFeatureSupport(TEARING)
   ├─ D3D12SerializeRootSignature（動的ロード）
   ├─ CreateRootSignature（Linear/Nearest）
   ├─ D3DCompileでシェーダーコンパイル（vs_5_0, ps_5_0）
   ├─ CreateGraphicsPipelineState（Linear/Nearest）
   ├─ CreateCommandAllocator / CreateCommandList
   └─ CreateFence

3. [毎フレーム] ImGui_ImplDX12_NewFrame()
   └─ PSO未作成なら CreateDeviceObjects()

4. [毎フレーム] ImGui_ImplDX12_RenderDrawData(draw_data, command_list)
   ├─ テクスチャ更新
   ├─ VB/IB作成・拡張（D3D12_HEAP_TYPE_UPLOAD）
   ├─ VB/IB Map/Unmap
   ├─ SetupRenderState
   ├─ RenderState設定（コールバック用）
   └─ 描画コマンド実行（DrawIndexedInstanced）

5. ImGui_ImplDX12_UpdateTexture(tex)
   ├─ テクスチャリソース作成（D3D12_HEAP_TYPE_DEFAULT）
   ├─ アップロードバッファ作成・再利用
   ├─ ResourceBarrier（PIXEL_SHADER_RESOURCE → COPY_DEST）
   ├─ CopyTextureRegion
   ├─ ResourceBarrier（COPY_DEST → PIXEL_SHADER_RESOURCE）
   ├─ ExecuteCommandLists
   └─ Fence同期（WaitForSingleObject）

6. ImGui_ImplDX12_Shutdown()
   └─ InvalidateDeviceObjects
```

### フローチャート

```mermaid
flowchart TD
    A[Init] --> B[NewFrame]
    B --> C{PSO作成済み?}
    C -->|No| D[CreateDeviceObjects]
    C -->|Yes| E[RenderDrawData]
    D --> E
    E --> F[Update Textures]
    F --> G[Create/Map VB/IB]
    G --> H[SetupRenderState]
    H --> I[Set RenderState for Callbacks]
    I --> J[For each DrawList/DrawCmd]
    J --> K[RSSetScissorRects]
    K --> L[SetGraphicsRootDescriptorTable]
    L --> M[DrawIndexedInstanced]
    M --> N[Shutdown]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | シェーダーモデル | Shader Model 5.0（vs_5_0/ps_5_0） | シェーダーコンパイル時 |
| BR-002 | テクスチャ形式 | DXGI_FORMAT_R8G8B8A8_UNORM | テクスチャ作成時 |
| BR-003 | 大規模メッシュ対応 | 64K頂点以上サポート | DrawIndexedInstancedのVtxOffset使用 |
| BR-004 | フレームリソース | NumFramesInFlight分のVB/IBを保持 | マルチバッファリング |
| BR-005 | SRVディスクリプタ管理 | アプリケーション側でAlloc/Freeを実装 | テクスチャ作成/破棄時 |

### 計算ロジック

**正射影行列**（行174-180）:
```cpp
float mvp[4][4] = {
    { 2.0f/(R-L),   0.0f,           0.0f,       0.0f },
    { 0.0f,         2.0f/(T-B),     0.0f,       0.0f },
    { 0.0f,         0.0f,           0.5f,       0.0f },
    { (R+L)/(L-R),  (T+B)/(B-T),    0.5f,       1.0f },
};
```

**テクスチャアップロードピッチ計算**（行458-459）:
```cpp
UINT upload_pitch_src = upload_w * tex->BytesPerPixel;
UINT upload_pitch_dst = (upload_pitch_src + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u)
                       & ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u);
```

## データベース操作仕様

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IM_ASSERT | 初期化エラー | 二重初期化 | 初期化状態確認 |
| FAILED(hr) | シェーダーコンパイル失敗 | D3DCompile失敗 | return false |
| < 0 | リソース作成失敗 | CreateCommittedResource失敗 | return |
| != S_OK | Map失敗 | VB/IB Map失敗 | return |
| nullptr | DLL読込失敗 | d3d12.dll読込失敗 | return false |

### リトライ仕様

リトライなし

## トランザクション仕様

該当なし

## パフォーマンス要件

- D3D12_HEAP_TYPE_UPLOAD使用によるVB/IBアップロード
- D3D12_HEAP_TYPE_DEFAULT使用によるテクスチャ管理
- フレームリソースの再利用（NumFramesInFlight分のバッファ）
- アップロードバッファの再利用（サイズ増加時のみ再作成）
- Fence同期による明示的なGPU完了待機
- Tearing対応チェック

## セキュリティ考慮事項

- デバイスポインタの検証
- コマンドキューポインタの検証
- SRVディスクリプタコールバックの検証

## 備考

- d3dcompiler.libと自動リンク（#pragma comment）
- D3D12On7対応（Windows 7でのd3d12.dll動的ロード）
- ImGui_ImplDX12_RenderState構造体でコールバック用状態を公開
- Linear/Nearestサンプラー用に2つのPSOを保持
- レガシーInit関数は単一SRVディスクリプタモードで動作（複数テクスチャ非対応）

---

## コードリーディングガイド

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui_impl_dx12.h | `backends/imgui_impl_dx12.h` | ImGui_ImplDX12_InitInfo構造体（行34-54）を確認 |
| 1-2 | imgui_impl_dx12.cpp | `backends/imgui_impl_dx12.cpp` | ImGui_ImplDX12_Data構造体（行91-122）を確認 |
| 1-3 | imgui_impl_dx12.cpp | `backends/imgui_impl_dx12.cpp` | ImGui_ImplDX12_Texture構造体（行82-89）を確認 |
| 1-4 | imgui_impl_dx12.cpp | `backends/imgui_impl_dx12.cpp` | ImGui_ImplDX12_RenderBuffers構造体（行132-138）を確認 |

**読解のコツ**: DX12では明示的なリソース管理が必要なため、Fence/Event、アップロードバッファ、フレームリソース配列など多数のメンバーを持つ。

#### Step 2: 初期化処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui_impl_dx12.h | `backends/imgui_impl_dx12.h` | 公開API宣言（行57-74）を確認 |
| 2-2 | imgui_impl_dx12.cpp | `backends/imgui_impl_dx12.cpp` | Init関数（行905-949）を確認 |

**主要処理フロー**:
- **行912-914**: InitInfoのディープコピー
- **行927-928**: ImGuiBackendFlags設定
- **行934**: SrvDescriptorAllocFn/FreeFnの検証
- **行938-946**: フレームリソース配列の初期化

#### Step 3: デバイスオブジェクト作成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_impl_dx12.cpp | `backends/imgui_impl_dx12.cpp` | CreateDeviceObjects関数（行570-840）を確認 |

**主要処理フロー**:
- **行578**: CreateDXGIFactory1
- **行582-583**: Tearing対応チェック
- **行586-674**: ルートシグネチャ作成（D3D12SerializeRootSignature動的ロード）
- **行682-737**: 頂点シェーダーソース（vs_5_0）
- **行741-764**: ピクセルシェーダーソース（ps_5_0）
- **行766-806**: ブレンド/ラスタライザ/デプスステンシルステート設定
- **行808-823**: CreateGraphicsPipelineState（Linear/Nearest）
- **行826-837**: コマンドアロケータ/リスト/Fence作成

#### Step 4: テクスチャ処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | imgui_impl_dx12.cpp | `backends/imgui_impl_dx12.cpp` | UpdateTexture関数（行386-568）を確認 |

**主要処理フロー**:
- **行397-398**: SrvDescriptorAllocFn呼び出し
- **行400-421**: テクスチャリソース作成（D3D12_HEAP_TYPE_DEFAULT）
- **行423-431**: SRV作成
- **行462-500**: アップロードバッファ作成・再利用
- **行510-520**: ResourceBarrier（PIXEL_SHADER_RESOURCE → COPY_DEST）
- **行536**: CopyTextureRegion
- **行538-547**: ResourceBarrier（COPY_DEST → PIXEL_SHADER_RESOURCE）
- **行551-554**: ExecuteCommandLists、Signal
- **行560-561**: Fence同期（WaitForSingleObject）

#### Step 5: レンダリング処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | imgui_impl_dx12.cpp | `backends/imgui_impl_dx12.cpp` | RenderDrawData関数（行224-365）を確認 |
| 5-2 | imgui_impl_dx12.cpp | `backends/imgui_impl_dx12.cpp` | SetupRenderState関数（行164-213）を確認 |

**主要処理フロー**:
- **行239-240**: frameIndex更新、フレームリソース取得
- **行243-284**: VB/IB作成・拡張（CreateCommittedResource）
- **行286-310**: Map/Unmap
- **行315-320**: RenderState構造体設定
- **行355-358**: SetGraphicsRootDescriptorTable、DrawIndexedInstanced

### プログラム呼び出し階層図

```
アプリケーション
    │
    ├─ ImGui_ImplDX12_Init(init_info)
    │      ├─ InitInfo ディープコピー
    │      ├─ SrvDescriptor コールバック設定
    │      └─ pFrameResources 配列初期化
    │
    ├─ [フレームループ]
    │      │
    │      ├─ ImGui_ImplDX12_NewFrame()
    │      │      └─ ImGui_ImplDX12_CreateDeviceObjects()
    │      │             ├─ CreateDXGIFactory1()
    │      │             ├─ CheckFeatureSupport(TEARING)
    │      │             ├─ D3D12SerializeRootSignature() [動的ロード]
    │      │             ├─ CreateRootSignature() [Linear/Nearest]
    │      │             ├─ D3DCompile() [vs_5_0, ps_5_0]
    │      │             ├─ CreateGraphicsPipelineState() [Linear/Nearest]
    │      │             ├─ CreateCommandAllocator()
    │      │             ├─ CreateCommandList()
    │      │             └─ CreateFence()
    │      │
    │      └─ ImGui_ImplDX12_RenderDrawData()
    │             ├─ ImGui_ImplDX12_UpdateTexture()
    │             │      ├─ SrvDescriptorAllocFn()
    │             │      ├─ CreateCommittedResource() [テクスチャ]
    │             │      ├─ CreateShaderResourceView()
    │             │      ├─ CreateCommittedResource() [アップロードバッファ]
    │             │      ├─ pTexCmdList->ResourceBarrier()
    │             │      ├─ pTexCmdList->CopyTextureRegion()
    │             │      ├─ pCommandQueue->ExecuteCommandLists()
    │             │      ├─ pCommandQueue->Signal()
    │             │      └─ WaitForSingleObject()
    │             │
    │             ├─ CreateCommittedResource() [VB/IB]
    │             ├─ Map() / Unmap()
    │             ├─ ImGui_ImplDX12_SetupRenderState()
    │             │      ├─ RSSetViewports()
    │             │      ├─ IASetVertexBuffers()
    │             │      ├─ IASetIndexBuffer()
    │             │      ├─ IASetPrimitiveTopology()
    │             │      ├─ SetGraphicsRootSignature()
    │             │      ├─ SetPipelineState()
    │             │      ├─ SetGraphicsRoot32BitConstants()
    │             │      └─ OMSetBlendFactor()
    │             │
    │             ├─ RSSetScissorRects()
    │             ├─ SetGraphicsRootDescriptorTable()
    │             └─ DrawIndexedInstanced()
    │
    └─ ImGui_ImplDX12_Shutdown()
           ├─ ImGui_ImplDX12_InvalidateDeviceObjects()
           └─ delete[] pFrameResources
```

### データフロー図

```
[入力]                         [処理]                              [出力]

ImGui_ImplDX12_InitInfo ──▶ Init() ───────────────────────▶ バックエンドデータ
  ├─ Device                    ├─ InitInfo コピー                └─ pFrameResources[]
  ├─ CommandQueue              └─ SrvDescriptor 設定
  ├─ NumFramesInFlight
  ├─ RTVFormat
  ├─ SrvDescriptorAllocFn
  └─ SrvDescriptorFreeFn

ImDrawData ─────────────▶ RenderDrawData() ───────────▶ Direct3D12描画
  ├─ DisplaySize               ├─ CreateCommittedResource()        └─ バックバッファ
  ├─ FramebufferScale          ├─ Map/Unmap [VB/IB]
  ├─ CmdLists[]                ├─ SetupRenderState()
  │   ├─ VtxBuffer             └─ DrawIndexedInstanced()
  │   └─ IdxBuffer
  │
  └─ Textures[] ──────────▶ UpdateTexture() ──────────▶ D3D12_GPU_DESCRIPTOR_HANDLE
       └─ ImTextureData       ├─ SrvDescriptorAllocFn()
                              ├─ CreateCommittedResource() [テクスチャ]
                              ├─ CreateShaderResourceView()
                              ├─ CreateCommittedResource() [アップロードバッファ]
                              ├─ ResourceBarrier()
                              ├─ CopyTextureRegion()
                              ├─ ExecuteCommandLists()
                              └─ WaitForSingleObject() [Fence同期]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui_impl_dx12.h | `backends/imgui_impl_dx12.h` | ヘッダー | 公開API宣言、InitInfo/RenderState構造体（90行） |
| imgui_impl_dx12.cpp | `backends/imgui_impl_dx12.cpp` | ソース | バックエンド実装本体（1011行） |
| d3d12.h | システム | ヘッダー | DirectX12 API宣言 |
| dxgi1_5.h | システム | ヘッダー | DXGI 1.5（Tearing対応） |
| d3dcompiler.h | システム | ヘッダー | シェーダーコンパイラ |
