这个问题是这个主题的延续: 如何正确绑定数千个缓冲区
这个问题与粒子模拟课题有关。假设我需要一个全局结构,其中包括:
- 一个 3D 矩阵 (32*32*32) 的 uints(保存散列链表的标头 id)。
- 一个计数器,告诉我散列链表中的粒子数量。
- 散列的粒子链表。
第一个想法是为第一项使用 3D 纹理,第二项使用原子计数器缓冲区,第三项使用 SSB。
SSB 中的每个条目都是一个粒子加上一个 uint,其值指向同一体素中下一个粒子的位置。
这里没有什么神奇的。
现在,为了独立于空间(不绑定到唯一的立方空间),我必须能够将粒子从立方体传递到它周围的其他物体。由于我在 3D 空间中,27 个立方体(正面)作为物理计算的输入变量,还有 27 个立方体(背面)作为输出,因为我可以将一个粒子从一个立方体(正面)写入另一个(背面)覆盖空间的不同部分。
这导致我需要绑定 54 个纹理、54 个 SSB 和 54 个原子计数器。虽然这两个第一个可能不是问题(我的硬件限制都在 90 左右),但 ACB 绑定限制是 8。
假设有一个单独的 ACB 包含每个立方体的粒子数并不容易维护(我没有考虑很长时间,这可能是解决方案,但这不是这里的问题)。
语境 :
SSB 可以包含任何内容。因此,一种解决方案是将三个结构(标题矩阵、计数器和链表)连接到一个 SSB 中,这将是我的立方体超结构。
我需要在每次通过之前知道 SSB 中有多少粒子来执行正确的 glDispatchCompute() 调用。
问题 :
绑定 SSB 只是为了读取包含粒子数量的 uint 会不会很糟糕?
如果不是,那么访问计数的两种方法中的一种是否比另一种更好?为什么 ?
GLuint value;
//1st method
m_pFunctions->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
m_pFunctions->glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, OFFSET_TO_VALUE, sizeof(GLuint), &value);
m_pFunctions->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
//2nd method
m_pFunctions->glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, m_buffer, OFFSET_TO_VALUE, sizeof(GLuint));
m_pFunctions->glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(GLuint), &value);
m_pFunctions->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
如果没有,有没有好的方法或者我应该将计数器与 SSB 分开?