feat(RHI): 添加 RHIFactory 工厂类
- 新增 RHIFactory 头文件和实现,支持通过 RHIType 或字符串创建设备 - 修复 D3D12Buffer 缺失的 Map/Unmap/SetData 实现 - 添加 RHI 工厂测试用例 - 更新 CMakeLists.txt 添加新文件
This commit is contained in:
@@ -83,6 +83,7 @@ add_library(XCEngine STATIC
|
|||||||
|
|
||||||
# RHI
|
# RHI
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/RHIEnums.h
|
${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/D3D12/D3D12Enum.h
|
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12Enum.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/D3D12/D3D12Device.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/D3D12CommandQueue.h
|
||||||
@@ -125,31 +126,8 @@ add_library(XCEngine STATIC
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12QueryHeap.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12QueryHeap.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12UnorderedAccessView.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/D3D12/D3D12UnorderedAccessView.cpp
|
||||||
|
|
||||||
# OpenGL RHI
|
# RHI Factory
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/OpenGL/OpenGLDevice.h
|
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/RHIFactory.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/OpenGL/OpenGLShader.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/OpenGL/OpenGLBuffer.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/OpenGL/OpenGLVertexArray.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/OpenGL/OpenGLTexture.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/OpenGL/OpenGLPipelineState.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/OpenGL/OpenGLCommandList.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/OpenGL/OpenGLSwapChain.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/OpenGL/OpenGLFence.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/OpenGL/OpenGLSampler.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/OpenGL/OpenGLRenderTargetView.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLDevice.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLShader.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLBuffer.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLVertexArray.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLTexture.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLPipelineState.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLCommandList.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLSwapChain.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLFence.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLSampler.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLRenderTargetView.cpp
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RHI/OpenGL/OpenGLDepthStencilView.cpp
|
|
||||||
|
|
||||||
# Resources
|
# Resources
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/Resources.h
|
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Resources/Resources.h
|
||||||
|
|||||||
20
engine/include/XCEngine/RHI/RHIFactory.h
Normal file
20
engine/include/XCEngine/RHI/RHIFactory.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "RHIEnums.h"
|
||||||
|
#include "RHIDevice.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace XCEngine {
|
||||||
|
namespace RHI {
|
||||||
|
|
||||||
|
class RHIFactory {
|
||||||
|
public:
|
||||||
|
static RHIDevice* CreateRHIDevice(RHIType type);
|
||||||
|
static RHIDevice* CreateRHIDevice(const std::string& typeName);
|
||||||
|
|
||||||
|
private:
|
||||||
|
RHIFactory() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace RHI
|
||||||
|
} // namespace XCEngine
|
||||||
@@ -155,5 +155,24 @@ void D3D12Buffer::UpdateData(const void* data, uint64_t size) {
|
|||||||
m_resource->Unmap(0, nullptr);
|
m_resource->Unmap(0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* D3D12Buffer::Map() {
|
||||||
|
D3D12_RANGE readRange = { 0, 0 };
|
||||||
|
void* data = nullptr;
|
||||||
|
m_resource->Map(0, &readRange, &data);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D12Buffer::Unmap() {
|
||||||
|
m_resource->Unmap(0, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D12Buffer::SetData(const void* data, size_t size, size_t offset) {
|
||||||
|
D3D12_RANGE writeRange = { offset, offset + size };
|
||||||
|
unsigned char* pBuffer = nullptr;
|
||||||
|
m_resource->Map(0, &writeRange, reinterpret_cast<void**>(&pBuffer));
|
||||||
|
memcpy(pBuffer + offset, data, size);
|
||||||
|
m_resource->Unmap(0, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace RHI
|
} // namespace RHI
|
||||||
} // namespace XCEngine
|
} // namespace XCEngine
|
||||||
|
|||||||
42
engine/src/RHI/RHIFactory.cpp
Normal file
42
engine/src/RHI/RHIFactory.cpp
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#include "XCEngine/RHI/RHIFactory.h"
|
||||||
|
#include "XCEngine/RHI/D3D12/D3D12Device.h"
|
||||||
|
|
||||||
|
namespace XCEngine {
|
||||||
|
namespace RHI {
|
||||||
|
|
||||||
|
RHIDevice* RHIFactory::CreateRHIDevice(RHIType type) {
|
||||||
|
switch (type) {
|
||||||
|
case RHIType::D3D12:
|
||||||
|
return new D3D12Device();
|
||||||
|
case RHIType::OpenGL:
|
||||||
|
#ifdef XCENGINE_SUPPORT_OPENGL
|
||||||
|
{
|
||||||
|
#include "XCEngine/RHI/OpenGL/OpenGLDevice.h"
|
||||||
|
return new OpenGLDevice();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
|
case RHIType::Vulkan:
|
||||||
|
case RHIType::Metal:
|
||||||
|
default:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RHIDevice* RHIFactory::CreateRHIDevice(const std::string& typeName) {
|
||||||
|
if (typeName == "D3D12" || typeName == "d3d12") {
|
||||||
|
return new D3D12Device();
|
||||||
|
} else if (typeName == "OpenGL" || typeName == "opengl" || typeName == "GL") {
|
||||||
|
#ifdef XCENGINE_SUPPORT_OPENGL
|
||||||
|
#include "XCEngine/RHI/OpenGL/OpenGLDevice.h"
|
||||||
|
return new OpenGLDevice();
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace RHI
|
||||||
|
} // namespace XCEngine
|
||||||
@@ -38,6 +38,7 @@ add_subdirectory(memory)
|
|||||||
add_subdirectory(threading)
|
add_subdirectory(threading)
|
||||||
add_subdirectory(debug)
|
add_subdirectory(debug)
|
||||||
add_subdirectory(D3D12)
|
add_subdirectory(D3D12)
|
||||||
|
add_subdirectory(RHI)
|
||||||
add_subdirectory(RHI/D3D12)
|
add_subdirectory(RHI/D3D12)
|
||||||
add_subdirectory(RHI/OpenGL)
|
add_subdirectory(RHI/OpenGL)
|
||||||
add_subdirectory(Resources)
|
add_subdirectory(Resources)
|
||||||
|
|||||||
43
tests/RHI/CMakeLists.txt
Normal file
43
tests/RHI/CMakeLists.txt
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.15)
|
||||||
|
|
||||||
|
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)
|
||||||
44
tests/RHI/test_factory.cpp
Normal file
44
tests/RHI/test_factory.cpp
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "XCEngine/RHI/RHIFactory.h"
|
||||||
|
#include "XCEngine/RHI/D3D12/D3D12Device.h"
|
||||||
|
|
||||||
|
using namespace XCEngine::RHI;
|
||||||
|
|
||||||
|
TEST(RHIFactory, CreateD3D12Device_ReturnsValidPointer) {
|
||||||
|
RHIDevice* device = RHIFactory::CreateRHIDevice(RHIType::D3D12);
|
||||||
|
|
||||||
|
ASSERT_NE(device, nullptr);
|
||||||
|
|
||||||
|
delete device;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(RHIFactory, CreateD3D12DeviceByName_ReturnsValidPointer) {
|
||||||
|
RHIDevice* device = RHIFactory::CreateRHIDevice("D3D12");
|
||||||
|
|
||||||
|
ASSERT_NE(device, nullptr);
|
||||||
|
|
||||||
|
delete device;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(RHIFactory, CreateInvalidDevice_ReturnsNullptr) {
|
||||||
|
RHIDevice* device = RHIFactory::CreateRHIDevice("InvalidAPI");
|
||||||
|
|
||||||
|
ASSERT_EQ(device, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(RHIFactory, CreateInvalidType_ReturnsNullptr) {
|
||||||
|
RHIDevice* device = RHIFactory::CreateRHIDevice(RHIType::Vulkan);
|
||||||
|
|
||||||
|
ASSERT_EQ(device, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(D3D12DeviceCreation, DirectCreation_Success) {
|
||||||
|
D3D12Device* device = new D3D12Device();
|
||||||
|
|
||||||
|
ASSERT_NE(device, nullptr);
|
||||||
|
|
||||||
|
delete device;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user