Files
XCEngine/tests/RHI/D3D12/TEST_SPEC.md
ssdfasd 34c04af6cb D3D12: Fix texture ownership semantics and remove GetSwapChain() exposure
This commit fixes the D3D12 texture architecture issues:

1. D3D12Texture ownership semantics:
   - Add m_ownsResource member to track resource ownership
   - InitializeFromExisting() now takes ownsResource parameter (default false)
   - Shutdown() only releases resource if ownsResource is true
   - Initialize() sets m_ownsResource = true for created resources

2. D3D12SwapChain changes:
   - Remove GetSwapChain() method (was exposing native D3D12 API)
   - Change GetBackBuffer() to return reference instead of pointer
   - Back buffers initialized with ownsResource = false

3. minimal/main.cpp updates:
   - Remove gColorRTs[2] array (was duplicating back buffer wrapping)
   - Direct use of gSwapChain.GetBackBuffer(i) instead
   - All references updated to use encapsulated API

4. Documentation:
   - Update TEST_SPEC.md v1.3
   - Remove known limitation 7.2 (minimal GetBuffer issue fixed)
   - Add D3D12_Texture_Architecture_Fix_Plan.md design document
2026-03-20 17:58:27 +08:00

7.8 KiB
Raw Blame History

D3D12 测试专项规范

本文档是 XCEngine 测试规范的 D3D12 专项补充。

前置阅读: tests/TEST_SPEC.md - 通用测试规范


1. 概述

1.1 D3D12 测试特点

特点 说明
硬件依赖 需要支持 D3D12 的显卡
窗口依赖 集成测试需要 GUI 窗口
GPU 状态 测试间可能有 GPU 状态污染

1.2 测试层级

层级 位置 执行方式 框架
单元测试 tests/RHI/D3D12/unit/ CTest Google Test
集成测试 tests/RHI/D3D12/integration/ CTest + Python Python wrapper

2. 单元测试规范

2.1 Fixture 设计

每个测试独立创建设备,避免 GPU 状态污染:

class D3D12TestFixture : public ::testing::Test {
protected:
    void SetUp() override;   // 创建设备、命令队列等
    void TearDown() override; // 清理资源
    
    ID3D12Device* GetDevice();
    ID3D12CommandQueue* GetCommandQueue();
    ID3D12CommandAllocator* GetCommandAllocator();
    ID3D12GraphicsCommandList* GetCommandList();
    
    void WaitForGPU();
};

2.2 测试前缀对应

类名 测试前缀
D3D12Device Device
D3D12CommandQueue CommandQueue
D3D12CommandAllocator CommandAllocator
D3D12CommandList CommandList
D3D12Buffer Buffer
D3D12Texture Texture
D3D12DescriptorHeap DescriptorHeap
D3D12Fence Fence
D3D12PipelineState PipelineState
D3D12RootSignature RootSignature
D3D12Shader Shader
D3D12RenderTargetView RTV
D3D12DepthStencilView DSV

2.3 当前测试统计

组件 测试数 状态
Device 6 通过
Fence 5 通过
CommandQueue 2 通过
CommandAllocator 3 通过
CommandList 2 通过
Buffer 5 通过
Texture 4 通过
DescriptorHeap 5 通过
PipelineState 2 通过
RootSignature 2 通过
Shader 3 通过
Views 4 通过
总计 44 全部通过

3. 集成测试规范

3.1 目录结构

每个集成测试独占一个子文件夹,资源相互隔离:

integration/
├── CMakeLists.txt                    # 构建配置
├── run_integration_test.py          # 公共测试运行脚本
├── compare_ppm.py                   # PPM 图像比对脚本
├── run.bat                         # Windows 启动脚本
├── minimal/                         # 最小化测试
│   ├── main.cpp
│   ├── GT.ppm
│   └── Res/
│       └── Shader/
│           ├── ndctriangle.hlsl
│           └── gs.hlsl
├── render_model/                    # 模型渲染测试
│   ├── main.cpp
│   ├── GT.ppm
│   └── Res/
│       ├── Image/
│       ├── Model/
│       └── Shader/
└── triangle/                       # 三角形渲染测试 (待实现)
    ├── main.cpp
    ├── GT_triangle.ppm
    └── Res/

3.2 Python Wrapper

位置: tests/RHI/D3D12/integration/run_integration_test.py

职责:

  1. 启动 D3D12 exe
  2. 等待进程完成
  3. 检查输出文件 (PPM 截图)
  4. 调用 compare_ppm.py 比对 Golden Image
  5. 返回 0(成功)/1(失败)

3.3 CTest 注册格式

add_test(NAME D3D12_Minimal_Integration
    COMMAND ${Python3_EXECUTABLE} $<TARGET_FILE_DIR:D3D12_Minimal>/run_integration_test.py
        $<TARGET_FILE:D3D12_Minimal>
        minimal.ppm
        ${CMAKE_CURRENT_SOURCE_DIR}/minimal/GT.ppm
        5
    WORKING_DIRECTORY $<TARGET_FILE_DIR:D3D12_Minimal>
)

3.4 Golden Image 规范

属性
格式 PPM (P6)
命名 GT_<test_name>.ppm
阈值 默认 5%
存储位置 tests/RHI/D3D12/integration/<test_name>/

3.5 Golden Image 生成流程

  1. 在干净硬件环境运行集成测试
  2. 截图保存为 GT_<name>.ppm
  3. 人工验证截图正确性
  4. 提交到版本控制

3.6 当前集成测试

测试名 Golden Image 状态
D3D12_Minimal_Integration minimal/GT.ppm 通过
D3D12_RenderModel_Integration render_model/GT.ppm 待修复
D3D12_Triangle_Integration triangle/GT_triangle.ppm 🔄 待实现

4. 测试执行

4.1 单元测试

# 方式 1: 使用统一脚本
python scripts/run_tests.py --unit-only

# 方式 2: 直接使用 CTest
cd build/tests/RHI/D3D12/unit
ctest -C Debug --output-on-failure

4.2 集成测试

# 方式 1: 使用统一脚本
python scripts/run_tests.py --integration

# 方式 2: 直接使用 CTest
cd build/tests/RHI/D3D12/integration
ctest -C Debug --output-on-failure

4.3 构建和测试

# 构建
cmake --build . --target D3D12_Minimal D3D12_RenderModel --config Debug

# 运行测试
python scripts/run_tests.py --build

5. CI 集成

5.1 GitHub Actions 配置

name: D3D12 Tests
on: [push, pull_request]

jobs:
  test:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Configure CMake
        run: cmake -B build -DCMAKE_BUILD_TYPE=Debug
      
      - name: Build D3D12 Tests
        run: cmake --build build --target D3D12_Minimal D3D12_RenderModel --config Debug
      
      - name: Run Unit Tests
        run: cd build/tests/RHI/D3D12/unit && ctest -C Debug --output-on-failure
      
      - name: Run Integration Tests
        run: python scripts/run_tests.py --integration

5.2 CI 模式

--ci 模式会跳过需要 GUI 的集成测试:

python scripts/run_tests.py --ci  # 仅运行单元测试

6. 文件结构

tests/RHI/D3D12/
├── CMakeLists.txt
├── TEST_SPEC.md                    # 本文档 (D3D12 专项)
├── TEST_IMPROVEMENT_PLAN.md        # 改进计划
├── unit/
│   ├── CMakeLists.txt
│   ├── fixtures/
│   │   ├── D3D12TestFixture.h
│   │   └── D3D12TestFixture.cpp
│   ├── test_device.cpp
│   ├── test_buffer.cpp
│   └── ...
└── integration/
    ├── CMakeLists.txt
    ├── run_integration_test.py      # 公共脚本
    ├── compare_ppm.py               # 公共脚本
    ├── run.bat                      # 公共脚本
    ├── minimal/                     # 测试子文件夹
    │   ├── main.cpp
    │   ├── GT.ppm
    │   └── Res/
    ├── render_model/                # 测试子文件夹
    │   ├── main.cpp                 # 有 API 问题,待修复
    │   ├── GT.ppm
    │   └── Res/
    └── triangle/                    # 测试子文件夹 (待实现)
        ├── main.cpp
        ├── GT_triangle.ppm
        └── Res/

engine/
└── third_party/
    └── stb/                         # stb 图像库
        ├── stb_image.h
        └── stb_image.cpp

7. 已知问题

7.1 render_model API 不兼容

问题: D3D12Buffer::InitializeD3D12Screenshot::Capture API 签名变更

影响: D3D12_RenderModel_Integration 无法编译

状态: 待修复


8. 规范更新记录

版本 日期 变更
1.0 2026-03-20 初始版本
1.1 2026-03-20 添加 CI 集成章节,补充 Phase 5 内容
1.2 2026-03-20 重构集成测试目录结构每个测试独立子文件夹stb 库移至 engine/third_party/stb/
1.3 2026-03-20 修复 minimal GetBuffer 原生调用问题:添加 D3D12Texture 所有权语义,删除 GetSwapChain() 暴露方法,移除 gColorRTs 数组

规范版本: 1.3
最后更新: 2026-03-20
前置文档: tests/TEST_SPEC.md