feat(RHI): 实现 RHIDevice 抽象基类

This commit is contained in:
2026-03-17 17:45:01 +08:00
parent af718279ff
commit 14fb51e61e
5 changed files with 309 additions and 39 deletions

View File

@@ -589,7 +589,80 @@ public:
- OpenGLGLsync - OpenGLGLsync
- 解决GetNativeHandle() 返回 void* - 解决GetNativeHandle() 返回 void*
### 5.10 根签名 vs OpenGL 资源绑定 ### 5.10 设备RHIDevice抽象设计
#### 5.10.1 设计理念对应
| 差异点 | 设计理念 | 处理方案 |
|--------|---------|---------|
| 初始化参数差异 | 求同存异 | 统一 Initialize 接口,后端各自处理 |
| 工厂方法差异 | 特性降级 | D3D12 实现OpenGL 返回 nullptr |
| 窗口管理差异 | 特性降级 | OpenGL 有D3D12 通过 SwapChain 处理 |
| 适配器枚举差异 | 特性降级 | D3D12 实现OpenGL 空实现 |
| 底层设备类型差异 | 底层逃逸 | 统一返回 void* |
#### 5.10.2 现有实现对比
| 功能 | D3D12Device | OpenGLDevice | 处理方案 |
|------|--------------|---------------|----------|
| 初始化 | Initialize(debugLayer) | CreateRenderWindow/InitializeWithExistingWindow | 统一 Initialize |
| 关闭 | Shutdown() | Shutdown() | 统一 |
| 获取设备 | GetDevice() | 无 | GetNativeHandle 统一 |
| 适配器信息 | GetAdapterInfo() | GetDeviceInfo() | 统一 GetDeviceInfo |
| 工厂方法 | CreateBuffer/Texture/Shader... | 无 | OpenGL 返回 nullptr |
| 窗口管理 | 通过 SwapChain | GetWindow/SwapBuffers/PollEvents | OpenGL 有D3D12 无 |
#### 5.10.3 抽象接口定义
```cpp
class RHIDevice {
public:
virtual ~RHIDevice() = default;
virtual bool Initialize(const RHIDeviceDesc& desc) = 0;
virtual void Shutdown() = 0;
virtual const RHIDeviceInfo& GetDeviceInfo() const = 0;
virtual const RHICapabilities& GetCapabilities() const = 0;
virtual RHIBuffer* CreateBuffer(const BufferDesc& desc) = 0;
virtual RHITexture* CreateTexture(const TextureDesc& desc) = 0;
virtual RHIShader* CompileShader(const ShaderCompileDesc& desc) = 0;
virtual RHISampler* CreateSampler(const SamplerDesc& desc) = 0;
virtual RHIFence* CreateFence(const FenceDesc& desc) = 0;
virtual void* GetNativeDevice() = 0;
virtual void* GetNativeHandle() const = 0;
};
```
#### 5.10.4 差异处理策略
1. **初始化参数差异(求同存异)**
- D3D12`Initialize(enableDebugLayer)`
- OpenGL`CreateRenderWindow` / `InitializeWithExistingWindow`
- 解决:统一 `Initialize(const RHIDeviceDesc& desc)` 接口Desc 中包含窗口参数
2. **工厂方法差异(特性降级)**
- D3D12有完整的工厂方法
- OpenGL资源直接用 glGen* 创建,没有工厂方法
- 解决OpenGL 后端返回 nullptr上层需直接创建 OpenGL 资源
3. **窗口管理差异(特性降级)**
- OpenGL直接管理窗口有 GetWindow/SwapBuffers/PollEvents
- D3D12通过 SwapChain 处理
- 解决OpenGL 提供窗口管理接口D3D12 空实现
4. **适配器枚举差异(特性降级)**
- D3D12支持 EnumerateAdapters
- OpenGL无此概念
- 解决D3D12 实现具体功能OpenGL 返回空
5. **底层设备类型差异(底层逃逸)**
- D3D12ID3D12Device*
- OpenGL无对等概念
- 解决GetNativeDevice() 返回 void*OpenGL 返回 nullptr 或窗口句柄
- **D3D12**:显式 `RootSignature` 定义资源绑定规则 - **D3D12**:显式 `RootSignature` 定义资源绑定规则
- **OpenGL**:隐式通过 `glUniformLocation`、`glBindTextureUnit` 绑定 - **OpenGL**:隐式通过 `glUniformLocation`、`glBindTextureUnit` 绑定
- **解决方案** - **解决方案**

View File

@@ -6,6 +6,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "../RHIDevice.h"
#include "../RHIEnums.h" #include "../RHIEnums.h"
#include "../RHITypes.h" #include "../RHITypes.h"
#include "D3D12Enum.h" #include "D3D12Enum.h"
@@ -44,13 +45,13 @@ struct AdapterInfo {
bool isSoftware; bool isSoftware;
}; };
class D3D12Device { class D3D12Device : public RHIDevice {
public: public:
D3D12Device(); D3D12Device();
~D3D12Device(); ~D3D12Device() override;
bool Initialize(bool enableDebugLayer = false); bool Initialize(const RHIDeviceDesc& desc) override;
void Shutdown(); void Shutdown() override;
ID3D12Device* GetDevice() const { return m_device.Get(); } ID3D12Device* GetDevice() const { return m_device.Get(); }
IDXGIFactory4* GetFactory() const { return m_factory.Get(); } IDXGIFactory4* GetFactory() const { return m_factory.Get(); }
@@ -65,20 +66,33 @@ public:
void SetDeviceRemoved() { m_isDeviceRemoved = true; } void SetDeviceRemoved() { m_isDeviceRemoved = true; }
bool IsDeviceRemoved() const { return m_isDeviceRemoved; } bool IsDeviceRemoved() const { return m_isDeviceRemoved; }
// Factory methods RHIBuffer* CreateBuffer(const BufferDesc& desc) override;
D3D12CommandQueue* CreateCommandQueue(const CommandQueueDesc& desc); RHITexture* CreateTexture(const TextureDesc& desc) override;
D3D12CommandList* CreateCommandList(const CommandListDesc& desc); RHISwapChain* CreateSwapChain(const SwapChainDesc& desc) override;
RHICommandList* CreateCommandList(const CommandListDesc& desc) override;
RHICommandQueue* CreateCommandQueue(const CommandQueueDesc& desc) override;
RHIShader* CompileShader(const ShaderCompileDesc& desc) override;
RHIPipelineState* CreatePipelineState(const PipelineStateDesc& desc) override;
RHIFence* CreateFence(const FenceDesc& desc) override;
RHISampler* CreateSampler(const SamplerDesc& desc) override;
const RHICapabilities& GetCapabilities() const override;
const RHIDeviceInfo& GetDeviceInfo() const override;
void* GetNativeDevice() override;
void* GetNativeHandle() const override;
bool PollEvents() override;
void SwapBuffers() override;
bool ShouldClose() const override;
void SetShouldClose(bool shouldClose) override;
D3D12CommandQueue* CreateCommandQueueImpl(const CommandQueueDesc& desc);
D3D12CommandList* CreateCommandListImpl(const CommandListDesc& desc);
D3D12CommandAllocator* CreateCommandAllocator(const CommandAllocatorDesc& desc); D3D12CommandAllocator* CreateCommandAllocator(const CommandAllocatorDesc& desc);
D3D12Fence* CreateFence(const FenceDesc& desc);
D3D12DescriptorHeap* CreateDescriptorHeap(const DescriptorHeapDesc& desc); D3D12DescriptorHeap* CreateDescriptorHeap(const DescriptorHeapDesc& desc);
D3D12QueryHeap* CreateQueryHeap(const QueryHeapDesc& desc); D3D12QueryHeap* CreateQueryHeap(const QueryHeapDesc& desc);
D3D12RootSignature* CreateRootSignature(const RootSignatureDesc& desc); D3D12RootSignature* CreateRootSignature(const RootSignatureDesc& desc);
D3D12PipelineState* CreatePipelineState(const PipelineStateDesc& desc);
D3D12Sampler* CreateSampler(const SamplerDesc& desc);
D3D12Texture* CreateTexture(const TextureDesc& desc);
D3D12Buffer* CreateBuffer(const BufferDesc& desc);
D3D12SwapChain* CreateSwapChain(const SwapChainDesc& desc);
D3D12Shader* CompileShader(const ShaderCompileDesc& desc);
D3D12RenderTargetView* CreateRenderTargetView(D3D12Buffer* resource, const RenderTargetViewDesc& desc); D3D12RenderTargetView* CreateRenderTargetView(D3D12Buffer* resource, const RenderTargetViewDesc& desc);
D3D12DepthStencilView* CreateDepthStencilView(D3D12Buffer* resource, const DepthStencilViewDesc& desc); D3D12DepthStencilView* CreateDepthStencilView(D3D12Buffer* resource, const DepthStencilViewDesc& desc);
@@ -86,8 +100,6 @@ public:
D3D12UnorderedAccessView* CreateUnorderedAccessView(D3D12Buffer* resource, const UnorderedAccessViewDesc& desc); D3D12UnorderedAccessView* CreateUnorderedAccessView(D3D12Buffer* resource, const UnorderedAccessViewDesc& desc);
D3D12ConstantBufferView* CreateConstantBufferView(D3D12Buffer* resource, const ConstantBufferViewDesc& desc); D3D12ConstantBufferView* CreateConstantBufferView(D3D12Buffer* resource, const ConstantBufferViewDesc& desc);
void* GetNativeHandle() const;
private: private:
bool CreateDXGIFactory(bool enableDebugLayer); bool CreateDXGIFactory(bool enableDebugLayer);
bool CreateDevice(IDXGIAdapter1* adapter); bool CreateDevice(IDXGIAdapter1* adapter);
@@ -98,6 +110,8 @@ private:
ComPtr<IDXGIAdapter1> m_adapter; ComPtr<IDXGIAdapter1> m_adapter;
AdapterInfo m_adapterInfo; AdapterInfo m_adapterInfo;
RHICapabilities m_capabilities;
RHIDeviceInfo m_deviceInfo;
bool m_isDeviceRemoved; bool m_isDeviceRemoved;
bool m_initialized; bool m_initialized;
}; };

View File

@@ -3,37 +3,52 @@
#include <string> #include <string>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include "../RHIDevice.h"
#include "../RHICapabilities.h"
namespace XCEngine { namespace XCEngine {
namespace RHI { namespace RHI {
struct OpenGLDeviceInfo { class OpenGLDevice : public RHIDevice {
std::string vendor;
std::string renderer;
std::string version;
int majorVersion;
int minorVersion;
};
class OpenGLDevice {
public: public:
OpenGLDevice(); OpenGLDevice();
~OpenGLDevice(); ~OpenGLDevice() override;
bool Initialize(const RHIDeviceDesc& desc) override;
void Shutdown() override;
bool CreateRenderWindow(int width, int height, const char* title, bool enableDebug = false); bool CreateRenderWindow(int width, int height, const char* title, bool enableDebug = false);
bool InitializeWithExistingWindow(GLFWwindow* window); bool InitializeWithExistingWindow(GLFWwindow* window);
void Shutdown();
GLFWwindow* GetWindow() const { return m_window; } GLFWwindow* GetWindow() const { return m_window; }
const OpenGLDeviceInfo& GetDeviceInfo() const { return m_deviceInfo; } const OpenGLDeviceInfo& GetDeviceInfoImpl() const { return m_deviceInfo; }
void SwapBuffers(); void SwapBuffers() override;
bool PollEvents(); bool PollEvents() override;
void SetShouldClose(bool shouldClose); void SetShouldClose(bool shouldClose) override;
bool ShouldClose() const; bool ShouldClose() const override;
RHIBuffer* CreateBuffer(const BufferDesc& desc) override;
RHITexture* CreateTexture(const TextureDesc& desc) override;
RHISwapChain* CreateSwapChain(const SwapChainDesc& desc) override;
RHICommandList* CreateCommandList(const CommandListDesc& desc) override;
RHICommandQueue* CreateCommandQueue(const CommandQueueDesc& desc) override;
RHIShader* CompileShader(const ShaderCompileDesc& desc) override;
RHIPipelineState* CreatePipelineState(const PipelineStateDesc& desc) override;
RHIFence* CreateFence(const FenceDesc& desc) override;
RHISampler* CreateSampler(const SamplerDesc& desc) override;
const RHICapabilities& GetCapabilities() const override;
const RHIDeviceInfo& GetDeviceInfo() const override;
void* GetNativeDevice() override;
void* GetNativeHandle() const override;
private: private:
GLFWwindow* m_window; GLFWwindow* m_window;
OpenGLDeviceInfo m_deviceInfo; OpenGLDeviceInfo m_deviceInfo;
RHICapabilities m_capabilities;
RHIDeviceInfo m_deviceInfoBase;
bool m_initialized; bool m_initialized;
bool m_ownsWindow; bool m_ownsWindow;
}; };

View File

@@ -36,24 +36,24 @@ D3D12Device::~D3D12Device() {
Shutdown(); Shutdown();
} }
bool D3D12Device::Initialize(bool enableDebugLayer) { bool D3D12Device::Initialize(const RHIDeviceDesc& desc) {
if (m_initialized) { if (m_initialized) {
return true; return true;
} }
if (!CreateDXGIFactory(enableDebugLayer)) { if (!CreateDXGIFactory(desc.enableDebugLayer)) {
return false; return false;
} }
ComPtr<IDXGIAdapter1> adapter; ComPtr<IDXGIAdapter1> adapter;
int adapterIndex = 0; int adapterIndex = desc.adapterIndex;
bool adapterFound = false; bool adapterFound = false;
while (m_factory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND) { while (m_factory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND) {
DXGI_ADAPTER_DESC1 desc; DXGI_ADAPTER_DESC1 descAdapter;
adapter->GetDesc1(&desc); adapter->GetDesc1(&descAdapter);
if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { if (descAdapter.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) {
adapterIndex++; adapterIndex++;
continue; continue;
} }
@@ -185,5 +185,100 @@ void* D3D12Device::GetNativeHandle() const {
return m_device.Get(); return m_device.Get();
} }
void* D3D12Device::GetNativeDevice() {
return m_device.Get();
}
const RHICapabilities& D3D12Device::GetCapabilities() const {
return m_capabilities;
}
const RHIDeviceInfo& D3D12Device::GetDeviceInfo() const {
return m_deviceInfo;
}
RHIBuffer* D3D12Device::CreateBuffer(const BufferDesc& desc) {
auto* buffer = new D3D12Buffer();
if (buffer->Initialize(m_device.Get(), desc.size, desc.stride, desc.bufferType)) {
return buffer;
}
delete buffer;
return nullptr;
}
RHITexture* D3D12Device::CreateTexture(const TextureDesc& desc) {
auto* texture = new D3D12Texture();
if (texture->Initialize(m_device.Get(), desc)) {
return texture;
}
delete texture;
return nullptr;
}
RHIShader* D3D12Device::CompileShader(const ShaderCompileDesc& desc) {
auto* shader = new D3D12Shader();
if (shader->CompileFromFile(desc.fileName.c_str(), desc.entryPoint.c_str(), desc.profile.c_str())) {
return shader;
}
delete shader;
return nullptr;
}
RHISampler* D3D12Device::CreateSampler(const SamplerDesc& desc) {
auto* sampler = new D3D12Sampler();
if (sampler->Initialize(m_device.Get(), desc)) {
return sampler;
}
delete sampler;
return nullptr;
}
RHIFence* D3D12Device::CreateFence(const FenceDesc& desc) {
auto* fence = new D3D12Fence();
if (fence->Initialize(m_device.Get(), desc.initialValue)) {
return fence;
}
delete fence;
return nullptr;
}
RHISwapChain* D3D12Device::CreateSwapChain(const SwapChainDesc& desc) {
return nullptr;
}
RHICommandList* D3D12Device::CreateCommandList(const CommandListDesc& desc) {
return nullptr;
}
RHICommandQueue* D3D12Device::CreateCommandQueue(const CommandQueueDesc& desc) {
return nullptr;
}
RHIPipelineState* D3D12Device::CreatePipelineState(const PipelineStateDesc& desc) {
return nullptr;
}
bool D3D12Device::PollEvents() {
return false;
}
void D3D12Device::SwapBuffers() {
}
bool D3D12Device::ShouldClose() const {
return false;
}
void D3D12Device::SetShouldClose(bool shouldClose) {
}
D3D12CommandQueue* D3D12Device::CreateCommandQueueImpl(const CommandQueueDesc& desc) {
return nullptr;
}
D3D12CommandList* D3D12Device::CreateCommandListImpl(const CommandListDesc& desc) {
return nullptr;
}
} // namespace RHI } // namespace RHI
} // namespace XCEngine } // namespace XCEngine

View File

@@ -16,6 +16,23 @@ OpenGLDevice::~OpenGLDevice() {
Shutdown(); Shutdown();
} }
bool OpenGLDevice::Initialize(const RHIDeviceDesc& desc) {
if (m_initialized) {
return true;
}
if (desc.windowHandle) {
return InitializeWithExistingWindow(static_cast<GLFWwindow*>(desc.windowHandle));
}
std::string titleStr = "XCEngine";
if (!desc.appName.empty()) {
titleStr = std::string(desc.appName.begin(), desc.appName.end());
}
return CreateRenderWindow(desc.width, desc.height, titleStr.c_str(), desc.enableDebugLayer);
}
bool OpenGLDevice::CreateRenderWindow(int width, int height, const char* title, bool enableDebug) { bool OpenGLDevice::CreateRenderWindow(int width, int height, const char* title, bool enableDebug) {
if (m_initialized) { if (m_initialized) {
return true; return true;
@@ -99,5 +116,61 @@ bool OpenGLDevice::ShouldClose() const {
return m_window && glfwWindowShouldClose(m_window) == GLFW_TRUE; return m_window && glfwWindowShouldClose(m_window) == GLFW_TRUE;
} }
RHIBuffer* OpenGLDevice::CreateBuffer(const BufferDesc& desc) {
return nullptr;
}
RHITexture* OpenGLDevice::CreateTexture(const TextureDesc& desc) {
return nullptr;
}
RHISwapChain* OpenGLDevice::CreateSwapChain(const SwapChainDesc& desc) {
return nullptr;
}
RHICommandList* OpenGLDevice::CreateCommandList(const CommandListDesc& desc) {
return nullptr;
}
RHICommandQueue* OpenGLDevice::CreateCommandQueue(const CommandQueueDesc& desc) {
return nullptr;
}
RHIShader* OpenGLDevice::CompileShader(const ShaderCompileDesc& desc) {
return nullptr;
}
RHIPipelineState* OpenGLDevice::CreatePipelineState(const PipelineStateDesc& desc) {
return nullptr;
}
RHIFence* OpenGLDevice::CreateFence(const FenceDesc& desc) {
return nullptr;
}
RHISampler* OpenGLDevice::CreateSampler(const SamplerDesc& desc) {
return nullptr;
}
const RHICapabilities& OpenGLDevice::GetCapabilities() const {
return m_capabilities;
}
const RHIDeviceInfo& OpenGLDevice::GetDeviceInfo() const {
m_deviceInfoBase.description = L"OpenGL Device";
m_deviceInfoBase.vendor = std::wstring(m_deviceInfo.vendor.begin(), m_deviceInfo.vendor.end());
m_deviceInfoBase.renderer = std::wstring(m_deviceInfo.renderer.begin(), m_deviceInfo.renderer.end());
m_deviceInfoBase.version = std::wstring(m_deviceInfo.version.begin(), m_deviceInfo.version.end());
return m_deviceInfoBase;
}
void* OpenGLDevice::GetNativeDevice() {
return nullptr;
}
void* OpenGLDevice::GetNativeHandle() const {
return nullptr;
}
} // namespace RHI } // namespace RHI
} // namespace XCEngine } // namespace XCEngine