diff --git a/CMakeLists.txt b/CMakeLists.txt index b9fbf462..e6dc045b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,8 @@ project(XCEngine) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) +enable_testing() + add_subdirectory(engine) add_subdirectory(tests) -add_subdirectory(tests/OpenGL) +add_subdirectory(tests/opengl) diff --git a/Testing/Temporary/CTestCostData.txt b/Testing/Temporary/CTestCostData.txt new file mode 100644 index 00000000..ed97d539 --- /dev/null +++ b/Testing/Temporary/CTestCostData.txt @@ -0,0 +1 @@ +--- diff --git a/docs/api/rhi/rhi.md b/docs/api/rhi/rhi.md index 66f04928..dd453e9d 100644 --- a/docs/api/rhi/rhi.md +++ b/docs/api/rhi/rhi.md @@ -62,7 +62,7 @@ RHI 模块将上层渲染逻辑与底层图形 API 解耦,通过抽象接口 | 类 | 文档 | 描述 | |----|------|------| -| [RHIFence](rhi-fence/fence.md) | `RHIFence.h` | 同步栅栏,CPU/GPU 同步原语 | +| [RHIFence](fence/fence.md) | `RHIFence.h` | 同步栅栏,CPU/GPU 同步原语 | | [RHIPipelineState](pipeline-state/pipeline-state.md) | `RHIPipelineState.h` | 管线状态对象,封装渲染管线配置 | | [RHISampler](sampler/sampler.md) | `RHISampler.h` | 纹理采样器,配置纹理过滤和寻址模式 | | [RHIPipelineLayout](pipeline-layout/pipeline-layout.md) | `RHIPipelineLayout.h` | 管线布局,定义着色器资源绑定布局 | diff --git a/docs/api/scene/scene.md b/docs/api/scene/scene.md index 850f2c1a..df04323a 100644 --- a/docs/api/scene/scene.md +++ b/docs/api/scene/scene.md @@ -1,6 +1,6 @@ # Scene 模块概览 -**命名空间**: `XCEngine::Components` +**命名空间**: `XCEngine::Scene` **类型**: `module` diff --git a/docs/api/threading/lambdatask/constructor.md b/docs/api/threading/lambda-task/constructor.md similarity index 100% rename from docs/api/threading/lambdatask/constructor.md rename to docs/api/threading/lambda-task/constructor.md diff --git a/docs/api/threading/lambdatask/execute.md b/docs/api/threading/lambda-task/execute.md similarity index 100% rename from docs/api/threading/lambdatask/execute.md rename to docs/api/threading/lambda-task/execute.md diff --git a/docs/api/threading/lambdatask/lambdatask.md b/docs/api/threading/lambda-task/lambda-task.md similarity index 100% rename from docs/api/threading/lambdatask/lambdatask.md rename to docs/api/threading/lambda-task/lambda-task.md diff --git a/docs/api/threading/mutex/lock_const.md b/docs/api/threading/mutex/lock-const.md similarity index 100% rename from docs/api/threading/mutex/lock_const.md rename to docs/api/threading/mutex/lock-const.md diff --git a/docs/api/threading/mutex/mutex.md b/docs/api/threading/mutex/mutex.md index 2cedc33e..095e740d 100644 --- a/docs/api/threading/mutex/mutex.md +++ b/docs/api/threading/mutex/mutex.md @@ -23,9 +23,9 @@ Mutex 类是对 std::mutex 的封装,提供线程安全的互斥访问机制 | [`Lock`](lock.md) | 获取互斥锁(非 const) | | [`Unlock`](unlock.md) | 释放互斥锁(非 const) | | [`TryLock`](trylock.md) | 尝试获取互斥锁(非 const) | -| [`lock`](lock_const.md) | 获取互斥锁(const,STL 兼容) | -| [`unlock`](unlock_const.md) | 释放互斥锁(const,STL 兼容) | -| [`try_lock`](try_lock_const.md) | 尝试获取互斥锁(const,STL 兼容) | +| [`lock`](lock-const.md) | 获取互斥锁(const,STL 兼容) | +| [`unlock`](unlock-const.md) | 释放互斥锁(const,STL 兼容) | +| [`try_lock`](try-lock-const.md) | 尝试获取互斥锁(const,STL 兼容) | ## 使用示例 @@ -58,6 +58,6 @@ int main() { ## 相关文档 - [SpinLock](../spinlock/spinlock.md) - 自旋锁 -- [ReadWriteLock](../readwritelock/readwritelock.md) - 读写锁 +- [ReadWriteLock](../read-write-lock/read-write-lock.md) - 读写锁 - [TaskSystem](../task-system/task-system.md) - 任务系统 - [../threading/threading.md](../threading.md) - 模块总览 diff --git a/docs/api/threading/mutex/try_lock_const.md b/docs/api/threading/mutex/try-lock-const.md similarity index 100% rename from docs/api/threading/mutex/try_lock_const.md rename to docs/api/threading/mutex/try-lock-const.md diff --git a/docs/api/threading/mutex/unlock_const.md b/docs/api/threading/mutex/unlock-const.md similarity index 100% rename from docs/api/threading/mutex/unlock_const.md rename to docs/api/threading/mutex/unlock-const.md diff --git a/docs/api/threading/readwritelock/constructor.md b/docs/api/threading/read-write-lock/constructor.md similarity index 100% rename from docs/api/threading/readwritelock/constructor.md rename to docs/api/threading/read-write-lock/constructor.md diff --git a/docs/api/threading/readwritelock/destructor.md b/docs/api/threading/read-write-lock/destructor.md similarity index 100% rename from docs/api/threading/readwritelock/destructor.md rename to docs/api/threading/read-write-lock/destructor.md diff --git a/docs/api/threading/readwritelock/readwritelock.md b/docs/api/threading/read-write-lock/read-write-lock.md similarity index 100% rename from docs/api/threading/readwritelock/readwritelock.md rename to docs/api/threading/read-write-lock/read-write-lock.md diff --git a/docs/api/threading/readwritelock/readlock.md b/docs/api/threading/read-write-lock/readlock.md similarity index 100% rename from docs/api/threading/readwritelock/readlock.md rename to docs/api/threading/read-write-lock/readlock.md diff --git a/docs/api/threading/readwritelock/readunlock.md b/docs/api/threading/read-write-lock/readunlock.md similarity index 100% rename from docs/api/threading/readwritelock/readunlock.md rename to docs/api/threading/read-write-lock/readunlock.md diff --git a/docs/api/threading/readwritelock/writelock.md b/docs/api/threading/read-write-lock/writelock.md similarity index 100% rename from docs/api/threading/readwritelock/writelock.md rename to docs/api/threading/read-write-lock/writelock.md diff --git a/docs/api/threading/readwritelock/writeunlock.md b/docs/api/threading/read-write-lock/writeunlock.md similarity index 100% rename from docs/api/threading/readwritelock/writeunlock.md rename to docs/api/threading/read-write-lock/writeunlock.md diff --git a/docs/api/threading/spinlock/lock_1.md b/docs/api/threading/spinlock/lock-stl.md similarity index 100% rename from docs/api/threading/spinlock/lock_1.md rename to docs/api/threading/spinlock/lock-stl.md diff --git a/docs/api/threading/spinlock/spinlock.md b/docs/api/threading/spinlock/spinlock.md index 3c026375..8bb2ee06 100644 --- a/docs/api/threading/spinlock/spinlock.md +++ b/docs/api/threading/spinlock/spinlock.md @@ -19,9 +19,9 @@ | [`Lock`](lock.md) | 获取锁(忙等待) | | [`Unlock`](unlock.md) | 释放锁 | | [`TryLock`](trylock.md) | 尝试获取锁(非阻塞) | -| [`lock`](lock_1.md) | STL 兼容的 Lock | -| [`unlock`](unlock_1.md) | STL 兼容的 Unlock | -| [`try_lock`](try_lock.md) | STL 兼容的 TryLock | +| [`lock`](lock-stl.md) | STL 兼容的 Lock | +| [`unlock`](unlock-stl.md) | STL 兼容的 Unlock | +| [`try_lock`](try-lock.md) | STL 兼容的 TryLock | ## STL 兼容方法 @@ -52,5 +52,5 @@ void SafeIncrement() { ## 相关文档 - [Mutex](../mutex/mutex.md) - 互斥锁 -- [ReadWriteLock](../readwritelock/readwritelock.md) - 读写锁 +- [ReadWriteLock](../read-write-lock/read-write-lock.md) - 读写锁 - [../threading.md](../threading.md) - 模块总览 diff --git a/docs/api/threading/spinlock/try_lock.md b/docs/api/threading/spinlock/try-lock.md similarity index 100% rename from docs/api/threading/spinlock/try_lock.md rename to docs/api/threading/spinlock/try-lock.md diff --git a/docs/api/threading/spinlock/unlock_1.md b/docs/api/threading/spinlock/unlock-stl.md similarity index 100% rename from docs/api/threading/spinlock/unlock_1.md rename to docs/api/threading/spinlock/unlock-stl.md diff --git a/docs/api/threading/task-group/constructor.md b/docs/api/threading/task-group/constructor.md new file mode 100644 index 00000000..caba323c --- /dev/null +++ b/docs/api/threading/task-group/constructor.md @@ -0,0 +1,34 @@ +# TaskGroup::TaskGroup + +```cpp +TaskGroup(); +``` + +默认构造函数。构造一个空的任务组。 + +**参数:** 无 + +**返回:** 无 + +**线程安全:** ✅ + +**复杂度:** O(1) + +**注意:** +- 构造后的任务组不包含任何任务。 +- 任务组创建后需要通过 TaskSystem::CreateTaskGroup() 实际创建。 + +**示例:** + +```cpp +#include "XCEngine/Threading/TaskGroup.h" + +XCEngine::Threading::TaskGroup group; +// 使用 group 添加任务... +``` + +## 相关文档 + +- [`TaskGroup`](task-group.md) - 返回类总览 +- [`AddTask`](add-task.md) - 添加任务 +- [`Wait`](wait.md) - 等待任务完成 diff --git a/docs/api/threading/task-group/destructor.md b/docs/api/threading/task-group/destructor.md new file mode 100644 index 00000000..30c96187 --- /dev/null +++ b/docs/api/threading/task-group/destructor.md @@ -0,0 +1,40 @@ +# TaskGroup::~TaskGroup + +```cpp +~TaskGroup(); +``` + +析构函数。销毁任务组。 + +**参数:** 无 + +**返回:** 无 + +**线程安全:** ⚠️ + +**复杂度:** O(n),n 为任务组中的任务数 + +**注意:** +- 析构前会等待所有任务完成。 +- 如果有任务正在执行,会等待其完成。 +- 未执行的任务将被取消。 + +**示例:** + +```cpp +#include "XCEngine/Threading/TaskGroup.h" + +{ + XCEngine::Threading::TaskGroup group; + group.AddTask([]() { + // 执行任务... + }); + group.Wait(); +} // group 在这里销毁 +``` + +## 相关文档 + +- [`TaskGroup`](task-group.md) - 返回类总览 +- [`Cancel`](cancel.md) - 取消任务 +- [`Wait`](wait.md) - 等待任务完成 diff --git a/docs/api/threading/task-group/task-group.md b/docs/api/threading/task-group/task-group.md index 14585706..feb3f782 100644 --- a/docs/api/threading/task-group/task-group.md +++ b/docs/api/threading/task-group/task-group.md @@ -24,8 +24,8 @@ TaskGroup 用于将多个相关任务组织在一起,统一管理它们的执 | 方法 | 描述 | |------|------| -| [`Task()`](task-group.md) | 默认构造函数 | -| [`~Task()`](task-group.md) | 析构函数 | +| [`Task()`](constructor.md) | 默认构造函数 | +| [`~Task()`](destructor.md) | 析构函数 | | [`AddTask`](add-task.md) | 添加任务到组(支持 ITask 或 Callback) | | [`AddDependency`](add-dependency.md) | 添加任务依赖关系 | | [`Wait`](wait.md) | 阻塞等待所有任务完成 | diff --git a/docs/api/threading/tasksystemconfig/enable-task-profiling.md b/docs/api/threading/task-system-config/enable-task-profiling.md similarity index 100% rename from docs/api/threading/tasksystemconfig/enable-task-profiling.md rename to docs/api/threading/task-system-config/enable-task-profiling.md diff --git a/docs/api/threading/tasksystemconfig/max-task-queue-size.md b/docs/api/threading/task-system-config/max-task-queue-size.md similarity index 100% rename from docs/api/threading/tasksystemconfig/max-task-queue-size.md rename to docs/api/threading/task-system-config/max-task-queue-size.md diff --git a/docs/api/threading/tasksystemconfig/steal-tasks.md b/docs/api/threading/task-system-config/steal-tasks.md similarity index 100% rename from docs/api/threading/tasksystemconfig/steal-tasks.md rename to docs/api/threading/task-system-config/steal-tasks.md diff --git a/docs/api/threading/tasksystemconfig/tasksystemconfig.md b/docs/api/threading/task-system-config/task-system-config.md similarity index 100% rename from docs/api/threading/tasksystemconfig/tasksystemconfig.md rename to docs/api/threading/task-system-config/task-system-config.md diff --git a/docs/api/threading/tasksystemconfig/thread-stack-size.md b/docs/api/threading/task-system-config/thread-stack-size.md similarity index 100% rename from docs/api/threading/tasksystemconfig/thread-stack-size.md rename to docs/api/threading/task-system-config/thread-stack-size.md diff --git a/docs/api/threading/tasksystemconfig/worker-thread-count.md b/docs/api/threading/task-system-config/worker-thread-count.md similarity index 100% rename from docs/api/threading/tasksystemconfig/worker-thread-count.md rename to docs/api/threading/task-system-config/worker-thread-count.md diff --git a/docs/api/threading/threading.md b/docs/api/threading/threading.md index 6ac0e86a..91956710 100644 --- a/docs/api/threading/threading.md +++ b/docs/api/threading/threading.md @@ -20,7 +20,7 @@ Threading 模块提供了一套完整的多线程编程工具,包括线程封 |------|------|------| | [Mutex](mutex/mutex.md) | `Mutex.h` | 互斥锁 | | [SpinLock](spinlock/spinlock.md) | `SpinLock.h` | 自旋锁 | -| [ReadWriteLock](readwritelock/readwritelock.md) | `ReadWriteLock.h` | 读写锁 | +| [ReadWriteLock](read-write-lock/read-write-lock.md) | `ReadWriteLock.h` | 读写锁 | ### 线程 @@ -33,10 +33,10 @@ Threading 模块提供了一套完整的多线程编程工具,包括线程封 | 组件 | 文件 | 描述 | |------|------|------| | [ITask](task/task.md) | `Task.h` | 任务基类 | -| [LambdaTask](lambdatask/lambdatask.md) | `LambdaTask.h` | Lambda 任务封装模板 | +| [LambdaTask](lambda-task/lambda-task.md) | `LambdaTask.h` | Lambda 任务封装模板 | | [TaskGroup](task-group/task-group.md) | `TaskGroup.h` | 任务组 | | [TaskSystem](task-system/task-system.md) | `TaskSystem.h` | 并行任务调度系统 | -| [TaskSystemConfig](tasksystemconfig/tasksystemconfig.md) | `TaskSystemConfig.h` | 任务系统配置 | +| [TaskSystemConfig](task-system-config/task-system-config.md) | `TaskSystemConfig.h` | 任务系统配置 | ## 同步原语对比 diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index eedf01c8..096278a7 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -85,7 +85,7 @@ add_library(XCEngine STATIC ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/RHIEnums.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/RHIFactory.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/RHIDescriptorPool.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12Enum.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12Enums.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12Device.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12CommandQueue.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12CommandAllocator.h @@ -155,7 +155,7 @@ add_library(XCEngine STATIC ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLRenderTargetView.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLDepthStencilView.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLScreenshot.cpp - ${CMAKE_SOURCE_DIR}/tests/OpenGL/package/src/glad.c + ${CMAKE_SOURCE_DIR}/tests/opengl/package/src/glad.c # RHI Factory ${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/RHIFactory.cpp @@ -283,7 +283,7 @@ target_include_directories(XCEngine PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/third_party - ${CMAKE_SOURCE_DIR}/tests/OpenGL/package/include + ${CMAKE_SOURCE_DIR}/tests/opengl/package/include ) if(MSVC) diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12Buffer.h b/engine/include/XCEngine/RHI/D3D12/D3D12Buffer.h index 44236de0..b02c718d 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12Buffer.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12Buffer.h @@ -5,7 +5,7 @@ #include #include "../RHIBuffer.h" -#include "D3D12Enum.h" +#include "D3D12Enums.h" using Microsoft::WRL::ComPtr; diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12CommandList.h b/engine/include/XCEngine/RHI/D3D12/D3D12CommandList.h index 295aed2b..1800e263 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12CommandList.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12CommandList.h @@ -8,7 +8,7 @@ #include "../RHICommandList.h" #include "../RHIEnums.h" #include "../RHITypes.h" -#include "D3D12Enum.h" +#include "D3D12Enums.h" using Microsoft::WRL::ComPtr; diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12CommandQueue.h b/engine/include/XCEngine/RHI/D3D12/D3D12CommandQueue.h index 261d73bf..52bb6b5f 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12CommandQueue.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12CommandQueue.h @@ -5,7 +5,7 @@ #include "../RHICommandQueue.h" #include "../RHIEnums.h" -#include "D3D12Enum.h" +#include "D3D12Enums.h" using Microsoft::WRL::ComPtr; diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12DepthStencilView.h b/engine/include/XCEngine/RHI/D3D12/D3D12DepthStencilView.h index 7146398c..74600227 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12DepthStencilView.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12DepthStencilView.h @@ -4,7 +4,7 @@ #include #include "../RHIEnums.h" -#include "D3D12Enum.h" +#include "D3D12Enums.h" using Microsoft::WRL::ComPtr; diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12DescriptorHeap.h b/engine/include/XCEngine/RHI/D3D12/D3D12DescriptorHeap.h index 9f0ccead..505f1e9e 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12DescriptorHeap.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12DescriptorHeap.h @@ -6,7 +6,7 @@ #include "../RHIEnums.h" #include "../RHITypes.h" #include "../RHIDescriptorPool.h" -#include "D3D12Enum.h" +#include "D3D12Enums.h" using Microsoft::WRL::ComPtr; diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12Device.h b/engine/include/XCEngine/RHI/D3D12/D3D12Device.h index 4e9b3862..92ce50fd 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12Device.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12Device.h @@ -9,7 +9,7 @@ #include "../RHIDevice.h" #include "../RHIEnums.h" #include "../RHITypes.h" -#include "D3D12Enum.h" +#include "D3D12Enums.h" using Microsoft::WRL::ComPtr; diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12Enum.h b/engine/include/XCEngine/RHI/D3D12/D3D12Enums.h similarity index 99% rename from engine/include/XCEngine/RHI/D3D12/D3D12Enum.h rename to engine/include/XCEngine/RHI/D3D12/D3D12Enums.h index 0328d27a..360d0d92 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12Enum.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12Enums.h @@ -293,4 +293,4 @@ inline D3D12_COMMAND_LIST_TYPE ToD3D12(CommandQueueType type) { } } // namespace RHI -} // namespace XCEngine +} // namespace XCEngine \ No newline at end of file diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12PipelineState.h b/engine/include/XCEngine/RHI/D3D12/D3D12PipelineState.h index eb8730b3..49248b3b 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12PipelineState.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12PipelineState.h @@ -6,7 +6,7 @@ #include "../RHIPipelineState.h" #include "../RHIEnums.h" -#include "D3D12Enum.h" +#include "D3D12Enums.h" using Microsoft::WRL::ComPtr; diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12QueryHeap.h b/engine/include/XCEngine/RHI/D3D12/D3D12QueryHeap.h index 1ac947b9..5308a75f 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12QueryHeap.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12QueryHeap.h @@ -4,7 +4,7 @@ #include #include -#include "D3D12Enum.h" +#include "D3D12Enums.h" using Microsoft::WRL::ComPtr; diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12RenderTargetView.h b/engine/include/XCEngine/RHI/D3D12/D3D12RenderTargetView.h index b9ce40fc..3034fe50 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12RenderTargetView.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12RenderTargetView.h @@ -4,7 +4,7 @@ #include #include "../RHIEnums.h" -#include "D3D12Enum.h" +#include "D3D12Enums.h" using Microsoft::WRL::ComPtr; diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12RootSignature.h b/engine/include/XCEngine/RHI/D3D12/D3D12RootSignature.h index 0dec1be3..36619bda 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12RootSignature.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12RootSignature.h @@ -5,7 +5,7 @@ #include #include "../RHIEnums.h" -#include "D3D12Enum.h" +#include "D3D12Enums.h" using Microsoft::WRL::ComPtr; diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12Sampler.h b/engine/include/XCEngine/RHI/D3D12/D3D12Sampler.h index 80ad7557..4240b4bf 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12Sampler.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12Sampler.h @@ -4,7 +4,7 @@ #include #include "../RHISampler.h" -#include "D3D12Enum.h" +#include "D3D12Enums.h" using Microsoft::WRL::ComPtr; diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12Shader.h b/engine/include/XCEngine/RHI/D3D12/D3D12Shader.h index 4f5fdfdd..6b3d329b 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12Shader.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12Shader.h @@ -6,7 +6,7 @@ #include #include "../RHIShader.h" -#include "D3D12Enum.h" +#include "D3D12Enums.h" #include "../RHITypes.h" using Microsoft::WRL::ComPtr; diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12ShaderResourceView.h b/engine/include/XCEngine/RHI/D3D12/D3D12ShaderResourceView.h index 53d04161..d570e5b6 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12ShaderResourceView.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12ShaderResourceView.h @@ -4,7 +4,7 @@ #include #include "../RHIEnums.h" -#include "D3D12Enum.h" +#include "D3D12Enums.h" using Microsoft::WRL::ComPtr; diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12SwapChain.h b/engine/include/XCEngine/RHI/D3D12/D3D12SwapChain.h index 5cb6af24..3f3488f8 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12SwapChain.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12SwapChain.h @@ -6,7 +6,7 @@ #include #include "../RHISwapChain.h" -#include "D3D12Enum.h" +#include "D3D12Enums.h" #include "D3D12Texture.h" using Microsoft::WRL::ComPtr; diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12Texture.h b/engine/include/XCEngine/RHI/D3D12/D3D12Texture.h index 7acdd6ff..ad4ce1f0 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12Texture.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12Texture.h @@ -5,7 +5,7 @@ #include #include "../RHITexture.h" -#include "D3D12Enum.h" +#include "D3D12Enums.h" using Microsoft::WRL::ComPtr; diff --git a/engine/src/RHI/D3D12/D3D12CommandAllocator.cpp b/engine/src/RHI/D3D12/D3D12CommandAllocator.cpp index 3de91348..ea43f380 100644 --- a/engine/src/RHI/D3D12/D3D12CommandAllocator.cpp +++ b/engine/src/RHI/D3D12/D3D12CommandAllocator.cpp @@ -1,5 +1,5 @@ #include "XCEngine/RHI/D3D12/D3D12CommandAllocator.h" -#include "XCEngine/RHI/D3D12/D3D12Enum.h" +#include "XCEngine/RHI/D3D12/D3D12Enums.h" namespace XCEngine { namespace RHI { diff --git a/engine/src/RHI/D3D12/D3D12Device.cpp b/engine/src/RHI/D3D12/D3D12Device.cpp index 1e2d25ee..d1c67711 100644 --- a/engine/src/RHI/D3D12/D3D12Device.cpp +++ b/engine/src/RHI/D3D12/D3D12Device.cpp @@ -217,7 +217,9 @@ RHIBuffer* D3D12Device::CreateBuffer(const BufferDesc& desc) { RHITexture* D3D12Device::CreateTexture(const TextureDesc& desc) { auto* texture = new D3D12Texture(); D3D12_RESOURCE_DESC d3d12Desc = {}; - d3d12Desc.Dimension = static_cast(desc.textureType); + + d3d12Desc.Dimension = ToD3D12(static_cast(desc.textureType)); + d3d12Desc.Width = desc.width; d3d12Desc.Height = desc.height; d3d12Desc.DepthOrArraySize = desc.depth; diff --git a/minimal.ppm b/minimal.ppm new file mode 100644 index 00000000..631172b1 Binary files /dev/null and b/minimal.ppm differ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 01ee14b9..f9e42cec 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -37,13 +37,11 @@ add_subdirectory(containers) add_subdirectory(memory) add_subdirectory(threading) add_subdirectory(debug) -add_subdirectory(Components) -add_subdirectory(Scene) -add_subdirectory(RHI) -add_subdirectory(RHI/D3D12) -add_subdirectory(RHI/OpenGL) -add_subdirectory(Resources) -add_subdirectory(Input) +add_subdirectory(components) +add_subdirectory(scene) +add_subdirectory(rhi) +add_subdirectory(resources) +add_subdirectory(input) # ============================================================ # Test Summary diff --git a/tests/Components/CMakeLists.txt b/tests/Components/CMakeLists.txt index cf6d1745..59c7a772 100644 --- a/tests/Components/CMakeLists.txt +++ b/tests/Components/CMakeLists.txt @@ -8,22 +8,23 @@ set(COMPONENTS_TEST_SOURCES test_game_object.cpp ) -add_executable(xcengine_components_tests ${COMPONENTS_TEST_SOURCES}) +add_executable(components_tests ${COMPONENTS_TEST_SOURCES}) if(MSVC) - set_target_properties(xcengine_components_tests PROPERTIES + set_target_properties(components_tests PROPERTIES LINK_FLAGS "/NODEFAULTLIB:libcpmt.lib /NODEFAULTLIB:libcmt.lib" ) endif() -target_link_libraries(xcengine_components_tests PRIVATE +target_link_libraries(components_tests PRIVATE XCEngine GTest::gtest GTest::gtest_main ) -target_include_directories(xcengine_components_tests PRIVATE +target_include_directories(components_tests PRIVATE ${CMAKE_SOURCE_DIR}/engine/include ) -add_test(NAME ComponentTests COMMAND xcengine_components_tests) \ No newline at end of file +include(GoogleTest) +gtest_discover_tests(components_tests) \ No newline at end of file diff --git a/tests/Input/CMakeLists.txt b/tests/Input/CMakeLists.txt index a90ea5fc..aa1763b3 100644 --- a/tests/Input/CMakeLists.txt +++ b/tests/Input/CMakeLists.txt @@ -7,24 +7,25 @@ set(INPUT_TEST_SOURCES test_windows_input_module.cpp ) -add_executable(xcengine_input_tests ${INPUT_TEST_SOURCES}) +add_executable(input_tests ${INPUT_TEST_SOURCES}) if(MSVC) - set_target_properties(xcengine_input_tests PROPERTIES + set_target_properties(input_tests PROPERTIES LINK_FLAGS "/NODEFAULTLIB:libcpmt.lib /NODEFAULTLIB:libcmt.lib" ) endif() -target_link_libraries(xcengine_input_tests +target_link_libraries(input_tests PRIVATE XCEngine GTest::gtest GTest::gtest_main ) -target_include_directories(xcengine_input_tests PRIVATE +target_include_directories(input_tests PRIVATE ${CMAKE_SOURCE_DIR}/engine/include ${CMAKE_SOURCE_DIR}/tests/fixtures ) -add_test(NAME InputTests COMMAND xcengine_input_tests) +include(GoogleTest) +gtest_discover_tests(input_tests) diff --git a/tests/RHI/CMakeLists.txt b/tests/RHI/CMakeLists.txt index b8c3e405..4c8a524e 100644 --- a/tests/RHI/CMakeLists.txt +++ b/tests/RHI/CMakeLists.txt @@ -5,41 +5,5 @@ project(RHIEngineTests) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -get_filename_component(PROJECT_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../.. ABSOLUTE) - -find_package(OpenGL REQUIRED) - -include_directories(${CMAKE_SOURCE_DIR}/tests/OpenGL/package/include/) -include_directories(${PROJECT_ROOT_DIR}/engine/include) -include_directories(${PROJECT_ROOT_DIR}/engine/src) - -link_directories(${CMAKE_SOURCE_DIR}/tests/OpenGL/package/lib/) - -find_package(GTest REQUIRED) - -set(TEST_SOURCES - test_factory.cpp -) - -add_executable(rhi_engine_tests ${TEST_SOURCES}) - -target_link_libraries(rhi_engine_tests PRIVATE - opengl32 - glfw3 - d3d12 - dxgi - d3dcompiler - XCEngine - GTest::gtest - GTest::gtest_main -) - -target_include_directories(rhi_engine_tests PRIVATE - ${PROJECT_ROOT_DIR}/engine/include - ${PROJECT_ROOT_DIR}/engine/src -) - -enable_testing() -add_test(NAME RHIEngineTests COMMAND rhi_engine_tests) - -add_subdirectory(unit) +add_subdirectory(D3D12) +add_subdirectory(OpenGL) diff --git a/tests/RHI/D3D12/CMakeLists.txt b/tests/RHI/D3D12/CMakeLists.txt index ac615394..8ffaf8ff 100644 --- a/tests/RHI/D3D12/CMakeLists.txt +++ b/tests/RHI/D3D12/CMakeLists.txt @@ -1,11 +1,9 @@ cmake_minimum_required(VERSION 3.15) -project(D3D12EngineTests) +project(rhi_d3d12_tests) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_subdirectory(unit) - -# Integration tests add_subdirectory(integration) diff --git a/tests/RHI/D3D12/integration/CMakeLists.txt b/tests/RHI/D3D12/integration/CMakeLists.txt index be0426ec..c5f37846 100644 --- a/tests/RHI/D3D12/integration/CMakeLists.txt +++ b/tests/RHI/D3D12/integration/CMakeLists.txt @@ -1,11 +1,7 @@ cmake_minimum_required(VERSION 3.15) -project(D3D12_Integration) - find_package(Python3 REQUIRED) -enable_testing() - add_subdirectory(minimal) add_subdirectory(triangle) add_subdirectory(quad) diff --git a/tests/RHI/D3D12/integration/minimal/CMakeLists.txt b/tests/RHI/D3D12/integration/minimal/CMakeLists.txt index 2d4256fa..2b9034c9 100644 --- a/tests/RHI/D3D12/integration/minimal/CMakeLists.txt +++ b/tests/RHI/D3D12/integration/minimal/CMakeLists.txt @@ -31,10 +31,10 @@ target_link_libraries(D3D12_Minimal PRIVATE add_custom_command(TARGET D3D12_Minimal POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_SOURCE_DIR}/tests/RHI/D3D12/integration/compare_ppm.py + ${CMAKE_SOURCE_DIR}/tests/rhi/d3d12/integration/compare_ppm.py $/ COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_SOURCE_DIR}/tests/RHI/D3D12/integration/run_integration_test.py + ${CMAKE_SOURCE_DIR}/tests/rhi/d3d12/integration/run_integration_test.py $/ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/GT.ppm diff --git a/tests/RHI/D3D12/integration/quad/CMakeLists.txt b/tests/RHI/D3D12/integration/quad/CMakeLists.txt index 4aeedbe7..53e48e26 100644 --- a/tests/RHI/D3D12/integration/quad/CMakeLists.txt +++ b/tests/RHI/D3D12/integration/quad/CMakeLists.txt @@ -40,10 +40,10 @@ add_custom_command(TARGET D3D12_Quad POST_BUILD add_custom_command(TARGET D3D12_Quad POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_SOURCE_DIR}/tests/RHI/D3D12/integration/compare_ppm.py + ${CMAKE_SOURCE_DIR}/tests/rhi/d3d12/integration/compare_ppm.py $/ COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_SOURCE_DIR}/tests/RHI/D3D12/integration/run_integration_test.py + ${CMAKE_SOURCE_DIR}/tests/rhi/d3d12/integration/run_integration_test.py $/ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/GT.ppm diff --git a/tests/RHI/D3D12/integration/sphere/CMakeLists.txt b/tests/RHI/D3D12/integration/sphere/CMakeLists.txt index 7a96d4a9..b41aa60b 100644 --- a/tests/RHI/D3D12/integration/sphere/CMakeLists.txt +++ b/tests/RHI/D3D12/integration/sphere/CMakeLists.txt @@ -38,10 +38,10 @@ add_custom_command(TARGET D3D12_Sphere POST_BUILD add_custom_command(TARGET D3D12_Sphere POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_SOURCE_DIR}/tests/RHI/D3D12/integration/compare_ppm.py + ${CMAKE_SOURCE_DIR}/tests/rhi/d3d12/integration/compare_ppm.py $/ COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_SOURCE_DIR}/tests/RHI/D3D12/integration/run_integration_test.py + ${CMAKE_SOURCE_DIR}/tests/rhi/d3d12/integration/run_integration_test.py $/ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/GT.ppm diff --git a/tests/RHI/D3D12/integration/triangle/CMakeLists.txt b/tests/RHI/D3D12/integration/triangle/CMakeLists.txt index 07332289..7078e717 100644 --- a/tests/RHI/D3D12/integration/triangle/CMakeLists.txt +++ b/tests/RHI/D3D12/integration/triangle/CMakeLists.txt @@ -37,10 +37,10 @@ add_custom_command(TARGET D3D12_Triangle POST_BUILD add_custom_command(TARGET D3D12_Triangle POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_SOURCE_DIR}/tests/RHI/D3D12/integration/compare_ppm.py + ${CMAKE_SOURCE_DIR}/tests/rhi/d3d12/integration/compare_ppm.py $/ COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_SOURCE_DIR}/tests/RHI/D3D12/integration/run_integration_test.py + ${CMAKE_SOURCE_DIR}/tests/rhi/d3d12/integration/run_integration_test.py $/ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/GT.ppm diff --git a/tests/RHI/D3D12/unit/CMakeLists.txt b/tests/RHI/D3D12/unit/CMakeLists.txt index 71f67893..a135f6e8 100644 --- a/tests/RHI/D3D12/unit/CMakeLists.txt +++ b/tests/RHI/D3D12/unit/CMakeLists.txt @@ -21,9 +21,9 @@ set(TEST_SOURCES test_swap_chain.cpp ) -add_executable(d3d12_engine_tests ${TEST_SOURCES}) +add_executable(rhi_d3d12_tests ${TEST_SOURCES}) -target_link_libraries(d3d12_engine_tests PRIVATE +target_link_libraries(rhi_d3d12_tests PRIVATE d3d12 dxgi d3dcompiler @@ -32,14 +32,12 @@ target_link_libraries(d3d12_engine_tests PRIVATE GTest::gtest_main ) -target_include_directories(d3d12_engine_tests PRIVATE +target_include_directories(rhi_d3d12_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/fixtures ${PROJECT_ROOT_DIR}/engine/include ${PROJECT_ROOT_DIR}/engine/src ) - - enable_testing() include(GoogleTest) -gtest_discover_tests(d3d12_engine_tests) +gtest_discover_tests(rhi_d3d12_tests) diff --git a/tests/RHI/D3D12/unit/fixtures/D3D12TestFixture.cpp b/tests/RHI/D3D12/unit/fixtures/D3D12TestFixture.cpp index 94cc5e12..a1204017 100644 --- a/tests/RHI/D3D12/unit/fixtures/D3D12TestFixture.cpp +++ b/tests/RHI/D3D12/unit/fixtures/D3D12TestFixture.cpp @@ -1,4 +1,8 @@ #include "D3D12TestFixture.h" +#include + +namespace XCEngine { +namespace RHI { void D3D12TestFixture::SetUpTestSuite() { } @@ -7,65 +11,67 @@ void D3D12TestFixture::TearDownTestSuite() { } void D3D12TestFixture::SetUp() { - HRESULT hr = D3D12CreateDevice( - nullptr, - D3D_FEATURE_LEVEL_12_0, - IID_PPV_ARGS(&mDevice) - ); + m_device = std::make_unique(); - if (FAILED(hr)) { - GTEST_SKIP() << "Failed to create D3D12 device"; + RHIDeviceDesc desc; + desc.enableDebugLayer = false; + desc.enableGPUValidation = false; + + if (!m_device->Initialize(desc)) { + GTEST_SKIP() << "Failed to initialize D3D12Device"; return; } - D3D12_COMMAND_QUEUE_DESC queueDesc = {}; - queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; - - hr = mDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue)); - if (FAILED(hr)) { + m_commandQueue = std::make_unique(); + if (!m_commandQueue->Initialize(m_device->GetDevice(), CommandQueueType::Direct)) { GTEST_SKIP() << "Failed to create command queue"; return; } - hr = mDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&mCommandAllocator)); - if (FAILED(hr)) { + m_commandAllocator = std::make_unique(); + if (!m_commandAllocator->Initialize(m_device->GetDevice(), CommandQueueType::Direct)) { GTEST_SKIP() << "Failed to create command allocator"; return; } - hr = mDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, mCommandAllocator.Get(), nullptr, IID_PPV_ARGS(&mCommandList)); - if (FAILED(hr)) { + m_commandList = std::make_unique(); + if (!m_commandList->Initialize(m_device->GetDevice(), CommandQueueType::Direct, m_commandAllocator->GetCommandAllocator())) { GTEST_SKIP() << "Failed to create command list"; return; } } void D3D12TestFixture::TearDown() { - if (mCommandQueue) { + if (m_commandQueue) { WaitForGPU(); } - mCommandList.Reset(); - mCommandAllocator.Reset(); - mCommandQueue.Reset(); - mDevice.Reset(); + if (m_commandList) { + m_commandList->Shutdown(); + m_commandList.reset(); + } + if (m_commandAllocator) { + m_commandAllocator->Shutdown(); + m_commandAllocator.reset(); + } + if (m_commandQueue) { + m_commandQueue->Shutdown(); + m_commandQueue.reset(); + } + if (m_device) { + m_device->Shutdown(); + m_device.reset(); + } } void D3D12TestFixture::WaitForGPU() { - if (!mCommandQueue || !mDevice) return; + if (!m_commandQueue) return; - ComPtr fence; - UINT64 fenceValue = 1; - - HRESULT hr = mDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)); - if (SUCCEEDED(hr)) { - mCommandQueue->Signal(fence.Get(), fenceValue); - if (fence->GetCompletedValue() < fenceValue) { - HANDLE eventHandle = CreateEvent(nullptr, FALSE, FALSE, nullptr); - if (eventHandle) { - fence->SetEventOnCompletion(fenceValue, eventHandle); - WaitForSingleObject(eventHandle, INFINITE); - CloseHandle(eventHandle); - } - } + auto fence = std::make_unique(); + if (fence->Initialize(m_device->GetDevice(), 0)) { + m_commandQueue->Signal(fence.get(), 1); + fence->Wait(1); } } + +} // namespace RHI +} // namespace XCEngine \ No newline at end of file diff --git a/tests/RHI/D3D12/unit/fixtures/D3D12TestFixture.h b/tests/RHI/D3D12/unit/fixtures/D3D12TestFixture.h index a0ac4597..829a7f15 100644 --- a/tests/RHI/D3D12/unit/fixtures/D3D12TestFixture.h +++ b/tests/RHI/D3D12/unit/fixtures/D3D12TestFixture.h @@ -1,8 +1,6 @@ #pragma once #include -#include -#include #include #include "XCEngine/RHI/D3D12/D3D12Device.h" @@ -11,7 +9,8 @@ #include "XCEngine/RHI/D3D12/D3D12CommandList.h" #include "XCEngine/RHI/D3D12/D3D12Fence.h" -using namespace Microsoft::WRL; +namespace XCEngine { +namespace RHI { class D3D12TestFixture : public ::testing::Test { protected: @@ -21,16 +20,19 @@ protected: void SetUp() override; void TearDown() override; - ID3D12Device* GetDevice() { return mDevice.Get(); } - ID3D12CommandQueue* GetCommandQueue() { return mCommandQueue.Get(); } - ID3D12GraphicsCommandList* GetCommandList() { return mCommandList.Get(); } - ID3D12CommandAllocator* GetCommandAllocator() { return mCommandAllocator.Get(); } + D3D12Device* GetDevice() { return m_device.get(); } + D3D12CommandQueue* GetCommandQueue() { return m_commandQueue.get(); } + D3D12CommandList* GetCommandList() { return m_commandList.get(); } + D3D12CommandAllocator* GetCommandAllocator() { return m_commandAllocator.get(); } void WaitForGPU(); private: - ComPtr mDevice; - ComPtr mCommandQueue; - ComPtr mCommandAllocator; - ComPtr mCommandList; + std::unique_ptr m_device; + std::unique_ptr m_commandQueue; + std::unique_ptr m_commandAllocator; + std::unique_ptr m_commandList; }; + +} // namespace RHI +} // namespace XCEngine \ No newline at end of file diff --git a/tests/RHI/D3D12/unit/test_buffer.cpp b/tests/RHI/D3D12/unit/test_buffer.cpp index 286c0155..3e2a35c7 100644 --- a/tests/RHI/D3D12/unit/test_buffer.cpp +++ b/tests/RHI/D3D12/unit/test_buffer.cpp @@ -1,146 +1,78 @@ #include "fixtures/D3D12TestFixture.h" +#include "XCEngine/RHI/D3D12/D3D12Buffer.h" +#include "XCEngine/RHI/RHIEnums.h" + +using namespace XCEngine::RHI; TEST_F(D3D12TestFixture, Buffer_Create_DefaultHeap) { - const uint64_t bufferSize = 1024; + BufferDesc desc = {}; + desc.size = 1024; + desc.stride = 0; + desc.bufferType = static_cast(BufferType::Vertex); + desc.flags = 0; - D3D12_HEAP_PROPERTIES heapProps = {}; - heapProps.Type = D3D12_HEAP_TYPE_DEFAULT; - heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; - heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + RHIBuffer* buffer = GetDevice()->CreateBuffer(desc); + ASSERT_NE(buffer, nullptr); - D3D12_RESOURCE_DESC resourceDesc = {}; - resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - resourceDesc.Width = bufferSize; - resourceDesc.Height = 1; - resourceDesc.DepthOrArraySize = 1; - resourceDesc.MipLevels = 1; - resourceDesc.Format = DXGI_FORMAT_UNKNOWN; - resourceDesc.SampleDesc.Count = 1; - resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + auto* d3d12Buffer = static_cast(buffer); + EXPECT_EQ(d3d12Buffer->GetSize(), 1024); - D3D12_RESOURCE_STATES initialState = D3D12_RESOURCE_STATE_COMMON; - - ComPtr buffer; - HRESULT hr = GetDevice()->CreateCommittedResource( - &heapProps, - D3D12_HEAP_FLAG_NONE, - &resourceDesc, - initialState, - nullptr, - IID_PPV_ARGS(&buffer) - ); - ASSERT_HRESULT_SUCCEEDED(hr); - ASSERT_NE(buffer.Get(), nullptr); - - D3D12_RESOURCE_DESC desc = buffer->GetDesc(); - EXPECT_EQ(desc.Dimension, D3D12_RESOURCE_DIMENSION_BUFFER); - EXPECT_EQ(desc.Width, bufferSize); + buffer->Shutdown(); + delete buffer; } TEST_F(D3D12TestFixture, Buffer_Create_UploadHeap) { - const uint64_t bufferSize = 2048; + BufferDesc desc = {}; + desc.size = 2048; + desc.stride = 0; + desc.bufferType = static_cast(BufferType::Constant); + desc.flags = 0; - D3D12_HEAP_PROPERTIES heapProps = {}; - heapProps.Type = D3D12_HEAP_TYPE_UPLOAD; - heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; - heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + RHIBuffer* buffer = GetDevice()->CreateBuffer(desc); + ASSERT_NE(buffer, nullptr); - D3D12_RESOURCE_DESC resourceDesc = {}; - resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - resourceDesc.Width = bufferSize; - resourceDesc.Height = 1; - resourceDesc.DepthOrArraySize = 1; - resourceDesc.MipLevels = 1; - resourceDesc.Format = DXGI_FORMAT_UNKNOWN; - resourceDesc.SampleDesc.Count = 1; - resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - - ComPtr buffer; - HRESULT hr = GetDevice()->CreateCommittedResource( - &heapProps, - D3D12_HEAP_FLAG_NONE, - &resourceDesc, - D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, - IID_PPV_ARGS(&buffer) - ); - ASSERT_HRESULT_SUCCEEDED(hr); - ASSERT_NE(buffer.Get(), nullptr); + buffer->Shutdown(); + delete buffer; } TEST_F(D3D12TestFixture, Buffer_Get_GPUVirtualAddress) { - const uint64_t bufferSize = 512; + BufferDesc desc = {}; + desc.size = 512; + desc.stride = 0; + desc.bufferType = static_cast(BufferType::Vertex); + desc.flags = 0; - D3D12_HEAP_PROPERTIES heapProps = {}; - heapProps.Type = D3D12_HEAP_TYPE_DEFAULT; + RHIBuffer* buffer = GetDevice()->CreateBuffer(desc); + ASSERT_NE(buffer, nullptr); - D3D12_RESOURCE_DESC resourceDesc = {}; - resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - resourceDesc.Width = bufferSize; - resourceDesc.Height = 1; - resourceDesc.DepthOrArraySize = 1; - resourceDesc.MipLevels = 1; - resourceDesc.Format = DXGI_FORMAT_UNKNOWN; - resourceDesc.SampleDesc.Count = 1; - resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + auto* d3d12Buffer = static_cast(buffer); + EXPECT_NE(d3d12Buffer->GetGPUAddress(), 0); - ComPtr buffer; - HRESULT hr = GetDevice()->CreateCommittedResource( - &heapProps, - D3D12_HEAP_FLAG_NONE, - &resourceDesc, - D3D12_RESOURCE_STATE_COMMON, - nullptr, - IID_PPV_ARGS(&buffer) - ); - ASSERT_HRESULT_SUCCEEDED(hr); - - D3D12_GPU_VIRTUAL_ADDRESS gpuAddress = buffer->GetGPUVirtualAddress(); - EXPECT_NE(gpuAddress, 0); + buffer->Shutdown(); + delete buffer; } TEST_F(D3D12TestFixture, Buffer_Map_Unmap) { - const uint64_t bufferSize = 256; + BufferDesc desc = {}; + desc.size = 256; + desc.stride = 0; + desc.bufferType = static_cast(BufferType::Constant); + desc.flags = 0; - D3D12_HEAP_PROPERTIES heapProps = {}; - heapProps.Type = D3D12_HEAP_TYPE_UPLOAD; + RHIBuffer* buffer = GetDevice()->CreateBuffer(desc); + ASSERT_NE(buffer, nullptr); - D3D12_RESOURCE_DESC resourceDesc = {}; - resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - resourceDesc.Width = bufferSize; - resourceDesc.Height = 1; - resourceDesc.DepthOrArraySize = 1; - resourceDesc.MipLevels = 1; - resourceDesc.Format = DXGI_FORMAT_UNKNOWN; - resourceDesc.SampleDesc.Count = 1; - resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - - ComPtr buffer; - HRESULT hr = GetDevice()->CreateCommittedResource( - &heapProps, - D3D12_HEAP_FLAG_NONE, - &resourceDesc, - D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, - IID_PPV_ARGS(&buffer) - ); - ASSERT_HRESULT_SUCCEEDED(hr); - - void* mappedData = nullptr; - hr = buffer->Map(0, nullptr, &mappedData); - ASSERT_HRESULT_SUCCEEDED(hr); + void* mappedData = buffer->Map(); ASSERT_NE(mappedData, nullptr); - memset(mappedData, 0xAB, static_cast(bufferSize)); + memset(mappedData, 0xAB, 256); - buffer->Unmap(0, nullptr); + buffer->Unmap(); + + buffer->Shutdown(); + delete buffer; } TEST_F(D3D12TestFixture, Buffer_Get_AlignmentRequirements) { - D3D12_CONSTANT_BUFFER_VIEW_DESC cbvDesc = {}; - cbvDesc.BufferLocation = 256; - cbvDesc.SizeInBytes = 256; - - EXPECT_GE(cbvDesc.SizeInBytes, 256); - EXPECT_EQ(cbvDesc.BufferLocation % 256, 0); -} + EXPECT_GE(256 % 256, 0); +} \ No newline at end of file diff --git a/tests/RHI/D3D12/unit/test_command_allocator.cpp b/tests/RHI/D3D12/unit/test_command_allocator.cpp index 17f9f623..22553130 100644 --- a/tests/RHI/D3D12/unit/test_command_allocator.cpp +++ b/tests/RHI/D3D12/unit/test_command_allocator.cpp @@ -1,41 +1,35 @@ #include "fixtures/D3D12TestFixture.h" +#include "XCEngine/RHI/D3D12/D3D12CommandAllocator.h" + +using namespace XCEngine::RHI; TEST_F(D3D12TestFixture, CommandAllocator_Reset_Basic) { - ComPtr allocator; - HRESULT hr = GetDevice()->CreateCommandAllocator( - D3D12_COMMAND_LIST_TYPE_DIRECT, - IID_PPV_ARGS(&allocator) - ); - ASSERT_HRESULT_SUCCEEDED(hr); + auto allocator = std::make_unique(); + ASSERT_TRUE(allocator->Initialize(GetDevice()->GetDevice(), CommandQueueType::Direct)); - hr = allocator->Reset(); - ASSERT_HRESULT_SUCCEEDED(hr); + allocator->Reset(); + EXPECT_TRUE(allocator->IsReady()); } TEST_F(D3D12TestFixture, CommandAllocator_Reset_Multiple) { - ComPtr allocator; - HRESULT hr = GetDevice()->CreateCommandAllocator( - D3D12_COMMAND_LIST_TYPE_DIRECT, - IID_PPV_ARGS(&allocator) - ); - ASSERT_HRESULT_SUCCEEDED(hr); + auto allocator = std::make_unique(); + ASSERT_TRUE(allocator->Initialize(GetDevice()->GetDevice(), CommandQueueType::Direct)); for (int i = 0; i < 10; ++i) { - hr = allocator->Reset(); - ASSERT_HRESULT_SUCCEEDED(hr); + allocator->Reset(); + EXPECT_TRUE(allocator->IsReady()); } } TEST_F(D3D12TestFixture, CommandAllocator_Create_DifferentTypes) { - D3D12_COMMAND_LIST_TYPE types[] = { - D3D12_COMMAND_LIST_TYPE_DIRECT, - D3D12_COMMAND_LIST_TYPE_COMPUTE, - D3D12_COMMAND_LIST_TYPE_COPY + CommandQueueType types[] = { + CommandQueueType::Direct, + CommandQueueType::Compute, + CommandQueueType::Copy }; for (auto type : types) { - ComPtr allocator; - HRESULT hr = GetDevice()->CreateCommandAllocator(type, IID_PPV_ARGS(&allocator)); - ASSERT_HRESULT_SUCCEEDED(hr); + auto allocator = std::make_unique(); + ASSERT_TRUE(allocator->Initialize(GetDevice()->GetDevice(), type)); } -} +} \ No newline at end of file diff --git a/tests/RHI/D3D12/unit/test_command_list.cpp b/tests/RHI/D3D12/unit/test_command_list.cpp index 9ce27021..30fd4fa3 100644 --- a/tests/RHI/D3D12/unit/test_command_list.cpp +++ b/tests/RHI/D3D12/unit/test_command_list.cpp @@ -1,11 +1,14 @@ #include "fixtures/D3D12TestFixture.h" +#include "XCEngine/RHI/D3D12/D3D12Enums.h" + +using namespace XCEngine::RHI; TEST_F(D3D12TestFixture, CommandList_Close_Basic) { - HRESULT hr = GetCommandList()->Close(); - ASSERT_HRESULT_SUCCEEDED(hr); + GetCommandList()->Reset(); + GetCommandList()->Close(); } TEST_F(D3D12TestFixture, CommandList_Get_Desc) { - D3D12_COMMAND_LIST_TYPE type = GetCommandList()->GetType(); + auto type = GetCommandList()->GetCommandList()->GetType(); EXPECT_EQ(type, D3D12_COMMAND_LIST_TYPE_DIRECT); -} +} \ No newline at end of file diff --git a/tests/RHI/D3D12/unit/test_command_queue.cpp b/tests/RHI/D3D12/unit/test_command_queue.cpp index 3adcb661..15f15dcd 100644 --- a/tests/RHI/D3D12/unit/test_command_queue.cpp +++ b/tests/RHI/D3D12/unit/test_command_queue.cpp @@ -1,23 +1,18 @@ #include "fixtures/D3D12TestFixture.h" +#include "XCEngine/RHI/D3D12/D3D12CommandQueue.h" + +using namespace XCEngine::RHI; TEST_F(D3D12TestFixture, CommandQueue_Get_TimestampFrequency) { - D3D12_COMMAND_QUEUE_DESC desc = {}; - desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; - - ComPtr queue; - HRESULT hr = GetDevice()->CreateCommandQueue(&desc, IID_PPV_ARGS(&queue)); - ASSERT_HRESULT_SUCCEEDED(hr); - - UINT64 frequency; - hr = queue->GetTimestampFrequency(&frequency); - ASSERT_HRESULT_SUCCEEDED(hr); + ASSERT_NE(GetCommandQueue(), nullptr); + UINT64 frequency = GetCommandQueue()->GetTimestampFrequency(); EXPECT_GT(frequency, 0); } TEST_F(D3D12TestFixture, CommandQueue_Execute_EmptyCommandLists) { - GetCommandList()->Reset(GetCommandAllocator(), nullptr); - ID3D12CommandList* commandLists[] = { GetCommandList() }; + GetCommandList()->Reset(); + void* commandLists[] = { GetCommandList()->GetCommandList() }; GetCommandQueue()->ExecuteCommandLists(1, commandLists); GetCommandList()->Close(); WaitForGPU(); -} +} \ No newline at end of file diff --git a/tests/RHI/D3D12/unit/test_descriptor_heap.cpp b/tests/RHI/D3D12/unit/test_descriptor_heap.cpp index 48d353f0..31346151 100644 --- a/tests/RHI/D3D12/unit/test_descriptor_heap.cpp +++ b/tests/RHI/D3D12/unit/test_descriptor_heap.cpp @@ -5,7 +5,7 @@ using namespace XCEngine::RHI; TEST_F(D3D12TestFixture, DescriptorHeap_Wrapper_Initialize_RTV) { D3D12DescriptorHeap heap; - bool result = heap.Initialize(GetDevice(), DescriptorHeapType::RTV, 4); + bool result = heap.Initialize(GetDevice()->GetDevice(), DescriptorHeapType::RTV, 4); ASSERT_TRUE(result); EXPECT_EQ(heap.GetDescriptorCount(), 4u); EXPECT_EQ(heap.GetType(), DescriptorHeapType::RTV); @@ -14,7 +14,7 @@ TEST_F(D3D12TestFixture, DescriptorHeap_Wrapper_Initialize_RTV) { TEST_F(D3D12TestFixture, DescriptorHeap_Wrapper_GetCPUDescriptorHandle) { D3D12DescriptorHeap heap; - ASSERT_TRUE(heap.Initialize(GetDevice(), DescriptorHeapType::RTV, 4)); + ASSERT_TRUE(heap.Initialize(GetDevice()->GetDevice(), DescriptorHeapType::RTV, 4)); uint32_t descriptorSize = heap.GetDescriptorSize(); CPUDescriptorHandle handle0 = heap.GetCPUDescriptorHandle(0); @@ -29,7 +29,7 @@ TEST_F(D3D12TestFixture, DescriptorHeap_Wrapper_GetCPUDescriptorHandle) { TEST_F(D3D12TestFixture, DescriptorHeap_Wrapper_GetGPUDescriptorHandle) { D3D12DescriptorHeap heap; - ASSERT_TRUE(heap.Initialize(GetDevice(), DescriptorHeapType::CBV_SRV_UAV, 4, true)); + ASSERT_TRUE(heap.Initialize(GetDevice()->GetDevice(), DescriptorHeapType::CBV_SRV_UAV, 4, true)); uint32_t descriptorSize = heap.GetDescriptorSize(); GPUDescriptorHandle handle0 = heap.GetGPUDescriptorHandle(0); @@ -42,86 +42,60 @@ TEST_F(D3D12TestFixture, DescriptorHeap_Wrapper_GetGPUDescriptorHandle) { TEST_F(D3D12TestFixture, DescriptorHeap_Wrapper_GetDescriptorSize) { D3D12DescriptorHeap rtvHeap; - ASSERT_TRUE(rtvHeap.Initialize(GetDevice(), DescriptorHeapType::RTV, 4)); + ASSERT_TRUE(rtvHeap.Initialize(GetDevice()->GetDevice(), DescriptorHeapType::RTV, 4)); EXPECT_GT(rtvHeap.GetDescriptorSize(), 0u); D3D12DescriptorHeap cbvHeap; - ASSERT_TRUE(cbvHeap.Initialize(GetDevice(), DescriptorHeapType::CBV_SRV_UAV, 4)); + ASSERT_TRUE(cbvHeap.Initialize(GetDevice()->GetDevice(), DescriptorHeapType::CBV_SRV_UAV, 4)); EXPECT_GT(cbvHeap.GetDescriptorSize(), 0u); } TEST_F(D3D12TestFixture, DescriptorHeap_Wrapper_Shutdown) { D3D12DescriptorHeap heap; - ASSERT_TRUE(heap.Initialize(GetDevice(), DescriptorHeapType::RTV, 2)); + ASSERT_TRUE(heap.Initialize(GetDevice()->GetDevice(), DescriptorHeapType::RTV, 2)); heap.Shutdown(); } TEST_F(D3D12TestFixture, DescriptorHeap_Create_CBV_SRV_UAV) { - D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {}; - heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - heapDesc.NumDescriptors = 10; - heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - - ComPtr descriptorHeap; - HRESULT hr = GetDevice()->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&descriptorHeap)); - ASSERT_HRESULT_SUCCEEDED(hr); - ASSERT_NE(descriptorHeap.Get(), nullptr); - - D3D12_DESCRIPTOR_HEAP_DESC desc = descriptorHeap->GetDesc(); - EXPECT_EQ(desc.Type, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - EXPECT_EQ(desc.NumDescriptors, 10); + D3D12DescriptorHeap heap; + bool result = heap.Initialize(GetDevice()->GetDevice(), DescriptorHeapType::CBV_SRV_UAV, 10, true); + ASSERT_TRUE(result); + EXPECT_EQ(heap.GetDescriptorCount(), 10u); + heap.Shutdown(); } TEST_F(D3D12TestFixture, DescriptorHeap_Create_Sampler) { - D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {}; - heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; - heapDesc.NumDescriptors = 5; - heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - - ComPtr descriptorHeap; - HRESULT hr = GetDevice()->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&descriptorHeap)); - ASSERT_HRESULT_SUCCEEDED(hr); - - D3D12_DESCRIPTOR_HEAP_DESC desc = descriptorHeap->GetDesc(); - EXPECT_EQ(desc.Type, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); + D3D12DescriptorHeap heap; + bool result = heap.Initialize(GetDevice()->GetDevice(), DescriptorHeapType::Sampler, 5, true); + ASSERT_TRUE(result); + EXPECT_EQ(heap.GetType(), DescriptorHeapType::Sampler); + heap.Shutdown(); } TEST_F(D3D12TestFixture, DescriptorHeap_Create_RTV) { - D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {}; - heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; - heapDesc.NumDescriptors = 4; - heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; - - ComPtr descriptorHeap; - HRESULT hr = GetDevice()->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&descriptorHeap)); - ASSERT_HRESULT_SUCCEEDED(hr); - - D3D12_DESCRIPTOR_HEAP_DESC desc = descriptorHeap->GetDesc(); - EXPECT_EQ(desc.Type, D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + D3D12DescriptorHeap heap; + bool result = heap.Initialize(GetDevice()->GetDevice(), DescriptorHeapType::RTV, 4, false); + ASSERT_TRUE(result); + EXPECT_EQ(heap.GetType(), DescriptorHeapType::RTV); + heap.Shutdown(); } TEST_F(D3D12TestFixture, DescriptorHeap_Create_DSV) { - D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {}; - heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; - heapDesc.NumDescriptors = 2; - heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; - - ComPtr descriptorHeap; - HRESULT hr = GetDevice()->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&descriptorHeap)); - ASSERT_HRESULT_SUCCEEDED(hr); - - D3D12_DESCRIPTOR_HEAP_DESC desc = descriptorHeap->GetDesc(); - EXPECT_EQ(desc.Type, D3D12_DESCRIPTOR_HEAP_TYPE_DSV); + D3D12DescriptorHeap heap; + bool result = heap.Initialize(GetDevice()->GetDevice(), DescriptorHeapType::DSV, 2, false); + ASSERT_TRUE(result); + EXPECT_EQ(heap.GetType(), DescriptorHeapType::DSV); + heap.Shutdown(); } TEST_F(D3D12TestFixture, DescriptorHeap_Get_HandleIncrementSize) { - UINT cbvSrvUavSize = GetDevice()->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); - UINT samplerSize = GetDevice()->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); - UINT rtvSize = GetDevice()->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); - UINT dsvSize = GetDevice()->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); + UINT cbvSrvUavSize = GetDevice()->GetDescriptorHandleIncrementSize(DescriptorHeapType::CBV_SRV_UAV); + UINT samplerSize = GetDevice()->GetDescriptorHandleIncrementSize(DescriptorHeapType::Sampler); + UINT rtvSize = GetDevice()->GetDescriptorHandleIncrementSize(DescriptorHeapType::RTV); + UINT dsvSize = GetDevice()->GetDescriptorHandleIncrementSize(DescriptorHeapType::DSV); EXPECT_GT(cbvSrvUavSize, 0); EXPECT_GT(samplerSize, 0); EXPECT_GT(rtvSize, 0); EXPECT_GT(dsvSize, 0); -} +} \ No newline at end of file diff --git a/tests/RHI/D3D12/unit/test_device.cpp b/tests/RHI/D3D12/unit/test_device.cpp index 5d7d547d..5616c4e7 100644 --- a/tests/RHI/D3D12/unit/test_device.cpp +++ b/tests/RHI/D3D12/unit/test_device.cpp @@ -1,38 +1,40 @@ #include "fixtures/D3D12TestFixture.h" -#include -#include -#include +#include "XCEngine/RHI/RHIEnums.h" + +using namespace XCEngine::RHI; TEST_F(D3D12TestFixture, Device_Create_Success) { ASSERT_NE(GetDevice(), nullptr); + ASSERT_NE(GetDevice()->GetDevice(), nullptr); } TEST_F(D3D12TestFixture, Device_Get_CommandQueue) { ASSERT_NE(GetCommandQueue(), nullptr); + ASSERT_NE(GetCommandQueue()->GetCommandQueue(), nullptr); } TEST_F(D3D12TestFixture, Device_Get_FeatureLevel) { - static const D3D_FEATURE_LEVEL requestedLevels[] = { D3D_FEATURE_LEVEL_12_0 }; D3D12_FEATURE_DATA_FEATURE_LEVELS featureLevels = {}; + static const D3D_FEATURE_LEVEL requestedLevels[] = { D3D_FEATURE_LEVEL_12_0 }; featureLevels.NumFeatureLevels = 1; featureLevels.pFeatureLevelsRequested = requestedLevels; - HRESULT hr = GetDevice()->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS, &featureLevels, sizeof(featureLevels)); - ASSERT_HRESULT_SUCCEEDED(hr); + bool result = GetDevice()->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS, &featureLevels, sizeof(featureLevels)); + ASSERT_TRUE(result); EXPECT_EQ(featureLevels.MaxSupportedFeatureLevel, D3D_FEATURE_LEVEL_12_0); } TEST_F(D3D12TestFixture, Device_Get_DescriptorHandleIncrementSize) { - UINT cbvSrvUavSize = GetDevice()->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + UINT cbvSrvUavSize = GetDevice()->GetDescriptorHandleIncrementSize(DescriptorHeapType::CBV_SRV_UAV); EXPECT_GT(cbvSrvUavSize, 0); - UINT samplerSize = GetDevice()->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); + UINT samplerSize = GetDevice()->GetDescriptorHandleIncrementSize(DescriptorHeapType::Sampler); EXPECT_GT(samplerSize, 0); - UINT rtvSize = GetDevice()->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + UINT rtvSize = GetDevice()->GetDescriptorHandleIncrementSize(DescriptorHeapType::RTV); EXPECT_GT(rtvSize, 0); - UINT dsvSize = GetDevice()->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); + UINT dsvSize = GetDevice()->GetDescriptorHandleIncrementSize(DescriptorHeapType::DSV); EXPECT_GT(dsvSize, 0); } @@ -40,23 +42,23 @@ TEST_F(D3D12TestFixture, Device_Get_ShaderModelSupport) { D3D12_FEATURE_DATA_SHADER_MODEL shaderModel = {}; shaderModel.HighestShaderModel = D3D_SHADER_MODEL_6_0; - HRESULT hr = GetDevice()->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &shaderModel, sizeof(shaderModel)); - ASSERT_HRESULT_SUCCEEDED(hr); + bool result = GetDevice()->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &shaderModel, sizeof(shaderModel)); + ASSERT_TRUE(result); EXPECT_GE(shaderModel.HighestShaderModel, D3D_SHADER_MODEL_6_0); } TEST_F(D3D12TestFixture, Device_Get_ResourceBindingTier) { D3D12_FEATURE_DATA_D3D12_OPTIONS options = {}; - HRESULT hr = GetDevice()->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options)); - ASSERT_HRESULT_SUCCEEDED(hr); + bool result = GetDevice()->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options)); + ASSERT_TRUE(result); EXPECT_GE(options.ResourceBindingTier, D3D12_RESOURCE_BINDING_TIER_1); } TEST_F(D3D12TestFixture, Device_Get_TiledResourcesTier) { D3D12_FEATURE_DATA_D3D12_OPTIONS options = {}; - HRESULT hr = GetDevice()->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options)); - ASSERT_HRESULT_SUCCEEDED(hr); + bool result = GetDevice()->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options)); + ASSERT_TRUE(result); EXPECT_GE(options.TiledResourcesTier, D3D12_TILED_RESOURCES_TIER_NOT_SUPPORTED); -} +} \ No newline at end of file diff --git a/tests/RHI/D3D12/unit/test_fence.cpp b/tests/RHI/D3D12/unit/test_fence.cpp index 472bdc41..ec4e4004 100644 --- a/tests/RHI/D3D12/unit/test_fence.cpp +++ b/tests/RHI/D3D12/unit/test_fence.cpp @@ -1,60 +1,70 @@ #include "fixtures/D3D12TestFixture.h" +#include "XCEngine/RHI/D3D12/D3D12Fence.h" #include +using namespace XCEngine::RHI; + TEST_F(D3D12TestFixture, Fence_Create_Success) { ASSERT_NE(GetDevice(), nullptr); - ComPtr fence; - HRESULT hr = GetDevice()->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)); - ASSERT_HRESULT_SUCCEEDED(hr); - ASSERT_NE(fence.Get(), nullptr); + FenceDesc desc = {}; + desc.initialValue = 0; + desc.flags = 0; + + RHIFence* fence = GetDevice()->CreateFence(desc); + ASSERT_NE(fence, nullptr); + + fence->Shutdown(); + delete fence; } TEST_F(D3D12TestFixture, Fence_Get_CompletedValue_Initial) { - ComPtr fence; - HRESULT hr = GetDevice()->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)); - ASSERT_HRESULT_SUCCEEDED(hr); + FenceDesc desc = {}; + desc.initialValue = 0; + desc.flags = 0; + + RHIFence* fence = GetDevice()->CreateFence(desc); + ASSERT_NE(fence, nullptr); EXPECT_EQ(fence->GetCompletedValue(), 0); + + fence->Shutdown(); + delete fence; } TEST_F(D3D12TestFixture, Fence_Signal_Wait) { - ComPtr fence; - HRESULT hr = GetDevice()->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)); - ASSERT_HRESULT_SUCCEEDED(hr); + FenceDesc desc = {}; + desc.initialValue = 0; + desc.flags = 0; + + RHIFence* fence = GetDevice()->CreateFence(desc); + ASSERT_NE(fence, nullptr); const UINT64 fenceValue = 100; - hr = GetCommandQueue()->Signal(fence.Get(), fenceValue); - ASSERT_HRESULT_SUCCEEDED(hr); - - HANDLE eventHandle = CreateEvent(nullptr, FALSE, FALSE, nullptr); - ASSERT_NE(eventHandle, nullptr); - - hr = fence->SetEventOnCompletion(fenceValue, eventHandle); - ASSERT_HRESULT_SUCCEEDED(hr); - - DWORD waitResult = WaitForSingleObject(eventHandle, 1000); - EXPECT_EQ(waitResult, WAIT_OBJECT_0); + GetCommandQueue()->Signal(fence, fenceValue); + fence->Wait(fenceValue); EXPECT_EQ(fence->GetCompletedValue(), fenceValue); - CloseHandle(eventHandle); + fence->Shutdown(); + delete fence; } TEST_F(D3D12TestFixture, Fence_Set_EventOnCompletion) { - ComPtr fence; - HRESULT hr = GetDevice()->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)); - ASSERT_HRESULT_SUCCEEDED(hr); + FenceDesc desc = {}; + desc.initialValue = 0; + desc.flags = 0; + + auto* fence = new D3D12Fence(); + ASSERT_TRUE(fence->Initialize(GetDevice()->GetDevice(), 200)); const UINT64 fenceValue = 200; - hr = GetCommandQueue()->Signal(fence.Get(), fenceValue); - ASSERT_HRESULT_SUCCEEDED(hr); + GetCommandQueue()->Signal(fence, fenceValue); HANDLE eventHandle = CreateEvent(nullptr, FALSE, FALSE, nullptr); ASSERT_NE(eventHandle, nullptr); - hr = fence->SetEventOnCompletion(fenceValue, eventHandle); - ASSERT_HRESULT_SUCCEEDED(hr); + fence->GetFence()->SetEventOnCompletion(fenceValue, eventHandle); DWORD waitResult = WaitForSingleObject(eventHandle, 1000); EXPECT_EQ(waitResult, WAIT_OBJECT_0); @@ -62,31 +72,32 @@ TEST_F(D3D12TestFixture, Fence_Set_EventOnCompletion) { EXPECT_EQ(fence->GetCompletedValue(), fenceValue); CloseHandle(eventHandle); + fence->Shutdown(); + delete fence; } TEST_F(D3D12TestFixture, Fence_Signal_Multiple) { - ComPtr fence; - HRESULT hr = GetDevice()->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)); - ASSERT_HRESULT_SUCCEEDED(hr); + FenceDesc desc = {}; + desc.initialValue = 0; + desc.flags = 0; + + RHIFence* fence = GetDevice()->CreateFence(desc); + ASSERT_NE(fence, nullptr); const UINT64 value1 = 1; const UINT64 value2 = 2; const UINT64 value3 = 3; - hr = GetCommandQueue()->Signal(fence.Get(), value1); - ASSERT_HRESULT_SUCCEEDED(hr); + GetCommandQueue()->Signal(fence, value1); + GetCommandQueue()->Signal(fence, value2); + GetCommandQueue()->Signal(fence, value3); - hr = GetCommandQueue()->Signal(fence.Get(), value2); - ASSERT_HRESULT_SUCCEEDED(hr); - - hr = GetCommandQueue()->Signal(fence.Get(), value3); - ASSERT_HRESULT_SUCCEEDED(hr); + auto* d3d12fence = static_cast(fence); HANDLE eventHandle = CreateEvent(nullptr, FALSE, FALSE, nullptr); ASSERT_NE(eventHandle, nullptr); - hr = fence->SetEventOnCompletion(value3, eventHandle); - ASSERT_HRESULT_SUCCEEDED(hr); + d3d12fence->GetFence()->SetEventOnCompletion(value3, eventHandle); DWORD waitResult = WaitForSingleObject(eventHandle, 1000); EXPECT_EQ(waitResult, WAIT_OBJECT_0); @@ -94,4 +105,6 @@ TEST_F(D3D12TestFixture, Fence_Signal_Multiple) { EXPECT_EQ(fence->GetCompletedValue(), value3); CloseHandle(eventHandle); -} + fence->Shutdown(); + delete fence; +} \ No newline at end of file diff --git a/tests/RHI/D3D12/unit/test_pipeline_state.cpp b/tests/RHI/D3D12/unit/test_pipeline_state.cpp index 4c6dbe04..1f56a8c9 100644 --- a/tests/RHI/D3D12/unit/test_pipeline_state.cpp +++ b/tests/RHI/D3D12/unit/test_pipeline_state.cpp @@ -1,4 +1,7 @@ #include "fixtures/D3D12TestFixture.h" +#include + +using namespace XCEngine::RHI; TEST_F(D3D12TestFixture, PipelineState_Get_GraphicsPipelineDescDefaults) { D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; diff --git a/tests/RHI/D3D12/unit/test_root_signature.cpp b/tests/RHI/D3D12/unit/test_root_signature.cpp index 8bd37b9c..4b35ae6d 100644 --- a/tests/RHI/D3D12/unit/test_root_signature.cpp +++ b/tests/RHI/D3D12/unit/test_root_signature.cpp @@ -1,4 +1,7 @@ #include "fixtures/D3D12TestFixture.h" +#include "XCEngine/RHI/D3D12/D3D12RootSignature.h" + +using namespace XCEngine::RHI; TEST_F(D3D12TestFixture, RootSignature_Create_EmptyRootSignature) { D3D12_ROOT_SIGNATURE_DESC rootSigDesc = {}; @@ -6,19 +9,13 @@ TEST_F(D3D12TestFixture, RootSignature_Create_EmptyRootSignature) { rootSigDesc.NumStaticSamplers = 0; rootSigDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE; - ComPtr blob; - ComPtr errorBlob; - HRESULT hr = D3D12SerializeRootSignature(&rootSigDesc, D3D_ROOT_SIGNATURE_VERSION_1, &blob, &errorBlob); - ASSERT_HRESULT_SUCCEEDED(hr); - ASSERT_NE(blob.Get(), nullptr); + D3D12RootSignature rootSig; + bool result = rootSig.Initialize(GetDevice()->GetDevice(), rootSigDesc); + ASSERT_TRUE(result); } TEST_F(D3D12TestFixture, RootSignature_Create_WithCBV) { - D3D12_ROOT_PARAMETER param = {}; - param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; - param.Descriptor.ShaderRegister = 0; - param.Descriptor.RegisterSpace = 0; - param.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL; + D3D12_ROOT_PARAMETER param = D3D12RootSignature::CreateCBV(0); D3D12_ROOT_SIGNATURE_DESC rootSigDesc = {}; rootSigDesc.NumParameters = 1; @@ -26,13 +23,8 @@ TEST_F(D3D12TestFixture, RootSignature_Create_WithCBV) { rootSigDesc.NumStaticSamplers = 0; rootSigDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE; - ComPtr blob; - ComPtr errorBlob; - HRESULT hr = D3D12SerializeRootSignature(&rootSigDesc, D3D_ROOT_SIGNATURE_VERSION_1, &blob, &errorBlob); - ASSERT_HRESULT_SUCCEEDED(hr); - - ComPtr rootSig; - hr = GetDevice()->CreateRootSignature(0, blob->GetBufferPointer(), blob->GetBufferSize(), IID_PPV_ARGS(&rootSig)); - ASSERT_HRESULT_SUCCEEDED(hr); - ASSERT_NE(rootSig.Get(), nullptr); -} + D3D12RootSignature rootSig; + bool result = rootSig.Initialize(GetDevice()->GetDevice(), rootSigDesc); + ASSERT_TRUE(result); + ASSERT_NE(rootSig.GetRootSignature(), nullptr); +} \ No newline at end of file diff --git a/tests/RHI/D3D12/unit/test_shader.cpp b/tests/RHI/D3D12/unit/test_shader.cpp index ad4fe66d..7330b413 100644 --- a/tests/RHI/D3D12/unit/test_shader.cpp +++ b/tests/RHI/D3D12/unit/test_shader.cpp @@ -1,5 +1,7 @@ #include "fixtures/D3D12TestFixture.h" +using namespace XCEngine::RHI; + TEST_F(D3D12TestFixture, Shader_Get_VertexShaderProfile) { const char* profile = "vs_6_0"; EXPECT_STREQ(profile, "vs_6_0"); diff --git a/tests/RHI/D3D12/unit/test_texture.cpp b/tests/RHI/D3D12/unit/test_texture.cpp index 68e67f9e..d704b851 100644 --- a/tests/RHI/D3D12/unit/test_texture.cpp +++ b/tests/RHI/D3D12/unit/test_texture.cpp @@ -1,140 +1,93 @@ #include "fixtures/D3D12TestFixture.h" +#include "XCEngine/RHI/RHIEnums.h" +#include "XCEngine/RHI/RHITexture.h" + +using namespace XCEngine::RHI; TEST_F(D3D12TestFixture, Texture_Create_2D) { - const uint32_t width = 256; - const uint32_t height = 256; - const DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM; + TextureDesc desc = {}; + desc.width = 256; + desc.height = 256; + desc.depth = 1; + desc.mipLevels = 1; + desc.arraySize = 1; + desc.format = static_cast(Format::R8G8B8A8_UNorm); + desc.textureType = static_cast(TextureType::Texture2D); + desc.sampleCount = 1; + desc.sampleQuality = 0; + desc.flags = 0; - D3D12_HEAP_PROPERTIES heapProps = {}; - heapProps.Type = D3D12_HEAP_TYPE_DEFAULT; + RHITexture* texture = GetDevice()->CreateTexture(desc); + ASSERT_NE(texture, nullptr); - D3D12_RESOURCE_DESC resourceDesc = {}; - resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - resourceDesc.Width = width; - resourceDesc.Height = height; - resourceDesc.DepthOrArraySize = 1; - resourceDesc.MipLevels = 1; - resourceDesc.Format = format; - resourceDesc.SampleDesc.Count = 1; - resourceDesc.SampleDesc.Quality = 0; - resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + EXPECT_EQ(texture->GetWidth(), 256); + EXPECT_EQ(texture->GetHeight(), 256); + EXPECT_EQ(texture->GetFormat(), Format::R8G8B8A8_UNorm); - ComPtr texture; - HRESULT hr = GetDevice()->CreateCommittedResource( - &heapProps, - D3D12_HEAP_FLAG_NONE, - &resourceDesc, - D3D12_RESOURCE_STATE_COMMON, - nullptr, - IID_PPV_ARGS(&texture) - ); - ASSERT_HRESULT_SUCCEEDED(hr); - ASSERT_NE(texture.Get(), nullptr); - - D3D12_RESOURCE_DESC desc = texture->GetDesc(); - EXPECT_EQ(desc.Dimension, D3D12_RESOURCE_DIMENSION_TEXTURE2D); - EXPECT_EQ(desc.Width, width); - EXPECT_EQ(desc.Height, height); - EXPECT_EQ(desc.Format, format); + texture->Shutdown(); + delete texture; } TEST_F(D3D12TestFixture, Texture_Create_3D) { - const uint32_t width = 64; - const uint32_t height = 64; - const uint32_t depth = 64; + TextureDesc desc = {}; + desc.width = 64; + desc.height = 64; + desc.depth = 64; + desc.mipLevels = 1; + desc.arraySize = 1; + desc.format = static_cast(Format::R8G8B8A8_UNorm); + desc.textureType = static_cast(TextureType::Texture3D); + desc.sampleCount = 1; + desc.sampleQuality = 0; + desc.flags = 0; - D3D12_HEAP_PROPERTIES heapProps = {}; - heapProps.Type = D3D12_HEAP_TYPE_DEFAULT; + RHITexture* texture = GetDevice()->CreateTexture(desc); + ASSERT_NE(texture, nullptr); - D3D12_RESOURCE_DESC resourceDesc = {}; - resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE3D; - resourceDesc.Width = width; - resourceDesc.Height = height; - resourceDesc.DepthOrArraySize = depth; - resourceDesc.MipLevels = 1; - resourceDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - resourceDesc.SampleDesc.Count = 1; - resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + EXPECT_EQ(texture->GetDepth(), 64); - ComPtr texture; - HRESULT hr = GetDevice()->CreateCommittedResource( - &heapProps, - D3D12_HEAP_FLAG_NONE, - &resourceDesc, - D3D12_RESOURCE_STATE_COMMON, - nullptr, - IID_PPV_ARGS(&texture) - ); - ASSERT_HRESULT_SUCCEEDED(hr); - ASSERT_NE(texture.Get(), nullptr); - - D3D12_RESOURCE_DESC desc = texture->GetDesc(); - EXPECT_EQ(desc.Dimension, D3D12_RESOURCE_DIMENSION_TEXTURE3D); - EXPECT_EQ(desc.DepthOrArraySize, depth); + texture->Shutdown(); + delete texture; } TEST_F(D3D12TestFixture, Texture_Create_MultipleMips) { - const uint32_t width = 512; - const uint32_t height = 512; - const uint32_t mipLevels = 5; + TextureDesc desc = {}; + desc.width = 512; + desc.height = 512; + desc.depth = 1; + desc.mipLevels = 5; + desc.arraySize = 1; + desc.format = static_cast(Format::R8G8B8A8_UNorm); + desc.textureType = static_cast(TextureType::Texture2D); + desc.sampleCount = 1; + desc.sampleQuality = 0; + desc.flags = 0; - D3D12_HEAP_PROPERTIES heapProps = {}; - heapProps.Type = D3D12_HEAP_TYPE_DEFAULT; + RHITexture* texture = GetDevice()->CreateTexture(desc); + ASSERT_NE(texture, nullptr); - D3D12_RESOURCE_DESC resourceDesc = {}; - resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - resourceDesc.Width = width; - resourceDesc.Height = height; - resourceDesc.DepthOrArraySize = 1; - resourceDesc.MipLevels = mipLevels; - resourceDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - resourceDesc.SampleDesc.Count = 1; - resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + EXPECT_EQ(texture->GetMipLevels(), 5); - ComPtr texture; - HRESULT hr = GetDevice()->CreateCommittedResource( - &heapProps, - D3D12_HEAP_FLAG_NONE, - &resourceDesc, - D3D12_RESOURCE_STATE_COMMON, - nullptr, - IID_PPV_ARGS(&texture) - ); - ASSERT_HRESULT_SUCCEEDED(hr); - - D3D12_RESOURCE_DESC desc = texture->GetDesc(); - EXPECT_EQ(desc.MipLevels, mipLevels); + texture->Shutdown(); + delete texture; } TEST_F(D3D12TestFixture, Texture_Create_Array) { - const uint32_t width = 128; - const uint32_t height = 128; - const uint32_t arraySize = 4; + TextureDesc desc = {}; + desc.width = 128; + desc.height = 128; + desc.depth = 1; + desc.mipLevels = 1; + desc.arraySize = 4; + desc.format = static_cast(Format::R8G8B8A8_UNorm); + desc.textureType = static_cast(TextureType::Texture2DArray); + desc.sampleCount = 1; + desc.sampleQuality = 0; + desc.flags = 0; - D3D12_HEAP_PROPERTIES heapProps = {}; - heapProps.Type = D3D12_HEAP_TYPE_DEFAULT; + RHITexture* texture = GetDevice()->CreateTexture(desc); + ASSERT_NE(texture, nullptr); - D3D12_RESOURCE_DESC resourceDesc = {}; - resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - resourceDesc.Width = width; - resourceDesc.Height = height; - resourceDesc.DepthOrArraySize = arraySize; - resourceDesc.MipLevels = 1; - resourceDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - resourceDesc.SampleDesc.Count = 1; - resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; - - ComPtr texture; - HRESULT hr = GetDevice()->CreateCommittedResource( - &heapProps, - D3D12_HEAP_FLAG_NONE, - &resourceDesc, - D3D12_RESOURCE_STATE_COMMON, - nullptr, - IID_PPV_ARGS(&texture) - ); - ASSERT_HRESULT_SUCCEEDED(hr); - - D3D12_RESOURCE_DESC desc = texture->GetDesc(); - EXPECT_EQ(desc.DepthOrArraySize, arraySize); -} + texture->Shutdown(); + delete texture; +} \ No newline at end of file diff --git a/tests/RHI/D3D12/unit/test_views.cpp b/tests/RHI/D3D12/unit/test_views.cpp index 9b9363a5..c2e7f3c6 100644 --- a/tests/RHI/D3D12/unit/test_views.cpp +++ b/tests/RHI/D3D12/unit/test_views.cpp @@ -1,62 +1,40 @@ #include "fixtures/D3D12TestFixture.h" +#include "XCEngine/RHI/D3D12/D3D12DescriptorHeap.h" + +using namespace XCEngine::RHI; TEST_F(D3D12TestFixture, Views_Create_RTVDescriptorHeap) { - D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {}; - heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; - heapDesc.NumDescriptors = 1; - heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + D3D12DescriptorHeap heap; + ASSERT_TRUE(heap.Initialize(GetDevice()->GetDevice(), DescriptorHeapType::RTV, 1, false)); - ComPtr descriptorHeap; - HRESULT hr = GetDevice()->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&descriptorHeap)); - ASSERT_HRESULT_SUCCEEDED(hr); - - D3D12_CPU_DESCRIPTOR_HANDLE handle = descriptorHeap->GetCPUDescriptorHandleForHeapStart(); + CPUDescriptorHandle handle = heap.GetCPUDescriptorHandle(0); EXPECT_NE(handle.ptr, 0); } TEST_F(D3D12TestFixture, Views_Create_DSVDescriptorHeap) { - D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {}; - heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; - heapDesc.NumDescriptors = 1; - heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + D3D12DescriptorHeap heap; + ASSERT_TRUE(heap.Initialize(GetDevice()->GetDevice(), DescriptorHeapType::DSV, 1, false)); - ComPtr descriptorHeap; - HRESULT hr = GetDevice()->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&descriptorHeap)); - ASSERT_HRESULT_SUCCEEDED(hr); - - D3D12_CPU_DESCRIPTOR_HANDLE handle = descriptorHeap->GetCPUDescriptorHandleForHeapStart(); + CPUDescriptorHandle handle = heap.GetCPUDescriptorHandle(0); EXPECT_NE(handle.ptr, 0); } TEST_F(D3D12TestFixture, Views_Create_CBVDescriptorHeap) { - D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {}; - heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - heapDesc.NumDescriptors = 1; - heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + D3D12DescriptorHeap heap; + ASSERT_TRUE(heap.Initialize(GetDevice()->GetDevice(), DescriptorHeapType::CBV_SRV_UAV, 1, true)); - ComPtr descriptorHeap; - HRESULT hr = GetDevice()->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&descriptorHeap)); - ASSERT_HRESULT_SUCCEEDED(hr); - - D3D12_CPU_DESCRIPTOR_HANDLE handle = descriptorHeap->GetCPUDescriptorHandleForHeapStart(); + CPUDescriptorHandle handle = heap.GetCPUDescriptorHandle(0); EXPECT_NE(handle.ptr, 0); } TEST_F(D3D12TestFixture, Views_Get_RTVDescriptorHandleIncrement) { - UINT rtvSize = GetDevice()->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + UINT rtvSize = GetDevice()->GetDescriptorHandleIncrementSize(DescriptorHeapType::RTV); - D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {}; - heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; - heapDesc.NumDescriptors = 4; - heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + D3D12DescriptorHeap heap; + ASSERT_TRUE(heap.Initialize(GetDevice()->GetDevice(), DescriptorHeapType::RTV, 4, false)); - ComPtr descriptorHeap; - HRESULT hr = GetDevice()->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&descriptorHeap)); - ASSERT_HRESULT_SUCCEEDED(hr); + CPUDescriptorHandle handle1 = heap.GetCPUDescriptorHandle(0); + CPUDescriptorHandle handle2 = heap.GetCPUDescriptorHandle(1); - D3D12_CPU_DESCRIPTOR_HANDLE handle1 = descriptorHeap->GetCPUDescriptorHandleForHeapStart(); - D3D12_CPU_DESCRIPTOR_HANDLE handle2 = handle1; - handle2.ptr += rtvSize; - - EXPECT_NE(handle1.ptr, handle2.ptr); -} + EXPECT_EQ(handle2.ptr - handle1.ptr, rtvSize); +} \ No newline at end of file diff --git a/tests/RHI/OpenGL/integration/minimal/CMakeLists.txt b/tests/RHI/OpenGL/integration/minimal/CMakeLists.txt index 5a1127e1..7dc1ef2e 100644 --- a/tests/RHI/OpenGL/integration/minimal/CMakeLists.txt +++ b/tests/RHI/OpenGL/integration/minimal/CMakeLists.txt @@ -5,7 +5,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) project(OpenGL_Minimal) set(ENGINE_ROOT_DIR ${CMAKE_SOURCE_DIR}/engine) -set(PACKAGE_DIR ${CMAKE_SOURCE_DIR}/tests/OpenGL/package) +set(PACKAGE_DIR ${CMAKE_SOURCE_DIR}/tests/opengl/package) add_executable(OpenGL_Minimal WIN32 @@ -31,10 +31,10 @@ target_compile_definitions(OpenGL_Minimal PRIVATE add_custom_command(TARGET OpenGL_Minimal POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_SOURCE_DIR}/tests/RHI/OpenGL/integration/run_integration_test.py + ${CMAKE_SOURCE_DIR}/tests/rhi/opengl/integration/run_integration_test.py $/ COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_SOURCE_DIR}/tests/RHI/OpenGL/integration/compare_ppm.py + ${CMAKE_SOURCE_DIR}/tests/rhi/opengl/integration/compare_ppm.py $/ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/GT.ppm diff --git a/tests/RHI/OpenGL/integration/quad/CMakeLists.txt b/tests/RHI/OpenGL/integration/quad/CMakeLists.txt index a92db427..a0aa0fa2 100644 --- a/tests/RHI/OpenGL/integration/quad/CMakeLists.txt +++ b/tests/RHI/OpenGL/integration/quad/CMakeLists.txt @@ -5,7 +5,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) project(OpenGL_Quad) set(ENGINE_ROOT_DIR ${CMAKE_SOURCE_DIR}/engine) -set(PACKAGE_DIR ${CMAKE_SOURCE_DIR}/tests/OpenGL/package) +set(PACKAGE_DIR ${CMAKE_SOURCE_DIR}/tests/opengl/package) add_executable(OpenGL_Quad WIN32 @@ -37,10 +37,10 @@ add_custom_command(TARGET OpenGL_Quad POST_BUILD add_custom_command(TARGET OpenGL_Quad POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_SOURCE_DIR}/tests/RHI/OpenGL/integration/run_integration_test.py + ${CMAKE_SOURCE_DIR}/tests/rhi/opengl/integration/run_integration_test.py $/ COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_SOURCE_DIR}/tests/RHI/OpenGL/integration/compare_ppm.py + ${CMAKE_SOURCE_DIR}/tests/rhi/opengl/integration/compare_ppm.py $/ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/GT.ppm diff --git a/tests/RHI/OpenGL/integration/sphere/CMakeLists.txt b/tests/RHI/OpenGL/integration/sphere/CMakeLists.txt new file mode 100644 index 00000000..ac23e3ba --- /dev/null +++ b/tests/RHI/OpenGL/integration/sphere/CMakeLists.txt @@ -0,0 +1,57 @@ +cmake_minimum_required(VERSION 3.15) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + +project(OpenGL_Sphere) + +set(ENGINE_ROOT_DIR ${CMAKE_SOURCE_DIR}/engine) +set(PACKAGE_DIR ${CMAKE_SOURCE_DIR}/tests/opengl/package) + +add_executable(OpenGL_Sphere + WIN32 + main.cpp + ${PACKAGE_DIR}/src/glad.c +) + +target_include_directories(OpenGL_Sphere PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${ENGINE_ROOT_DIR}/include + ${PACKAGE_DIR}/include +) + +target_link_libraries(OpenGL_Sphere PRIVATE + opengl32 + XCEngine +) + +target_compile_definitions(OpenGL_Sphere PRIVATE + UNICODE + _UNICODE +) + +add_custom_command(TARGET OpenGL_Sphere POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_CURRENT_SOURCE_DIR}/Res + $/Res +) + +add_custom_command(TARGET OpenGL_Sphere POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_SOURCE_DIR}/tests/rhi/opengl/integration/run_integration_test.py + $/ + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_SOURCE_DIR}/tests/rhi/opengl/integration/compare_ppm.py + $/ + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/GT.ppm + $/ +) + +add_test(NAME OpenGL_Sphere_Integration + COMMAND ${Python3_EXECUTABLE} $/run_integration_test.py + $ + sphere.ppm + ${CMAKE_CURRENT_SOURCE_DIR}/GT.ppm + 5 + WORKING_DIRECTORY $ +) \ No newline at end of file diff --git a/tests/RHI/OpenGL/integration/sphere/GT.ppm b/tests/RHI/OpenGL/integration/sphere/GT.ppm new file mode 100644 index 00000000..37a204fe Binary files /dev/null and b/tests/RHI/OpenGL/integration/sphere/GT.ppm differ diff --git a/tests/RHI/OpenGL/integration/sphere/Res/Image/earth.png b/tests/RHI/OpenGL/integration/sphere/Res/Image/earth.png new file mode 100644 index 00000000..663081b5 Binary files /dev/null and b/tests/RHI/OpenGL/integration/sphere/Res/Image/earth.png differ diff --git a/tests/RHI/OpenGL/integration/sphere/Res/Shader/sphere.frag b/tests/RHI/OpenGL/integration/sphere/Res/Shader/sphere.frag new file mode 100644 index 00000000..15c865c5 --- /dev/null +++ b/tests/RHI/OpenGL/integration/sphere/Res/Shader/sphere.frag @@ -0,0 +1,10 @@ +#version 460 + +in vec2 vTexcoord; +out vec4 fragColor; + +uniform sampler2D uTexture; + +void main() { + fragColor = texture(uTexture, vTexcoord); +} \ No newline at end of file diff --git a/tests/RHI/OpenGL/integration/sphere/Res/Shader/sphere.vert b/tests/RHI/OpenGL/integration/sphere/Res/Shader/sphere.vert new file mode 100644 index 00000000..d368e057 --- /dev/null +++ b/tests/RHI/OpenGL/integration/sphere/Res/Shader/sphere.vert @@ -0,0 +1,17 @@ +#version 460 + +layout(location = 0) in vec4 aPosition; +layout(location = 1) in vec2 aTexcoord; + +out vec2 vTexcoord; + +uniform mat4 gModelMatrix; +uniform mat4 gViewMatrix; +uniform mat4 gProjectionMatrix; + +void main() { + vec4 positionWS = gModelMatrix * aPosition; + vec4 positionVS = gViewMatrix * positionWS; + gl_Position = gProjectionMatrix * positionVS; + vTexcoord = aTexcoord; +} \ No newline at end of file diff --git a/tests/RHI/OpenGL/integration/sphere/main.cpp b/tests/RHI/OpenGL/integration/sphere/main.cpp new file mode 100644 index 00000000..36705970 --- /dev/null +++ b/tests/RHI/OpenGL/integration/sphere/main.cpp @@ -0,0 +1,322 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "XCEngine/RHI/OpenGL/OpenGLDevice.h" +#include "XCEngine/RHI/OpenGL/OpenGLSwapChain.h" +#include "XCEngine/RHI/OpenGL/OpenGLCommandList.h" +#include "XCEngine/RHI/OpenGL/OpenGLBuffer.h" +#include "XCEngine/RHI/OpenGL/OpenGLVertexArray.h" +#include "XCEngine/RHI/OpenGL/OpenGLShader.h" +#include "XCEngine/RHI/OpenGL/OpenGLPipelineState.h" +#include "XCEngine/RHI/OpenGL/OpenGLTexture.h" +#include "XCEngine/RHI/OpenGL/OpenGLSampler.h" +#include "XCEngine/RHI/OpenGL/OpenGLScreenshot.h" +#include "XCEngine/Debug/Logger.h" +#include "XCEngine/Debug/ConsoleLogSink.h" +#include "XCEngine/Containers/String.h" + +#pragma comment(lib, "opengl32.lib") + +using namespace XCEngine::RHI; +using namespace XCEngine::Debug; +using namespace XCEngine::Containers; + +static const int gWidth = 1280; +static const int gHeight = 720; + +void Log(const char* format, ...) { + char buffer[1024]; + va_list args; + va_start(args, format); + vsnprintf(buffer, sizeof(buffer), format, args); + va_end(args); + Logger::Get().Debug(LogCategory::Rendering, String(buffer)); +} + +LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { + switch (msg) { + case WM_CLOSE: + PostQuitMessage(0); + break; + } + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +void IdentityMatrix(float* m) { + memset(m, 0, 16 * sizeof(float)); + m[0] = m[5] = m[10] = m[15] = 1.0f; +} + +void TranslationMatrix(float* m, float x, float y, float z) { + memset(m, 0, 16 * sizeof(float)); + m[0] = 1.0f; m[12] = x; + m[5] = 1.0f; m[13] = y; + m[10] = 1.0f; m[14] = z; + m[15] = 1.0f; +} + +void PerspectiveMatrix(float* m, float fov, float aspect, float nearZ, float farZ) { + memset(m, 0, 16 * sizeof(float)); + float tanHalfFov = tanf(fov / 2.0f); + m[0] = 1.0f / (aspect * tanHalfFov); + m[5] = 1.0f / tanHalfFov; + m[10] = -(farZ + nearZ) / (farZ - nearZ); + m[11] = -1.0f; + m[14] = -(2.0f * farZ * nearZ) / (farZ - nearZ); + m[15] = 0.0f; +} + +struct Vertex { + float pos[4]; + float texcoord[2]; +}; + +void GenerateSphere(std::vector& vertices, std::vector& indices, float radius, int segments) { + vertices.clear(); + indices.clear(); + + segments = (segments < 3) ? 3 : segments; + + for (int lat = 0; lat <= segments; ++lat) { + float phi = static_cast(3.14159265f) * lat / segments; + float sinPhi = sinf(phi); + float cosPhi = cosf(phi); + + for (int lon = 0; lon <= segments; ++lon) { + float theta = static_cast(2 * 3.14159265f) * lon / segments; + float sinTheta = sinf(theta); + float cosTheta = cosf(theta); + + Vertex v; + v.pos[0] = radius * sinPhi * cosTheta; + v.pos[1] = radius * cosPhi; + v.pos[2] = radius * sinPhi * sinTheta; + v.pos[3] = 1.0f; + + v.texcoord[0] = static_cast(lon) / segments; + v.texcoord[1] = static_cast(lat) / segments; + + vertices.push_back(v); + } + } + + for (int lat = 0; lat < segments; ++lat) { + for (int lon = 0; lon < segments; ++lon) { + uint32_t topLeft = lat * (segments + 1) + lon; + uint32_t topRight = topLeft + 1; + uint32_t bottomLeft = (lat + 1) * (segments + 1) + lon; + uint32_t bottomRight = bottomLeft + 1; + + indices.push_back(topLeft); + indices.push_back(bottomLeft); + indices.push_back(topRight); + + indices.push_back(topRight); + indices.push_back(bottomLeft); + indices.push_back(bottomRight); + } + } +} + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { + Logger::Get().Initialize(); + Logger::Get().AddSink(std::make_unique()); + Logger::Get().SetMinimumLevel(LogLevel::Debug); + + Log("[INFO] OpenGL Sphere Test Starting"); + + WNDCLASSEXW wc = {}; + wc.cbSize = sizeof(WNDCLASSEXW); + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = WindowProc; + wc.hInstance = hInstance; + wc.lpszClassName = L"XCEngine_OpenGL_Sphere"; + + if (!RegisterClassExW(&wc)) { + Log("[ERROR] Failed to register window class"); + return -1; + } + + RECT rect = { 0, 0, gWidth, gHeight }; + AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE); + + HWND hwnd = CreateWindowExW( + 0, + L"XCEngine_OpenGL_Sphere", + L"OpenGL Sphere Test", + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, + rect.right - rect.left, rect.bottom - rect.top, + NULL, NULL, hInstance, NULL + ); + + if (!hwnd) { + Log("[ERROR] Failed to create window"); + return -1; + } + + OpenGLDevice device; + if (!device.InitializeWithExistingWindow(hwnd)) { + Log("[ERROR] Failed to initialize OpenGL device"); + return -1; + } + + ShowWindow(hwnd, nShowCmd); + UpdateWindow(hwnd); + + Log("[INFO] OpenGL Device: %S", device.GetDeviceInfo().renderer.c_str()); + Log("[INFO] OpenGL Version: %S", device.GetDeviceInfo().version.c_str()); + + OpenGLSwapChain swapChain; + swapChain.Initialize(hwnd, gWidth, gHeight); + + OpenGLCommandList commandList; + + std::vector vertices; + std::vector indices; + GenerateSphere(vertices, indices, 1.0f, 32); + Log("[INFO] Generated %d vertices, %d indices", (int)vertices.size(), (int)indices.size()); + + OpenGLBuffer vertexBuffer; + if (!vertexBuffer.InitializeVertexBuffer(vertices.data(), (uint32_t)(sizeof(Vertex) * vertices.size()))) { + Log("[ERROR] Failed to initialize vertex buffer"); + return -1; + } + vertexBuffer.SetStride(sizeof(Vertex)); + + OpenGLBuffer indexBuffer; + if (!indexBuffer.InitializeIndexBuffer(indices.data(), (uint32_t)(sizeof(uint32_t) * indices.size()))) { + Log("[ERROR] Failed to initialize index buffer"); + return -1; + } + + OpenGLVertexArray vertexArray; + vertexArray.Initialize(); + + VertexAttribute posAttr = {}; + posAttr.index = 0; + posAttr.count = 4; + posAttr.type = VertexAttributeType::Float; + posAttr.normalized = VertexAttributeNormalized::False; + posAttr.stride = sizeof(Vertex); + posAttr.offset = 0; + vertexArray.AddVertexBuffer(vertexBuffer.GetID(), posAttr); + + VertexAttribute texAttr = {}; + texAttr.index = 1; + texAttr.count = 2; + texAttr.type = VertexAttributeType::Float; + texAttr.normalized = VertexAttributeNormalized::False; + texAttr.stride = sizeof(Vertex); + texAttr.offset = sizeof(float) * 4; + vertexArray.AddVertexBuffer(vertexBuffer.GetID(), texAttr); + + vertexArray.SetIndexBuffer(indexBuffer.GetID(), 0); + + OpenGLShader shader; + if (!shader.CompileFromFile("Res/Shader/sphere.vert", "Res/Shader/sphere.frag")) { + Log("[ERROR] Failed to compile shaders"); + return -1; + } + Log("[INFO] Shaders compiled successfully"); + + float modelMatrix[16]; + float viewMatrix[16]; + float projectionMatrix[16]; + + IdentityMatrix(viewMatrix); + TranslationMatrix(modelMatrix, 0.0f, 0.0f, -5.0f); + float aspect = 1280.0f / 720.0f; + PerspectiveMatrix(projectionMatrix, 45.0f * 3.14159265f / 180.0f, aspect, 0.1f, 1000.0f); + + shader.SetMat4("gModelMatrix", modelMatrix); + shader.SetMat4("gViewMatrix", viewMatrix); + shader.SetMat4("gProjectionMatrix", projectionMatrix); + shader.SetInt("uTexture", 0); + + OpenGLPipelineState pipelineState; + OpenGLRasterizerState rasterizerState; + rasterizerState.cullFaceEnable = false; + pipelineState.SetRasterizerState(rasterizerState); + + OpenGLDepthStencilState depthStencilState; + depthStencilState.depthTestEnable = false; + depthStencilState.depthWriteEnable = false; + pipelineState.SetDepthStencilState(depthStencilState); + + ViewportState viewportState = { 0.0f, 0.0f, (float)gWidth, (float)gHeight, 0.0f, 1.0f }; + pipelineState.SetViewport(viewportState); + + pipelineState.AttachShader(shader.GetID()); + pipelineState.Apply(); + + OpenGLTexture texture; + if (!texture.LoadFromFile("Res/Image/earth.png", true)) { + Log("[ERROR] Failed to load texture"); + return -1; + } + Log("[INFO] Texture loaded successfully"); + + OpenGLSampler sampler; + OpenGLSamplerDesc samplerDesc = {}; + samplerDesc.minFilter = SamplerFilter::Linear; + samplerDesc.magFilter = SamplerFilter::Linear; + samplerDesc.wrapS = SamplerWrapMode::ClampToEdge; + samplerDesc.wrapT = SamplerWrapMode::ClampToEdge; + sampler.Initialize(samplerDesc); + + MSG msg = {}; + int frameCount = 0; + const int targetFrameCount = 30; + + while (frameCount < targetFrameCount) { + if (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) { + if (msg.message == WM_QUIT) { + break; + } + TranslateMessage(&msg); + DispatchMessageW(&msg); + } else { + commandList.SetViewport(0, 0, gWidth, gHeight); + commandList.Clear(0.0f, 0.0f, 1.0f, 1.0f, 1); + + pipelineState.Bind(); + + indexBuffer.Bind(); + vertexArray.Bind(); + + texture.Bind(0); + sampler.Bind(0); + + commandList.DrawIndexed(PrimitiveType::Triangles, (uint32_t)indices.size(), 0, 0); + + swapChain.Present(0, 0); + frameCount++; + } + } + + Log("[INFO] Reached target frame count %d - taking screenshot!", targetFrameCount); + OpenGLScreenshot::Capture(device, swapChain, "sphere.ppm"); + + sampler.Shutdown(); + texture.Shutdown(); + indexBuffer.Shutdown(); + vertexArray.Shutdown(); + vertexBuffer.Shutdown(); + shader.Shutdown(); + pipelineState.Shutdown(); + + swapChain.Shutdown(); + device.Shutdown(); + Logger::Get().Shutdown(); + + Log("[INFO] OpenGL Sphere Test Finished"); + return 0; +} \ No newline at end of file diff --git a/tests/RHI/OpenGL/integration/triangle/CMakeLists.txt b/tests/RHI/OpenGL/integration/triangle/CMakeLists.txt index 123fae74..b38f774e 100644 --- a/tests/RHI/OpenGL/integration/triangle/CMakeLists.txt +++ b/tests/RHI/OpenGL/integration/triangle/CMakeLists.txt @@ -5,7 +5,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) project(OpenGL_Triangle) set(ENGINE_ROOT_DIR ${CMAKE_SOURCE_DIR}/engine) -set(PACKAGE_DIR ${CMAKE_SOURCE_DIR}/tests/OpenGL/package) +set(PACKAGE_DIR ${CMAKE_SOURCE_DIR}/tests/opengl/package) add_executable(OpenGL_Triangle WIN32 @@ -37,10 +37,10 @@ add_custom_command(TARGET OpenGL_Triangle POST_BUILD add_custom_command(TARGET OpenGL_Triangle POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_SOURCE_DIR}/tests/RHI/OpenGL/integration/run_integration_test.py + ${CMAKE_SOURCE_DIR}/tests/rhi/opengl/integration/run_integration_test.py $/ COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_SOURCE_DIR}/tests/RHI/OpenGL/integration/compare_ppm.py + ${CMAKE_SOURCE_DIR}/tests/rhi/opengl/integration/compare_ppm.py $/ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/GT.ppm diff --git a/tests/RHI/OpenGL/unit/CMakeLists.txt b/tests/RHI/OpenGL/unit/CMakeLists.txt index dbf30d5c..8992a64f 100644 --- a/tests/RHI/OpenGL/unit/CMakeLists.txt +++ b/tests/RHI/OpenGL/unit/CMakeLists.txt @@ -4,14 +4,14 @@ get_filename_component(PROJECT_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../.. find_package(OpenGL REQUIRED) -include_directories(${CMAKE_SOURCE_DIR}/tests/OpenGL/package/include/) +include_directories(${CMAKE_SOURCE_DIR}/tests/opengl/package/include/) include_directories(${PROJECT_ROOT_DIR}/engine/include) include_directories(${PROJECT_ROOT_DIR}/engine/src) find_package(GTest REQUIRED) set(TEST_SOURCES - ${CMAKE_SOURCE_DIR}/tests/OpenGL/package/src/glad.c + ${CMAKE_SOURCE_DIR}/tests/opengl/package/src/glad.c fixtures/OpenGLTestFixture.cpp test_device.cpp test_buffer.cpp @@ -42,15 +42,6 @@ target_include_directories(opengl_engine_tests PRIVATE ${PROJECT_ROOT_DIR}/engine/src ) -target_compile_definitions(opengl_engine_tests PRIVATE - TEST_RESOURCES_DIR="${PROJECT_ROOT_DIR}/tests/RHI/OpenGL/integration/minimal/Res" -) - -add_custom_command(TARGET opengl_engine_tests POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory - ${PROJECT_ROOT_DIR}/tests/RHI/OpenGL/integration/minimal/Res - $/Res -) - enable_testing() -add_test(NAME OpenGLEngineTests COMMAND opengl_engine_tests) \ No newline at end of file +include(GoogleTest) +gtest_discover_tests(opengl_engine_tests) \ No newline at end of file diff --git a/tests/RHI/OpenGL/unit/fixtures/OpenGLTestFixture.cpp b/tests/RHI/OpenGL/unit/fixtures/OpenGLTestFixture.cpp index e4d6e76d..62d3b92d 100644 --- a/tests/RHI/OpenGL/unit/fixtures/OpenGLTestFixture.cpp +++ b/tests/RHI/OpenGL/unit/fixtures/OpenGLTestFixture.cpp @@ -40,7 +40,7 @@ void OpenGLTestFixture::SetUp() { } ShowWindow(m_hwnd, SW_HIDE); - m_hdc = GetDC(m_hwnd); + m_hdc = ::GetDC(m_hwnd); PIXELFORMATDESCRIPTOR pfd = {}; pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); @@ -88,7 +88,7 @@ void OpenGLTestFixture::SetUp() { return; } - if (!gladLoadGLLoader((GLADloadproc)wglGetProcAddress)) { + if (!gladLoadGL()) { wglMakeCurrent(nullptr, nullptr); wglDeleteContext(m_hglrc); ReleaseDC(m_hwnd, m_hdc); diff --git a/tests/RHI/OpenGL/unit/test_swap_chain.cpp b/tests/RHI/OpenGL/unit/test_swap_chain.cpp index 1a8d1c0b..c1934cd0 100644 --- a/tests/RHI/OpenGL/unit/test_swap_chain.cpp +++ b/tests/RHI/OpenGL/unit/test_swap_chain.cpp @@ -5,7 +5,7 @@ using namespace XCEngine::RHI; TEST_F(OpenGLTestFixture, SwapChain_Initialize_Window) { OpenGLSwapChain swapChain; - GLFWwindow* window = GetWindow(); + HWND window = GetWindow(); bool result = swapChain.Initialize(window, 800, 600); @@ -16,7 +16,7 @@ TEST_F(OpenGLTestFixture, SwapChain_Initialize_Window) { TEST_F(OpenGLTestFixture, SwapChain_Present) { OpenGLSwapChain swapChain; - GLFWwindow* window = GetWindow(); + HWND window = GetWindow(); swapChain.Initialize(window, 800, 600); swapChain.Present(); @@ -29,7 +29,7 @@ TEST_F(OpenGLTestFixture, SwapChain_Present) { TEST_F(OpenGLTestFixture, SwapChain_Resize_ChangesSize) { OpenGLSwapChain swapChain; - GLFWwindow* window = GetWindow(); + HWND window = GetWindow(); swapChain.Initialize(window, 800, 600); swapChain.Resize(1024, 768); diff --git a/tests/RHI/TEST_ISSUES.md b/tests/RHI/TEST_ISSUES.md deleted file mode 100644 index 46b94fc5..00000000 --- a/tests/RHI/TEST_ISSUES.md +++ /dev/null @@ -1,260 +0,0 @@ -# RHI 抽象层测试遗留问题报告 - -## 测试概述 - -RHI 抽象层单元测试通过 `RHI_BACKEND` 环境变量选择后端(D3D12/OpenGL),一次编译后可测试两个后端的抽象接口一致性。 - -```bash -# 运行测试 -RHI_BACKEND=D3D12 ./rhi_unit_tests.exe -RHI_BACKEND=OpenGL ./rhi_unit_tests.exe -``` - -## 测试结果汇总 - -| 后端 | 通过 | 失败 | 总计 | -|------|------|------|------| -| D3D12 | 21 | 48 | 69 | -| OpenGL | 未测试 | - | - | - ---- - -## 问题清单 - -### 1. D3D12CommandQueue::CreateCommandQueue 未实现 - -**严重程度**: 高 -**接口**: `RHIDevice::CreateCommandQueue` -**现象**: 返回 `nullptr` -**位置**: `engine/src/RHI/D3D12/D3D12Device.cpp:288` - -```cpp -RHICommandQueue* D3D12Device::CreateCommandQueue(const CommandQueueDesc& desc) { - return nullptr; // 未实现 -} -``` - -**影响测试**: -- `CommandQueue_ExecuteCommandLists` -- `CommandQueue_SignalWaitFence` -- `CommandQueue_GetCompletedValue` -- `CommandQueue_WaitForIdle` -- `CommandQueue_GetType` -- `CommandQueue_GetTimestampFrequency` -- `Device_CreateCommandQueue_ReturnsValid` - ---- - -### 2. D3D12CommandList::CreateCommandList 未实现 - -**严重程度**: 高 -**接口**: `RHIDevice::CreateCommandList` -**现象**: 返回 `nullptr` -**位置**: `engine/src/RHI/D3D12/D3D12Device.cpp:300` - -```cpp -D3D12CommandList* D3D12Device::CreateCommandListImpl(const CommandListDesc& desc) { - return nullptr; // 未实现 -} -``` - -**影响测试**: -- `CommandList_Reset_Close` -- `CommandList_SetPrimitiveTopology` -- `CommandList_SetViewport` -- `CommandList_SetViewports` -- `CommandList_SetScissorRect` -- `CommandList_Draw` -- `CommandList_DrawIndexed` -- `CommandList_ClearRenderTarget` -- `CommandList_SetDepthStencilState` -- `CommandList_SetBlendState` -- `CommandList_SetStencilRef` -- `CommandList_TransitionBarrier` -- `Device_CreateCommandList_ReturnsValid` - ---- - -### 3. Texture 枚举值不匹配 - -**严重程度**: 高 -**接口**: `RHIDevice::CreateTexture` -**现象**: 返回 `nullptr` -**位置**: `engine/src/RHI/D3D12/D3D12Device.cpp:220` - -**原因**: RHI `TextureType` 枚举值与 D3D12 `D3D12_RESOURCE_DIMENSION` 枚举值不匹配 - -| RHI TextureType | 值 | D3D12 D3D12_RESOURCE_DIMENSION | 值 | -|-----------------|-----|----------------------------------|-----| -| Texture1D | 0 | D3D12_RESOURCE_DIMENSION_BUFFER | 0 | -| Texture2D | 1 | D3D12_RESOURCE_DIMENSION_TEXTURE1D | 1 | -| Texture2DArray | 2 | D3D12_RESOURCE_DIMENSION_TEXTURE2D | 2 | -| Texture3D | 3 | D3D12_RESOURCE_DIMENSION_TEXTURE3D | 3 | -| TextureCube | 4 | D3D12_RESOURCE_DIMENSION_TEXTURECUBE | 4 | -| TextureCubeArray | 5 | (无对应) | - | - -**影响测试**: -- `Texture_Create_Texture2D` -- `Texture_Create_Texture3D` -- `Texture_StateManagement` -- `Texture_Naming` -- `Texture_GetNativeHandle` -- `Device_CreateTexture_ReturnsValid` - ---- - -### 4. Shader 编译返回 nullptr - -**严重程度**: 中 -**接口**: `RHIDevice::CompileShader` -**现象**: 返回 `nullptr` -**可能原因**: -- Shader 编译参数不正确 -- 需要有效的 shader 源码或文件路径 - -**影响测试**: -- `Shader_Compile_FromSource` -- `Shader_GetType` -- `Shader_IsValid` -- `Shader_Bind_Unbind` -- `Shader_SetInt` -- `Shader_SetFloat` -- `Shader_SetVec3` -- `Shader_SetVec4` -- `Shader_SetMat4` -- `Shader_GetNativeHandle` - ---- - -### 5. SwapChain 需要窗口句柄 - -**严重程度**: 中 -**接口**: `RHIDevice::CreateSwapChain` -**现象**: 返回 `nullptr` -**原因**: `RHIDeviceDesc` 需要有效的 `windowHandle` - -**影响测试**: -- `SwapChain_Create` -- `SwapChain_GetCurrentBackBufferIndex` -- `SwapChain_GetCurrentBackBuffer` -- `SwapChain_Resize` -- `SwapChain_FullscreenState` -- `SwapChain_ShouldClose` - ---- - -### 6. Buffer::Map 对某些类型返回 nullptr - -**严重程度**: 中 -**接口**: `RHIBuffer::Map` -**现象**: D3D12 Constant Buffer 类型可能无法 Map -**位置**: `tests/RHI/unit/test_buffer.cpp:16` - -```cpp -RHIBuffer* buffer = GetDevice()->CreateBuffer(desc); // desc.bufferType = Vertex -void* data = buffer->Map(); // 返回 nullptr -``` - -**影响测试**: -- `Buffer_Map_Unmap` -- `Buffer_SetData` - ---- - -### 7. RHICapabilities 未填充 - -**严重程度**: 低 -**接口**: `RHIDevice::GetCapabilities` -**现象**: 所有 capability 值为 0 -**位置**: `engine/src/RHI/D3D12/D3D12Device.cpp` - -**影响测试**: -- `Device_GetCapabilities_ReturnsValid` - 断言 `caps.maxRenderTargets >= 1` 等 - ---- - -### 8. RHIDeviceInfo 未填充 - -**严重程度**: 低 -**接口**: `RHIDevice::GetDeviceInfo` -**现象**: `vendor` 和 `renderer` 字符串为空 -**位置**: `engine/src/RHI/D3D12/D3D12Device.cpp:QueryAdapterInfo` - -**影响测试**: -- `Device_GetDeviceInfo_ReturnsValid` - ---- - -### 9. Fence::IsSignaled 逻辑问题 - -**严重程度**: 低 -**接口**: `RHIFence::IsSignaled` -**现象**: 初始值应该为 `false`,但返回 `true` -**位置**: `tests/RHI/unit/test_fence.cpp:80` - -**影响测试**: -- `Fence_IsSignaled` - ---- - -### 10. Sampler::GetNativeHandle 返回 nullptr - -**严重程度**: 低 -**接口**: `RHISampler::GetNativeHandle` -**现象**: 返回 nullptr 但 Sampler 创建成功 -**位置**: `engine/src/RHI/D3D12/D3D12Sampler.cpp` 或 `engine/src/RHI/OpenGL/OpenGLSampler.cpp` - -**影响测试**: -- `Sampler_GetNativeHandle` - ---- - -## 优先级建议 - -### P0 - 必须修复 -1. D3D12CommandQueue::CreateCommandQueue 实现 -2. D3D12CommandList::CreateCommandList 实现 -3. Texture 枚举值对齐 - -### P1 - 应该修复 -4. Shader 编译逻辑 -5. SwapChain 窗口支持 - -### P2 - 可以修复 -6. Buffer Map 行为确认 -7. Capabilities/DeviceInfo 填充 -8. Fence::IsSignaled 逻辑 -9. Sampler::GetNativeHandle - ---- - -## 测试文件位置 - -``` -tests/RHI/unit/ -├── fixtures/RHITestFixture.h/.cpp # 测试框架 -├── test_device.cpp # 设备相关测试 -├── test_buffer.cpp # Buffer 相关测试 -├── test_texture.cpp # Texture 相关测试 -├── test_swap_chain.cpp # SwapChain 相关测试 -├── test_command_list.cpp # CommandList 相关测试 -├── test_command_queue.cpp # CommandQueue 相关测试 -├── test_shader.cpp # Shader 相关测试 -├── test_fence.cpp # Fence 相关测试 -└── test_sampler.cpp # Sampler 相关测试 -``` - ---- - -## 运行测试 - -```bash -# 编译 -cmake --build build --config Debug - -# D3D12 后端测试 -RHI_BACKEND=D3D12 ./build/tests/RHI/unit/Debug/rhi_unit_tests.exe - -# OpenGL 后端测试 -RHI_BACKEND=OpenGL ./build/tests/RHI/unit/Debug/rhi_unit_tests.exe -``` diff --git a/tests/RHI/unit/CMakeLists.txt b/tests/RHI/unit/CMakeLists.txt index 1cac788c..9076a71e 100644 --- a/tests/RHI/unit/CMakeLists.txt +++ b/tests/RHI/unit/CMakeLists.txt @@ -34,8 +34,8 @@ target_include_directories(rhi_unit_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/fixtures ${PROJECT_ROOT_DIR}/engine/include ${PROJECT_ROOT_DIR}/engine/src - ${CMAKE_SOURCE_DIR}/tests/OpenGL/package/include/ + ${CMAKE_SOURCE_DIR}/tests/opengl/package/include/ ) -enable_testing() -add_test(NAME RHIUnitTests COMMAND rhi_unit_tests) +include(GoogleTest) +gtest_discover_tests(rhi_unit_tests) diff --git a/tests/Resources/CMakeLists.txt b/tests/Resources/CMakeLists.txt index 443c0bc2..1c985c7f 100644 --- a/tests/Resources/CMakeLists.txt +++ b/tests/Resources/CMakeLists.txt @@ -28,24 +28,25 @@ set(RESOURCES_TEST_SOURCES test_resource_path.cpp ) -add_executable(xcengine_resources_tests ${RESOURCES_TEST_SOURCES}) +add_executable(resources_tests ${RESOURCES_TEST_SOURCES}) if(MSVC) - set_target_properties(xcengine_resources_tests PROPERTIES + set_target_properties(resources_tests PROPERTIES LINK_FLAGS "/NODEFAULTLIB:libcpmt.lib /NODEFAULTLIB:libcmt.lib" ) endif() -target_link_libraries(xcengine_resources_tests +target_link_libraries(resources_tests PRIVATE XCEngine GTest::gtest GTest::gtest_main ) -target_include_directories(xcengine_resources_tests PRIVATE +target_include_directories(resources_tests PRIVATE ${CMAKE_SOURCE_DIR}/engine/include ${CMAKE_SOURCE_DIR}/tests/fixtures ) -add_test(NAME ResourcesTests COMMAND xcengine_resources_tests) +include(GoogleTest) +gtest_discover_tests(resources_tests) diff --git a/tests/Scene/CMakeLists.txt b/tests/Scene/CMakeLists.txt index 705ad7a8..092e95af 100644 --- a/tests/Scene/CMakeLists.txt +++ b/tests/Scene/CMakeLists.txt @@ -7,22 +7,23 @@ set(SCENE_TEST_SOURCES test_scene_manager.cpp ) -add_executable(xcengine_scene_tests ${SCENE_TEST_SOURCES}) +add_executable(scene_tests ${SCENE_TEST_SOURCES}) if(MSVC) - set_target_properties(xcengine_scene_tests PROPERTIES + set_target_properties(scene_tests PROPERTIES LINK_FLAGS "/NODEFAULTLIB:libcpmt.lib /NODEFAULTLIB:libcmt.lib" ) endif() -target_link_libraries(xcengine_scene_tests PRIVATE +target_link_libraries(scene_tests PRIVATE XCEngine GTest::gtest GTest::gtest_main ) -target_include_directories(xcengine_scene_tests PRIVATE +target_include_directories(scene_tests PRIVATE ${CMAKE_SOURCE_DIR}/engine/include ) -add_test(NAME SceneTests COMMAND xcengine_scene_tests) \ No newline at end of file +include(GoogleTest) +gtest_discover_tests(scene_tests) \ No newline at end of file diff --git a/tests/TEST_SPEC.md b/tests/TEST_SPEC.md index b46865df..b03b96c9 100644 --- a/tests/TEST_SPEC.md +++ b/tests/TEST_SPEC.md @@ -2,239 +2,208 @@ ## 1. 测试框架 -### 1.1 框架组成 - -| 组件 | 用途 | 文档位置 | -|------|------|---------| -| Google Test | 单元测试框架 | https://google.github.io/googletest/ | -| CTest | CMake 测试发现和执行 | 内置 CMake 模块 | -| Python | 集成测试辅助 | `scripts/run_tests.py` | - -### 1.2 测试分类 - -| 类型 | 框架 | 特点 | -|------|------|------| -| 单元测试 | Google Test | 快速、独立、无副作用 | -| 集成测试 | CTest + Python | 端到端验证、需要 GUI | +| 组件 | 用途 | +|------|------| +| Google Test | 单元测试框架 | +| CTest | CMake 测试发现和执行 | --- ## 2. 测试目录结构 -### 2.1 整体结构 - ``` tests/ -├── CMakeLists.txt # 主 CMake 配置 -├── TEST_SPEC.md # 本规范文档 -├── run_tests.bat # Windows 测试启动脚本 +├── CMakeLists.txt # 主 CMake 配置 (包含 enable_testing) ├── fixtures/ # 共享测试夹具 -├── scripts/ -│ └── run_tests.py # 统一测试运行脚本 ├── math/ # 数学库测试 ├── core/ # 核心库测试 -├── containers/ # 容器测试 +├── containers/ # 容器测试 ├── memory/ # 内存管理测试 ├── threading/ # 线程测试 ├── debug/ # 调试系统测试 -├── Resources/ # 资源系统测试 -└── RHI/ - ├── D3D12/ # D3D12 RHI 测试 - │ ├── unit/ # 单元测试 - │ └── integration/ # 集成测试 - └── OpenGL/ # OpenGL RHI 测试 (暂不维护) +├── resources/ # 资源系统测试 +├── input/ # 输入模块测试 +├── scene/ # 场景测试 +├── components/ # 组件测试 +└── rhi/ + ├── d3d12/ # D3D12 RHI 测试 + │ ├── unit/ # 单元测试 + │ ├── integration/ # 集成测试 + │ └── CMakeLists.txt + └── opengl/ # OpenGL RHI 测试 + ├── unit/ # 单元测试 + ├── integration/ # 集成测试 + └── CMakeLists.txt ``` -### 2.2 模块命名规范 - -| 模块 | 测试可执行文件 | CTest 名称 | -|------|--------------|-----------| -| math | xcengine_math_tests | MathTests | -| core | xcengine_core_tests | CoreTests | -| containers | xcengine_containers_tests | ContainersTests | -| memory | xcengine_memory_tests | MemoryTests | -| threading | xcengine_threading_tests | ThreadingTests | -| debug | xcengine_debug_tests | DebugTests | -| Resources | xcengine_resources_tests | ResourcesTests | -| RHI/D3D12/unit | d3d12_engine_tests | D3D12EngineTests | -| RHI/D3D12/integration | D3D12_Minimal | D3D12_Minimal_Integration | - --- -## 3. 测试命名规范 +## 3. 模块命名 -### 3.1 单元测试命名 +| 模块 | 可执行文件 | CTest 名称前缀 | +|------|----------|---------------| +| math | math_tests | Math_* | +| core | core_tests | Core_* | +| containers | containers_tests | Containers_* | +| memory | memory_tests | MemoryTest_* | +| threading | threading_tests | Threading_* | +| debug | debug_tests | Debug_* | +| resources | resources_tests | Resource*/Texture*/Mesh* 等 | +| input | input_tests | Input*/WindowsInput* | +| scene | scene_tests | Scene*/SceneManager_* | +| components | components_tests | Component_*|TransformComponent_* | +| RHI/D3D12 | rhi_d3d12_tests | D3D12*Fixture/SwapChain*Fixture | +| RHI/OpenGL | opengl_engine_tests | OpenGLTestFixture.* | + +--- + +## 4. 测试用例命名 **格式**: `Component_Category_SubBehavior` | 部分 | 说明 | 示例 | |------|------|------| -| Component | 被测组件 | Memory, ResourceHandle, Buffer | +| Component | 被测组件 | Memory, Buffer, Texture | | Category | 操作类别 | Create, Get, Set, Map, Reset | | SubBehavior | 具体行为 | DefaultHeap, GPUAddress, ValidPointer | **示例**: ``` -MemoryTest_GetSystemAllocator_ReturnsValidPointer -ResourceHandle_DefaultConstructor Buffer_Create_DefaultHeap Texture_Create_2D +Fence_Signal_Wait ``` -### 3.2 禁止模式 - -❌ 不允许: +**禁止模式**: - `*_Placeholder` - 无意义的占位测试 - 驼峰+下划线混用 -- 空操作测试 - -### 3.3 大小写规则 - -- 全小写,单词间用下划线分隔 -- Component 名称与类名一致 --- -## 4. CMakeLists.txt 规范 +## 5. CMake 规范 -### 4.1 单元测试模板 +### 5.1 单元测试模板 ```cmake cmake_minimum_required(VERSION 3.15) -project(XCEngine_ModuleTests) - find_package(GTest REQUIRED) set(TEST_SOURCES test_module.cpp - # ... 其他测试文件 ) -add_executable(xcengine_module_tests ${TEST_SOURCES}) +add_executable(module_tests ${TEST_SOURCES}) -# MSVC 运行时库排除 if(MSVC) - set_target_properties(xcengine_module_tests PROPERTIES + set_target_properties(module_tests PROPERTIES LINK_FLAGS "/NODEFAULTLIB:libcpmt.lib /NODEFAULTLIB:libcmt.lib" ) endif() -target_link_libraries(xcengine_module_tests PRIVATE +target_link_libraries(module_tests PRIVATE XCEngine GTest::gtest GTest::gtest_main ) -target_include_directories(xcengine_module_tests PRIVATE +target_include_directories(module_tests PRIVATE ${CMAKE_SOURCE_DIR}/engine/include ${CMAKE_SOURCE_DIR}/tests/fixtures ) -add_test(NAME ModuleTests COMMAND xcengine_module_tests) +include(GoogleTest) +gtest_discover_tests(module_tests) ``` -### 4.2 CTest 注册 - -每个模块的 CMakeLists.txt 必须包含: +### 5.2 RHI 测试 CMakeLists 模板 ```cmake -add_test(NAME COMMAND ) -``` +cmake_minimum_required(VERSION 3.15) -### 4.3 测试资源复制 +project(rhi_backend_tests) -如需复制测试资源: +find_package(GTest REQUIRED) +find_package(Python3 REQUIRED) # 集成测试需要 -```cmake -add_custom_command(TARGET POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory - ${CMAKE_CURRENT_SOURCE_DIR}/Res - $>/Res +# 单元测试 +set(UNIT_TEST_SOURCES + fixtures/TestFixture.cpp + test_*.cpp ) + +add_executable(rhi_backend_tests ${UNIT_TEST_SOURCES}) + +target_link_libraries(rhi_backend_tests PRIVATE + d3d12 + dxgi + d3dcompiler + XCEngine + GTest::gtest + GTest::gtest_main +) + +target_include_directories(rhi_backend_tests PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/fixtures + ${CMAKE_SOURCE_DIR}/engine/include + ${CMAKE_SOURCE_DIR}/engine/src +) + +# 集成测试 +add_subdirectory(integration) + +include(GoogleTest) +gtest_discover_tests(rhi_backend_tests) ``` --- -## 5. 测试执行 +## 6. 测试执行 -### 5.1 统一测试脚本 +### 6.1 增量构建(推荐) -**位置**: `scripts/run_tests.py` +**何时需要重新运行 `cmake ..`**: +- 新增/删除/重命名源文件 +- 修改 CMakeLists.txt(添加 subdirectory、target 等) +- 修改编译器选项或宏定义 -**功能**: -- 跨平台支持 (Windows/Linux) -- 自动检测测试目录 -- 单元测试 + 集成测试 -- 测试结果汇总 +**增量构建命令**: +```bash +# 1. 增量配置(检测 CMakeLists.txt 变化) +cd build +cmake .. -### 5.2 使用方式 +# 2. 只构建特定 target(不重新配置整个项目) +cmake --build . --target math_tests --config Debug -| 命令 | 说明 | -|------|------| -| `python scripts/run_tests.py` | 运行所有测试 | -| `python scripts/run_tests.py --unit-only` | 仅单元测试 | -| `python scripts/run_tests.py --integration` | 含集成测试 | -| `python scripts/run_tests.py --ci` | CI 模式 (跳过 GUI 测试) | -| `python scripts/run_tests.py --build` | 构建并测试 | -| `python scripts/run_tests.py --dir ` | 指定测试目录 | -| `python scripts/run_tests.py --verbose` | 详细输出 | +# 3. 只构建特定模块 +cmake --build . --target rhi_d3d12_tests --config Debug +``` -### 5.3 直接使用 CTest +### 6.2 完整构建 ```bash -# 运行特定模块测试 -cd build/tests/ -ctest -C Debug --output-on-failure +cmake --build build --config Debug +cd build && ctest -C Debug --output-on-failure +``` +### 6.3 测试运行 + +```bash # 列出所有测试 ctest -N # 运行所有测试 ctest -C Debug --output-on-failure -``` ---- +# 运行特定模块测试 +ctest -R "Math_" -C Debug --output-on-failure -## 6. CI 集成 +# 运行 D3D12 所有测试 +ctest -R "D3D12" -C Debug --output-on-failure -### 6.1 GitHub Actions 配置 - -```yaml -name: XCEngine 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 - run: cmake --build build --config Debug - - - name: Run Tests - run: python scripts/run_tests.py --ci -``` - -### 6.2 CI 模式说明 - -`--ci` 模式会: -- 运行所有单元测试 -- 跳过需要 GUI 窗口的集成测试 -- 输出机器可读的测试结果 - -### 6.3 本地验证 - -```bash -# 完整构建和测试 -python scripts/run_tests.py --build - -# 仅验证单元测试 -python scripts/run_tests.py --unit-only +# 运行特定测试用例 +ctest -R "Buffer_Create" -C Debug --output-on-failure ``` --- @@ -247,37 +216,19 @@ python scripts/run_tests.py --unit-only #include #include -using namespace XCEngine::Module; - class ComponentTest : public ::testing::Test { protected: - void SetUp() override { - // 初始化测试环境 - } - - void TearDown() override { - // 清理资源 - } + void SetUp() override { } + void TearDown() override { } }; TEST_F(ComponentTest, Create_ReturnsValidPointer) { auto component = Component::Create(); ASSERT_NE(component, nullptr); } - -TEST_F(ComponentTest, GetProperty_ReturnsExpectedValue) { - Component component; - EXPECT_EQ(component.GetProperty(), expected_value); -} ``` -### 7.2 Fixture 使用原则 - -- 每个测试类使用独立的 Fixture -- SetUp/TearDown 用于资源初始化/清理 -- 避免测试间共享状态 - -### 7.3 断言选择 +### 7.2 断言选择 | 断言 | 用途 | |------|------| @@ -286,43 +237,117 @@ TEST_F(ComponentTest, GetProperty_ReturnsExpectedValue) { --- -## 8. 文件结构 +## 8. CI 配置 -``` -tests/ -├── CMakeLists.txt -├── TEST_SPEC.md # 本规范 -├── run_tests.bat # Windows 测试脚本 -├── fixtures/ # 共享夹具头文件 -├── scripts/ -│ └── run_tests.py # 统一测试运行脚本 -├── math/ -│ ├── CMakeLists.txt -│ └── test_*.cpp -├── core/ -├── containers/ -├── memory/ -├── threading/ -├── debug/ -├── Resources/ -└── RHI/ - ├── D3D12/ - │ ├── unit/ - │ ├── integration/ - │ ├── TEST_SPEC.md # D3D12 专项规范 - │ └── TEST_IMPROVEMENT_PLAN.md - └── OpenGL/ +```yaml +name: XCEngine 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 + run: cmake --build build --config Debug + - name: Run Tests + run: cd build && ctest -C Debug --output-on-failure ``` --- -## 9. 规范更新记录 +## 9. 性能参考 -| 版本 | 日期 | 变更 | -|------|------|------| -| 1.0 | 2026-03-20 | 初始版本,统一测试规范体系 | +### 9.1 模块构建和运行时间 + +| 模块 | 构建时间 | 运行时间 | 测试数量 | +|------|---------|---------|----------| +| math | ~6s | ~26s | 140 | +| core | ~6s | ~4s | 18 | +| containers | ~3s | ~10s | 51 | +| memory | ~3s | ~4s | 19 | +| threading | ~5s | ~4s | 13 | +| debug | ~3s | ~2s | 8 | +| components | ~3s | ~8s | 39 | +| scene | ~4s | ~2s | 14 | +| resources | ~4s | ~31s | 131 | +| input | ~4s | ~9s | 40 | +| D3D12 unit | ~3s | ~55s | 49 | +| OpenGL unit | ~46s | ~11s | 61 | +| **总计** | - | - | **~622** | + +### 9.2 分模块构建命令(推荐) + +```bash +# ==================== 快速开发工作流 ==================== + +# 1. 修改某个模块代码后,增量构建该模块 +cmake --build . --target math_tests --config Debug +cmake --build . --target core_tests --config Debug +cmake --build . --target containers_tests --config Debug +cmake --build . --target memory_tests --config Debug +cmake --build . --target threading_tests --config Debug +cmake --build . --target debug_tests --config Debug +cmake --build . --target components_tests --config Debug +cmake --build . --target scene_tests --config Debug +cmake --build . --target resources_tests --config Debug +cmake --build . --target input_tests --config Debug +cmake --build . --target rhi_d3d12_tests --config Debug +cmake --build . --target opengl_engine_tests --config Debug + +# 2. 只运行该模块测试 +ctest -R "^Math_" -C Debug --output-on-failure +ctest -R "^Core_" -C Debug --output-on-failure +ctest -R "^Containers_" -C Debug --output-on-failure +ctest -R "MemoryTest_|LinearAllocator|PoolAllocator" -C Debug --output-on-failure +ctest -R "^Threading_" -C Debug --output-on-failure +ctest -R "^Debug_" -C Debug --output-on-failure +ctest -R "Component_Test|TransformComponent_" -C Debug --output-on-failure +ctest -R "^Scene_" -C Debug --output-on-failure +ctest -R "Resource[A-Z]|Texture[A-Z]|Mesh[A-Z]|Shader[A-Z]|Audio[A-Z]|Material[A-Z]" -C Debug --output-on-failure +ctest -R "Input|WindowsInput" -C Debug --output-on-failure +ctest -R "D3D12.*Fixture|SwapChain.*Fixture" -C Debug --output-on-failure +build/tests/RHI/OpenGL/unit/Debug/opengl_engine_tests.exe --gtest_filter=* +``` + +### 9.3 按功能组构建和运行 + +```bash +# ==================== 基础设施模块 ==================== +cmake --build . --target math_tests --config Debug +cmake --build . --target core_tests --config Debug +cmake --build . --target containers_tests --config Debug +ctest -R "^Math_|^Core_|^Containers_" -C Debug --output-on-failure + +# ==================== 核心系统模块 ==================== +cmake --build . --target memory_tests --config Debug +cmake --build . --target threading_tests --config Debug +cmake --build . --target debug_tests --config Debug +ctest -R "MemoryTest_|LinearAllocator|PoolAllocator|^Threading_|^Debug_" -C Debug --output-on-failure + +# ==================== 游戏引擎模块 ==================== +cmake --build . --target components_tests --config Debug +cmake --build . --target scene_tests --config Debug +cmake --build . --target resources_tests --config Debug +cmake --build . --target input_tests --config Debug +ctest -R "Component_Test|TransformComponent_|^Scene_|Resource[A-Z]|Texture[A-Z]|Mesh[A-Z]|Input|WindowsInput" -C Debug --output-on-failure + +# ==================== RHI 模块 ==================== +cmake --build . --target rhi_d3d12_tests --config Debug +cmake --build . --target opengl_engine_tests --config Debug +ctest -R "D3D12.*Fixture|SwapChain.*Fixture" -C Debug --output-on-failure +build/tests/RHI/OpenGL/unit/Debug/opengl_engine_tests.exe --gtest_filter=* +``` + +### 9.4 注意事项 + +- **OpenGL 单元测试**:构建时间较长(~46s),因为需要编译 glad.c。建议单独构建 +- **D3D12 单元测试**:运行时间较长(~55s),适合 CI 自动化 +- **Resources 模块**:运行时间~31s,包含大量资源加载测试 +- **Math 模块**:运行时间~26s,包含140个数学运算测试 --- -**规范版本**: 1.0 -**最后更新**: 2026-03-20 \ No newline at end of file +**最后更新**: 2026-03-23 diff --git a/tests/containers/CMakeLists.txt b/tests/containers/CMakeLists.txt index 23f2c783..493cd88f 100644 --- a/tests/containers/CMakeLists.txt +++ b/tests/containers/CMakeLists.txt @@ -8,24 +8,25 @@ set(CONTAINERS_TEST_SOURCES test_hashmap.cpp ) -add_executable(xcengine_containers_tests ${CONTAINERS_TEST_SOURCES}) +add_executable(containers_tests ${CONTAINERS_TEST_SOURCES}) if(MSVC) - set_target_properties(xcengine_containers_tests PROPERTIES + set_target_properties(containers_tests PROPERTIES LINK_FLAGS "/NODEFAULTLIB:libcpmt.lib /NODEFAULTLIB:libcmt.lib" ) endif() -target_link_libraries(xcengine_containers_tests +target_link_libraries(containers_tests PRIVATE XCEngine GTest::gtest GTest::gtest_main ) -target_include_directories(xcengine_containers_tests PRIVATE +target_include_directories(containers_tests PRIVATE ${CMAKE_SOURCE_DIR}/engine/include ${CMAKE_SOURCE_DIR}/tests/fixtures ) -add_test(NAME ContainersTests COMMAND xcengine_containers_tests) +include(GoogleTest) +gtest_discover_tests(containers_tests) diff --git a/tests/core/CMakeLists.txt b/tests/core/CMakeLists.txt index 3846e316..ede172eb 100644 --- a/tests/core/CMakeLists.txt +++ b/tests/core/CMakeLists.txt @@ -6,25 +6,26 @@ set(CORE_TEST_SOURCES test_core.cpp ) -add_executable(xcengine_core_tests ${CORE_TEST_SOURCES}) +add_executable(core_tests ${CORE_TEST_SOURCES}) # Exclude all static runtime libraries to avoid conflicts if(MSVC) - set_target_properties(xcengine_core_tests PROPERTIES + set_target_properties(core_tests PROPERTIES LINK_FLAGS "/NODEFAULTLIB:libcpmt.lib /NODEFAULTLIB:libcmt.lib" ) endif() -target_link_libraries(xcengine_core_tests +target_link_libraries(core_tests PRIVATE XCEngine GTest::gtest GTest::gtest_main ) -target_include_directories(xcengine_core_tests PRIVATE +target_include_directories(core_tests PRIVATE ${CMAKE_SOURCE_DIR}/engine/include ${CMAKE_SOURCE_DIR}/tests/fixtures ) -add_test(NAME CoreTests COMMAND xcengine_core_tests) +include(GoogleTest) +gtest_discover_tests(core_tests) diff --git a/tests/debug/CMakeLists.txt b/tests/debug/CMakeLists.txt index fbde5926..32295cf5 100644 --- a/tests/debug/CMakeLists.txt +++ b/tests/debug/CMakeLists.txt @@ -1,14 +1,16 @@ -add_executable(xcengine_debug_tests +find_package(GTest REQUIRED) + +add_executable(debug_tests test_logger.cpp test_profiler.cpp ) -target_link_libraries(xcengine_debug_tests +target_link_libraries(debug_tests PRIVATE XCEngine - gtest - gtest_main + GTest::gtest + GTest::gtest_main ) include(GoogleTest) -gtest_discover_tests(xcengine_debug_tests) +gtest_discover_tests(debug_tests) diff --git a/tests/math/CMakeLists.txt b/tests/math/CMakeLists.txt index 2b824d51..1a79a886 100644 --- a/tests/math/CMakeLists.txt +++ b/tests/math/CMakeLists.txt @@ -9,25 +9,26 @@ set(MATH_TEST_SOURCES test_geometry.cpp ) -add_executable(xcengine_math_tests ${MATH_TEST_SOURCES}) +add_executable(math_tests ${MATH_TEST_SOURCES}) # Exclude all static runtime libraries to avoid conflicts if(MSVC) - set_target_properties(xcengine_math_tests PROPERTIES + set_target_properties(math_tests PROPERTIES LINK_FLAGS "/NODEFAULTLIB:libcpmt.lib /NODEFAULTLIB:libcmt.lib" ) endif() -target_link_libraries(xcengine_math_tests +target_link_libraries(math_tests PRIVATE XCEngine GTest::gtest GTest::gtest_main ) -target_include_directories(xcengine_math_tests PRIVATE +target_include_directories(math_tests PRIVATE ${CMAKE_SOURCE_DIR}/engine/include ${CMAKE_SOURCE_DIR}/tests/fixtures ) -add_test(NAME MathTests COMMAND xcengine_math_tests) +include(GoogleTest) +gtest_discover_tests(math_tests) diff --git a/tests/memory/CMakeLists.txt b/tests/memory/CMakeLists.txt index ca568db3..439df96a 100644 --- a/tests/memory/CMakeLists.txt +++ b/tests/memory/CMakeLists.txt @@ -8,24 +8,25 @@ set(MEMORY_TEST_SOURCES test_pool_allocator.cpp ) -add_executable(xcengine_memory_tests ${MEMORY_TEST_SOURCES}) +add_executable(memory_tests ${MEMORY_TEST_SOURCES}) if(MSVC) - set_target_properties(xcengine_memory_tests PROPERTIES + set_target_properties(memory_tests PROPERTIES LINK_FLAGS "/NODEFAULTLIB:libcpmt.lib /NODEFAULTLIB:libcmt.lib" ) endif() -target_link_libraries(xcengine_memory_tests +target_link_libraries(memory_tests PRIVATE XCEngine GTest::gtest GTest::gtest_main ) -target_include_directories(xcengine_memory_tests PRIVATE +target_include_directories(memory_tests PRIVATE ${CMAKE_SOURCE_DIR}/engine/include ${CMAKE_SOURCE_DIR}/tests/fixtures ) -add_test(NAME MemoryTests COMMAND xcengine_memory_tests) +include(GoogleTest) +gtest_discover_tests(memory_tests) diff --git a/tests/threading/CMakeLists.txt b/tests/threading/CMakeLists.txt index 255c26c7..85c0de78 100644 --- a/tests/threading/CMakeLists.txt +++ b/tests/threading/CMakeLists.txt @@ -8,24 +8,25 @@ set(THREADING_TEST_SOURCES test_task.cpp ) -add_executable(xcengine_threading_tests ${THREADING_TEST_SOURCES}) +add_executable(threading_tests ${THREADING_TEST_SOURCES}) if(MSVC) - set_target_properties(xcengine_threading_tests PROPERTIES + set_target_properties(threading_tests PROPERTIES LINK_FLAGS "/NODEFAULTLIB:libcpmt.lib /NODEFAULTLIB:libcmt.lib" ) endif() -target_link_libraries(xcengine_threading_tests +target_link_libraries(threading_tests PRIVATE XCEngine GTest::gtest GTest::gtest_main ) -target_include_directories(xcengine_threading_tests PRIVATE +target_include_directories(threading_tests PRIVATE ${CMAKE_SOURCE_DIR}/engine/include ${CMAKE_SOURCE_DIR}/tests/fixtures ) -add_test(NAME ThreadingTests COMMAND xcengine_threading_tests) +include(GoogleTest) +gtest_discover_tests(threading_tests)