diff --git a/docs/RHI抽象层设计与实现.md b/docs/RHI抽象层设计与实现.md index d8571bd5..1e7dbab0 100644 --- a/docs/RHI抽象层设计与实现.md +++ b/docs/RHI抽象层设计与实现.md @@ -896,6 +896,60 @@ public: - 解决:统一 Present(syncInterval, flags) +### 5.14 管线状态(RHIPipelineState)抽象设计 + +#### 5.14.1 设计理念对应 + +| 差异点 | 设计理念 | 处理方案 | +|--------|---------|---------| +| 初始化差异 | 求同存异 | 后端各自处理 | +| 状态管理差异 | 特性降级 | D3D12 实现状态块,OpenGL 分离状态 | +| 绑定方式差异 | 求同存异 | 统一 Bind 接口 | + +#### 5.14.2 现有实现对比 + +| 功能 | D3D12PipelineState | OpenGLPipelineState | 处理方案 | +|------|-------------------|-------------------|----------| +| 初始化 | device + desc | 构造函数 | 后端各自处理 | +| 状态设置 | 单一 PSO 对象 | 分离状态对象 | 后端各自处理 | +| 绑定 | CommandList->SetPipelineState | AttachShader/Apply | 统一 Bind | +| 句柄 | ID3D12PipelineState* | GLuint (program) | 统一 void* | + +#### 5.14.3 抽象接口定义 + +```cpp +class RHIPipelineState { +public: + virtual ~RHIPipelineState() = default; + + virtual void Shutdown() = 0; + + virtual void Bind() = 0; + virtual void Unbind() = 0; + + virtual void* GetNativeHandle() = 0; + virtual PipelineType GetType() const = 0; +}; +``` + +#### 5.14.4 差异处理策略 + +1. **初始化差异(求同存异)** + - D3D12:device + D3D12_GRAPHICS_PIPELINE_STATE_DESC + - OpenGL:通过 SetDepthStencilState/BlendState/RasterizerState + - 解决:Device 的 CreatePipelineState() 统一接收 PipelineStateDesc + +2. **状态管理差异(特性降级)** + - D3D12:单一 PSO 对象包含所有状态 + - OpenGL:分离的状态对象 + - 解决:后端各自实现,基类提供统一 Bind/Unbind + +3. **绑定方式差异(求同存异)** + - D3D12:通过 CommandList->SetPipelineState + - OpenGL:AttachShader + Apply + - 解决:统一 Bind/Unbind 接口 + + ## 6. 后端实现示例 ### 6.1 D3D12 设备实现(D3D12Device.h) ```cpp diff --git a/engine/include/XCEngine/RHI/D3D12/D3D12PipelineState.h b/engine/include/XCEngine/RHI/D3D12/D3D12PipelineState.h index 882a0718..eb8730b3 100644 --- a/engine/include/XCEngine/RHI/D3D12/D3D12PipelineState.h +++ b/engine/include/XCEngine/RHI/D3D12/D3D12PipelineState.h @@ -4,6 +4,7 @@ #include #include +#include "../RHIPipelineState.h" #include "../RHIEnums.h" #include "D3D12Enum.h" @@ -12,18 +13,21 @@ using Microsoft::WRL::ComPtr; namespace XCEngine { namespace RHI { -class D3D12PipelineState { +class D3D12PipelineState : public RHIPipelineState { public: D3D12PipelineState(); - ~D3D12PipelineState(); + ~D3D12PipelineState() override; bool Initialize(ID3D12Device* device, const D3D12_GRAPHICS_PIPELINE_STATE_DESC& desc); - void Shutdown(); + void Shutdown() override; ID3D12PipelineState* GetPipelineState() const { return m_pipelineState.Get(); } - void* GetNativeHandle() const { return m_pipelineState.Get(); } - PipelineType GetType() const { return PipelineType::Graphics; } + void* GetNativeHandle() override { return m_pipelineState.Get(); } + PipelineType GetType() const override { return PipelineType::Graphics; } + + void Bind() override; + void Unbind() override; static D3D12_GRAPHICS_PIPELINE_STATE_DESC CreateDesc( ID3D12RootSignature* rootSignature, diff --git a/engine/include/XCEngine/RHI/OpenGL/OpenGLPipelineState.h b/engine/include/XCEngine/RHI/OpenGL/OpenGLPipelineState.h index 56bdbe2e..876c659f 100644 --- a/engine/include/XCEngine/RHI/OpenGL/OpenGLPipelineState.h +++ b/engine/include/XCEngine/RHI/OpenGL/OpenGLPipelineState.h @@ -4,6 +4,8 @@ #include #include +#include "../RHIPipelineState.h" + namespace XCEngine { namespace RHI { @@ -136,10 +138,18 @@ struct LogicalOperation { uint32_t operation = 0; }; -class OpenGLPipelineState { +class OpenGLPipelineState : public RHIPipelineState { public: OpenGLPipelineState(); - ~OpenGLPipelineState(); + ~OpenGLPipelineState() override; + + void Shutdown() override; + + void Bind() override; + void Unbind() override; + + void* GetNativeHandle() override; + PipelineType GetType() const override { return PipelineType::Graphics; } void SetDepthStencilState(const DepthStencilState& state); void SetBlendState(const BlendState& state); diff --git a/engine/include/XCEngine/RHI/RHIPipelineState.h b/engine/include/XCEngine/RHI/RHIPipelineState.h new file mode 100644 index 00000000..3915fddf --- /dev/null +++ b/engine/include/XCEngine/RHI/RHIPipelineState.h @@ -0,0 +1,23 @@ +#pragma once + +#include "RHITypes.h" +#include "RHIEnums.h" + +namespace XCEngine { +namespace RHI { + +class RHIPipelineState { +public: + virtual ~RHIPipelineState() = default; + + virtual void Shutdown() = 0; + + virtual void Bind() = 0; + virtual void Unbind() = 0; + + virtual void* GetNativeHandle() = 0; + virtual PipelineType GetType() const = 0; +}; + +} // namespace RHI +} // namespace XCEngine diff --git a/engine/src/RHI/D3D12/D3D12PipelineState.cpp b/engine/src/RHI/D3D12/D3D12PipelineState.cpp index 9869c47f..70525c50 100644 --- a/engine/src/RHI/D3D12/D3D12PipelineState.cpp +++ b/engine/src/RHI/D3D12/D3D12PipelineState.cpp @@ -85,5 +85,11 @@ D3D12_INPUT_ELEMENT_DESC D3D12PipelineState::CreateInputElement( return CreateInputElement(semanticName, semanticIndex, format, inputSlot, D3D12_APPEND_ALIGNED_ELEMENT); } +void D3D12PipelineState::Bind() { +} + +void D3D12PipelineState::Unbind() { +} + } // namespace RHI } // namespace XCEngine diff --git a/engine/src/RHI/OpenGL/OpenGLPipelineState.cpp b/engine/src/RHI/OpenGL/OpenGLPipelineState.cpp index 2d3d5431..7c8d69cb 100644 --- a/engine/src/RHI/OpenGL/OpenGLPipelineState.cpp +++ b/engine/src/RHI/OpenGL/OpenGLPipelineState.cpp @@ -268,5 +268,25 @@ void OpenGLPipelineState::DetachShader() { glUseProgram(0); } +void OpenGLPipelineState::Shutdown() { + m_program = 0; + m_programAttached = false; +} + +void OpenGLPipelineState::Bind() { + if (m_programAttached) { + glUseProgram(m_program); + } + Apply(); +} + +void OpenGLPipelineState::Unbind() { + glUseProgram(0); +} + +void* OpenGLPipelineState::GetNativeHandle() { + return reinterpret_cast(static_cast(m_program)); +} + } // namespace RHI } // namespace XCEngine