Adreno OpenGL ES 3.1 介绍(3)

4.1.7单独的着色器对象

OpenGL ES中的关键对象类型之一是程序对象。 他们需要进行任何类型的draw call。 随着应用程序变得越来越复杂,现代OpenGL ES应用程序创建数百个程序对象的情况并不少见。

使用大量程序对象会带来一些成本:

  • 加载时间更长,因为每个程序对象都需要链接(或从外部存储)可用于绘图操作
  • 内存使用量增加

单独的着色器对象解决了这些问题。 现在,不需要昂贵的过程来构造程序对象并链接多个着色器对象。 而是可以将每个着色器对象制成一个着色器程序。 然后可以将着色器程序(每个着色器阶段一个)插入到称为管道对象的新对象中。 一旦将管道对象绑定到渲染上下文,只要没有其他程序对象被激活,就可以将其用于所有绘制调用。

在将着色器程序用于管道对象之前,需要先对其进行链接。 此过程类似于链接程序对象,但仅限于该特定的着色器阶段。 链接着色器程序后,也可以保存二进制表示形式,以在下次启动应用程序时重新使用它。

现在,使用着色器程序,应用程序可以即时构建管道对象。 由于以下原因,这比使用程序对象的旧方法要有效得多:

  • 管道对象不需要链接; 将着色器程序插入管道对象,然后开始发出绘图调用。
  • 应用程序通常使用许多程序对象,这些程序对象共有相同的顶点着色器,并由片段着色器进行区分。 使用单独的着色器对象,仅需要构建一次用于顶点着色器的着色器程序。 然后,可以根据需要在管道对象中重复使用相同的着色器程序多次。 这样可以节省链接器原本必须重复分析同一顶点着色器的时间。

着色器程序保存统一的状态信息。 如果使用单独的着色器对象方法,请分别为每个着色器程序配置统一值。 使用程序对象时不是这种情况。 统一状态以持久方式存储,因此不必担心在切换到其他管道对象时信息会丢失。 但是,如果在多个管线对象之间重用相同的顶点着色器程序,请记住更新所有需要针对不同管线配置采用不同值的统一。

4.1.8着色器存储缓冲区对象

在上一章中讨论了统一缓冲区。 这些是OpenGL ES 3.0中引入的更重要的功能之一。 但是,它们仍然有两个不幸的约束:

  • 在最坏的情况下,最大大小可以低至16 KB。 如果将数量乘以单个着色器阶段(12个)中可用的最坏情况下的最大统一块数,则总数为192KB。 通常这是足够的,但是它确实要求可以拆分数据,这并不总是可行的。
  • 统一缓冲区是只读的。

OpenGL ES 3.1中引入的SSBO解决了这两个问题。 保证它们支持最大227个字节(134,217,728字节)的数据块,并且它们可用于读取和写入操作。 实际的最大数据块大小取决于OpenGL ES的实现,并且可能超过上述值。 可以通过将pname参数设置为GL_MAX_SHADER_STORAGE_BLOCK_SIZE的glGetInteger64v进行检查。

在计算着色器阶段,所有OpenGL ES 3.1实现都必须支持SSBO。 其他着色器阶段的支持是可选的。

等同于统一块的SSBO被称为着色器存储块,具有以下主要区别:

  • 在OpenGL ES着色语言代码中,统一关键字被buffer替换。
  • 着色器存储块的最后一个成员可以是未调整大小的数组。 数组的大小是在运行时计算的,其方式是充分利用支持着色器存储块的数据存储的实际大小。
  • 在基于Adreno的平台上,访问统一块比着色器存储块要快得多。

着色器调用可以随时修改着色器存储块的内容。 注意内存访问的同步。 第4.1.4节讨论了一系列内存限定符关键字。 这些关键字可以为OpenGL ES实施提供有关变量将如何使用的宝贵提示。 可以在着色器存储块变量的声明中使用相同的关键字。 一个绝对必要的用例是,要对单个绘制调用执行的不同着色器阶段之间重复使用数据。 在某些情况下,需要使用内存屏障来确保不发生线程争用。 这些障碍可以在OpenGL ES着色器语言代码中或在OpenGL ES API级别上运行。 可以在此处找到更多详细信息:

在某些情况下,有可能避免使用上述同步技术的需要。 或者,使用原子函数。 原子函数是在OpenGL ES 3.1着色语言中引入的一组函数,这些函数将许多不同的原子操作应用于带符号或无符号整数类型的缓冲区或共享变量。

提供以下功能:

  • atomicAdd –将两个值加在一起
  • atomicAnd –对两个值执行按位AND运算
  • atomicCompSwap–如果变量内容的现有值与调用方在另一个参数中提供的值不同,则为该变量分配一个值
  • atomicExchange –将变量设置为新值并返回原始值
  • atomicMax –返回两个值中的最大值
  • atomicMin –返回两个值中的最小值
  • atomicOr –对两个值执行按位“或”运算
  • atomicXor –对两个值执行按位异或运算

以下是着色器存储缓冲区对象的一些示例用例:

  • 是计算着色器与外界交换数据的主要方式
  • 着色器可以使用它来访问大型数据集,这些数据集太大而无法适合纹理,例如顶点拉动技术
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值