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

309 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# D3D12 测试专项规范
本文档是 XCEngine 测试规范的 D3D12 专项补充。
**前置阅读**: [tests/TEST_SPEC.md](../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 状态污染:
```cpp
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 注册格式
```cmake
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 单元测试
```bash
# 方式 1: 使用统一脚本
python scripts/run_tests.py --unit-only
# 方式 2: 直接使用 CTest
cd build/tests/RHI/D3D12/unit
ctest -C Debug --output-on-failure
```
### 4.2 集成测试
```bash
# 方式 1: 使用统一脚本
python scripts/run_tests.py --integration
# 方式 2: 直接使用 CTest
cd build/tests/RHI/D3D12/integration
ctest -C Debug --output-on-failure
```
### 4.3 构建和测试
```bash
# 构建
cmake --build . --target D3D12_Minimal D3D12_RenderModel --config Debug
# 运行测试
python scripts/run_tests.py --build
```
---
## 5. CI 集成
### 5.1 GitHub Actions 配置
```yaml
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 的集成测试:
```bash
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::Initialize``D3D12Screenshot::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](../TEST_SPEC.md)