我们使用缓冲区对象来减少CPU-GPU的复制操作,对于纹理缓冲区对象,我们可以将目标从顶点更改为缓冲区对象中的纹理。这里有纹理缓冲对象的其他优点吗?另外,它不允许过滤,这有什么不利之处吗?
答案 0 :(得分:11)
缓冲区纹理类似于1D纹理,但有一个后备缓冲区存储,它不是 纹理对象的一部分(与任何其他纹理对象相比),但是实现了绑定到TEXTURE_BUFFER
的实际缓冲区对象。使用缓冲区纹理有几个含义,AFAIK是一个无法映射到任何其他类型纹理的用例。
请注意,缓冲区纹理不是缓冲区对象 - 缓冲区纹理仅与使用glTexBuffer的缓冲区对象相关联。
相比之下,缓冲区纹理可能很大。表23.53及其核心OpenGL 4.4规范定义了 texels MAX_TEXTURE_BUFFER_SIZE
的最小最大值(即实现必须提供的最小值)。存储在缓冲区对象中的潜在纹素数量计算如下(如GL_ARB_texture_buffer_object中所示):
floor(<buffer_size> / (<components> * sizeof(<base_type>))
限制为MAX_TEXTURE_BUFFER_SIZE
的结果值是可寻址纹素的数量。
示例:强>
您有一个存储4MiB数据的缓冲区对象。您想要的是用于寻址RGBA纹素的缓冲区纹理,因此您可以选择内部格式RGBA8
。然后,可寻址的纹素数量为
floor(4MiB / (4 * sizeof(UNSIGNED_BYTE)) == 1024^2 texels == 2^20 texels
如果您的实现支持此编号,则可以处理缓冲区对象中的所有值。上面的内容并不令人印象深刻,可以简单地通过当前实现中的任何其他纹理来实现。但是,我写这个答案的机器支持2^28 == 268435456
纹素。
使用OpenGL 4.4(和4.3以及可能的早期4.x版本),MAX_TEXTURE_SIZE
每个1D纹理是2 ^ 16个纹素,因此缓冲纹理仍然可以是4倍大。在我的本地机器上,我可以分配2GiB缓冲区纹理(实际上甚至更大),但在使用RGBAF32
纹素时只能分配1GiB 1D纹理。
缓冲区纹理的用例是随机(和原子,如果需要)读/写访问(后者通过图像加载/存储)到着色器内的大型数据存储。是的,您可以在一个或多个块内对制服阵列进行随机读取 - 访问但如果您必须处理大量数据并且必须使用多个块,则会非常繁琐即便如此,在单个阶段的所有统一块中查看所有统一组件的最大组合大小(其中单个浮点组件的大小为4个字节),
MAX_(stage)_UNIFORM_BLOCKS *
MAX_UNIFORM_BLOCK_SIZE +
MAX_(stage)_UNIFORM_COMPONENTS * 4
在着色器阶段实际上没有足够的空间(取决于您的实现允许以上数字的大小)。
纹理和缓冲区纹理之间的一个重要区别是,数据存储作为常规缓冲区对象,可用于纹理根本不起作用的操作中。扩展提到:
使用缓冲区对象提供存储允许纹理数据 可以通过多种不同方式指定:通过缓冲区对象加载 (BufferData),直接CPU写入(MapBuffer),帧缓冲回读 (EXT_pixel_buffer_object扩展名)。还可以加载缓冲区对象 通过转换反馈(NV_transform_feedback扩展),捕获 选择由GL处理的顶点的变换属性。一些 这些机制不需要额外的数据副本,这将是 使用传统的类似TexImage的入口点时需要。
使用缓冲区纹理的含义是着色器内的查找只能通过texelFetch
完成。缓冲区纹理也不是mip-mapping,正如您已经提到的,在提取期间没有过滤。
附录:
自OpenGL 4.3以来,我们拥有所谓的a
Shader Storage Buffer。这些也提供对大型数据存储的随机(原子)读/写访问,但不需要使用texelFetch()
或图像加载/存储函数来访问,如缓冲区纹理的情况。使用缓冲区纹理还意味着必须处理gvec4
和texelFetch()
/ imageLoad()
的{{1}}返回值。一旦你想要使用结构(或其数组)并且你不想使用imageStore()
的多个实例或使用多个缓冲区纹理来实现某些东西,你就不会想到一些愚蠢的打包方案,这变得非常繁琐。类似。使用作为着色器存储访问的缓冲区,您可以简单地索引到数据存储,并直接从缓冲区中提取一些vec4
的一个或多个实例。
此外,由于它们与统一块非常相似,因此使用它们应该相当直接 - 如果您知道如何使用统一缓冲区,那么要学习如何使用着色器存储缓冲区还有很长的路要走。 。
同样值得浏览相应ARB extension的问题部分。
效果影响
Daniel Rakos几年前做了一些性能分析,既有comparison of uniform buffers and buffer textures,也有基于AMD的OpenCL编程指南信息的more general注释。现在有一个非常新的版本,专门针对OpenCL optimization AMD平台。
影响绩效的因素很多:
一如既往地担心性能:实施有效的方法,看看解决方案是否足够快,满足您的需求。否则,实施两种或多种解决问题的方法,配置文件,并进行比较。
此外,供应商特定指南可提供大量见解。上面提到的OpenCL用户和优化指南提供了一个高级架构视角和关于如何优化CL内核的特定提示 - 这些内容在开发着色器时也是相关的。
答案 1 :(得分:0)
我发现的一个用例是存储每个原始属性(在gl_PrimitiveID的帮助下在片段着色器中访问),同时仍然在索引网格中保持唯一的顶点。