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

- 新增 RHISampler 抽象基类
- D3D12Sampler 继承 RHISampler
- OpenGLSampler 继承 RHISampler,使用 OpenGLSamplerDesc
- 文档更新 RHISampler 差异处理策略
This commit is contained in:
2026-03-17 17:31:32 +08:00
parent e38d5ccede
commit f046e17ad6
6 changed files with 1650 additions and 26 deletions

View File

@@ -491,7 +491,55 @@ public:
- OpenGLglUseProgram
- 解决:基类提供 Bind/Unbind 接口
### 5.8 根签名 vs OpenGL 资源绑定
### 5.8 采样器RHISampler抽象设计
#### 5.8.1 设计理念对应
| 差异点 | 设计理念 | 处理方案 |
|--------|---------|---------|
| 初始化参数差异 | 求同存异 | 后端各自实现初始化 |
| 句柄类型差异 | 底层逃逸 | 统一返回 void* |
| 绑定方式 | 求同存异 | 基类提供 Bind/Unbind |
#### 5.8.2 现有实现对比
| 功能 | D3D12Sampler | OpenGLSampler |
|------|--------------|---------------|
| 初始化 | Initialize(device, desc) | Initialize(desc) |
| 销毁 | Shutdown() | Shutdown() |
| 绑定 | 通过 DescriptorHeap | Bind(unit) |
| 句柄 | GetNativeHandle() | GetID() |
#### 5.8.3 抽象接口定义
```cpp
class RHISampler {
public:
virtual ~RHISampler() = default;
virtual void Shutdown() = 0;
virtual void Bind(unsigned int unit) = 0;
virtual void Unbind(unsigned int unit) = 0;
virtual void* GetNativeHandle() = 0;
virtual unsigned int GetID() = 0;
};
```
#### 5.8.4 差异处理策略
1. **初始化参数差异(求同存异)**
- D3D12需要 device 参数
- OpenGL不需要 device
- 解决Device 的 CreateSampler() 统一接收 SamplerDesc后端各自实现 Initialize()
2. **句柄类型差异(底层逃逸)**
- D3D12通过 DescriptorHeap 管理
- OpenGLGLuint
- 解决GetNativeHandle() 返回 void*
### 5.9 根签名 vs OpenGL 资源绑定
- **D3D12**:显式 `RootSignature` 定义资源绑定规则
- **OpenGL**:隐式通过 `glUniformLocation`、`glBindTextureUnit` 绑定
- **解决方案**

File diff suppressed because it is too large Load Diff

View File

@@ -3,6 +3,7 @@
#include <d3d12.h>
#include <wrl/client.h>
#include "../RHISampler.h"
#include "D3D12Enum.h"
using Microsoft::WRL::ComPtr;
@@ -10,17 +11,21 @@ using Microsoft::WRL::ComPtr;
namespace XCEngine {
namespace RHI {
class D3D12Sampler {
class D3D12Sampler : public RHISampler {
public:
D3D12Sampler();
~D3D12Sampler();
~D3D12Sampler() override;
bool Initialize(ID3D12Device* device, const D3D12_SAMPLER_DESC& desc);
void Shutdown();
void Shutdown() override;
D3D12_SAMPLER_DESC GetDesc() const { return m_desc; }
void* GetNativeHandle() const { return nullptr; }
void* GetNativeHandle() override { return nullptr; }
unsigned int GetID() override { return 0; }
void Bind(unsigned int unit) override { }
void Unbind(unsigned int unit) override { }
private:
D3D12_SAMPLER_DESC m_desc;

View File

@@ -2,6 +2,9 @@
#include <GLFW/glfw3.h>
#include "../RHISampler.h"
#include "../RHITypes.h"
namespace XCEngine {
namespace RHI {
@@ -26,7 +29,7 @@ enum class SamplerCompareMode {
CompareToRef
};
struct SamplerDesc {
struct OpenGLSamplerDesc {
SamplerFilter minFilter = SamplerFilter::LinearMipmapLinear;
SamplerFilter magFilter = SamplerFilter::Linear;
SamplerWrapMode wrapS = SamplerWrapMode::Repeat;
@@ -39,22 +42,24 @@ struct SamplerDesc {
float maxLod = 1000.0f;
};
class OpenGLSampler {
class OpenGLSampler : public RHISampler {
public:
OpenGLSampler();
~OpenGLSampler();
~OpenGLSampler() override;
bool Initialize(const SamplerDesc& desc);
void Shutdown();
bool Initialize(const OpenGLSamplerDesc& desc);
void Shutdown() override;
void Bind(unsigned int unit);
void Unbind(unsigned int unit);
void Bind(unsigned int unit) override;
void Unbind(unsigned int unit) override;
unsigned int GetID() const { return m_sampler; }
unsigned int GetID() override { return m_sampler; }
void* GetNativeHandle() override { return reinterpret_cast<void*>(static_cast<uintptr_t>(m_sampler)); }
private:
unsigned int m_sampler;
SamplerDesc m_desc;
OpenGLSamplerDesc m_desc;
};
} // namespace RHI

View File

@@ -0,0 +1,23 @@
#pragma once
#include "RHITypes.h"
#include "RHIEnums.h"
namespace XCEngine {
namespace RHI {
class RHISampler {
public:
virtual ~RHISampler() = default;
virtual void Shutdown() = 0;
virtual void Bind(unsigned int unit) = 0;
virtual void Unbind(unsigned int unit) = 0;
virtual void* GetNativeHandle() = 0;
virtual unsigned int GetID() = 0;
};
} // namespace RHI
} // namespace XCEngine

View File

@@ -34,7 +34,7 @@ OpenGLSampler::OpenGLSampler() : m_sampler(0) {
OpenGLSampler::~OpenGLSampler() {
}
bool OpenGLSampler::Initialize(const SamplerDesc& desc) {
bool OpenGLSampler::Initialize(const OpenGLSamplerDesc& desc) {
m_desc = desc;
glGenSamplers(1, &m_sampler);