docs(api): clarify OpenGL descriptor binding semantics

This commit is contained in:
2026-03-28 01:45:53 +08:00
parent 36097869c0
commit ae93952ce0
7 changed files with 15 additions and 1 deletions

View File

@@ -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) 不会按这里的重映射结果逆向解绑。
## 相关文档 ## 相关文档

View File

@@ -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)

View File

@@ -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()` 的重映射结果。
## 线程语义 ## 线程语义

View File

@@ -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`
- 不会销毁外部资源视图或采样器对象。 - 不会销毁外部资源视图或采样器对象。
## 失败与限制 ## 失败与限制

View File

@@ -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, ...)`,而不是按局部范围增量更新。
## 当前限制 ## 当前限制

View File

@@ -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`,再用该值初始化它。
## 当前限制 ## 当前限制

View File

@@ -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)。
## 当前限制 ## 当前限制