# 機能設計書 273-imgui_impl_sdlgpu3

## 概要

本ドキュメントは、Dear ImGuiのSDL3 GPUバックエンド（imgui_impl_sdlgpu3）の機能設計について記述する。SDL3の新しいグラフィックス抽象化レイヤーであるSDL_GPUを使用してDear ImGuiのUI描画をレンダリングするためのバックエンド実装を提供する。

### 本機能の処理概要

SDL3 GPU APIを使用してDear ImGuiの描画データをレンダリングする高性能なバックエンド機能を提供する。SDL_GPUはVulkan、Direct3D 12、Metalなどの低レベルグラフィックスAPIを抽象化した最新のレンダリングAPIである。

**業務上の目的・背景**：SDL3の新しいGPU抽象化レイヤーを使用して、プラットフォーム非依存で高性能なImGuiレンダリングを実現する。従来のSDL_Rendererより高度なグラフィックス制御が可能で、カスタムシェーダー、複雑なレンダーパス、最新GPUの機能を活用できる。ゲームエンジンや高性能なツール開発に最適。

**機能の利用シーン**：SDL3ベースの高性能ゲーム、3Dエディタ、レンダリングツールなどにおいて、ImGuiを統合する際に使用される。特に、既存のSDL_GPUレンダーパスにImGuiを組み込む場合や、カスタムパイプラインを使用したい場合に適している。

**主要な処理内容**：
1. SDL_GPUデバイスとグラフィックスパイプラインの初期化
2. シェーダー（SPIR-V、DXBC、Metal）のロードとパイプライン作成
3. 頂点/インデックスバッファの動的管理（転送バッファ経由）
4. テクスチャの作成・更新・破棄
5. コピーパス（PrepareDrawData）とレンダーパス（RenderDrawData）の分離
6. サンプラー（Linear/Nearest）の管理

**関連システム・外部連携**：SDL3ライブラリ、SDL_GPU API。Vulkan、Direct3D 12、Metalを内部で使用。

**権限による制御**：特になし。アプリケーションレベルで制御。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | SDL_GPUを使用するすべてのImGuiウィンドウのレンダリング |

## 機能種別

レンダリング処理 / GPUバックエンド実装

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| info | ImGui_ImplSDLGPU3_InitInfo* | Yes | 初期化情報（Device, ColorTargetFormat等） | Device != nullptr, ColorTargetFormat != INVALID |
| draw_data | ImDrawData* | Yes | ImGuiの描画データ | PrepareDrawData/RenderDrawData呼び出し時 |
| command_buffer | SDL_GPUCommandBuffer* | Yes | GPUコマンドバッファ | 描画時に必要 |
| render_pass | SDL_GPURenderPass* | Yes | レンダーパス | RenderDrawData呼び出し時 |
| pipeline | SDL_GPUGraphicsPipeline* | No | カスタムパイプライン（省略時は内蔵使用） | RenderDrawData呼び出し時 |

### 入力データソース

- ImGui::Render()によって生成されるImDrawData
- ImGui::GetPlatformIO().Textures[]のテクスチャ更新リスト
- ユーザー提供のSDL_GPUCommandBuffer、SDL_GPURenderPass

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 描画結果 | SDL_GPURenderPass出力 | レンダリングされたImGui UI |
| SDL_GPUTexture* | ImTextureID | 作成されたテクスチャのID |

### 出力先

ユーザー提供のSDL_GPURenderPass（カラーターゲット）

## 処理フロー

### 処理シーケンス

```
1. Init: バックエンド初期化
   └─ InitInfo保存、バックエンドフラグ設定
2. CreateDeviceObjects: GPUリソース作成
   a. サンプラー作成（Linear/Nearest）
   b. シェーダー作成（プラットフォーム別）
   c. グラフィックスパイプライン作成
3. PrepareDrawData: 描画データ準備（コピーパス）
   a. テクスチャ更新
   b. 頂点/インデックスバッファ作成・リサイズ
   c. 転送バッファへのデータコピー
   d. GPUバッファへのアップロード
4. RenderDrawData: 実際の描画（レンダーパス）
   a. パイプラインバインド
   b. バッファバインド
   c. ビューポート/シザー設定
   d. 描画コマンド発行
5. Shutdown: クリーンアップ
   └─ 全GPUリソース解放
```

### フローチャート

```mermaid
flowchart TD
    A[ImGui_ImplSDLGPU3_Init] --> B[CreateDeviceObjects]
    B --> C[シェーダー作成]
    C --> D[パイプライン作成]
    D --> E[サンプラー作成]
    E --> F[NewFrame]
    F --> G[ImGui::Render]
    G --> H[PrepareDrawData - コピーパス]
    H --> I{テクスチャ更新あり?}
    I -->|Yes| J[UpdateTexture]
    I -->|No| K[バッファ作成/リサイズ]
    J --> K
    K --> L[転送バッファにコピー]
    L --> M[SDL_UploadToGPUBuffer]
    M --> N[RenderDrawData - レンダーパス]
    N --> O[パイプライン/バッファバインド]
    O --> P[描画コマンドループ]
    P --> Q[SDL_DrawGPUIndexedPrimitives]
    Q --> R[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-273-01 | 2段階描画 | PrepareDrawDataをRenderDrawDataの前に呼び出す必要がある | 常に適用 |
| BR-273-02 | テクスチャフォーマット | R8G8B8A8_UNORMフォーマットを使用 | テクスチャ作成時 |
| BR-273-03 | シェーダー選択 | ドライバーに応じてSPIR-V/DXBC/Metalを選択 | デバイス作成時 |
| BR-273-04 | 大規模メッシュ対応 | VtxOffsetを使用して64k+頂点をサポート | 常に適用 |

### 計算ロジック

- スケール/トランスレーション: `scale = 2.0f / DisplaySize`, `translation = -1.0f - DisplayPos * scale`
- クリッピング矩形計算: `clip_min/max = (pcmd->ClipRect - clip_off) * clip_scale`

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | アサーション | Device == nullptr | 初期化時にnullチェック |
| - | アサーション | ColorTargetFormat == INVALID | 初期化時にフォーマットチェック |
| - | アサーション | シェーダー作成失敗 | SDL_GetError()で詳細確認 |
| - | アサーション | パイプライン作成失敗 | SDL_GetError()で詳細確認 |
| - | アサーション | バッファ作成失敗 | SDL_GetError()で詳細確認 |

### リトライ仕様

リトライ処理なし。エラー時はアサーションで停止。

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

該当なし（グラフィックスAPI操作のため）

## パフォーマンス要件

- 転送バッファの再利用による高速化（毎フレーム再作成を回避）
- GPUバッファのサイズは必要に応じてのみ拡張
- SDL_WaitForGPUIdle()はバッファリサイズ時のみ呼び出し
- テクスチャは部分更新対応

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

- ユーザー提供のテクスチャポインタは直接SDL_GPUTextureとして使用
- シェーダーは事前コンパイル済みのバイナリを使用（動的コンパイルなし）

## 備考

- PrepareDrawDataとRenderDrawDataの分離は、SDL_GPUがコピーパスとレンダーパスの同時実行を許可しないため必須
- 2025/08/08以降、ImTextureIDの型がSDL_GPUTextureSamplerBinding*からSDL_GPUTexture*に変更
- macOSではMSL/Metallibシェーダーを使用（macOS 10.14+対応にはMSL、14+ではMetallib）
- カスタムパイプラインを渡すことで、レンダーステートのカスタマイズが可能

---

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

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui_impl_sdlgpu3.h | `backends/imgui_impl_sdlgpu3.h` | InitInfo構造体（31-38行目）、RenderState構造体（57-63行目） |
| 1-2 | imgui_impl_sdlgpu3.cpp | `backends/imgui_impl_sdlgpu3.cpp` | FrameData構造体（46-54行目）、Data構造体（56-71行目） |

**読解のコツ**: FrameDataは頂点/インデックスバッファと転送バッファを保持。Dataはパイプライン、シェーダー、サンプラーを保持。

#### Step 2: 初期化フローを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui_impl_sdlgpu3.cpp | `backends/imgui_impl_sdlgpu3.cpp` | Init関数（644-663行目） |
| 2-2 | imgui_impl_sdlgpu3.cpp | `backends/imgui_impl_sdlgpu3.cpp` | CreateDeviceObjects関数（574-608行目） |

**主要処理フロー**:
1. **644-663行目**: Init - InitInfo保存、バックエンドフラグ設定
2. **574-608行目**: CreateDeviceObjects - サンプラー/パイプライン作成

#### Step 3: シェーダー/パイプライン作成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_impl_sdlgpu3.cpp | `backends/imgui_impl_sdlgpu3.cpp` | CreateShaders関数（413-489行目） |
| 3-2 | imgui_impl_sdlgpu3.cpp | `backends/imgui_impl_sdlgpu3.cpp` | CreateGraphicsPipeline関数（491-572行目） |
| 3-3 | imgui_impl_sdlgpu3_shaders.h | `backends/imgui_impl_sdlgpu3_shaders.h` | シェーダーバイナリ |

**主要処理フロー**:
- **419行目**: ドライバー名取得（vulkan/direct3d12/metal）
- **437-454行目**: プラットフォーム別シェーダー選択
- **497-523行目**: 頂点入力レイアウト設定
- **541-549行目**: ブレンドステート設定

#### Step 4: 描画データ準備を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | imgui_impl_sdlgpu3.cpp | `backends/imgui_impl_sdlgpu3.cpp` | PrepareDrawData関数（157-216行目） |
| 4-2 | imgui_impl_sdlgpu3.cpp | `backends/imgui_impl_sdlgpu3.cpp` | CreateOrResizeBuffers関数（129-152行目） |

**主要処理フロー**:
- **167-170行目**: テクスチャ更新
- **178-181行目**: バッファリサイズ判定
- **183-193行目**: 転送バッファへのデータコピー
- **212-215行目**: GPUへのアップロード（コピーパス）

#### Step 5: 描画処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | imgui_impl_sdlgpu3.cpp | `backends/imgui_impl_sdlgpu3.cpp` | RenderDrawData関数（218-308行目） |
| 5-2 | imgui_impl_sdlgpu3.cpp | `backends/imgui_impl_sdlgpu3.cpp` | SetupRenderState関数（88-127行目） |

**主要処理フロー**:
- **244行目**: SetupRenderState呼び出し
- **250-300行目**: 描画コマンドループ
- **287-290行目**: テクスチャ/サンプラーバインド
- **295行目**: SDL_DrawGPUIndexedPrimitives呼び出し

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

```
ImGui_ImplSDLGPU3_Init
    └─ IM_NEW(ImGui_ImplSDLGPU3_Data)

ImGui_ImplSDLGPU3_NewFrame
    └─ ImGui_ImplSDLGPU3_CreateDeviceObjects (初回のみ)
           ├─ ImGui_ImplSDLGPU3_CreateShaders
           │      └─ SDL_CreateGPUShader (x2)
           ├─ ImGui_ImplSDLGPU3_CreateGraphicsPipeline
           │      └─ SDL_CreateGPUGraphicsPipeline
           └─ SDL_CreateGPUSampler (x2)

ImGui_ImplSDLGPU3_PrepareDrawData
    ├─ ImGui_ImplSDLGPU3_UpdateTexture (必要時)
    │      ├─ SDL_CreateGPUTexture
    │      └─ SDL_UploadToGPUTexture
    ├─ CreateOrResizeBuffers (必要時)
    │      ├─ SDL_CreateGPUBuffer
    │      └─ SDL_CreateGPUTransferBuffer
    └─ SDL_UploadToGPUBuffer (コピーパス)

ImGui_ImplSDLGPU3_RenderDrawData
    ├─ ImGui_ImplSDLGPU3_SetupRenderState
    │      ├─ SDL_BindGPUGraphicsPipeline
    │      ├─ SDL_BindGPUVertexBuffers
    │      ├─ SDL_BindGPUIndexBuffer
    │      └─ SDL_SetGPUViewport
    └─ SDL_DrawGPUIndexedPrimitives (各コマンド)

ImGui_ImplSDLGPU3_Shutdown
    └─ ImGui_ImplSDLGPU3_DestroyDeviceObjects
           ├─ SDL_ReleaseGPUBuffer
           ├─ SDL_ReleaseGPUTransferBuffer
           ├─ SDL_ReleaseGPUShader
           ├─ SDL_ReleaseGPUSampler
           └─ SDL_ReleaseGPUGraphicsPipeline
```

### データフロー図

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

ImDrawData ───────────▶ PrepareDrawData ──────────▶ GPUバッファ
  │                      (コピーパス)                    │
  ├─ VtxBuffer           ├─ 転送バッファにコピー          │
  └─ IdxBuffer           └─ SDL_UploadToGPUBuffer        │
                                                         │
                         RenderDrawData ◀────────────────┘
                         (レンダーパス)
                              │
                              ├─ パイプラインバインド
                              ├─ テクスチャ/サンプラーバインド
                              └─ SDL_DrawGPUIndexedPrimitives
                                        │
                                        ▼
                                 SDL_GPURenderPass

ImTextureData ─────────▶ UpdateTexture ────────────▶ SDL_GPUTexture*
  │                         │
  ├─ Pixels                 ├─ SDL_CreateGPUTexture
  └─ Status                 └─ SDL_UploadToGPUTexture
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui_impl_sdlgpu3.h | `backends/imgui_impl_sdlgpu3.h` | ヘッダー | 公開APIの宣言 |
| imgui_impl_sdlgpu3.cpp | `backends/imgui_impl_sdlgpu3.cpp` | ソース | バックエンド実装 |
| imgui_impl_sdlgpu3_shaders.h | `backends/imgui_impl_sdlgpu3_shaders.h` | ヘッダー | プリコンパイル済みシェーダー |
| imgui.h | `imgui.h` | ヘッダー | ImGui コアAPI |
| SDL3/SDL_gpu.h | (外部ライブラリ) | ヘッダー | SDL_GPU API |
