docs(api): clarify OpenGL descriptor binding semantics
This commit is contained in:
@@ -27,6 +27,7 @@ void BindWithPipelineLayout(
|
|||||||
- `SRV` 通过 `glActiveTexture(GL_TEXTURE0 + bindingPoint)` 绑定为采样纹理。
|
- `SRV` 通过 `glActiveTexture(GL_TEXTURE0 + bindingPoint)` 绑定为采样纹理。
|
||||||
- `UAV` 通过 `glBindImageTexture(bindingPoint, textureId, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8)` 绑定。
|
- `UAV` 通过 `glBindImageTexture(bindingPoint, textureId, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8)` 绑定。
|
||||||
- `Sampler` 通过 `glBindSampler(bindingPoint, samplerId)` 绑定。
|
- `Sampler` 通过 `glBindSampler(bindingPoint, samplerId)` 绑定。
|
||||||
|
- 这一条路径不会使用初始化阶段申请到的 `textureUnits`,而是完全依赖 `pipelineLayout` 解析出的 binding point。
|
||||||
- 如果 `pipelineLayout == nullptr` 或 layout 不使用 set layout,则回退为使用原始 `binding` 编号。
|
- 如果 `pipelineLayout == nullptr` 或 layout 不使用 set layout,则回退为使用原始 `binding` 编号。
|
||||||
|
|
||||||
## 当前限制
|
## 当前限制
|
||||||
@@ -34,6 +35,7 @@ void BindWithPipelineLayout(
|
|||||||
- `SRV` 仍然固定按 `GL_TEXTURE_2D` 绑定。
|
- `SRV` 仍然固定按 `GL_TEXTURE_2D` 绑定。
|
||||||
- `UAV` 固定使用 `GL_RGBA8`,并且固定使用 mip `0`、layer `0`。
|
- `UAV` 固定使用 `GL_RGBA8`,并且固定使用 mip `0`、layer `0`。
|
||||||
- 该函数不会检查 shader 反射结果与 layout 是否一致。
|
- 该函数不会检查 shader 反射结果与 layout 是否一致。
|
||||||
|
- [`Unbind`](Unbind.md) 不会按这里的重映射结果逆向解绑。
|
||||||
|
|
||||||
## 相关文档
|
## 相关文档
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,10 @@ uint32_t GetBindingPoint(uint32_t binding) const;
|
|||||||
- 它不是 [`BindWithPipelineLayout`](BindWithPipelineLayout.md) 使用的最终 pipeline layout 重映射结果。
|
- 它不是 [`BindWithPipelineLayout`](BindWithPipelineLayout.md) 使用的最终 pipeline layout 重映射结果。
|
||||||
- 该接口目前主要被测试代码用于验证不同 binding 是否分配到了不同 unit。
|
- 该接口目前主要被测试代码用于验证不同 binding 是否分配到了不同 unit。
|
||||||
|
|
||||||
|
## 需要特别注意
|
||||||
|
|
||||||
|
返回 `0` 既可能表示“没有可返回的 unit”,也可能表示“实际分配到的正好就是纹理单元 0”。调用方如果要做严格区分,不能只靠这个返回值本身。
|
||||||
|
|
||||||
## 相关文档
|
## 相关文档
|
||||||
|
|
||||||
- [Initialize](Initialize.md)
|
- [Initialize](Initialize.md)
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ OpenGL 没有 Vulkan / D3D12 那样原生的 `descriptor set` 对象,只有全
|
|||||||
- 只有 `SRV`、`UAV`、`Sampler` 会向 `OpenGLTextureUnitAllocator` 申请 unit。
|
- 只有 `SRV`、`UAV`、`Sampler` 会向 `OpenGLTextureUnitAllocator` 申请 unit。
|
||||||
- `CBV` 不占用 texture unit,而是共用一个懒上传的 UBO。
|
- `CBV` 不占用 texture unit,而是共用一个懒上传的 UBO。
|
||||||
- `Initialize()` 的 `count` 参数当前没有被使用,实际以 `layout.bindingCount` 为准。
|
- `Initialize()` 的 `count` 参数当前没有被使用,实际以 `layout.bindingCount` 为准。
|
||||||
|
- 这些 texture unit 主要服务于 [`Bind`](Bind.md) 和 [`GetBindingPoint`](GetBindingPoint.md);[`BindWithPipelineLayout`](BindWithPipelineLayout.md) 走的是另一套按 layout 重映射后的 binding point。
|
||||||
|
|
||||||
### 常量缓冲策略
|
### 常量缓冲策略
|
||||||
|
|
||||||
@@ -46,12 +47,14 @@ OpenGL 没有 Vulkan / D3D12 那样原生的 `descriptor set` 对象,只有全
|
|||||||
- [`Bind`](Bind.md) 走“直接使用声明 binding 编号”的旧路径,更接近裸 OpenGL 资源绑定。
|
- [`Bind`](Bind.md) 走“直接使用声明 binding 编号”的旧路径,更接近裸 OpenGL 资源绑定。
|
||||||
- [`BindWithPipelineLayout`](BindWithPipelineLayout.md) 才是 `OpenGLCommandList::SetGraphicsDescriptorSets()` / `SetComputeDescriptorSets()` 使用的主路径。
|
- [`BindWithPipelineLayout`](BindWithPipelineLayout.md) 才是 `OpenGLCommandList::SetGraphicsDescriptorSets()` / `SetComputeDescriptorSets()` 使用的主路径。
|
||||||
- 该主路径会借助 [`OpenGLPipelineLayout`](../OpenGLPipelineLayout/OpenGLPipelineLayout.md) 把 `set + binding` 映射到连续的 OpenGL binding point。
|
- 该主路径会借助 [`OpenGLPipelineLayout`](../OpenGLPipelineLayout/OpenGLPipelineLayout.md) 把 `set + binding` 映射到连续的 OpenGL binding point。
|
||||||
|
- [`Unbind`](Unbind.md) 只会按原始 `binding` 和初始化时申请到的 texture unit 做回滚,因此它不是 `BindWithPipelineLayout()` 的严格对称操作。
|
||||||
|
|
||||||
### 当前限制
|
### 当前限制
|
||||||
|
|
||||||
- `Update()` / `UpdateSampler()` 只更新每个 binding 的第 `0` 个元素,未提供数组元素级写入接口。
|
- `Update()` / `UpdateSampler()` 只更新每个 binding 的第 `0` 个元素,未提供数组元素级写入接口。
|
||||||
- 纹理绑定路径默认按 `GL_TEXTURE_2D` 处理普通采样纹理,没有根据真实 texture target 细分。
|
- 纹理绑定路径默认按 `GL_TEXTURE_2D` 处理普通采样纹理,没有根据真实 texture target 细分。
|
||||||
- `UAV` 绑定固定使用 `glBindImageTexture(..., GL_RGBA8)`,当前没有从 view format 推导 image format。
|
- `UAV` 绑定固定使用 `glBindImageTexture(..., GL_RGBA8)`,当前没有从 view format 推导 image format。
|
||||||
|
- [`Shutdown`](Shutdown.md) 不会清空 `m_constantBufferData`,也不会显式重置 `m_constantBufferDirty`。
|
||||||
- [`Unbind`](Unbind.md) 主要是 [`Bind`](Bind.md) 的对称清理函数,并不完整回滚 `BindWithPipelineLayout()` 的重映射结果。
|
- [`Unbind`](Unbind.md) 主要是 [`Bind`](Bind.md) 的对称清理函数,并不完整回滚 `BindWithPipelineLayout()` 的重映射结果。
|
||||||
|
|
||||||
## 线程语义
|
## 线程语义
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ void Shutdown() override;
|
|||||||
|
|
||||||
- 如果内部创建过 UBO,则调用 `glDeleteBuffers()` 删除。
|
- 如果内部创建过 UBO,则调用 `glDeleteBuffers()` 删除。
|
||||||
- 遍历所有 binding,把已经申请的 texture unit 归还给 allocator。
|
- 遍历所有 binding,把已经申请的 texture unit 归还给 allocator。
|
||||||
- 清空 binding 缓存、layout 拷贝和 dirty / bound 状态。
|
- 清空 binding 缓存和 layout 拷贝,并把 `m_bound` 设为 `false`。
|
||||||
|
- 不会清空 `m_constantBufferData`。
|
||||||
|
- 也不会显式把 `m_constantBufferDirty` 置回 `false`。
|
||||||
- 不会销毁外部资源视图或采样器对象。
|
- 不会销毁外部资源视图或采样器对象。
|
||||||
|
|
||||||
## 失败与限制
|
## 失败与限制
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ void WriteConstant(
|
|||||||
- 直接 `memcpy` 到共享字节数组。
|
- 直接 `memcpy` 到共享字节数组。
|
||||||
- 将 `m_constantBufferDirty` 标记为 `true`。
|
- 将 `m_constantBufferDirty` 标记为 `true`。
|
||||||
- 真正上传到 GPU 的时机是下一次 [`Bind`](Bind.md) 或 [`BindWithPipelineLayout`](BindWithPipelineLayout.md)。
|
- 真正上传到 GPU 的时机是下一次 [`Bind`](Bind.md) 或 [`BindWithPipelineLayout`](BindWithPipelineLayout.md)。
|
||||||
|
- 上传时会使用整块 `glBufferData(GL_UNIFORM_BUFFER, ...)`,而不是按局部范围增量更新。
|
||||||
|
|
||||||
## 当前限制
|
## 当前限制
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ OpenGL 没有现代图形 API 那样统一的 descriptor heap / descriptor set
|
|||||||
- 绑定和解绑都会调用 `glActiveTexture()`,但不会恢复之前的活动纹理单元。
|
- 绑定和解绑都会调用 `glActiveTexture()`,但不会恢复之前的活动纹理单元。
|
||||||
- `GetBoundTexture()` 只是分配器内部缓存,不是实际 GL 状态查询。
|
- `GetBoundTexture()` 只是分配器内部缓存,不是实际 GL 状态查询。
|
||||||
- 解绑逻辑固定使用 `GL_TEXTURE_2D` 清空当前 unit,这对非 2D 目标来说是简化实现。
|
- 解绑逻辑固定使用 `GL_TEXTURE_2D` 清空当前 unit,这对非 2D 目标来说是简化实现。
|
||||||
|
- `OpenGLDevice::Initialize(...)` 会先查询 `GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS`,再用该值初始化它。
|
||||||
|
|
||||||
## 当前限制
|
## 当前限制
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
- [BindBuffer](BindBuffer.md) 固定使用 `glBindBufferBase()`,不会做范围绑定。
|
- [BindBuffer](BindBuffer.md) 固定使用 `glBindBufferBase()`,不会做范围绑定。
|
||||||
- `GetBoundBuffer()` 只是本地缓存查询。
|
- `GetBoundBuffer()` 只是本地缓存查询。
|
||||||
- `OpenGLResourceView::InitializeAsConstantBuffer()` 会通过它分配绑定点。
|
- `OpenGLResourceView::InitializeAsConstantBuffer()` 会通过它分配绑定点。
|
||||||
|
- `OpenGLDevice::Initialize(...)` 会查询 `GL_MAX_UNIFORM_BUFFER_BINDINGS`,并把结果传给 [Initialize](Initialize.md)。
|
||||||
|
|
||||||
## 当前限制
|
## 当前限制
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user