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

- 新增 RHIFence 抽象基类
- D3D12Fence 继承 RHIFence
- OpenGLFence 继承 RHIFence
- 文档更新 RHIFence 差异处理策略
This commit is contained in:
2026-03-17 17:36:17 +08:00
parent f046e17ad6
commit af718279ff
6 changed files with 1305 additions and 17 deletions

View File

@@ -539,7 +539,57 @@ public:
- OpenGLGLuint
- 解决GetNativeHandle() 返回 void*
### 5.9 根签名 vs OpenGL 资源绑定
### 5.9 同步栅栏RHIFence抽象设计
#### 5.9.1 设计理念对应
| 差异点 | 设计理念 | 处理方案 |
|--------|---------|---------|
| 初始化参数差异 | 求同存异 | 后端各自实现初始化 |
| 句柄类型差异 | 底层逃逸 | 统一返回 void* |
| 状态查询 | 求同存异 | 统一 IsSignaled/GetCompletedValue 接口 |
#### 5.9.2 现有实现对比
| 功能 | D3D12Fence | OpenGLFence |
|------|-------------|-------------|
| 初始化 | Initialize(device, value) | Initialize(signaled) |
| Signal | Signal(value) | Signal()/Signal(value) |
| Wait | Wait(value) | Wait(timeoutNs) |
| 状态 | GetCompletedValue() | IsSignaled()/GetStatus() |
| 句柄 | ID3D12Fence* | GLsync |
#### 5.9.3 抽象接口定义
```cpp
class RHIFence {
public:
virtual ~RHIFence() = default;
virtual void Shutdown() = 0;
virtual void Signal(uint64_t value) = 0;
virtual void Wait(uint64_t value) = 0;
virtual uint64_t GetCompletedValue() = 0;
virtual bool IsSignaled() const = 0;
virtual void* GetNativeHandle() = 0;
};
```
#### 5.9.4 差异处理策略
1. **初始化参数差异(求同存异)**
- D3D12需要 device 参数
- OpenGL不需要 device
- 解决:后端各自实现 Initialize()
2. **句柄类型差异(底层逃逸)**
- D3D12ID3D12Fence*
- OpenGLGLsync
- 解决GetNativeHandle() 返回 void*
### 5.10 根签名 vs OpenGL 资源绑定
- **D3D12**:显式 `RootSignature` 定义资源绑定规则
- **OpenGL**:隐式通过 `glUniformLocation`、`glBindTextureUnit` 绑定
- **解决方案**

File diff suppressed because it is too large Load Diff

View File

@@ -3,26 +3,28 @@
#include <d3d12.h>
#include <wrl/client.h>
#include <cstdint>
#include "../RHIFence.h"
using Microsoft::WRL::ComPtr;
namespace XCEngine {
namespace RHI {
class D3D12Fence {
class D3D12Fence : public RHIFence {
public:
D3D12Fence();
~D3D12Fence();
~D3D12Fence() override;
bool Initialize(ID3D12Device* device, uint64_t initialValue = 0);
void Shutdown();
void Shutdown() override;
void Signal(uint64_t value);
void Wait(uint64_t value);
uint64_t GetCompletedValue();
void Signal(uint64_t value) override;
void Wait(uint64_t value) override;
uint64_t GetCompletedValue() const override;
bool IsSignaled() const override { return GetCompletedValue() > 0; }
void* GetEventHandle() { return m_eventHandle; }
void* GetNativeHandle() override { return m_fence.Get(); }
ID3D12Fence* GetFence() const { return m_fence.Get(); }
private:

View File

@@ -3,6 +3,8 @@
#include <GLFW/glfw3.h>
#include <cstdint>
#include "../RHIFence.h"
namespace XCEngine {
namespace RHI {
@@ -12,24 +14,26 @@ enum class FenceStatus {
Error
};
class OpenGLFence {
class OpenGLFence : public RHIFence {
public:
OpenGLFence();
~OpenGLFence();
~OpenGLFence() override;
bool Initialize(bool signaled = false);
void Shutdown();
void Shutdown() override;
void Signal();
void Signal(uint64_t value);
void Wait(uint64_t timeoutNs = UINT64_MAX);
void Signal() override;
void Signal(uint64_t value) override;
void Wait(uint64_t value) override;
void Reset();
bool IsSignaled() const;
bool IsSignaled() const override;
FenceStatus GetStatus() const;
uint64_t GetCompletedValue() const;
uint64_t GetCompletedValue() const override;
uint64_t GetCurrentValue() const { return m_fenceValue; }
void* GetNativeHandle() override { return m_sync; }
private:
void* m_sync;
uint64_t m_fenceValue;

View File

@@ -0,0 +1,24 @@
#pragma once
#include "RHITypes.h"
namespace XCEngine {
namespace RHI {
class RHIFence {
public:
virtual ~RHIFence() = default;
virtual void Shutdown() = 0;
virtual void Signal() = 0;
virtual void Signal(uint64_t value) = 0;
virtual void Wait(uint64_t value) = 0;
virtual uint64_t GetCompletedValue() const = 0;
virtual bool IsSignaled() const = 0;
virtual void* GetNativeHandle() = 0;
};
} // namespace RHI
} // namespace XCEngine

View File

@@ -44,7 +44,7 @@ void D3D12Fence::Wait(uint64_t value) {
}
}
uint64_t D3D12Fence::GetCompletedValue() {
uint64_t D3D12Fence::GetCompletedValue() const {
return m_fence->GetCompletedValue();
}