Opengl es 如果在映射的缓冲区上调用glBufferData,会发生什么?

Opengl es 如果在映射的缓冲区上调用glBufferData,会发生什么?,opengl-es,opengl-es-3.0,Opengl Es,Opengl Es 3.0,如果在当前使用glMapBufferRange映射的缓冲区上调用glBufferData,会发生什么情况?我建议这是非法的,但我在规范中找不到任何内容: 这在规范中是非法的 好的,额外的挑战: 如果我们有上下文资源共享,并且缓冲区当前在线程A中与上下文A映射,那么上下文B上的线程B调用它上的glBufferData会怎么样 对于单个上下文场景,当调用glBufferData()时,现有缓冲区对象将被删除,该上下文中该资源的任何活动绑定都将被解除绑定,所有活动映射都将被删除。如果在同一上下文中在

如果在当前使用glMapBufferRange映射的缓冲区上调用glBufferData,会发生什么情况?我建议这是非法的,但我在规范中找不到任何内容:

这在规范中是非法的

好的,额外的挑战:


如果我们有上下文资源共享,并且缓冲区当前在线程A中与上下文A映射,那么上下文B上的线程B调用它上的glBufferData会怎么样

对于单个上下文场景,当调用
glBufferData()
时,现有缓冲区对象将被删除,该上下文中该资源的任何活动绑定都将被解除绑定,所有活动映射都将被删除。如果在同一上下文中在
glBufferData()
之后调用
glUnmapBuffer()
,则会出现
GL\u INVALID\u操作
错误,因为新版本的缓冲区的状态最初未映射

对于多上下文场景,它变得更加复杂。OpenGL ES定义了弱一致性状态管理模型(以避免对性能关键的调用路径的昂贵锁定要求)

  • 属于上下文的呈现状态(例如绑定信息、启用位)永远不会被另一个上下文修改(可以无锁实现)
  • 属于对象的资源状态(例如缓冲区、采样器、纹理)弱相干。一个上下文将立即看到它自己的更改,但只有在绑定资源时才会拾取另一个上下文编写的更改(只需要锁定绑定更改)
  • 资源数据有效负载根本不一致。如果要确保数据从一个上下文到另一个上下文可用,则必须在线程之间包含手动同步
调用
glMapBuffer()
的线程将创建缓冲区“版本1”的主状态的副本,包括缓冲区“已映射”的本地状态设置

线程B调用
glBufferData()
将创建缓冲区资源“版本2”的新版本,但这不会影响线程a保持的状态,该状态将继续反映在线程a(版本1)中绑定缓冲区时的状态

线程A调用
glUnmapBuffer()
将正常工作,因为它将取消映射缓冲区“版本1”(映射状态是线程A上下文的本地状态,这仍然表示缓冲区已“映射”)


请注意,线程A在线程B调用
glBufferData()
后看到的缓冲区的数据内容是不可预测的(可能是旧数据,也可能是新数据),这与数据完全不一致的设计是一致的。如果没有挂起的绘图操作,则驱动程序可以简单地重用缓冲区“版本1”所支持的内存,以包含为“版本2”上载的内容。如果要保证跨上下文的数据一致性,则需要手动同步(从概念上讲,这就像两个线程同时在同一缓冲区上调用
glBufferData()


我建议阅读OpenGL ES 3.2规范的第5章。

了解单个上下文场景,当调用
glBufferData()
时,现有的缓冲区对象将被删除,该上下文中该资源的任何活动绑定都将被解除绑定,所有活动映射都将被删除。如果在同一上下文中在
glBufferData()
之后调用
glUnmapBuffer()
,则会出现
GL\u INVALID\u操作
错误,因为新版本的缓冲区的状态最初未映射

对于多上下文场景,它变得更加复杂。OpenGL ES定义了弱一致性状态管理模型(以避免对性能关键的调用路径的昂贵锁定要求)

  • 属于上下文的呈现状态(例如绑定信息、启用位)永远不会被另一个上下文修改(可以无锁实现)
  • 属于对象的资源状态(例如缓冲区、采样器、纹理)弱相干。一个上下文将立即看到它自己的更改,但只有在绑定资源时才会拾取另一个上下文编写的更改(只需要锁定绑定更改)
  • 资源数据有效负载根本不一致。如果要确保数据从一个上下文到另一个上下文可用,则必须在线程之间包含手动同步
调用
glMapBuffer()
的线程将创建缓冲区“版本1”的主状态的副本,包括缓冲区“已映射”的本地状态设置

线程B调用
glBufferData()
将创建缓冲区资源“版本2”的新版本,但这不会影响线程a保持的状态,该状态将继续反映在线程a(版本1)中绑定缓冲区时的状态

线程A调用
glUnmapBuffer()
将正常工作,因为它将取消映射缓冲区“版本1”(映射状态是线程A上下文的本地状态,这仍然表示缓冲区已“映射”)


请注意,线程A在线程B调用
glBufferData()
后看到的缓冲区的数据内容是不可预测的(可能是旧数据,也可能是新数据),这与数据完全不一致的设计是一致的。如果没有挂起的绘图操作,则驱动程序可以简单地重用缓冲区“版本1”所支持的内存,以包含为“版本2”上载的内容。如果要保证跨上下文的数据一致性,则需要手动同步(从概念上讲,这就像两个线程同时在同一缓冲区上调用
glBufferData()


我建议您阅读OpenGL ES 3.2规范的第5章。

Ok,假设映射区域具有一定的大小,线程A调用glMapBufferRange。然后线程B调用glBufferData,