- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 OpenGL Insights 中,它说“OpenGL 驱动程序必须等待,因为使用了 VBO通过上一帧的 glDrawElements。
这让我很困惑。据我所知, glBufferSubData 会将数据复制到临时内存中,然后再传输到GPU。
那为什么司机还需要等呢?它可以只将传输命令附加到命令队列,延迟将数据传输到 GPU,直到 glDrawElements 完成,对吧?
----- 已添加 -------------------------------------- ----------------------------------
在 OpenGL Insights 中,它说:
http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-AsynchronousBufferTransfers.pdf (第 397 页)
However, when using glBufferSubData or glMapBuffer[Range], nothing in the API itself prevents us from modifying data that are currently used by the device for rendering the previous frame, as shown in Figure 28.3. Drivers have to avoid this problem by blocking the function until the desired data are not used anymore: this is called an implicit synchronization.
在 Valve 和 NVIDIA 的“Beyond Porting”中,它说:
http://media.steampowered.com/apps/steamdevdays/slides/beyondporting.pdf
MAP_UNSYNCHRONIZED
- Avoids an application-GPU sync point (a CPU-GPU sync point)
- But causes the Client and Server threads to serialize
- This forces all pending work in the server thread to complete
- It’s quite expensive (almost always needs to be avoided)
他们都指出glBufferSubData/glMapBuffer会阻塞应用线程,而不仅仅是驱动线程。
这是为什么?
最佳答案
没有规定说司机要等。它需要确保在使用旧内容的绘制调用完成执行之前缓冲区内容未被修改。它需要在 glBufferSubData()
调用返回之前使用调用者传入的数据。只要产生的行为是正确的,驱动程序中的任何实现都是公平的。
让我们用一个典型的伪调用序列来说明问题,标记调用以便稍后解释:
(1) glBindBuffer(buf)
(2) glBufferSubData(dataA)
(3) glDraw()
(4) glBufferSubData(dataB)
(5) glDraw()
游戏中的约束是:
dataA
指向的数据在调用 (2) 返回后不能被驱动程序访问。 OpenGL 规范允许调用者在调用返回后对数据做任何想做的事情,因此驱动程序需要在调用返回之前使用它。dataB
指向的数据在调用(4)返回后不能被驱动程序访问。buf
的内容为dataA
时,需要执行调用(3)产生的绘图命令。buf
的内容为dataB
时,需要执行调用(5)产生的绘图命令。由于 OpenGL 固有的异步特性,有趣的情况是调用 (4)。假设此时 dataA
已存储在 buf
中,调用 (3) 的绘制命令已排队等待 GPU 执行。但我们还不能依赖 GPU 执行该绘制命令。所以我们不能将 dataB
存储在 buf
中,因为挂起的绘图命令必须由 GPU 执行,而 dataA
仍存储在 中>缓冲区
。但是我们无法在消费 dataB
之前从调用中返回。
有多种方法可以处理这种情况。蛮力解决方案是简单地阻止调用 (4) 的执行,直到 GPU 完成调用 (3) 的绘制命令。这肯定会起作用,但可能会产生非常糟糕的性能影响。因为我们在提交新工作之前等到 GPU 完成工作,所以 GPU 可能会暂时闲置。这通常被称为管道中的“气泡”,是非常不受欢迎的。最重要的是,在调用返回之前,应用程序也无法执行有用的工作。
解决此问题的最简单方法是让驱动程序在调用 (4) 中复制 dataB
,然后将此数据副本放入 buf
,在GPU 已完成调用 (3) 的绘图命令,但在执行调用 (5) 的绘图命令之前。缺点是它涉及额外的数据复制,但通常非常值得防止管道气泡。
关于opengl - 为什么 glBufferSubData 需要等到 VBO 没有被 glDrawElements 使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24220583/
我正在制作一个使用 lwjgl 动态呈现文本的系统。我有一个系统设置为自动生成纹理以用于渲染,图像确实有效。这就是问题所在。 我有这段代码来初始化 2 个 VBO 和一个 VAO,它们都设置为能够处理
我正在做一个渲染,我每帧多次调用 glBufferSubData。 这是我在代码中的做法: glBindBuffer(GL_ARRAY_BUFFER,_vboID); //Buffering
当尝试使用 glBufferSubData 访问 GL_ARRAY_BUFFER 到 128 字节缓冲区大小时,访问最多需要 200 微秒。相反,当使用 glBufferData 再次分配整个缓冲区时
我需要用新顶点更新我的网格。我这样创建了 VBO(最初创建时只有一个顶点): public Mesh(float[] vertex, int size) { texture = null;
移植来自 Superbible OpenGL 7th ed 的第 7 章实例渲染示例。并遇到函数 glBufferSubData 的问题 无论我对它做什么,它都不会接受数据。把它变成一个指针,一个字节
我注意到随着缓冲区大小的增加,更新 VBO 中的少量顶点变得非常缓慢。例如,当我更新时,比如说,512*512 缓冲区中的 2 个顶点比我更新整个 256*256 缓冲区时慢得多,尽管更新的数据量
我实际上正在使用 OpenGL 3.3 渲染引擎,确切地说,我正在尝试在我的场景中创建动态数量的灯光。 为此,我正在使用统一缓冲区对象 (UBO),当我尝试传递数据时遇到问题,而 UBO 将在具有不同
你好, 我正在尝试通过调用 glBufferSubData() 来更新 VBO 的一部分。当我从现有影子缓冲区的开头 (0) 更新时,没有问题,因为缓冲区从 0 开始读取。以下将从缓冲区读取 0 到
我正在尝试使用 vao 和 vbo 制作网格类。 首先我创建 vector 来保存要缓冲的数据: std::vector vertices; std::vector normals; std::vec
我正在使用实例化渲染来渲染大片草地,为此我使用了一个由大量 4x4 变换矩阵组成的实例化数组。 我在草叶上使用 LOD 算法,根据它们与相机的距离来确定渲染哪些叶子。为此,我将实例化数组更新为仅包含相
我正在尝试在 OpenGL 3.3 中渲染 Suzanne(来自 Blender),但缓冲区数据似乎不正确。我明白了: https://gyazo.com/ab82f9acb6854a49fccc52
我不太明白为什么这段代码对于 iOS 上的 GPU 很慢,但这段代码在 Windows 上运行良好,没有任何问题。 基本上我正在做的是我有一个大的动态顶点缓冲区(GL_STREAM_DRAW)并且我尝
为了更新我的统一缓冲区对象,我使用 glBufferSubData .使用速度更快吗glBufferSubData或 glMapBuffer与 glUnmapBuffer ? 最佳答案 关于glMap
我想让我的 VBO 移动,我想知道我是否应该使用 glBufferSubData 更新整个 VBO 的值,或者只使用已弃用的 glTranslatef 来移动我的东西. 如果我只是更新 VBO 中的值
似乎 glBufferSubData 在我的 glDrawArrays 调用之间覆盖或以某种方式破坏数据。我在 Windows 7 64 位系统中工作,使用适用于我的 Nvidia GeForce G
我正在开发一款基于图 block 的物理游戏,例如 Falling Sand Game。我目前正在为顶点使用静态 VBO,为与每种 block 类型关联的颜色使用动态 VBO。对于这种类型的游戏,颜色
我目前正在开发一款使用 Java 1.6 和 LWJGL 编写的 2d 自上而下 RPG。我在我的游戏中实现了 VBO 的使用,现在我维护其中两个:一个用于顶点数据,一个用于纹理坐标。 一切正常,只是
一段时间以来,我一直在减少这个段错误,这是我机器上的一个非常小的可重现示例(如下)。我有一种下沉的感觉,这是一个驱动程序错误,但我对 OpenGL 非常不熟悉,所以更有可能我只是做错了什么。 这是正确
我想在创建 VBO 后更新对象的顶点列表。我都看过 glBufferSubData和 glMapBuffer而且它们似乎都在做类似的事情,这意味着我现在不确定该使用哪一个。 我的伪工作流程是: Cre
在 OpenGL Insights 中,它说“OpenGL 驱动程序必须等待,因为使用了 VBO通过上一帧的 glDrawElements。 这让我很困惑。据我所知, glBufferSubData
我是一名优秀的程序员,十分优秀!