docs(api): deepen OpenGL screenshot pool and queue docs

This commit is contained in:
2026-03-28 00:50:49 +08:00
parent e522bad582
commit c01944871d
29 changed files with 469 additions and 454 deletions

View File

@@ -1,28 +1,19 @@
# OpenGLCommandQueue::OpenGLCommandQueue()
构造对象。
# OpenGLCommandQueue::OpenGLCommandQueue
```cpp
OpenGLCommandQueue();
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLCommandQueue.h`,当前页面用于固定 `OpenGLCommandQueue` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
构造一个空的 OpenGL 命令队列门面对象
**返回:** `void` - 无返回值。
## 当前实现行为
**示例:**
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLCommandQueue.h>
void Example() {
XCEngine::RHI::OpenGLCommandQueue object;
}
```
- 构造函数体为空
- 不创建任何 OpenGL 原生对象
## 相关文档
- [返回类总览](OpenGLCommandQueue.md)
- [返回模块目录](../OpenGL.md)
- [OpenGLCommandQueue](OpenGLCommandQueue.md)
- [Shutdown](Shutdown.md)

View File

@@ -1,29 +1,19 @@
# OpenGLCommandQueue::~OpenGLCommandQueue()
销毁对象并释放相关资源。
# OpenGLCommandQueue::~OpenGLCommandQueue
```cpp
~OpenGLCommandQueue() override;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLCommandQueue.h`,当前页面用于固定 `OpenGLCommandQueue` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
销毁命令队列对象
**返回:** `void` - 无返回值。
## 当前实现行为
**示例:**
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLCommandQueue.h>
void Example() {
XCEngine::RHI::OpenGLCommandQueue object;
// 对象离开作用域时会自动触发析构。
}
```
- 析构函数内部调用 [Shutdown](Shutdown.md)
- 因为当前类没有持久资源,所以没有额外释放逻辑
## 相关文档
- [返回类总览](OpenGLCommandQueue.md)
- [返回模块目录](../OpenGL.md)
- [Shutdown](Shutdown.md)
- [OpenGLCommandQueue](OpenGLCommandQueue.md)

View File

@@ -6,17 +6,20 @@ void ExecuteCommandLists(uint32_t count, void** lists) override;
## 作用
抽象层保留的“提交命令列表”入口。
保留统一 RHI 接口中的“提交命令列表”入口。
## 当前实现行为
当前实现为空。
- 空实现
- 不读取 `count`
- 不读取 `lists`
- 不触发任何 OpenGL 提交动作
## 正确理解
## 正确认识
这并不是疏漏,而是当前 OpenGL 后端架构决定的结果:`OpenGLCommandList` 上的大部分操作会立刻作用到当前上下文,因此这里不存在 D3D12/Vulkan 意义上的“统一提交时刻”
OpenGL 当前后端的命令大多在调用命令列表接口时就直接落到 GL 上下文,因此这里并没有 D3D12/Vulkan 那种集中提交点
## 相关文档
- [OpenGLCommandQueue](OpenGLCommandQueue.md)
- [OpenGLCommandList](../OpenGLCommandList/OpenGLCommandList.md)
- [Signal](Signal.md)
- [WaitForIdle](WaitForIdle.md)

View File

@@ -1,30 +1,22 @@
# OpenGLCommandQueue::GetCompletedValue
获取相关状态或对象。
```cpp
uint64_t GetCompletedValue() override;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLCommandQueue.h`,当前页面用于固定 `OpenGLCommandQueue` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
返回当前队列的完成值
**返回:** `uint64_t` - 返回值语义详见头文件声明。
## 当前实现行为
**示例:**
- 固定返回 `0`
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLCommandQueue.h>
## 正确认识
void Example() {
XCEngine::RHI::OpenGLCommandQueue object;
// 根据上下文补齐参数后调用 OpenGLCommandQueue::GetCompletedValue(...)。
(void)object;
}
```
这个值在当前 OpenGL 后端里不具备真实的 GPU 时间线意义,更适合作为接口占位返回值。
## 相关文档
- [返回类总览](OpenGLCommandQueue.md)
- [返回模块目录](../OpenGL.md)
- [GetCurrentFrame](GetCurrentFrame.md)
- [OpenGLCommandQueue](OpenGLCommandQueue.md)

View File

@@ -1,30 +1,22 @@
# OpenGLCommandQueue::GetCurrentFrame
获取相关状态或对象。
```cpp
uint64_t GetCurrentFrame() const override;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLCommandQueue.h`,当前页面用于固定 `OpenGLCommandQueue` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
返回当前帧序号
**返回:** `uint64_t` - 返回值语义详见头文件声明。
## 当前实现行为
**示例:**
- 固定返回 `0`
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLCommandQueue.h>
## 正确认识
void Example() {
XCEngine::RHI::OpenGLCommandQueue object;
// 根据上下文补齐参数后调用 OpenGLCommandQueue::GetCurrentFrame(...)。
(void)object;
}
```
这说明当前类没有内部帧编号系统。它只是为了满足统一接口而提供的占位返回值。
## 相关文档
- [返回类总览](OpenGLCommandQueue.md)
- [返回模块目录](../OpenGL.md)
- [WaitForPreviousFrame](WaitForPreviousFrame.md)
- [GetCompletedValue](GetCompletedValue.md)

View File

@@ -1,30 +1,22 @@
# OpenGLCommandQueue::GetNativeHandle
获取相关状态或对象。
```cpp
void* GetNativeHandle() override;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLCommandQueue.h`,当前页面用于固定 `OpenGLCommandQueue` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
返回命令队列的原生句柄表示
**返回:** `void*` - 返回值语义详见头文件声明。
## 当前实现行为
**示例:**
- 返回 `this`
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLCommandQueue.h>
## 设计说明
void Example() {
XCEngine::RHI::OpenGLCommandQueue object;
// 根据上下文补齐参数后调用 OpenGLCommandQueue::GetNativeHandle(...)。
(void)object;
}
```
这再次说明当前类没有对应的 OpenGL 原生命令队列对象,它只是引擎接口适配层。
## 相关文档
- [返回类总览](OpenGLCommandQueue.md)
- [返回模块目录](../OpenGL.md)
- [GetType](GetType.md)
- [OpenGLCommandQueue](OpenGLCommandQueue.md)

View File

@@ -1,30 +1,24 @@
# OpenGLCommandQueue::GetTimestampFrequency
获取相关状态或对象。
```cpp
uint64_t GetTimestampFrequency() const override;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLCommandQueue.h`,当前页面用于固定 `OpenGLCommandQueue` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
返回时间戳频率
**返回:** `uint64_t` - 返回值语义详见头文件声明。
## 当前实现行为
**示例:**
- 调用 `glGetInteger64v(GL_TIMESTAMP, &frequency)`
- 如果读取结果大于 `0`,直接返回该值
- 否则返回 `1000000000`
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLCommandQueue.h>
## 需要特别注意
void Example() {
XCEngine::RHI::OpenGLCommandQueue object;
// 根据上下文补齐参数后调用 OpenGLCommandQueue::GetTimestampFrequency(...)。
(void)object;
}
```
`GL_TIMESTAMP` 更像当前 GPU 时间戳值,而不是硬件频率寄存器。因此当前实现只是给统一接口提供一个“可用的正数返回值”,语义上并不严格等价于 D3D12 的 `GetTimestampFrequency()`
## 相关文档
- [返回类总览](OpenGLCommandQueue.md)
- [返回模块目录](../OpenGL.md)
- [OpenGLCommandQueue](OpenGLCommandQueue.md)
- [GetCompletedValue](GetCompletedValue.md)

View File

@@ -1,30 +1,22 @@
# OpenGLCommandQueue::GetType
获取相关状态或对象。
```cpp
CommandQueueType GetType() const override;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLCommandQueue.h`,当前页面用于固定 `OpenGLCommandQueue` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
返回命令队列类型
**返回:** `CommandQueueType` - 返回值语义详见头文件声明。
## 当前实现行为
**示例:**
- 始终返回 `CommandQueueType::Direct`
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLCommandQueue.h>
## 设计说明
void Example() {
XCEngine::RHI::OpenGLCommandQueue object;
// 根据上下文补齐参数后调用 OpenGLCommandQueue::GetType(...)。
(void)object;
}
```
这是为了和其他后端保持统一接口,而不是在 OpenGL 底层真的存在多种原生命令队列。
## 相关文档
- [返回类总览](OpenGLCommandQueue.md)
- [返回模块目录](../OpenGL.md)
- [OpenGLCommandQueue](OpenGLCommandQueue.md)
- [GetNativeHandle](GetNativeHandle.md)

View File

@@ -6,42 +6,72 @@
**头文件**: `XCEngine/RHI/OpenGL/OpenGLCommandQueue.h`
**描述**: 为统一 RHI 抽象保留的 OpenGL 队列门面;它不是一条真实的 GPU 提交队列。
**描述**: 为统一 RHI 抽象保留的 OpenGL 命令队列门面;它不是一条真实的 GPU 提交队列,而是一个接口适配层
## 概览
OpenGL 没有 D3D12/Vulkan 那种显式命令队列模型,所以 `OpenGLCommandQueue`主要价值是
OpenGL 没有 D3D12/Vulkan 那种显式 command queue 模型,因此 `OpenGLCommandQueue`存在主要是为了
- 让统一抽象层还能继续通过 `RHICommandQueue` 组织代码
- 提供少量和 flush / finish / fence 相关的后端适配
- 保持跨后端接口一致
- 给测试和上层 RHI 代码一个统一的 `RHICommandQueue` 入口
- 封装少量 `glFlush()` / `glFinish()` / fence 相关行为
## 设计定位
这个类应被理解为 shim而不是调度核心。
它能做的事情很有限:
- 把信号语义桥接到 [OpenGLFence](../OpenGLFence/OpenGLFence.md)
- 提供“等待 GPU 空闲”的同步入口
- 给测试返回一个统一的 queue 类型和 native handle
它当前做不了这些事:
- 真正的命令列表提交
- 真正的跨线程 GPU timeline 管理
- 帧序号推进
## 当前实现的真实行为
- `GetType()` 永远返回 `CommandQueueType::Direct`
- `ExecuteCommandLists()` 当前为空实现
- `Signal()` 会先调用抽象 fence 的 `Signal(value)`,再 `glFlush()`
- `Wait()` 当前为空实现
- `GetCompletedValue()` 当前固定返回 `0`
- `WaitForIdle()` 调用 `glFinish()`
- `GetTimestampFrequency()` 读取 `GL_TIMESTAMP`;这更像“当前时间戳查询”,不是严格意义上的硬件频率接口
- [GetType](GetType.md) 永远返回 `CommandQueueType::Direct`
- [GetNativeHandle](GetNativeHandle.md) 返回 `this`
- [ExecuteCommandLists](ExecuteCommandLists.md) 是空实现
- [Signal](Signal.md) 先调用 fence 的 `Signal(value)`,再执行 `glFlush()`
- [Wait](Wait.md) 是空实现
- [GetCompletedValue](GetCompletedValue.md) 固定返回 `0`
- [WaitForIdle](WaitForIdle.md) 调用 `glFinish()`
- [WaitForPreviousFrame](WaitForPreviousFrame.md) 是空实现
- [GetCurrentFrame](GetCurrentFrame.md) 固定返回 `0`
- [GetTimestampFrequency](GetTimestampFrequency.md) 读取 `GL_TIMESTAMP`,更像当前时间戳快照,而不是严格意义上的频率
## 正确理解
## 为什么这样设计
如果从商业引擎角度看,它更像“为了保持跨后端接口整齐而保留的一层 shim”而不是调度核心
这是一种很典型的“为了统一抽象而保留的后端占位层”
在商业级引擎里,只要继续支持 OpenGL类似的 shim 往往也不可避免,因为:
- 上层代码想按队列模型组织逻辑
- 但 OpenGL 底层并没有对应对象
当前实现选择了最保守的一条路:保留接口,让测试和基础流程先跑通,再逐步补更多语义。
## 当前限制
- 不支持真正的命令列表提交
- 不提供成熟的 GPU timeline 语
- `Wait()` / `ExecuteCommandLists()` 仍是占位实现
- `ExecuteCommandLists()``Wait()``WaitForPreviousFrame()` 都还是占位实现
- `GetCompletedValue()` 没有真实 GPU 进度含
- `GetTimestampFrequency()` 的语义并不精确
- 没有自己的资源或生命周期状态
## 重点公共方法
## 关键方法
- [ExecuteCommandLists](ExecuteCommandLists.md)
- [Signal](Signal.md)
- [WaitForIdle](WaitForIdle.md)
- [GetTimestampFrequency](GetTimestampFrequency.md)
## 相关文档
- [OpenGL](../OpenGL.md)
- [OpenGLFence](../OpenGLFence/OpenGLFence.md)
- [OpenGLCommandList](../OpenGLCommandList/OpenGLCommandList.md)

View File

@@ -1,30 +1,22 @@
# OpenGLCommandQueue::Shutdown
关闭并清理内部状态。
```cpp
void Shutdown() override;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLCommandQueue.h`,当前页面用于固定 `OpenGLCommandQueue` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
清理命令队列对象
**返回:** `void` - 无返回值。
## 当前实现行为
**示例:**
- 空实现
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLCommandQueue.h>
## 设计说明
void Example() {
XCEngine::RHI::OpenGLCommandQueue object;
// 根据上下文补齐参数后调用 OpenGLCommandQueue::Shutdown(...)。
(void)object;
}
```
当前类没有自己的 OpenGL 队列对象、同步对象或帧跟踪状态,因此对象级清理为空是符合当前实现定位的。
## 相关文档
- [返回类总览](OpenGLCommandQueue.md)
- [返回模块目录](../OpenGL.md)
- [Destructor](Destructor.md)
- [OpenGLCommandQueue](OpenGLCommandQueue.md)

View File

@@ -6,14 +6,19 @@ void Signal(RHIFence* fence, uint64_t value) override;
## 作用
给抽象 fence 写入一个值,并通过 `glFlush()` 触发驱动尽快开始处理已发出的 OpenGL 命令。
把“队列信号”语义桥接到 fence并刷新当前 GL 命令
## 当前实现行为
- `fence` 非空,调用 `fence->Signal(value)`
- 随后调用 `glFlush()`
- 如果 `fence` 非空,调用 `fence->Signal(value)`
- 随后执行 `glFlush()`
## 设计说明
真正的同步语义主要由 [OpenGLFence](../OpenGLFence/OpenGLFence.md) 实现。这里更像一个薄包装,负责保持 `RHICommandQueue` 侧的调用风格一致。
## 相关文档
- [Wait](Wait.md)
- [WaitForIdle](WaitForIdle.md)
- [OpenGLCommandQueue](OpenGLCommandQueue.md)
- [OpenGLFence](../OpenGLFence/OpenGLFence.md)

View File

@@ -1,32 +1,24 @@
# OpenGLCommandQueue::Wait
公开方法,详见头文件声明。
```cpp
void Wait(RHIFence* fence, uint64_t value) override;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLCommandQueue.h`,当前页面用于固定 `OpenGLCommandQueue` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
- `fence` - 参数语义详见头文件声明。
- `value` - 参数语义详见头文件声明。
保留统一接口中的“队列等待 fence”入口。
**返回:** `void` - 无返回值。
## 当前实现行为
**示例:**
- 空实现
- 不读取 `fence`
- 不读取 `value`
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLCommandQueue.h>
## 当前限制
void Example() {
XCEngine::RHI::OpenGLCommandQueue object;
// 根据上下文补齐参数后调用 OpenGLCommandQueue::Wait(...)。
(void)object;
}
```
这意味着调用它不会真正让 OpenGL 队列语义上等待某个 fence 值。若需要等待,当前更可靠的路径仍然是直接操作 fence 或调用 [WaitForIdle](WaitForIdle.md)。
## 相关文档
- [返回类总览](OpenGLCommandQueue.md)
- [返回模块目录](../OpenGL.md)
- [Signal](Signal.md)
- [WaitForIdle](WaitForIdle.md)

View File

@@ -6,17 +6,17 @@ void WaitForIdle() override;
## 作用
阻塞 CPU直到当前上下文之前发出的 OpenGL 命令全部完成。
等待当前 OpenGL 命令流执行完成。
## 当前实现行为
直接调用 `glFinish()`
- 直接调用 `glFinish()`
## 设计说明
这是一条非常强的同步原语,适合初始化、截图、调试和测试,不适合高频帧循环
这是一条非常强的同步边界,适合测试、资源销毁前同步和调试验证,不适合高频运行路径
## 相关文档
- [Signal](Signal.md)
- [OpenGLCommandQueue](OpenGLCommandQueue.md)
- [Wait](Wait.md)

View File

@@ -1,30 +1,22 @@
# OpenGLCommandQueue::WaitForPreviousFrame
公开方法,详见头文件声明。
```cpp
void WaitForPreviousFrame() override;
void WaitForPreviousFrame() override {}
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLCommandQueue.h`,当前页面用于固定 `OpenGLCommandQueue` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
保留统一接口中的“等待上一帧”入口
**返回:** `void` - 无返回值。
## 当前实现行为
**示例:**
- 空实现
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLCommandQueue.h>
## 设计说明
void Example() {
XCEngine::RHI::OpenGLCommandQueue object;
// 根据上下文补齐参数后调用 OpenGLCommandQueue::WaitForPreviousFrame(...)。
(void)object;
}
```
当前 OpenGL 后端没有自己的帧序列推进逻辑,因此这里没有和 D3D12 `frame fence` 对应的行为。
## 相关文档
- [返回类总览](OpenGLCommandQueue.md)
- [返回模块目录](../OpenGL.md)
- [GetCurrentFrame](GetCurrentFrame.md)
- [OpenGLCommandQueue](OpenGLCommandQueue.md)

View File

@@ -1,31 +1,32 @@
# OpenGLDescriptorPool::AllocateSet
公开方法,详见头文件声明。
```cpp
RHIDescriptorSet* AllocateSet(const DescriptorSetLayoutDesc& layout) override;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h`,当前页面用于固定 `OpenGLDescriptorPool` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
- `layout` - 参数语义详见头文件声明。
创建一个新的 [OpenGLDescriptorSet](../OpenGLDescriptorSet/OpenGLDescriptorSet.md)。
**返回:** `RHIDescriptorSet*` - 返回值语义详见头文件声明。
## 当前实现行为
**示例:**
- 如果 `m_allocatedSets.size() >= m_maxSets`,返回 `nullptr`
- 创建新的 `OpenGLDescriptorSet`
- 调用 `newSet->Initialize(m_textureUnitAllocator, layout.bindingCount, layout)`
- 失败时删除新对象并返回 `nullptr`
- 成功时把它加入 `m_allocatedSets`
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h>
## 与 allocator 的关系
void Example() {
XCEngine::RHI::OpenGLDescriptorPool object;
// 根据上下文补齐参数后调用 OpenGLDescriptorPool::AllocateSet(...)。
(void)object;
}
```
如果 layout 中包含 `SRV``Sampler``UAV``OpenGLDescriptorSet::Initialize(...)` 会尝试从 `OpenGLTextureUnitAllocator` 申请 texture unit。也就是说pool 只是创建入口,真正的 unit 分配发生在 set 初始化内部。
## 当前限制
- 没有更细粒度容量控制
- layout 合法性基本依赖 `OpenGLDescriptorSet`
- 如果外部绕过 [FreeSet](FreeSet.md) 直接 delete setpool 内部跟踪会失真
## 相关文档
- [返回类总览](OpenGLDescriptorPool.md)
- [返回模块目录](../OpenGL.md)
- [FreeSet](FreeSet.md)
- [SetTextureUnitAllocator](SetTextureUnitAllocator.md)

View File

@@ -1,28 +1,20 @@
# OpenGLDescriptorPool::OpenGLDescriptorPool()
构造对象。
# OpenGLDescriptorPool::OpenGLDescriptorPool
```cpp
OpenGLDescriptorPool();
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h`,当前页面用于固定 `OpenGLDescriptorPool` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
构造一个空的 OpenGL descriptor pool 对象
**返回:** `void` - 无返回值。
## 当前实现行为
**示例:**
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h>
void Example() {
XCEngine::RHI::OpenGLDescriptorPool object;
}
```
- `m_type` 初始化为 `DescriptorHeapType::CBV_SRV_UAV`
- `m_maxSets` 初始化为 `0`
- `m_textureUnitAllocator` 初始化为 `nullptr`
## 相关文档
- [返回类总览](OpenGLDescriptorPool.md)
- [返回模块目录](../OpenGL.md)
- [Initialize](Initialize.md)
- [OpenGLDescriptorPool](OpenGLDescriptorPool.md)

View File

@@ -1,29 +1,19 @@
# OpenGLDescriptorPool::~OpenGLDescriptorPool()
销毁对象并释放相关资源。
# OpenGLDescriptorPool::~OpenGLDescriptorPool
```cpp
~OpenGLDescriptorPool() override;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h`,当前页面用于固定 `OpenGLDescriptorPool` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
销毁 descriptor pool 对象
**返回:** `void` - 无返回值。
## 当前实现行为
**示例:**
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h>
void Example() {
XCEngine::RHI::OpenGLDescriptorPool object;
// 对象离开作用域时会自动触发析构。
}
```
- 析构函数内部调用 [Shutdown](Shutdown.md)
- 不会自动 delete `m_allocatedSets` 里仍然存在的 set 对象
## 相关文档
- [返回类总览](OpenGLDescriptorPool.md)
- [返回模块目录](../OpenGL.md)
- [Shutdown](Shutdown.md)
- [FreeSet](FreeSet.md)

View File

@@ -1,31 +1,25 @@
# OpenGLDescriptorPool::FreeSet
公开方法,详见头文件声明。
```cpp
void FreeSet(RHIDescriptorSet* set) override;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h`,当前页面用于固定 `OpenGLDescriptorPool` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
- `set` - 参数语义详见头文件声明。
释放由当前 pool 跟踪的 descriptor set。
**返回:** `void` - 无返回值。
## 当前实现行为
**示例:**
- 如果 `set == nullptr`,直接返回
- 在线性遍历 `m_allocatedSets` 中查找匹配指针
- 找到后从数组移除,并执行 `delete set`
- 如果没找到,则不做任何事
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h>
## 注意事项
void Example() {
XCEngine::RHI::OpenGLDescriptorPool object;
// 根据上下文补齐参数后调用 OpenGLDescriptorPool::FreeSet(...)。
(void)object;
}
```
这里不会先调用 `set->Shutdown()`;它依赖 set 自己的析构逻辑完成清理。
## 相关文档
- [返回类总览](OpenGLDescriptorPool.md)
- [返回模块目录](../OpenGL.md)
- [AllocateSet](AllocateSet.md)
- [Shutdown](Shutdown.md)

View File

@@ -1,30 +1,22 @@
# OpenGLDescriptorPool::GetDescriptorCount
获取相关状态或对象。
```cpp
uint32_t GetDescriptorCount() const override;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h`,当前页面用于固定 `OpenGLDescriptorPool` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
返回 pool 记录的容量值
**返回:** `uint32_t` - 返回值语义详见头文件声明。
## 当前实现行为
**示例:**
- 返回 `m_maxSets`
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h>
## 注意事项
void Example() {
XCEngine::RHI::OpenGLDescriptorPool object;
// 根据上下文补齐参数后调用 OpenGLDescriptorPool::GetDescriptorCount(...)。
(void)object;
}
```
在当前 OpenGL 实现里,这个值应理解为“最多能分配多少个 set”不是“总 descriptor 数”。
## 相关文档
- [返回类总览](OpenGLDescriptorPool.md)
- [返回模块目录](../OpenGL.md)
- [Initialize](Initialize.md)
- [AllocateSet](AllocateSet.md)

View File

@@ -1,30 +1,22 @@
# OpenGLDescriptorPool::GetNativeHandle
获取相关状态或对象。
```cpp
void* GetNativeHandle() override;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h`,当前页面用于固定 `OpenGLDescriptorPool` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
返回 pool 的原生句柄表示
**返回:** `void*` - 返回值语义详见头文件声明。
## 当前实现行为
**示例:**
- 返回 `this`
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h>
## 设计说明
void Example() {
XCEngine::RHI::OpenGLDescriptorPool object;
// 根据上下文补齐参数后调用 OpenGLDescriptorPool::GetNativeHandle(...)。
(void)object;
}
```
这再次说明当前类没有与之对应的 OpenGL 原生对象,它只是引擎侧抽象。
## 相关文档
- [返回类总览](OpenGLDescriptorPool.md)
- [返回模块目录](../OpenGL.md)
- [OpenGLDescriptorPool](OpenGLDescriptorPool.md)
- [GetType](GetType.md)

View File

@@ -1,30 +1,22 @@
# OpenGLDescriptorPool::GetType
获取相关状态或对象。
```cpp
DescriptorHeapType GetType() const override;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h`,当前页面用于固定 `OpenGLDescriptorPool` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
返回 pool 记录的 descriptor heap 类型
**返回:** `DescriptorHeapType` - 返回值语义详见头文件声明。
## 当前实现行为
**示例:**
- 直接返回 `m_type`
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h>
## 设计说明
void Example() {
XCEngine::RHI::OpenGLDescriptorPool object;
// 根据上下文补齐参数后调用 OpenGLDescriptorPool::GetType(...)。
(void)object;
}
```
即使 OpenGL 没有原生 descriptor heap 分类,这个字段仍然有价值,因为它帮助 RHI 上层保留统一心智模型,也影响 descriptor set 的使用约定。
## 相关文档
- [返回类总览](OpenGLDescriptorPool.md)
- [返回模块目录](../OpenGL.md)
- [Initialize](Initialize.md)
- [OpenGLDescriptorPool](OpenGLDescriptorPool.md)

View File

@@ -1,31 +1,30 @@
# OpenGLDescriptorPool::Initialize
初始化内部状态。
```cpp
bool Initialize(const DescriptorPoolDesc& desc) override;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h`,当前页面用于固定 `OpenGLDescriptorPool` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
- `desc` - 参数语义详见头文件声明。
初始化 pool 的基础配置。
**返回:** `bool` - 返回值语义详见头文件声明。
## 当前实现行为
**示例:**
- `m_type = desc.type`
- `m_maxSets = desc.descriptorCount`
- 始终返回 `true`
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h>
## 重要说明
void Example() {
XCEngine::RHI::OpenGLDescriptorPool object;
// 根据上下文补齐参数后调用 OpenGLDescriptorPool::Initialize(...)。
(void)object;
}
```
当前 `desc.descriptorCount` 并不是“总 descriptor 数量”,而是“允许分配的 set 上限”。
## 当前限制
- 不校验 `desc.descriptorCount`
- 忽略 `desc.shaderVisible`
- 不涉及任何 OpenGL 原生对象创建
## 相关文档
- [返回类总览](OpenGLDescriptorPool.md)
- [返回模块目录](../OpenGL.md)
- [GetDescriptorCount](GetDescriptorCount.md)
- [AllocateSet](AllocateSet.md)

View File

@@ -6,34 +6,75 @@
**头文件**: `XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h`
**描述**: 定义 `XCEngine/RHI/OpenGL` 子目录中的 `OpenGLDescriptorPool` public API
**描述**: OpenGL 后端的 descriptor pool 抽象,但当前实现本质上是 `OpenGLDescriptorSet` 的拥有容器和 texture unit 分配入口
## 概
## 概
`OpenGLDescriptorPool.h``XCEngine/RHI/OpenGL` 子目录 下的 public header当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明
OpenGL 没有 D3D12/Vulkan 那种原生 descriptor pool / descriptor set 体系,所以 `OpenGLDescriptorPool` 是一个纯引擎侧抽象
## 声明概览
它当前主要承担这些职责:
| 声明 | 类型 | 说明 |
|------|------|------|
| `OpenGLDescriptorPool` | `class` | 继承自 `RHIDescriptorPool` 的公开声明。 |
- 记录 pool 类型
- 限制最多可分配多少个 descriptor set
- 为新建的 [OpenGLDescriptorSet](../OpenGLDescriptorSet/OpenGLDescriptorSet.md) 注入 `OpenGLTextureUnitAllocator`
- 跟踪当前由自己分配出去的 set 指针
## 公共方法
## 设计定位
| 方法 | 描述 |
|------|------|
| [OpenGLDescriptorPool()](Constructor.md) | 构造对象。 |
| [~OpenGLDescriptorPool()](Destructor.md) | 销毁对象并释放相关资源。 |
| [Initialize](Initialize.md) | 初始化内部状态。 |
| [Shutdown](Shutdown.md) | 关闭并清理内部状态。 |
| [GetNativeHandle](GetNativeHandle.md) | 获取相关状态或对象。 |
| [GetDescriptorCount](GetDescriptorCount.md) | 获取相关状态或对象。 |
| [GetType](GetType.md) | 获取相关状态或对象。 |
| [AllocateSet](AllocateSet.md) | 公开方法,详见头文件声明。 |
| [FreeSet](FreeSet.md) | 公开方法,详见头文件声明。 |
| [SetTextureUnitAllocator](SetTextureUnitAllocator.md) | 设置相关状态或配置。 |
这里最容易误解的一点是 `DescriptorPoolDesc.descriptorCount`
在 D3D12 里,它更像 heap 容量;在当前 OpenGL 实现里,它被当成:
- `m_maxSets`
- 也就是“最多允许创建多少个 set”
而不是“总 descriptor 数量”。
## 生命周期
- 构造后默认类型为 `CBV_SRV_UAV``m_maxSets = 0`
- [Initialize](Initialize.md) 记录类型和 set 上限
- [AllocateSet](AllocateSet.md) 创建并跟踪新的 `OpenGLDescriptorSet`
- [FreeSet](FreeSet.md) 删除被跟踪的 set
- [Shutdown](Shutdown.md) 只清空跟踪信息,不负责 delete 仍在表中的 set
## 当前实现的真实行为
- [GetNativeHandle](GetNativeHandle.md) 返回 `this`
- [GetDescriptorCount](GetDescriptorCount.md) 返回 `m_maxSets`
- [Initialize](Initialize.md) 忽略 `shaderVisible`
- [AllocateSet](AllocateSet.md) 只有在 `m_allocatedSets.size() < m_maxSets` 时才允许分配
- 如果 layout 包含 `SRV` / `Sampler` / `UAV`,创建 set 时依赖 `OpenGLTextureUnitAllocator`
- [Shutdown](Shutdown.md) 不 delete 仍然存活的 set只是 `clear()` 指针列表并置空 allocator
## 为什么这样设计
OpenGL 后端没有必要模拟一份沉重的 descriptor heap 系统。当前实现选的是更实用的一条路线:
- 把 descriptor set 继续保留为跨后端统一抽象
- 用 pool 负责 set 的创建和数量管理
- 用 texture unit allocator 负责真正的纹理单元资源
这种设计简单、够用,而且和当前 `OpenGLDescriptorSet` 的绑定实现配合自然。
## 当前限制
- `descriptorCount` 语义和其他后端不同
- 不是 descriptor 级资源池,而是 set 数量上限
- `Shutdown()` 不会 delete 已分配 set
- 没有线程安全
- 没有碎片、复用策略或更细粒度配额
## 关键方法
- [Initialize](Initialize.md)
- [AllocateSet](AllocateSet.md)
- [FreeSet](FreeSet.md)
- [SetTextureUnitAllocator](SetTextureUnitAllocator.md)
- [Shutdown](Shutdown.md)
## 相关文档
- [当前目录](../OpenGL.md) - 返回 `OpenGL` 平行目录
- [API 总索引](../../../../main.md) - 返回顶层索引
- [OpenGL](../OpenGL.md)
- [OpenGLDescriptorSet](../OpenGLDescriptorSet/OpenGLDescriptorSet.md)
- [OpenGLTextureUnitAllocator](../OpenGLTextureUnitAllocator/OpenGLTextureUnitAllocator.md)

View File

@@ -1,31 +1,24 @@
# OpenGLDescriptorPool::SetTextureUnitAllocator
设置相关状态或配置。
```cpp
void SetTextureUnitAllocator(OpenGLTextureUnitAllocator* allocator);
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h`,当前页面用于固定 `OpenGLDescriptorPool` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
- `allocator` - 参数语义详见头文件声明。
为后续创建的 descriptor set 指定 texture unit allocator。
**返回:** `void` - 无返回值。
## 当前实现行为
**示例:**
- 直接保存 `allocator` 指针
- 不做所有权接管
- 不会反向更新已创建的 set
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h>
## 使用场景
void Example() {
XCEngine::RHI::OpenGLDescriptorPool object;
// 根据上下文补齐参数后调用 OpenGLDescriptorPool::SetTextureUnitAllocator(...)。
(void)object;
}
```
通常由 [OpenGLDevice](../OpenGLDevice/OpenGLDevice.md) 在创建 pool 后立即调用,用来把设备级的 texture unit allocator 注入到 pool。
## 相关文档
- [返回类总览](OpenGLDescriptorPool.md)
- [返回模块目录](../OpenGL.md)
- [AllocateSet](AllocateSet.md)
- [OpenGLTextureUnitAllocator](../OpenGLTextureUnitAllocator/OpenGLTextureUnitAllocator.md)

View File

@@ -1,30 +1,29 @@
# OpenGLDescriptorPool::Shutdown
关闭并清理内部状态。
```cpp
void Shutdown() override;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h`,当前页面用于固定 `OpenGLDescriptorPool` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
清空 pool 的内部跟踪状态
**返回:** `void` - 无返回值。
## 当前实现行为
**示例:**
- `m_allocatedSets.clear()`
- `m_textureUnitAllocator = nullptr`
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDescriptorPool.h>
## 注意事项
void Example() {
XCEngine::RHI::OpenGLDescriptorPool object;
// 根据上下文补齐参数后调用 OpenGLDescriptorPool::Shutdown(...)。
(void)object;
}
```
当前实现不会:
- delete `m_allocatedSets` 中仍然存在的 set
- 重置 `m_type`
- 重置 `m_maxSets`
因此正确的使用方式仍然是先显式释放各个 set再销毁 pool。
## 相关文档
- [返回类总览](OpenGLDescriptorPool.md)
- [返回模块目录](../OpenGL.md)
- [FreeSet](FreeSet.md)
- [Destructor](Destructor.md)

View File

@@ -1,63 +1,94 @@
# OpenGLScreenshot::Capture
公开方法,详见头文件声明。
```cpp
bool Capture(RHIDevice* device, RHISwapChain* swapChain, const char* filename) override;
static bool Capture(OpenGLDevice& device,
OpenGLSwapChain& swapChain,
const char* filename);
static bool Capture(OpenGLDevice& device,
OpenGLSwapChain& swapChain,
const char* filename,
int width,
int height);
```
该方法在 `XCEngine/RHI/OpenGL/OpenGLScreenshot.h` 中提供了 3 个重载,当前页面统一汇总这些公开声明。
## 作用
## 重载 1: 声明
从 OpenGL 当前呈现目标读取像素并写成 PPM 文件。
## 核心流程
三个公开重载最终都汇合到同一套同步读回流程:
1. 切换当前上下文 `device.MakeContextCurrent()`
2. 分配 RGB 像素缓冲
3. 调用 `glFinish()`
4. 配置 `GL_PACK_*` 像素打包状态
5. 根据当前 back buffer 情况选择读取路径
6. 调用 `glReadPixels(...)`
7.`P6` PPM 格式写盘,并在写盘时做上下翻转
## 重载 1: RHI 入口
```cpp
bool Capture(RHIDevice* device, RHISwapChain* swapChain, const char* filename) override;
```
**参数:**
- `device` - 参数语义详见头文件声明。
- `swapChain` - 参数语义详见头文件声明。
- `filename` - 参数语义详见头文件声明。
### 当前实现行为
**返回:** `bool` - 返回值语义详见头文件声明。
- 直接把 `device` 转成 `OpenGLDevice*`
- 直接把 `swapChain` 转成 `OpenGLSwapChain*`
- 然后转发到 OpenGL 包装对象重载
## 重载 2: 声明
### 注意事项
- 没有运行时类型检查
- 没有空指针保护
## 重载 2: 使用 swap chain 尺寸
```cpp
static bool Capture(OpenGLDevice& device, OpenGLSwapChain& swapChain, const char* filename);
static bool Capture(OpenGLDevice& device,
OpenGLSwapChain& swapChain,
const char* filename);
```
**参数:**
- `device` - 参数语义详见头文件声明。
- `swapChain` - 参数语义详见头文件声明。
- `filename` - 参数语义详见头文件声明。
### 当前实现行为
**返回:** `bool` - 返回值语义详见头文件声明。
- 直接使用 `swapChain.GetWidth()``swapChain.GetHeight()`
- 然后调用完整尺寸重载
## 重载 3: 声明
## 重载 3: 显式尺寸
```cpp
static bool Capture(OpenGLDevice& device, OpenGLSwapChain& swapChain, const char* filename, int width, int height);
static bool Capture(OpenGLDevice& device,
OpenGLSwapChain& swapChain,
const char* filename,
int width,
int height);
```
**参数:**
- `device` - 参数语义详见头文件声明。
- `swapChain` - 参数语义详见头文件声明。
- `filename` - 参数语义详见头文件声明。
- `width` - 参数语义详见头文件声明。
- `height` - 参数语义详见头文件声明。
### 当前实现行为
**返回:** `bool` - 返回值语义详见头文件声明。
- 分配 `width * height * 3` 字节的 RGB 缓冲
- 如果内存分配失败,记录错误日志并返回 `false`
- 判断当前 back buffer 是否可以走纹理读取路径:
- `backBufferTexture != nullptr`
- `backBufferTexture->GetID() != 0`
- `backBufferTexture->GetState() != ResourceStates::Common`
- 纹理路径下会创建临时 `GL_READ_FRAMEBUFFER`,把纹理挂到 `GL_COLOR_ATTACHMENT0` 后读取
- 否则直接 `glReadBuffer(GL_BACK)` 读取默认后备缓冲
- 打开输出文件失败时返回 `false`
- 写文件时从最后一行开始写,实现图像垂直翻转
**示例:**
## 输出格式
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLScreenshot.h>
void Example() {
XCEngine::RHI::OpenGLScreenshot object;
// 根据上下文补齐参数后调用 OpenGLScreenshot::Capture(...)。
(void)object;
}
```
- 固定输出 `P6` PPM
- 只写 RGB
- 不写 alpha
- 不压缩
## 相关文档
- [返回类总览](OpenGLScreenshot.md)
- [返回模块目录](../OpenGL.md)
- [OpenGLScreenshot](OpenGLScreenshot.md)
- [Shutdown](Shutdown.md)

View File

@@ -6,26 +6,75 @@
**头文件**: `XCEngine/RHI/OpenGL/OpenGLScreenshot.h`
**描述**: 定义 `XCEngine/RHI/OpenGL` 子目录中的 `OpenGLScreenshot` public API
**描述**: OpenGL 后端的截图工具类,负责从默认帧缓冲或当前 back buffer 纹理读取像素,并保存为 PPM 文件
## 概
## 概
`OpenGLScreenshot.h` `XCEngine/RHI/OpenGL` 子目录 下的 public header当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明
`OpenGLScreenshot` 和 [D3D12Screenshot](../../D3D12/D3D12Screenshot/D3D12Screenshot.md) 一样,属于“调试和测试优先”的同步截图工具,而不是完整的产品级截图系统
## 声明概览
它当前支持两条读图路径:
| 声明 | 类型 | 说明 |
|------|------|------|
| `OpenGLScreenshot` | `class` | 继承自 `RHIScreenshot` 的公开声明。 |
- 如果 swap chain 当前 back buffer 能被当作纹理读取,就临时创建一个 `GL_READ_FRAMEBUFFER` 并从颜色附件读取
- 否则直接从 `GL_BACK` 读默认后备缓冲
## 公共方法
随后它会把像素翻转后按 `P6` PPM 格式写到磁盘。
| 方法 | 描述 |
|------|------|
| [Capture](Capture.md) | 公开方法,详见头文件声明。 |
| [Shutdown](Shutdown.md) | 关闭并清理内部状态。 |
## 设计定位
这个类的目标非常明确:
- 给 RHI 集成测试提供统一截图出口
- 给 OpenGL 示例和调试流程提供最小依赖的抓图工具
- 尽量不引入额外图像编码依赖
因此它的实现风格也很直接:
- 同步 `glFinish()`
- 直接 `glReadPixels(...)`
- 直接 `fopen` / `fwrite`
## 当前实现的真实行为
- [Capture](Capture.md) 会先 `device.MakeContextCurrent()`
- 像素缓冲按 `width * height * 3` 分配,只读取 RGB
- 截图前会调用 `glFinish()`
- 如果 back buffer 纹理存在且 `GetState() != ResourceStates::Common`,会走临时 FBO 读取路径
- 否则从 `GL_BACK` 读取
- 写文件时会按 OpenGL 常见坐标系差异,把图像做上下翻转
- [Shutdown](Shutdown.md) 是空实现,因为对象本身没有持久资源
## 需要注意的实现细节
- 头文件里声明了私有 `SavePPM(...)`,但当前源码没有实现也没有使用它
- 截图逻辑假定输出是 8-bit RGB不处理 HDR、浮点格式或压缩格式
- RHI 接口重载内部直接 `static_cast``OpenGLDevice*` / `OpenGLSwapChain*`
## 为什么这样设计
在商业级引擎里,截图系统通常会进一步拆成:
- 异步像素传输
- 编码线程
- PNG/JPG/EXR 等多格式输出
- 调试工具链集成
但在底层 RHI 验证阶段,先保证“结果可抓、问题可定位、依赖够少”更重要。`OpenGLScreenshot` 正是这类早期实现。
## 当前限制
- 全程同步,`glFinish()` 开销明显
- 只输出 PPM
- 没有颜色空间、HDR 或 alpha 处理
- 类型转换依赖调用方保证处在 OpenGL 后端上下文
## 关键方法
- [Capture](Capture.md)
- [Shutdown](Shutdown.md)
## 相关文档
- [当前目录](../OpenGL.md) - 返回 `OpenGL` 平行目录
- [API 总索引](../../../../main.md) - 返回顶层索引
- [OpenGL](../OpenGL.md)
- [OpenGLSwapChain](../OpenGLSwapChain/OpenGLSwapChain.md)
- [OpenGLDevice](../OpenGLDevice/OpenGLDevice.md)
- [RHIScreenshot](../../RHIScreenshot/RHIScreenshot.md)

View File

@@ -1,30 +1,23 @@
# OpenGLScreenshot::Shutdown
关闭并清理内部状态。
```cpp
void Shutdown() override;
void Shutdown() override {}
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLScreenshot.h`,当前页面用于固定 `OpenGLScreenshot` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
满足 [RHIScreenshot](../../RHIScreenshot/RHIScreenshot.md) 接口要求的清理入口
**返回:** `void` - 无返回值。
## 当前实现行为
**示例:**
- 空实现
- 不释放任何资源
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLScreenshot.h>
## 设计说明
void Example() {
XCEngine::RHI::OpenGLScreenshot object;
// 根据上下文补齐参数后调用 OpenGLScreenshot::Shutdown(...)。
(void)object;
}
```
当前截图流程所需的内存、临时 FBO 和文件句柄都在 [Capture](Capture.md) 调用内部即时创建并释放,因此对象级别没有需要持久清理的状态。
## 相关文档
- [返回类总览](OpenGLScreenshot.md)
- [返回模块目录](../OpenGL.md)
- [Capture](Capture.md)
- [OpenGLScreenshot](OpenGLScreenshot.md)

View File

@@ -1,6 +1,6 @@
# API 文档重构状态
**生成时间**: `2026-03-28 00:40:20`
**生成时间**: `2026-03-28 00:49:41`
**来源**: `docs/api/_tools/audit_api_docs.py`