diff --git a/docs/RHI抽象层设计与实现.md b/docs/RHI抽象层设计与实现.md index 22f2c66b..5bb09da1 100644 --- a/docs/RHI抽象层设计与实现.md +++ b/docs/RHI抽象层设计与实现.md @@ -589,7 +589,80 @@ public: - OpenGL:GLsync - 解决: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. **底层设备类型差异(底层逃逸)** + - D3D12:ID3D12Device* + - OpenGL:无对等概念 + - 解决:GetNativeDevice() 返回 void*,OpenGL 返回 nullptr 或窗口句柄 - **D3D12**:显式 `RootSignature` 定义资源绑定规则 - **OpenGL**:隐式通过 `glUniformLocation`、`glBindTextureUnit` 绑定 - **解决方案**: diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12Device.h b/engine/include/XCEngine/RHI/D3D12/D3D12Device.h index 6b0d5b64..bebfbc11 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12Device.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12Device.h @@ -6,6 +6,7 @@ #include #include +#include "../RHIDevice.h" #include "../RHIEnums.h" #include "../RHITypes.h" #include "D3D12Enum.h" @@ -44,13 +45,13 @@ struct AdapterInfo { bool isSoftware; }; -class D3D12Device { +class D3D12Device : public RHIDevice { public: D3D12Device(); - ~D3D12Device(); + ~D3D12Device() override; - bool Initialize(bool enableDebugLayer = false); - void Shutdown(); + bool Initialize(const RHIDeviceDesc& desc) override; + void Shutdown() override; ID3D12Device* GetDevice() const { return m_device.Get(); } IDXGIFactory4* GetFactory() const { return m_factory.Get(); } @@ -65,20 +66,33 @@ public: void SetDeviceRemoved() { m_isDeviceRemoved = true; } bool IsDeviceRemoved() const { return m_isDeviceRemoved; } - // Factory methods - D3D12CommandQueue* CreateCommandQueue(const CommandQueueDesc& desc); - D3D12CommandList* CreateCommandList(const CommandListDesc& desc); + 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; + + 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); - D3D12Fence* CreateFence(const FenceDesc& desc); D3D12DescriptorHeap* CreateDescriptorHeap(const DescriptorHeapDesc& desc); D3D12QueryHeap* CreateQueryHeap(const QueryHeapDesc& 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); D3D12DepthStencilView* CreateDepthStencilView(D3D12Buffer* resource, const DepthStencilViewDesc& desc); @@ -86,8 +100,6 @@ public: D3D12UnorderedAccessView* CreateUnorderedAccessView(D3D12Buffer* resource, const UnorderedAccessViewDesc& desc); D3D12ConstantBufferView* CreateConstantBufferView(D3D12Buffer* resource, const ConstantBufferViewDesc& desc); - void* GetNativeHandle() const; - private: bool CreateDXGIFactory(bool enableDebugLayer); bool CreateDevice(IDXGIAdapter1* adapter); @@ -98,6 +110,8 @@ private: ComPtr m_adapter; AdapterInfo m_adapterInfo; + RHICapabilities m_capabilities; + RHIDeviceInfo m_deviceInfo; bool m_isDeviceRemoved; bool m_initialized; }; diff --git a/engine/include/XCEngine/RHI/OpenGL/OpenGLDevice.h b/engine/include/XCEngine/RHI/OpenGL/OpenGLDevice.h index 7d242ae2..bffa5906 100644 --- a/engine/include/XCEngine/RHI/OpenGL/OpenGLDevice.h +++ b/engine/include/XCEngine/RHI/OpenGL/OpenGLDevice.h @@ -3,37 +3,52 @@ #include #include +#include "../RHIDevice.h" +#include "../RHICapabilities.h" + namespace XCEngine { namespace RHI { -struct OpenGLDeviceInfo { - std::string vendor; - std::string renderer; - std::string version; - int majorVersion; - int minorVersion; -}; - -class OpenGLDevice { +class OpenGLDevice : public RHIDevice { public: 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 InitializeWithExistingWindow(GLFWwindow* window); - void Shutdown(); GLFWwindow* GetWindow() const { return m_window; } - const OpenGLDeviceInfo& GetDeviceInfo() const { return m_deviceInfo; } + const OpenGLDeviceInfo& GetDeviceInfoImpl() const { return m_deviceInfo; } - void SwapBuffers(); - bool PollEvents(); - void SetShouldClose(bool shouldClose); - bool ShouldClose() const; + void SwapBuffers() override; + bool PollEvents() override; + void SetShouldClose(bool shouldClose) override; + 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: GLFWwindow* m_window; OpenGLDeviceInfo m_deviceInfo; + RHICapabilities m_capabilities; + RHIDeviceInfo m_deviceInfoBase; bool m_initialized; bool m_ownsWindow; }; diff --git a/engine/src/RHI/D3D12/D3D12Device.cpp b/engine/src/RHI/D3D12/D3D12Device.cpp index 1f470db6..183da27d 100644 --- a/engine/src/RHI/D3D12/D3D12Device.cpp +++ b/engine/src/RHI/D3D12/D3D12Device.cpp @@ -36,24 +36,24 @@ D3D12Device::~D3D12Device() { Shutdown(); } -bool D3D12Device::Initialize(bool enableDebugLayer) { +bool D3D12Device::Initialize(const RHIDeviceDesc& desc) { if (m_initialized) { return true; } - if (!CreateDXGIFactory(enableDebugLayer)) { + if (!CreateDXGIFactory(desc.enableDebugLayer)) { return false; } ComPtr adapter; - int adapterIndex = 0; + int adapterIndex = desc.adapterIndex; bool adapterFound = false; while (m_factory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND) { - DXGI_ADAPTER_DESC1 desc; - adapter->GetDesc1(&desc); + DXGI_ADAPTER_DESC1 descAdapter; + adapter->GetDesc1(&descAdapter); - if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { + if (descAdapter.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { adapterIndex++; continue; } @@ -185,5 +185,100 @@ void* D3D12Device::GetNativeHandle() const { 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 XCEngine diff --git a/engine/src/RHI/OpenGL/OpenGLDevice.cpp b/engine/src/RHI/OpenGL/OpenGLDevice.cpp index 3782c001..5cb3d39b 100644 --- a/engine/src/RHI/OpenGL/OpenGLDevice.cpp +++ b/engine/src/RHI/OpenGL/OpenGLDevice.cpp @@ -16,6 +16,23 @@ OpenGLDevice::~OpenGLDevice() { Shutdown(); } +bool OpenGLDevice::Initialize(const RHIDeviceDesc& desc) { + if (m_initialized) { + return true; + } + + if (desc.windowHandle) { + return InitializeWithExistingWindow(static_cast(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) { if (m_initialized) { return true; @@ -99,5 +116,61 @@ bool OpenGLDevice::ShouldClose() const { 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 XCEngine