gpt4 book ai didi

opengl - 为什么 glBufferSubData 需要等到 VBO 没有被 glDrawElements 使用?

转载 作者:行者123 更新时间:2023-12-01 23:55:05 25 4
gpt4 key购买 nike

在 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com